eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'MessageNode':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: MessageNode


Inheritance:

   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

Description:


node for parse-trees, representing message sends
This is a helper class for the compiler.


Class protocol:

instance creation
o  receiver: recNode selector: selectorString

o  receiver: recNode selector: selectorString arg1: arg1Node arg2: arg2Node

o  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.

o  receiver: recNode selector: selectorString arg: argNode

o  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.

o  receiver: recNode selector: selectorString args: anArray

o  receiver: recNode selector: selectorString args: argArray fold: folding

o  receiver: recNode selector: selectorString args: argArray lineno: lineNo
if sent to MessageNode (and not a concrete class), create concrete nodes


Instance protocol:

RBParser compatibility
o  buildSelectorString
for RBParser compat.

accessing
o  arg1

o  arg2

o  arg3

o  args

o  arguments

o  endCharPosition

o  endCharPosition: something

o  endLineNr

o  endLineNr: something

o  javaScriptSelector

o  lineNumber

o  lineNumber: num

o  lines

o  lines: something

o  receiver

o  receiver: r selector: s args: a lineno: l
create the symbol only, if the symbol is already known in the system.

o  selector

o  selector: s
create the symbol only, if the symbol is already known in the system.

o  selectorPartPositions

o  selectorPartPositions: aCollectionOfIntervals
Modified (format): / 20-03-2019 / 20:51:09 / Claus Gittinger

o  selectorPosition
return the value of the instance variable 'selectorPosition' (automatically generated)

o  selectorPosition: something
set the value of the instance variable 'selectorPosition' (automatically generated)

checks
o  checkCondition
check ifTrue/ifFalse for plausibility.
TODO: rewite to use lint/lint rules and apply them before accepting

o  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

o  checkIdentityCompare
check #== applied to Floats, Strings or Fractions
TODO: rewite to use lint/lint rules and apply them before accepting

o  checkInlinability
early check for possible inlinability.
TODO: rewite to use lint/lint rules and apply them before accepting

o  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
o  codeOn: aStream inBlock: b for: aCompiler

o  codeOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
most work is in checking for inlinable code here.

enumerating
o  allSubNodesDo: aBlock
evaluate aBlock for each subnode

o  messageSelectorsDo: aBlock
evaluate aBlock for each message-selector here and in subnodes

o  messagesDo: aBlock
evaluate aBlock for each message-node here and in subnodes

o  nodeDo: anEnumerator
helper for parse tree walking

o  variableNodesDo: aBlock
evaluate aBlock for each variable-node here and in subnodes

evaluation
o  evaluateForCascadeIn: anEnvironment
evaluate, but return the receiver expression's value,
not the message-send's value

o  evaluateIn: anEnvironment

o  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

o  evaluationSelector

optimized code generation
o  codeAndIfElseOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
generate code for (x and:[y]) ifxxx:[ ... ] ifyyy:[ ... ]

o  codeAndIfOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
generate code for (x and:[y]) ifxxx:[ ... ]

o  codeAndOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
generate code for (x and:[y])

o  codeBlockEvaluation: aBlock on: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
gen code to evaluate a block

o  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.

o  codeForCascadeOn: aStream inBlock: b for: aCompiler
like codeOn, but always leave the receiver instead of the result

o  codeForSideEffectOn: aStream inBlock: b for: aCompiler

o  codeForSimpleReturnOn: aStream inBlock: b lineNumber: lineNrOrNil for: aCompiler
for now:

o  codeIfElseOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
generate code for x ifxxx:[ ... ] yyy:[ ...]

o  codeIfNilNotNilOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
generate code for x ifNil:[ ... ] ifNotNil:[...]
or: x ifNil:const1 ifNotNil:const2

o  codeIfNilOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
generate code for x ifNil:[ ... ]

o  codeIfOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
generate code for x ifxxx:[ ... ]

o  codeOrIfElseOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
generate code for (x or:[y]) ifxxx:[ ... ] ifyyy:[ ... ]

o  codeOrIfOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
generate code for (x or:[y]) ifxxx:[ ... ]

o  codeOrOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
generate code for (x or:[y])

o  codeQuestOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
generate code for x ? y.
However, this is only done for non-send args.

o  codeRepeatOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
generate code for
[ ... ] repeat
and:
[ ... ] loop

o  codeSendOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
like code on, but assumes that receiver has already been
coded onto stack - needed for cascade

o  codeTimesRepeatOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
generate code for n timesRepeat:[ ... ]

o  codeToByDoOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
generate code for a to:b by:c do:[:arg | ... ]

o  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.

o  codeValueSendOn: aStream for: aCompiler
send #value to the top of the stack ...

o  codeWhileOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
generate code for
[...] whileXXX:[ ... ]
and also
[...] whileXXX

o  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)

o  optimizedConditionFor: aReceiver with: aByteCode for: aCompiler

o  tryFoldedIfOn: aStream inBlock: b valueNeeded: valueNeeded for: aCompiler
true ifFalse:[] - evaluates to nil.

printing & storing
o  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.

o  printWhileOn: aStream indent: i
special handling of whileTrue/whileFalse

queries
o  argumentCount
VisualAge/ANSI compatibility - same as numArgs

o  collectBlocksInto: aCollection

o  containsReturn

o  isCascade

o  numArgs

o  precedence

o  realReceiver

o  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
o  isMessage

visiting
o  acceptVisitor: aVisitor
Double dispatch back to the visitor, passing my type encoded in
the selector (visitor pattern)



ST/X 7.2.0.0; WebServer 1.670 at bd0aa1f87cdd.unknown:8081; Tue, 23 Apr 2024 22:43:22 GMT