|
Class: MessageNode
Object
|
+--ParseNode
|
+--MessageNode
|
+--BinaryNode
|
+--CascadeNode
|
+--JavaScriptParser::FunctionCallNode
|
+--UnaryNode
- Package:
- stx:libcomp
- Category:
- System-Compiler-Support
- Version:
- rev:
1.234
date: 2019/08/11 12:19:37
- user: cg
- file: MessageNode.st directory: libcomp
- module: stx stc-classLibrary: libcomp
- Author:
- Claus Gittinger
node for parse-trees, representing message sends
This is a helper class for the compiler.
instance creation
-
receiver: recNode selector: selectorString
-
-
receiver: recNode selector: selectorString arg1: arg1Node arg2: arg2Node
-
-
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
-
-
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
-
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
-
-
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
-
VisualAge/ANSI compatibility - same as numArgs
-
collectBlocksInto: aCollection
-
-
containsReturn
-
-
isCascade
-
-
numArgs
-
-
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
-
visiting
-
acceptVisitor: aVisitor
-
Double dispatch back to the visitor, passing my type encoded in
the selector (visitor pattern)
|