Pharo's syntax highlighter

S
Shaping
Sat, Aug 6, 2022 2:53 AM

Are there any experts here on the Settings' Syntax Highlighter subsection
and associated parser classes that make the ASTs?  I have some
extensions/mods I would like to make to the highlighter.  Can someone
suggest which classes to study?

I'm alternating between improvement like this and porting my stuff from VW,
with Christian's help.  Thanks Christian.

Here's the issue sketching what I want to do in the highlighter:

https://github.com/pharo-project/pharo/issues/11505

Shaping

Are there any experts here on the Settings' Syntax Highlighter subsection and associated parser classes that make the ASTs? I have some extensions/mods I would like to make to the highlighter. Can someone suggest which classes to study? I'm alternating between improvement like this and porting my stuff from VW, with Christian's help. Thanks Christian. Here's the issue sketching what I want to do in the highlighter: https://github.com/pharo-project/pharo/issues/11505 Shaping
PM
Pierre Misse Chanabier
Sat, Aug 6, 2022 5:26 AM

I do not know the syntax highlighter, but I know the AST fairly well.
The first two points are fairly easy:

Color method temp variables and block parameter variables
differently. Currently they are identified too generally as just
#variables. They are therefore always the same color. Can someone
point me to the parser classes that extract these features?
Color differently Classes and other globals? I'm trying to find this
distinction as well in the parser classes. If someone familiar with
the parsing and related GUI classes can give me some pointers, I'll
do the work.
Let the user assign colors to the first 7 levels of parentheses and
first 7 levels of brackets.
  1. There is no differences in the AST about temporary / arguments
    declaration.
    They are both at the level of the sequence node of the method/block (the
    body).
    Thankfully we can ask for the parent and have a case for each.
    You'd have to modify visitTemporaryDeclarationNode:.

  2. There is no difference in the AST between classes / Globals.
    Because Classes are in fact Globals.
    You'd have to ask for the (self class environment classAt: aGlobal
    name)  ifNotNil: [ class behavior ] ifNil: [ global behavior ].

