|
Class: MessageNode
Object
|
+--ParseNode
|
+--MessageNode
|
+--BinaryNode
|
+--CascadeNode
|
+--JavaScriptParser::FunctionCallNode
|
+--UnaryNode
- Package:
- stx:libcomp
- Category:
- System-Compiler-Support
- Version:
- rev:
1.248
date: 2024/02/09 11:31:17
- user: stefan
- file: MessageNode.st directory: libcomp
- module: stx stc-classLibrary: libcomp
node for parse-trees, representing message sends
This is a helper class for the compiler.
copyrightCOPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
instance creation
-
receiver: recNode selector: selectorString
-
-
receiver: recNode selector: selectorString arg1: arg1Node arg2: arg2Node
-
return a new MessageNode for a message with 2 arguments
-
receiver: recNode selector: selectorString arg1: argNode1 arg2: argNode2 fold: folding
-
This is just a demonstration - of how complex constants can be folded.
This was inspired by some discussion in c.l.s about enhancing the language - I prefer
enhancing the compiler ....
The following optimization will convert '#(...) with:#(...) collect:[...]' into an array constant,
allowing constant arrays of complex objects.
Notice: this method is normally disabled - its just a demo after all.
-
receiver: recNode selector: selectorString arg: argNode
-
-
receiver: recNode selector: selectorString arg: argNode fold: folding
-
The constant folding code can usually not optimize much
- this may change when some kind of constant/macro declaration is added to smalltalk,
so that constant classVars can be inlined.
-
receiver: recNode selector: selectorString args: anArray
-
-
receiver: recNode selector: selectorString args: argArray fold: folding
-
-
receiver: recNode selector: selectorString args: argArray lineno: lineNo
-
if sent to MessageNode (and not a concrete class), create concrete nodes
RBParser compatibility
-
buildSelectorString
-
for RBParser compat.
accessing
-
arg1
-
-
arg2
-
-
arg3
-
-
args
-
-
arguments
-
-
endCharPosition
-
-
endCharPosition: something
-
-
endLineNr
-
-
endLineNr: something
-
-
javaScriptSelector
-
-
lineNumber
-
-
lineNumber: num
-
(comment from inherited method)
set linenumber - ignored here
-
lines
-
-
lines: something
-
-
receiver
-
-
receiver: r selector: s args: a lineno: l
-
create the symbol only, if the symbol is already known in the system.
-
selector
-
-
selector: s
-
create the symbol only, if the symbol is already known in the system.
-
selectorPartPositions
-
-
selectorPartPositions: aCollectionOfIntervals
-
Modified (format): / 20-03-2019 / 20:51:09 / Claus Gittinger
-
selectorPosition
-
return the value of the instance variable 'selectorPosition' (automatically generated)
-
selectorPosition: something
-
set the value of the instance variable 'selectorPosition' (automatically generated)
checks
-
checkCondition
-
check ifTrue/ifFalse for plausibility.
TODO: rewite to use lint/lint rules and apply them before accepting
-
checkGlobalFromNameSpaceConflictFor: aNode
-
check if aNode is a local-nameSpace's variable,
which hides a global from Smalltalk with the same name.
This is especially bad for Error handle: do:...
TODO: rewite to use lint/lint rules and apply them before accepting
-
checkIdentityCompare
-
check #== applied to Floats, Strings or Fractions
TODO: rewite to use lint/lint rules and apply them before accepting
-
checkInlinability
-
early check for possible inlinability.
TODO: rewite to use lint/lint rules and apply them before accepting
-
plausibilityCheckIn: aParser
-
some useful checks applied when accepting in a browser.
TODO: rewite to use lint/lint rules and apply them before accepting
code generation
-
codeOn: aStream inBlock: b for: aCompiler
-
-
codeOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
most work is in checking for inlinable code here.
enumerating
-
allSubNodesDo: aBlock
-
evaluate aBlock for each subnode
-
childrenDo: aBlock
-
evaluate aBlock for each subnode
-
messageSelectorsDo: aBlock
-
evaluate aBlock for each message-selector here and in subnodes
-
messagesDo: aBlock
-
evaluate aBlock for each message-node here and in subnodes
-
nodeDo: anEnumerator
-
helper for parse tree walking
-
variableNodesDo: aBlock
-
evaluate aBlock for each variable-node here and in subnodes
evaluation
-
evaluateForCascadeIn: anEnvironment
-
evaluate, but return the receiver expression's value,
not the message-send's value
-
evaluateIn: anEnvironment
-
-
evaluateIn: anEnvironment forCascade: forCascade
-
evaluate the send (possibly recursively evaluating the args before)
if forCascade is true, return the receiver expression's value,
otherwise return the message-send's value
-
evaluationSelector
-
optimized code generation
-
codeAndIfElseOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for (x and:[y]) ifxxx:[ ... ] ifyyy:[ ... ]
-
codeAndIfOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for (x and:[y]) ifxxx:[ ... ]
-
codeAndOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for (x and:[y])
-
codeBlockEvaluation: aBlock on: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
gen code to evaluate a block
-
codeCaseOfOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
expr
caseOf: {
[val1] -> [ caseStats1 ].
[val2] -> [ caseStats2 ].
...
[valN] -> [ caseStatsN ].
}
otherwise: [
otherStats
].
also handles caseOf, without otherwise: arg.
Compiled as a nested if-statement.
-
codeForCascadeOn: aStream inBlock: b for: aCompiler
-
like codeOn, but always leave the receiver instead of the result
-
codeForSideEffectOn: aStream inBlock: b for: aCompiler
-
(comment from inherited method)
generate code for this statement - value not needed
-
codeForSimpleReturnOn: aStream inBlock: b lineNumber: lineNrOrNil for: aCompiler
-
for now:
-
codeIfElseOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for x ifxxx:[ ... ] yyy:[ ...]
-
codeIfNilNotNilOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for x ifNil:[ ... ] ifNotNil:[...]
or: x ifNil:const1 ifNotNil:const2
-
codeIfNilOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for x ifNil:[ ... ]
-
codeIfOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for x ifxxx:[ ... ]
-
codeOrIfElseOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for (x or:[y]) ifxxx:[ ... ] ifyyy:[ ... ]
-
codeOrIfOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for (x or:[y]) ifxxx:[ ... ]
-
codeOrOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for (x or:[y])
-
codeQuestOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for x ? y.
However, this is only done for non-send args.
-
codeRepeatOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for
[ ... ] repeat
and:
[ ... ] loop
-
codeSendOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
like code on, but assumes that receiver has already been
coded onto stack - needed for cascade
-
codeTimesRepeatOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for n timesRepeat:[ ... ]
-
codeToByDoOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for a to:b by:c do:[:arg | ... ]
-
codeToDoOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for n to:m do:[:unusedArg | ... ]
This MAY ONLY be called, if the receiver is known to be an integer
or float.
-
codeValueSendOn: aStream for: aCompiler
-
send #value to the top of the stack ...
-
codeWhileOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for
[...] whileXXX:[ ... ]
and also
[...] whileXXX
-
new_codeWhileOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
generate code for
[...] whileXXX:[ ... ]
and also
[...] whileXXX
This generates the check at the end and should generate better
code (only 1 conditional-branch at the end instead of 2 branches).
However, for now, it is disabled, since the JIT has special provisions
to detect loops and actually generates better machine code for the
old bytecode sequence ... (sigh)
-
optimizedConditionFor: aReceiver with: aByteCode for: aCompiler
-
-
tryFoldedIfOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
-
true ifFalse:[] - evaluates to nil.
printing & storing
-
printOn: aStream indent: i
-
(comment from inherited method)
append a user printed representation of the receiver to aStream.
The format is suitable for a human - not meant to be read back.
-
printWhileOn: aStream indent: i
-
special handling of whileTrue/whileFalse
queries
-
argumentCount
-
ANSI compatibility - same as numArgs
-
collectBlocksInto: aCollection
-
-
containsReturn
-
-
isCascade
-
-
numArgs
-
marked as obsolete by Stefan Vogel at 9-Feb-2024
** This is an obsolete interface - do not use it (it may vanish in future versions) **
-
precedence
-
-
realReceiver
-
-
withConstantValueDo: aBlock
-
return true, if this evaluates to a constant value
and evaluate aBlock with it.
Also return true, if the node can be evaluated at compile time.
Used for constant folding
testing
-
isMessage
-
-
isMessageWithSelector: aStringOrSymbol
-
(comment from inherited method)
return true, if this is a node for a specific message expression
visiting
-
acceptVisitor: aVisitor
-
Double dispatch back to the visitor, passing my type encoded in
the selector (visitor pattern)
|