Parser is used for both parsing and evaluating smalltalk expressions;
it first builds a parseTree which is then interpreted (evaluate) or
compiled. Compilation is done in the subclass ByteCodeCompiler and/or
the (planned) MachineCodeCompiler.
methods of main interest are:
Parser evaluateExpression:...
and:
Parser parseExpression:...
Parser parseMethod:...
there is protocol to parse complete methods, selector specs, body only etc.
Parser is also used to find the referenced/modified inst/classvars of
a method - this is done by sending parseXXX message to a parser and asking
the parser for referencedXVars or modifiedXVars (see SystemBrowser).
You can also use parsers for all kinds of other things (ChangesBrowser for
example analyzes the expressions in the changelist ...) by looking at the
parsers tree. (Although this is somewhat dangerous, since it exports the
compilers internals ... better style is to add specialized query methods here)
One instance of Parser is created to parse one method or expression - i.e.
its not suggested to reuse parsers.
Constant folding:
The parser has various modes for constant folding; by default, only numeric
expressions involving integers and floats are constant folded
(i.e. something like 'Float pi sin' or '1.5 + 0.3' will be reduced to a constant).
Constant folding can be turned off completely (setting FoldConstants to nil)
to ``secure folding'', which only folds constant numbers (#level1) or to #full.
In full mode, more constant expressions are folded (for example: '1.0 @ 1.0' is
reduced to a constant point), but the resulting code may not be compatible with other
smalltalk systems (consider the case, where the point is modified using #x: or #y: messages).
Therefore, this mode is a bit dangerous and disabled by default.
The current implementation, base upon a global constant-folding setting is somewhat stupid
and intermediate - a better solution would be to allow the optimization to be controlled
by a method-pragma, since it may make sense to disable optimization on a method level,
if it's known that the used constant objects are subject of modifications as described above.
Immutable arrays:
Immutable arrays are experimental and being evaluated.
Consider the case of a method returning '#(1 2 3 4)', and that array being modified
by some other method (using #at:put:). Since the array-return is actually a return of
a reference to the compiler created array, the next invokation of the method will
return the modified array. These are hard to find bugs.
By an option, the compiler can generate immutable arrays, which don't allow modification
of its elements. For clean code, you should enable this option during development.
As mentioned above, this is experimental. If it is reported to be a useful feature,
the immutable feature will be extended to strings, point-literals etc. in a future version
of st/x.
[Instance variables:]
classToCompileFor <Class> the class (or nil) we are compiling for
selfValue <any> value to use as self when interpreting
contextToEvaluateIn <Context> the context (or nil) when interpreting
selector <Symbol> the selector of the parsed method
(valid after parseMethodSpecification)
methodArgs internal
methodArgNames <Collection> the names of the arguments
(valid after parseMethodSpecification)
methodVars internal
methodVarNames <Collection> the names of the method locals
(valid after parseMethodBodyVarSpec)
tree <ParseTree> the parse tree - valid after parsing
currentBlock if currently parsing for a block
usedInstVars set of all accessed instances variables
(valid after parsing)
usedClassVars same for classVars
usedVars all used variables (inst, class & globals)
modifiedInstVars set of all modified instance variables
modifiedClassVars same for clasVars
localVarDefPosition <Integer> the character offset of the local variable
def. (i.e. the first '|' if any)
Not yet used - prepared for automatic add of
undefined variables
evalExitBlock internal for interpretation
selfNode <Node> cached one-and-only 'self' node
superNode <Node> cached one-and-only 'super' node
hasPrimitiveCode <Boolean> true, if it contains ST/X style primitive code
hasNonOptionalPrimitiveCode
<Boolean> true, if it contains ST/X style primitive code
which is NOT flagged by the OPTIONAL directive.
primitiveNr <Integer> the parsed ST-80 type primitive number (or nil)
logged
warnedUndefVars <Set> set of all variables which the parser has
already output a warning (to avoid multiple
warnings about the same variable)
[Class variables:]
PrevClass <Class> class, of which properties are
cached in:
PrevInstVarNames <Collection> instance variablenames of cached class
PrevClassVarNames <Collection> class variablenames of cached class
PrevClassInstVarNames <Collection> class instance variablenames of cached class
LazyCompilation <Boolean> EXPERIMENTAL: lazy compilation
ArraysAreImmutable <Boolean> if true, create array literals
as instances of ImmutableArray,
which cannot be stored into.
Default is false, for compatibility.
Can be turned on while developing
new code to make certain that side
effects are avoided.
StringsAreImmutable <Boolean> same as above for string literals
WarnST80Directives <Boolean> if true, give warnings about
ST-80 directives (resource defs)
which are ignored in st/x.
defaults to false.
FoldConstants <Symbol> controls how constant folding should be
done.
Can be one of:
nil - no constant folding
#level1 - numeric optimizations only
#level2 - secure optimizations only
#full - full folding
level1: arithmetic on constant numbers
level2: above PLUS array conversions with #asFloatArray,
#asDoubleArray, string concatenation
full: constant points.

turn on/off lazy compilation - return previous setting.
Actually this flag belongs into the ByteCodeCompiler subclass,
but it also controls the reporting of some errors here; therefore
its located here

collect known selectors with their spelling distances to aString;
return the nMax best suggestions. If the argument, aClassOrNil is not nil,
the message is assumed to be sent to instances of that class (i.e. offer
corrections from that hierarchy only).
soon OBSOLETE: to be moved to DWIM

soon OBSOLETE and moved to DWIM.
Collect known selectors with their spelling distances to aString;
return the nMax best suggestions. If the argument, aClassOrNil is not nil,
the message is assumed to be sent to instances of that class
(i.e. offer corrections from that hierarchy only).
If forCompletion isTrue, prefix sequences are preferred.
The way spelling distance is computed is a heuristic which works
well in real life (i.e. offer USEFUL suggestions)

collect known selectors with their spelling distances to aString;
return the N best suggestions. If the argument, aClassOrNil is not nil,
the message is assumed to be sent to instances of that class (i.e. offer
corrections from that hierarchy only).
soon OBSOLETE: to be moved to DWIM

return the result of evaluating aString,
The compile argument specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
No doIt entry is added to the change-file.
If the failBlock argument is non-nil, it is evaluated if an error occurs.

return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.

return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.
Finally, compile specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

return the result of evaluating aString,
errors are reported to requestor.
The compile argument specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

return the result of evaluating aString,
errors are reported to requestor. Allow access toanObject as self and to its instVars (used in the inspector).
The compile argument specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

return the result of evaluating the next expression from aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.
Finally, compile specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

given a lineNr in some method, return the containing BlockNode or nil.
The given lineNr must be within a block for this to work.
This is used by the debugger, to guess reverse from a lineNumber,
to the corresponding block, in order to find out the block's
variable names
(mhmh - all of this wasnt't needed, if blocks stored their characterPosition internally).
WARNING: sometimes, the block is not correctly identified, if multiple blocks
are in one line.

parse a method in a given class.
Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver, args, locals,
used selectors, modified instvars, referenced classvars etc.
The noErrors and noWarnings arguments specify if error and warning
messages should be sent to the Transcript or suppressed.

parse a method.
Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver, args, locals,
used selectors etc.
Error and warning messages are sent to the Transcript.

parse a method in a given class.
Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver, args, locals,
used selectors, modified instvars, referenced classvars etc.
Error and warning messages are sent to the Transcript.

parse a method in a given class.
Return a parser (if ok) or #Error (syntax).
The parser can be queried for selector, receiver, args, locals,
used selectors, modified instvars, referenced classvars etc.
The noErrors and noWarnings arguments specify if error and warning
messages should be sent to the Transcript or suppressed.

parse a method in a given class.
Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver, args, locals,
used selectors, modified instvars, referenced classvars etc.
The warnBoolean arguments specifies if warning
messages should be sent to the Transcript or suppressed.

This method is OBSOLETE, and left in for backward compatibility.

** This is an obsolete interface - do not use it (it may vanish in future versions) **

parse a methods selector, arg and var spec (i.e. locals);
Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver etc.
Error and warning messages are sent to the Transcript.
This method is OBSOLETE.

** This is an obsolete interface - do not use it (it may vanish in future versions) **

parse a methods selector, arg and var spec in a given class;
Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver, args and locals.
Error and warning messages are sent to the Transcript.
This method is OBSOLETE.

** This is an obsolete interface - do not use it (it may vanish in future versions) **

parse a methods selector, arg and var spec in a given class;
If parseBody is true, also parse the statements
(for primitives & resourceSpecs).
The noErrors and noWarnings arguments specify if error and warning
messages should be sent to the Transcript or suppressed.

Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver, args and locals

parse a methods selector, arg and var spec (i.e. locals);
Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver etc.
Like #parseMethodArgAndVarSpecification:, but does NOT
display error/warning messages on the transcript.

parse a methods selector, arg and var spec in a given class;
Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver, args and locals.
Like #parseMethodArgAndVarSpecification:in:, but does not
display error/warning messages on the transcript.

parse a method.
Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver, args, locals,
used selectors etc.
Like #parseMethod:, but warning/error messages are suppressed.

parse a method in a given class.
Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver, args, locals,
used selectors, modified instvars, referenced classvars etc.
Like #parseMethod:in:, but warning/error messages are suppressed.

parse a methods selector & arg spec for a given class;
Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver etc.
noErrors and noWarnings specify if error- and warningMessages are
to be output onto the Transcript.

parse a methods selector & arg specification;
Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver etc.
Like #parseMethodSpecification:, but does not display any error/warning Messages on the transcript.

parse a methods selector & arg spec for a given class;
Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver etc.
Like #parseMethodSpecification:in:, but does not display any error/warning Messages on the transcript.

parse an expression - return the selector.
Even malformed expressions
(such as missing receiver or missing arg) are parsed.
Used for the SystemBrowser's implementors/senders query-box initial text.
Returns nil if unparsable.

define varName as undeclared variable
(actually, it will be installed as a funny global named 'Undeclared:::<name>').
You can browse for methods with undeclareds by searching for global accesses
to 'Undeclared:::*' (or use the search-undeclared item in the launchers menu).

this removes the definition of varName from the declaration part i.e.
if the source was '... | foo bar baz |...'
deleting the var 'bar' changes the source to '... | foo baz |...'.
The code below tries to be somewhat smart w.r.t. spaces by
trying to remove the whiteSpace around the removed variable also.
However, this seems to not always work correctly

collect known selectors with their spelling distances to aString;
return the N best suggestions. If the argument, aClassOrNil is not nil,
the message is assumed to be sent to instances of that class (i.e. offer
corrections from that hierarchy only)

return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.
Finally, compile specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.
Finally, compile specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.
Finally, compile specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.
Finally, compile specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.
Finally, compile specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.
Finally, compile specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.
Finally, compile specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.
Finally, compile specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

If checkForEndOfInput is set, generate an error if EOF has not been reached
at the end of the expression.

return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.
Finally, compile specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.
Finally, compile specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.

parse a method in a given class.
Return a parser (if ok) or #Error (syntax).
The parser can be queried for selector, receiver, args, locals,
used selectors, modified instvars, referenced classvars etc.
The noErrors and noWarnings arguments specify if error and warning
messages should be sent to the Transcript or suppressed.

parse a method in a given class.
Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver, args, locals,
used selectors, modified instvars, referenced classvars etc.
The noErrors and noWarnings arguments specify if error and warning
messages should be sent to the Transcript or suppressed.

parse an array index expression; this is a squeak/stx extension.
foo[x] is syntactic sugar for 'foo at:x'
and foo[x] := expr is syntactic sugar for 'foo at:x put:expr';
with commas, foo[x , y] generates foo at:x at:y.
This syntax extension must be enabled in the parserFlags as
allowArrayIndexSyntaxExtension (disabled by default)

parse a keyword-expression without receiver - for the selector only.
Return the selector or nil (if it cannot be determined).
This is not used in normal parsing, but instead to extract the selector from a code fragment.
(for example, the system browsers 'implementors'-function uses this to extract a selector from
the selection)

parse a functionCall;
this is an st/x extension.
foo(x)
is syntactic sugar for
foo value:x
This syntax extension must be enabled in the parserFlags as
allowFunctionCallSyntaxForBlockEvaluation (disabled by default)

an experimental ST/X feature.
InlineObject as #{ name1: value1. ... nameN: valueN }
creates a literal object with an anon class which provides getter/setters on all
names and is preinitialized with valueI.
The initial #{ is supposed to be skipped and its position passed in as pos1.
Notice: the values must be literals too;
currently the JavaScript style (using expressions) is not supported.

parse a dolphin computed literal; return a node-tree, or raise an Error.
In dolphin, these are written as: ##( expression )
and create a literal constant for the expressions value.
Right now, only a subset is supported - Strings, ByteArrays and Characters.
WARNING: this is only supported to allow file-in of dolphin code.
Since stc cannot handle this (at the moment), you should rewrite the code
if you ever plan to stc-compile it into a shared library.
The question is still: how should stc ever be able to do this, as it cannot execute
smalltalk code; it could generate code to execute it at initialization time of the
generated code, but then, it is no longer a compile-time constant
(for example, generating a compilation-Date constant is then not possible...)

parse a squeak computed array literal; return a node-tree, or raise an Error.
In squeak, these are written as: { expr1 . expr2 . ... exprN )
and create a message to construct an Array containing the exprI values

parse an ST-80 type primitive as '< primitive: nr >';
(return primitive number or #Error)
or a Squeak-style primitive, as '< primitive: string >';
(return primitive name or #Error)
or a V'Age-style primitive, as '< primitive: identifier >';
(return primitive name or #Error)

Also, resource specs are parsed; the result is left (as side effect) in primitiveResource.
It is used to flag methods, for faster finding of used keyboard accelerators,
and to mark resource methods (image, menu or canvas resources).

return a collection with possible message selectors (valid after parsing).
Includes things known or possibly used with #perform: or in specs.
The returned collection is filled by heuristics, not sharp, exact