A quick look seem that the behavior of the syntax highlighter is in the
IconStyler class.
(again, don't know it, just checking this out quickly).

Pierre

On 8/6/2022 4:53 AM, Shaping wrote:

Are there any experts here on the Settings’ Syntax Highlighter
subsection and associated parser classes that make the ASTs?  I have
some extensions/mods I would like to make to the highlighter.   Can
someone suggest which classes to study?

I’m alternating between improvement like this and porting my stuff
from VW, with Christian’s help. Thanks Christian.

Here’s the issue sketching what I want to do in the highlighter:

https://github.com/pharo-project/pharo/issues/11505

Shaping

I do not know the syntax highlighter, but I know the AST fairly well. The first two points are fairly easy: * Color method temp variables and block parameter variables differently. Currently they are identified too generally as just #variables. They are therefore always the same color. Can someone point me to the parser classes that extract these features? * Color differently Classes and other globals? I'm trying to find this distinction as well in the parser classes. If someone familiar with the parsing and related GUI classes can give me some pointers, I'll do the work. * Let the user assign colors to the first 7 levels of parentheses and first 7 levels of brackets. 1) There is no differences in the AST about temporary / arguments declaration. They are both at the level of the sequence node of the method/block (the body). Thankfully we can ask for the parent and have a case for each. You'd have to modify visitTemporaryDeclarationNode:. 2) There is no difference in the AST between classes / Globals. Because Classes are in fact Globals. You'd have to ask for the (self class environment classAt: aGlobal name)  ifNotNil: [ class behavior ] ifNil: [ global behavior ]. A quick look seem that the behavior of the syntax highlighter is in the IconStyler class. (again, don't know it, just checking this out quickly). Pierre On 8/6/2022 4:53 AM, Shaping wrote: > > Are there any experts here on the Settings’ Syntax Highlighter > subsection and associated parser classes that make the ASTs?  I have > some extensions/mods I would like to make to the highlighter.   Can > someone suggest which classes to study? > > I’m alternating between improvement like this and porting my stuff > from VW, with Christian’s help. Thanks Christian. > > Here’s the issue sketching what I want to do in the highlighter: > > https://github.com/pharo-project/pharo/issues/11505 > > Shaping >
MD
Marcus Denker
Tue, Aug 16, 2022 12:08 PM

On 6 Aug 2022, at 07:26, Pierre Misse Chanabier pierre.misse-chanabier@inria.fr wrote:

I do not know the syntax highlighter, but I know the AST fairly well.
The first two points are fairly easy:

Color method temp variables and block parameter variables differently. Currently they are identified too generally as just #variables. They are therefore always the same color. Can someone point me to the parser classes that extract these features?

Color differently Classes and other globals? I'm trying to find this distinction as well in the parser classes. If someone familiar with the parsing and related GUI classes can give me some pointers, I'll do the work.

Let the user assign colors to the first 7 levels of parentheses and first 7 levels of brackets.

  1. There is no differences in the AST about temporary / arguments declaration.
    They are both at the level of the sequence node of the method/block (the body).
    Thankfully we can ask for the parent and have a case for each.
    You'd have to modify visitTemporaryDeclarationNode:.

  2. There is no difference in the AST between classes / Globals.
    Because Classes are in fact Globals.
    You'd have to ask for the (self class environment classAt: aGlobal name)  ifNotNil: [ class behavior ] ifNil: [ global behavior ].

This is true, but kid of not: the AST does not distinguish kind of variables, as this is not Grammar but “Semantics”. That is, every variables
use (definition, read, write) just gets one (new) instance of RBVariableNode.

But: we do name analysis for the AST. This means that the AST that you have in hand is always annotated with semantic information.

For Variables this means that every RBVariableNode instance has a “semantic variable” attached to it that models the Variable.

(See Hierarchy of the class “Variable”).

Here now we get what we expect: for e.g. a temp there is one instance or a temp variable, and all the instances of RBVariableNode that are about that variable
reference the one instance.

With this, we can actually distinguish all the kinds of variables. (we pushed this so far that actually the compiler just asks the variable to generate bytecode, for example).
For ease of use, we have added test methods to RBVariableNode lile isTempVariable, isClassVariable, isInstanceVariable and so on.

A quick look seem that the behavior of the syntax highlighter is in the IconStyler class.
(again, don't know it, just checking this out quickly).

The main part of the syntax highlighter is class SHRBTextStyler.

This is “just” a visitor on the AST (by including the trait TRBProgramNodeVisitor).

For example, the method called via the #visitVariableNode: method is this:

resolveStyleFor: aVariableNode
aVariableNode binding ifNil: [^#default].
aVariableNode isArgumentVariable ifTrue: [ ^#methodArg].
aVariableNode isTempVariable ifTrue: [ ^#tempVar].
aVariableNode isGlobalVariable ifTrue: [ ^#globalVar].
"here we should add support for #classVar"
aVariableNode isClassVariable ifTrue: [ ^#globalVar].
aVariableNode isInstanceVariable ifTrue: [ ^#instVar].
"for now we use temp variable here, we could now color them with their own color"
aVariableNode isWorkspaceVariable ifTrue: [ ^#tempVar].

(self class formatIncompleteIdentifiers and: [ aVariableNode hasIncompleteIdentifier ]) 
	ifTrue:[ ^#incompleteIdentifier] .
"Note: if formatIncompleteIdentifiers is true, a non-exisiting variable might be incomplete"
aVariableNode isUndeclaredVariable ifTrue: [ ^#undefinedIdentifier ].

^#invalid.

This shows that we, right now, do not distinguish globals from class variables, but all that  would be very easy to add, as the annotated AST has all that information.

(I always wanted to rewrite that method to just delegate to the aVariableNode and from there delatete to the Variable subclass and add a #styleSymbol method there, would make all that even simpler).

Marcus
> On 6 Aug 2022, at 07:26, Pierre Misse Chanabier <pierre.misse-chanabier@inria.fr> wrote: > > I do not know the syntax highlighter, but I know the AST fairly well. > The first two points are fairly easy: > > Color method temp variables and block parameter variables differently. Currently they are identified too generally as just #variables. They are therefore always the same color. Can someone point me to the parser classes that extract these features? > > Color differently Classes and other globals? I'm trying to find this distinction as well in the parser classes. If someone familiar with the parsing and related GUI classes can give me some pointers, I'll do the work. > > Let the user assign colors to the first 7 levels of parentheses and first 7 levels of brackets. > > > 1) There is no differences in the AST about temporary / arguments declaration. > They are both at the level of the sequence node of the method/block (the body). > Thankfully we can ask for the parent and have a case for each. > You'd have to modify visitTemporaryDeclarationNode:. > > 2) There is no difference in the AST between classes / Globals. > Because Classes are in fact Globals. > You'd have to ask for the (self class environment classAt: aGlobal name) ifNotNil: [ class behavior ] ifNil: [ global behavior ]. > This is true, but kid of not: the AST does not distinguish kind of variables, as this is not Grammar but “Semantics”. That is, every variables use (definition, read, write) just gets one (new) instance of RBVariableNode. But: we do name analysis for the AST. This means that the AST that you have in hand is always annotated with semantic information. For Variables this means that every RBVariableNode instance has a “semantic variable” attached to it that models the Variable. (See Hierarchy of the class “Variable”). Here now we get what we expect: for e.g. a temp there is *one* instance or a temp variable, and all the instances of RBVariableNode that are about that variable reference the one instance. With this, we can actually distinguish all the kinds of variables. (we pushed this so far that actually the compiler just asks the variable to generate bytecode, for example). For ease of use, we have added test methods to RBVariableNode lile isTempVariable, isClassVariable, isInstanceVariable and so on. > A quick look seem that the behavior of the syntax highlighter is in the IconStyler class. > (again, don't know it, just checking this out quickly). The main part of the syntax highlighter is class SHRBTextStyler. This is “just” a visitor on the AST (by including the trait TRBProgramNodeVisitor). For example, the method called via the #visitVariableNode: method is this: resolveStyleFor: aVariableNode aVariableNode binding ifNil: [^#default]. aVariableNode isArgumentVariable ifTrue: [ ^#methodArg]. aVariableNode isTempVariable ifTrue: [ ^#tempVar]. aVariableNode isGlobalVariable ifTrue: [ ^#globalVar]. "here we should add support for #classVar" aVariableNode isClassVariable ifTrue: [ ^#globalVar]. aVariableNode isInstanceVariable ifTrue: [ ^#instVar]. "for now we use temp variable here, we could now color them with their own color" aVariableNode isWorkspaceVariable ifTrue: [ ^#tempVar]. (self class formatIncompleteIdentifiers and: [ aVariableNode hasIncompleteIdentifier ]) ifTrue:[ ^#incompleteIdentifier] . "Note: if formatIncompleteIdentifiers is true, a non-exisiting variable might be incomplete" aVariableNode isUndeclaredVariable ifTrue: [ ^#undefinedIdentifier ]. ^#invalid. This shows that we, right now, do not distinguish globals from class variables, but all that would be very easy to add, as the annotated AST has all that information. (I always wanted to rewrite that method to just delegate to the aVariableNode and from there delatete to the Variable subclass and add a #styleSymbol method there, would make all that even simpler). Marcus