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.248 date: 2024/02/09 11:31:17
user: stefan
file: MessageNode.st directory: libcomp
module: stx stc-classLibrary: libcomp

Description:


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

copyright

COPYRIGHT (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.

Class protocol:

instance creation
o  receiver: recNode selector: selectorString

o  receiver: recNode selector: selectorString arg1: arg1Node arg2: arg2Node
return a new MessageNode for a message with 2 arguments

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
(comment from inherited method)
set linenumber - ignored here

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  childrenDo: 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
(comment from inherited method)
generate code for this statement - value not needed

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
ANSI compatibility - same as numArgs

o  collectBlocksInto: aCollection

o  containsReturn

o  isCascade

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

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

o  isMessageWithSelector: aStringOrSymbol
(comment from inherited method)
return true, if this is a node for a specific message expression

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



ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Tue, 10 Dec 2024 08:45:17 GMT