--- a/MessageNode.st Sat Nov 18 17:59:14 1995 +0100
+++ b/MessageNode.st Thu Nov 23 03:15:59 1995 +0100
@@ -11,10 +11,10 @@
"
ParseNode subclass:#MessageNode
- instanceVariableNames:'receiver selector argArray lineNr'
- classVariableNames:''
- poolDictionaries:''
- category:'System-Compiler-Support'
+ instanceVariableNames:'receiver selector argArray lineNr'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'System-Compiler-Support'
!
!MessageNode class methodsFor:'documentation'!
@@ -33,14 +33,14 @@
"
!
-version
- ^ '$Header: /cvs/stx/stx/libcomp/MessageNode.st,v 1.31 1995-11-11 15:30:33 cg Exp $'
-!
-
documentation
"
node for parse-trees, representing message sends
"
+!
+
+version
+ ^ '$Header: /cvs/stx/stx/libcomp/MessageNode.st,v 1.32 1995-11-23 02:13:47 cg Exp $'
! !
!MessageNode class methodsFor:'instance creation'!
@@ -49,6 +49,52 @@
^ (self basicNew) receiver:recNode selector:selectorString args:nil lineno:0
!
+receiver:recNode selector:selectorString arg1:argNode1 arg2:argNode2 fold:folding
+ |result recVal argVal selector|
+
+ "
+ 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 a constant arrays of complex objects.
+
+ Notice: this method is normally disabled - its just a demo after all.
+ "
+ folding ifTrue:[
+ "do constant folding ..."
+ (recNode isConstant and:[argNode1 isConstant]) ifTrue:[
+ "check if we can do it ..."
+ selector := selectorString asSymbolIfInterned.
+ selector notNil ifTrue:[
+ recVal := recNode evaluate.
+ (recVal respondsTo:selector) ifTrue:[
+ "
+ we could do much more here - but then, we need a dependency from
+ the folded selectors method to the method we generate code for ...
+ limit optimizations to those that will never change
+ (or - if you change them - you will crash so bad ...)
+ "
+ argVal := argNode1 evaluate.
+ ((recVal isMemberOf:Array) and:[argVal isMemberOf:Array]) ifTrue:[
+ (selector == #with:collect:) ifTrue:[
+ (argNode2 isMemberOf:BlockNode) ifTrue:[
+ (SignalSet anySignal catch:[
+ result := recVal perform:selector with:argVal with:(argNode2 evaluate).
+ ]) ifTrue:[
+ ^ 'error in constant expression'
+ ].
+ ^ ConstantNode type:(ConstantNode typeOfConstant:result) value:result
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ].
+ ^ (self basicNew) receiver:recNode selector:selectorString args:(Array with:argNode1 with:argNode2) lineno:0
+!
+
receiver:recNode selector:selectorString arg:argNode
^ self receiver:recNode selector:selectorString arg:argNode fold:true
!
@@ -132,52 +178,6 @@
^ (self basicNew) receiver:recNode selector:selectorString args:(Array with:argNode) lineno:0
!
-receiver:recNode selector:selectorString arg1:argNode1 arg2:argNode2 fold:folding
- |result recVal argVal selector|
-
- "
- 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 a constant arrays of complex objects.
-
- Notice: this method is normally disabled - its just a demo after all.
- "
- folding ifTrue:[
- "do constant folding ..."
- (recNode isConstant and:[argNode1 isConstant]) ifTrue:[
- "check if we can do it ..."
- selector := selectorString asSymbolIfInterned.
- selector notNil ifTrue:[
- recVal := recNode evaluate.
- (recVal respondsTo:selector) ifTrue:[
- "
- we could do much more here - but then, we need a dependency from
- the folded selectors method to the method we generate code for ...
- limit optimizations to those that will never change
- (or - if you change them - you will crash so bad ...)
- "
- argVal := argNode1 evaluate.
- ((recVal isMemberOf:Array) and:[argVal isMemberOf:Array]) ifTrue:[
- (selector == #with:collect:) ifTrue:[
- (argNode2 isMemberOf:BlockNode) ifTrue:[
- (SignalSet anySignal catch:[
- result := recVal perform:selector with:argVal with:(argNode2 evaluate).
- ]) ifTrue:[
- ^ 'error in constant expression'
- ].
- ^ ConstantNode type:(ConstantNode typeOfConstant:result) value:result
- ]
- ]
- ]
- ]
- ]
- ]
- ].
- ^ (self basicNew) receiver:recNode selector:selectorString args:(Array with:argNode1 with:argNode2) lineno:0
-!
-
receiver:recNode selector:selectorString args:anArray
^ self receiver:recNode selector:selectorString args:anArray fold:true
!
@@ -205,45 +205,6 @@
"Modified: 3.9.1995 / 16:41:39 / claus"
! !
-!MessageNode methodsFor:'accessing'!
-
-receiver:r selector:s args:a lineno:l
- receiver := r.
- selector := s asSymbol.
- argArray := a.
- lineNr := l
-!
-
-receiver
- ^ receiver
-!
-
-selector
- ^ selector
-!
-
-args
- ^ argArray
-!
-
-arg1
- ^ argArray at:1
-!
-
-lineNumber
- ^ lineNr
-!
-
-lineNumber:num
- lineNr := num
-! !
-
-!MessageNode methodsFor:'queries'!
-
-isMessage
- ^ true
-! !
-
!MessageNode class methodsFor:'queries'!
hasLineNumber:sel
@@ -257,6 +218,27 @@
^ true
!
+isBuiltIn1ArgSelector:sel
+ "return true, if selector sel is built-in.
+ (i.e. there is a single bytecode for it)"
+
+ (sel == #at:) ifTrue:[^ true].
+ (sel == #value:) ifTrue:[^ true].
+ (sel == #bitAnd:) ifTrue:[^ true].
+ (sel == #bitOr:) ifTrue:[^ true].
+ (sel == #new:) ifTrue:[^ true].
+ (sel == #basicNew:) ifTrue:[^ true].
+ ^ false
+!
+
+isBuiltIn2ArgSelector:sel
+ "return true, if selector sel is built-in.
+ (i.e. there is a single bytecode for it)"
+
+ (sel == #at:put:) ifTrue:[^ true].
+ ^ false
+!
+
isBuiltInUnarySelector:sel
"return true, if unary selector sel is built-in.
(i.e. there is a single bytecode for it)"
@@ -280,115 +262,39 @@
(sel == #new) ifTrue:[^ true].
(sel == #basicNew) ifTrue:[^ true].
^ false
-!
-
-isBuiltIn1ArgSelector:sel
- "return true, if selector sel is built-in.
- (i.e. there is a single bytecode for it)"
-
- (sel == #at:) ifTrue:[^ true].
- (sel == #value:) ifTrue:[^ true].
- (sel == #bitAnd:) ifTrue:[^ true].
- (sel == #bitOr:) ifTrue:[^ true].
- (sel == #new:) ifTrue:[^ true].
- (sel == #basicNew:) ifTrue:[^ true].
- ^ false
-!
-
-isBuiltIn2ArgSelector:sel
- "return true, if selector sel is built-in.
- (i.e. there is a single bytecode for it)"
-
- (sel == #at:put:) ifTrue:[^ true].
- ^ false
! !
-!MessageNode methodsFor:'printing'!
-
-printOn:aStream indent:i
- |needParen selectorParts index index2 arg|
-
- (#(whileTrue: whileFalse:) includes:selector) ifTrue:[
- receiver isBlock ifTrue:[
- ^ self printWhileOn:aStream indent:i
- ].
- ].
+!MessageNode methodsFor:'accessing'!
- index := 1.
- selectorParts := OrderedCollection new.
- [index == 0] whileFalse:[
- index2 := selector indexOf:$: startingAt:index.
- index2 ~~ 0 ifTrue:[
- selectorParts add:(selector copyFrom:index to:index2).
- index2 := index2 + 1
- ].
- index := index2
- ].
+arg1
+ ^ argArray at:1
+!
- needParen := false.
- receiver isMessage ifTrue:[
- receiver isUnaryMessage ifFalse:[
- receiver isBinaryMessage ifFalse:[
- needParen := true
- ].
- ].
- ].
- needParen ifTrue:[
- aStream nextPutAll:'('
- ].
- receiver printOn:aStream indent:i.
- needParen ifTrue:[
- aStream nextPutAll:')'
- ].
+args
+ ^ argArray
+!
- 1 to:(argArray size) do:[:argIndex |
- aStream space.
- (selectorParts at:argIndex) printOn:aStream.
- aStream space.
- arg := argArray at:argIndex.
- needParen := false.
- arg isMessage ifTrue:[
- arg isBinaryMessage ifFalse:[
- arg isUnaryMessage ifFalse:[
- needParen := true
- ]
- ].
- ].
- needParen ifTrue:[
- aStream nextPutAll:'('
- ].
- arg printOn:aStream indent:i.
- needParen ifTrue:[
- aStream nextPutAll:') '
- ].
- ]
+lineNumber
+ ^ lineNr
!
-printWhileOn:aStream indent:i
- |needParen arg|
+lineNumber:num
+ lineNr := num
+!
- "special handling of whileTrue/whileFalse"
-
- aStream nextPutAll:'['.
- receiver statements printOn:aStream indent:i.
- aStream nextPutAll:'] whileTrue: '.
+receiver
+ ^ receiver
+!
- arg := argArray at:1.
- needParen := false.
- arg isMessage ifTrue:[
- arg isBinaryMessage ifFalse:[
- arg isUnaryMessage ifFalse:[
- needParen := true
- ]
- ].
- ].
- needParen ifTrue:[
- aStream nextPutAll:'('
- ].
- arg printOn:aStream indent:i.
- needParen ifTrue:[
- aStream nextPutAll:') '
- ].
+receiver:r selector:s args:a lineno:l
+ receiver := r.
+ selector := s asSymbol.
+ argArray := a.
+ lineNr := l
+!
+
+selector
+ ^ selector
! !
!MessageNode methodsFor:'checks'!
@@ -481,238 +387,8 @@
^ nil
! !
-!MessageNode methodsFor:'evaluating'!
-
-evaluate
- |r nargs argValueArray class|
-
- receiver isSuper ifTrue:[
- r := receiver value.
- receiver isHere ifTrue:[
- class := receiver definingClass.
- ] ifFalse:[
- class := receiver definingClass superclass.
- ].
- argArray notNil ifTrue:[
- argValueArray := argArray collect:[:arg | arg evaluate].
- ] ifFalse:[
- argValueArray := #()
- ].
- ^ r perform:selector inClass:class withArguments:argValueArray
- ].
-
-
- argArray isNil ifTrue:[
- ^ (receiver evaluate) perform:selector
- ].
- nargs := argArray size.
- (nargs == 1) ifTrue:[
- ^ (receiver evaluate) perform:selector with:(argArray at:1) evaluate
- ].
- (nargs == 2) ifTrue:[
- ^ (receiver evaluate) perform:selector
- with:(argArray at:1) evaluate
- with:(argArray at:2) evaluate
- ].
- (nargs == 3) ifTrue:[
- ^ (receiver evaluate) perform:selector
- with:(argArray at:1) evaluate
- with:(argArray at:2) evaluate
- with:(argArray at:3) evaluate
- ].
- r := receiver evaluate.
- argValueArray := argArray collect:[:arg | arg evaluate].
- ^ r perform:selector withArguments:argValueArray
-!
-
-evaluateForCascade
- |r nargs argValueArray class|
-
- receiver isSuper ifTrue:[
- r := receiver value.
- class := receiver definingClass.
- receiver isHere ifFalse:[
- class := class superclass.
- ].
- argArray notNil ifTrue:[
- argValueArray := argArray collect:[:arg | arg evaluate].
- ] ifFalse:[
- argValueArray := #()
- ].
- r perform:selector inClass:class withArguments:argValueArray.
- ^ r
- ].
-
- r := receiver evaluate.
- argArray isNil ifTrue:[
- r perform:selector.
- ^ r
- ].
- nargs := argArray size.
- (nargs == 1) ifTrue:[
- r perform:selector with:(argArray at:1) evaluate.
- ^ r
- ].
- (nargs == 2) ifTrue:[
- r perform:selector with:(argArray at:1) evaluate
- with:(argArray at:2) evaluate.
- ^ r
- ].
- (nargs == 3) ifTrue:[
- r perform:selector with:(argArray at:1) evaluate
- with:(argArray at:2) evaluate
- with:(argArray at:3) evaluate.
- ^ r
- ].
- argValueArray := argArray collect:[:arg | arg evaluate].
- r perform:selector withArguments:argValueArray.
- ^ r
-! !
-
!MessageNode methodsFor:'code generation'!
-codeForSideEffectOn:aStream inBlock:b for:aCompiler
- self codeOn:aStream inBlock:b valueNeeded:false for:aCompiler
-!
-
-codeOn:aStream inBlock:b for:aCompiler
- self codeOn:aStream inBlock:b valueNeeded:true for:aCompiler
-!
-
-optimizedConditionFor:aReceiver with:aByteCode
- |rec sel|
-
- rec := aReceiver.
- (rec isBlock) ifTrue:[
- rec statements nextStatement isNil ifTrue:[
- rec := rec statements expression
- ]
- ].
- (rec isUnaryMessage) ifTrue:[
- sel := rec selector.
- (sel == #isNil) ifTrue:[
- "/
- "/ isNil trueJmp -> nilJump
- "/ isNil falseJmp -> notNilJump
- "/
- (aByteCode == #trueJump) ifTrue:[^ #nilJump].
- (aByteCode == #falseJump) ifTrue:[^ #notNilJump]
- ].
- (sel == #notNil) ifTrue:[
- "/
- "/ notNil trueJmp -> notNilJump
- "/ notNil falseJmp -> nilJump
- "/
- (aByteCode == #trueJump) ifTrue:[^ #notNilJump].
- (aByteCode == #falseJump) ifTrue:[^ #nilJump]
- ].
- (sel == #not) ifTrue:[
- "/
- "/ not trueJmp -> falseJump
- "/ not falseJmp -> trueJump
- "/
- (aByteCode == #trueJump) ifTrue:[^ #falseJump].
- (aByteCode == #falseJump) ifTrue:[^ #trueJump]
- ].
- ^ nil
- ].
- (rec isBinaryMessage) ifTrue:[
- sel := rec selector.
- rec arg1 isConstant ifTrue:[
- (rec arg1 value == 0) ifTrue:[
- "/
- "/ ==0 trueJmp -> zeroJump
- "/ ==0 falseJmp -> notZeroJump
- "/
- (sel == #==) ifTrue:[
- (aByteCode == #trueJump) ifTrue:[^ #zeroJump].
- (aByteCode == #falseJump) ifTrue:[^ #notZeroJump]
- ].
- "/
- "/ ~~0 trueJmp -> notZeroJump
- "/ ~~0 falseJmp -> zeroJump
- "/
- (sel == #~~) ifTrue:[
- (aByteCode == #falseJump) ifTrue:[^ #zeroJump].
- (aByteCode == #trueJump) ifTrue:[^ #notZeroJump]
- ].
- ^ nil
- ]
- ].
- (sel == #==) ifTrue:[
- "/
- "/ == trueJmp -> eqJump
- "/ == falseJmp -> notEqJump
- "/
- (aByteCode == #trueJump) ifTrue:[^ #eqJump].
- (aByteCode == #falseJump) ifTrue:[^ #notEqJump]
- ].
- (sel == #~~) ifTrue:[
- "/
- "/ ~~ trueJmp -> notEqJump
- "/ ~~ falseJmp -> eqJump
- "/
- (aByteCode == #falseJump) ifTrue:[^ #eqJump].
- (aByteCode == #trueJump) ifTrue:[^ #notEqJump]
- ]
- ].
- ^ nil
-!
-
-codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
- "generate code for [...] whilexxx:[ ... ]"
-
- |pos pos2 theReceiver theArg theByteCode optByteCode|
-
- (selector == #whileTrue:) ifTrue:[
- theByteCode := #falseJump
- ] ifFalse:[
- theByteCode := #trueJump
- ].
-
- theReceiver := receiver.
- optByteCode := self optimizedConditionFor:theReceiver with:theByteCode.
- optByteCode notNil ifTrue:[
- ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
- theArg := receiver statements expression arg1
- ].
- theReceiver := receiver statements expression receiver.
- theByteCode := optByteCode
- ].
-
-"/ OLD:
-"/ valueNeeded ifTrue:[aStream nextPut:#pushNil].
-"/
- pos := aStream position.
- optByteCode notNil ifTrue:[
- theReceiver codeOn:aStream inBlock:b for:aCompiler.
- theArg notNil ifTrue:[
- theArg codeOn:aStream inBlock:b for:aCompiler
- ]
- ] ifFalse:[
- theReceiver codeInlineOn:aStream inBlock:b for:aCompiler
- ].
-
- (lineNr between:1 and:255) ifTrue:[
- aStream nextPut:#lineno; nextPut:lineNr.
- ].
-
- aStream nextPut:theByteCode.
- pos2 := aStream position.
- aStream nextPut:0.
-"/ OLD:
-"/ valueNeeded ifTrue:[aStream nextPut:#drop].
-"/
-"/ OLD:
-"/ (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-"/ NEW:
- (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:false for:aCompiler.
- aStream nextPut:#jump; nextPut:pos.
- (aStream contents) at:pos2 put:(aStream position).
-"/ NEW:
- valueNeeded ifTrue:[aStream nextPut:#pushNil].
-!
-
XXcodeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
"generate code for [...] whilexxx:[ ... ]"
@@ -758,27 +434,182 @@
(aStream contents) at:pos2 put:(aStream position).
!
-codeTimesRepeatOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
- "generate code for n timesRepeat:[ ... ]"
+codeAndIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
+ "generate code for (x and:[y]) ifxxx:[ ... ]"
+
+ |theByteCode optByteCode theReceiver theArg pos1 pos2 pos3 code here jmp|
+
+
+ theByteCode := #falseJump.
+ theReceiver := receiver receiver.
- |pos pos2 theReceiver|
-
- theReceiver := receiver.
+ optByteCode := self optimizedConditionFor:theReceiver
+ with:theByteCode.
+ optByteCode notNil ifTrue:[
+ ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
+ theArg := theReceiver arg1
+ ].
+ theReceiver := theReceiver receiver.
+ theByteCode := optByteCode
+ ].
theReceiver codeOn:aStream inBlock:b for:aCompiler.
- valueNeeded ifTrue:[aStream nextPut:#dup].
+ theArg notNil ifTrue:[
+ theArg codeOn:aStream inBlock:b for:aCompiler
+ ].
+ aStream nextPut:theByteCode.
+ pos1 := aStream position.
+ aStream nextPut:0.
- pos := aStream position.
-"/ aStream nextPut:#dup; nextPut:#push0; nextPut:#>; nextPut:lineNr; nextPut:#falseJump.
-"/ aStream nextPut:#dup; nextPut:#gt0; nextPut:lineNr; nextPut:#falseJump.
- aStream nextPut:#pushgt0; nextPut:lineNr; nextPut:#falseJump.
+ theReceiver := receiver arg1.
+ theReceiver codeInlineOn:aStream inBlock:b for:aCompiler.
+ (selector == #ifTrue:) ifTrue:[
+ jmp := #falseJump
+ ] ifFalse:[
+ jmp := #trueJump
+ ].
+ aStream nextPut:jmp.
pos2 := aStream position.
aStream nextPut:0.
- (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:false for:aCompiler.
- aStream nextPut:#minus1; nextPut:lineNr; nextPut:#jump; nextPut:pos.
+ code := aStream contents.
+ (selector == #ifFalse:) ifTrue:[
+ code at:pos1 put:(aStream position)
+ ].
+ (argArray at: 1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+
+ valueNeeded ifTrue:[
+ aStream nextPut:#jump.
+ pos3 := aStream position.
+ aStream nextPut:0.
+ here := aStream position.
+ (selector == #ifTrue:) ifTrue:[
+ code at:pos1 put:here
+ ].
+ code at:pos2 put:here.
+ aStream nextPut:#pushNil.
+ code at:pos3 put:(aStream position)
+ ] ifFalse:[
+ here := aStream position.
+ (selector == #ifTrue:) ifTrue:[
+ code at:pos1 put:here
+ ].
+ code at:pos2 put:here
+ ]
+!
+
+codeAndOrOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
+ "generate code for x and/or:[y] - but not in an if"
+
+ |pos theReceiver theByteCode|
+
+self halt.
+ theReceiver := receiver.
+ (selector == #and:) ifTrue:[
+ theByteCode := #falseJump
+ ] ifFalse:[
+ theByteCode := #trueJump
+ ].
+"
+ (self canOptimizeConditionFor:receiver) ifTrue:[
+ theByteCode := self optimizedConditionFor:theReceiver
+ with:theByteCode.
+ theReceiver := theReceiver receiver
+ ].
+"
+ theReceiver codeOn:aStream inBlock:b for:aCompiler.
+ aStream nextPut:theByteCode.
+ pos := aStream position.
+ aStream nextPut:0.
+ (argArray at: 1) codeInlineOn:aStream inBlock:b for:aCompiler.
+ (aStream contents) at:pos put:(aStream position).
+ valueNeeded ifFalse:[aStream nextPut:#drop]
+!
+
+codeForCascadeOn:aStream inBlock:b for:aCompiler
+ "like codeOn, but always leave the receiver instead of the result"
+
+ |nargs isBuiltIn code litIndex|
+
+ argArray isNil ifTrue:[
+ nargs := 0
+ ] ifFalse:[
+ nargs := argArray size
+ ].
+
+ isBuiltIn := false.
- (aStream contents) at:pos2 put:(aStream position).
- aStream nextPut:#drop.
+ (nargs == 0) ifTrue:[
+ isBuiltIn := self class isBuiltInUnarySelector:selector
+ ].
+ (nargs == 1) ifTrue:[
+ isBuiltIn := self class isBuiltIn1ArgSelector:selector
+ ].
+ (nargs == 2) ifTrue:[
+ isBuiltIn := self class isBuiltIn2ArgSelector:selector
+ ].
+
+ receiver codeOn:aStream inBlock:b for:aCompiler.
+ aStream nextPut:#dup.
+
+ "can we use a send-bytecode ?"
+ isBuiltIn ifTrue:[
+ receiver isSuper ifFalse:[
+ (nargs > 0) ifTrue:[
+ (argArray at:1) codeOn:aStream inBlock:b for:aCompiler.
+ (nargs > 1) ifTrue:[
+ (argArray at:2) codeOn:aStream inBlock:b for:aCompiler
+ ]
+ ].
+ aStream nextPut:selector.
+ (self class hasLineNumber:selector) ifTrue:[
+ aStream nextPut:lineNr.
+ ].
+ aStream nextPut:#drop.
+ ^ self
+ ]
+ ].
+
+ "no - generate a send"
+ argArray notNil ifTrue:[
+ argArray do:[:arg |
+ arg codeOn:aStream inBlock:b for:aCompiler
+ ]
+ ].
+ litIndex := aCompiler addLiteral:selector.
+ litIndex <= 255 ifTrue:[
+ receiver isSuper ifTrue:[
+ receiver isHere ifTrue:[
+ code := #hereSend
+ ] ifFalse:[
+ code := #superSend.
+ ].
+ aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:nil; nextPut:#drop.
+ ^ self
+ ].
+ (nargs <= 3) ifTrue:[
+ code := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3) at:(nargs+1).
+ aStream nextPut:code; nextPut:lineNr; nextPut:litIndex.
+ ^ self
+ ].
+
+ aStream nextPut:#sendDrop; nextPut:lineNr; nextPut:litIndex; nextPut:nargs.
+ ^ self
+ ].
+ "need 16bit litIndex"
+ receiver isSuper ifTrue:[
+ receiver isHere ifTrue:[
+ code := #hereSendL
+ ] ifFalse:[
+ code := #superSendL.
+ ].
+ aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:nil; nextPut:#drop.
+ ^ self
+ ].
+ aStream nextPut:#sendDropL; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs
+!
+
+codeForSideEffectOn:aStream inBlock:b for:aCompiler
+ self codeOn:aStream inBlock:b valueNeeded:false for:aCompiler
!
codeIfElseOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
@@ -915,183 +746,8 @@
]
!
-codeAndIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
- "generate code for (x and:[y]) ifxxx:[ ... ]"
-
- |theByteCode optByteCode theReceiver theArg pos1 pos2 pos3 code here jmp|
-
-
- theByteCode := #falseJump.
- theReceiver := receiver receiver.
-
- optByteCode := self optimizedConditionFor:theReceiver
- with:theByteCode.
- optByteCode notNil ifTrue:[
- ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
- theArg := theReceiver arg1
- ].
- theReceiver := theReceiver receiver.
- theByteCode := optByteCode
- ].
- theReceiver codeOn:aStream inBlock:b for:aCompiler.
- theArg notNil ifTrue:[
- theArg codeOn:aStream inBlock:b for:aCompiler
- ].
- aStream nextPut:theByteCode.
- pos1 := aStream position.
- aStream nextPut:0.
-
- theReceiver := receiver arg1.
- theReceiver codeInlineOn:aStream inBlock:b for:aCompiler.
- (selector == #ifTrue:) ifTrue:[
- jmp := #falseJump
- ] ifFalse:[
- jmp := #trueJump
- ].
- aStream nextPut:jmp.
- pos2 := aStream position.
- aStream nextPut:0.
-
- code := aStream contents.
- (selector == #ifFalse:) ifTrue:[
- code at:pos1 put:(aStream position)
- ].
- (argArray at: 1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-
- valueNeeded ifTrue:[
- aStream nextPut:#jump.
- pos3 := aStream position.
- aStream nextPut:0.
- here := aStream position.
- (selector == #ifTrue:) ifTrue:[
- code at:pos1 put:here
- ].
- code at:pos2 put:here.
- aStream nextPut:#pushNil.
- code at:pos3 put:(aStream position)
- ] ifFalse:[
- here := aStream position.
- (selector == #ifTrue:) ifTrue:[
- code at:pos1 put:here
- ].
- code at:pos2 put:here
- ]
-!
-
-codeOrIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
- "generate code for (x or:[y]) ifxxx:[ ... ]"
-
- |theByteCode optByteCode theReceiver theArg pos1 pos2 pos3 code here jmp|
-
- theByteCode := #trueJump.
- theReceiver := receiver receiver.
-
- optByteCode := self optimizedConditionFor:theReceiver with:theByteCode.
- optByteCode notNil ifTrue:[
- ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
- theArg := theReceiver arg1
- ].
- theReceiver := theReceiver receiver.
- theByteCode := optByteCode
- ].
- theReceiver codeOn:aStream inBlock:b for:aCompiler.
- theArg notNil ifTrue:[
- theArg codeOn:aStream inBlock:b for:aCompiler
- ].
- aStream nextPut:theByteCode.
- pos1 := aStream position.
- aStream nextPut:0.
-
-
- theReceiver := receiver arg1.
-
-"new:"
- (selector == #ifTrue:) ifTrue:[
- theByteCode := #falseJump
- ] ifFalse:[
- theByteCode := #trueJump
- ].
- optByteCode := self optimizedConditionFor:theReceiver with:theByteCode.
- optByteCode notNil ifTrue:[
- theReceiver isBlock ifTrue:[
- theReceiver := theReceiver statements expression
- ].
- ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
- theArg := theReceiver arg1
- ].
- theReceiver := theReceiver receiver.
- theByteCode := optByteCode.
-
- theReceiver codeOn:aStream inBlock:b for:aCompiler.
- theArg notNil ifTrue:[
- theArg codeOn:aStream inBlock:b for:aCompiler
- ].
- aStream nextPut:theByteCode.
-
- ] ifFalse:[
-"org"
- theReceiver codeInlineOn:aStream inBlock:b for:aCompiler.
- (selector == #ifTrue:) ifTrue:[
- jmp := #falseJump
- ] ifFalse:[
- jmp := #trueJump
- ].
- aStream nextPut:jmp
- ].
- pos2 := aStream position.
- aStream nextPut:0.
- (selector == #ifTrue:) ifTrue:[
- (aStream contents) at:pos1 put:(aStream position)
- ].
- (argArray at: 1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
-
- code := aStream contents.
- valueNeeded ifTrue:[
- aStream nextPut:#jump.
- pos3 := aStream position.
- aStream nextPut:0.
- here := aStream position.
- (selector == #ifFalse:) ifTrue:[
- code at:pos1 put:here
- ].
- code at:pos2 put:here.
- aStream nextPut:#pushNil.
- code at:pos3 put:(aStream position)
- ] ifFalse:[
- here := aStream position.
- (selector == #ifFalse:) ifTrue:[
- code at:pos1 put:here
- ].
- code at:pos2 put:here
- ]
-!
-
-codeAndOrOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
- "generate code for x and/or:[y] - but not in an if"
-
- |pos theReceiver theByteCode|
-
-self halt.
- theReceiver := receiver.
- (selector == #and:) ifTrue:[
- theByteCode := #falseJump
- ] ifFalse:[
- theByteCode := #trueJump
- ].
-"
- (self canOptimizeConditionFor:receiver) ifTrue:[
- theByteCode := self optimizedConditionFor:theReceiver
- with:theByteCode.
- theReceiver := theReceiver receiver
- ].
-"
- theReceiver codeOn:aStream inBlock:b for:aCompiler.
- aStream nextPut:theByteCode.
- pos := aStream position.
- aStream nextPut:0.
- (argArray at: 1) codeInlineOn:aStream inBlock:b for:aCompiler.
- (aStream contents) at:pos put:(aStream position).
- valueNeeded ifFalse:[aStream nextPut:#drop]
+codeOn:aStream inBlock:b for:aCompiler
+ self codeOn:aStream inBlock:b valueNeeded:true for:aCompiler
!
codeOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
@@ -1328,6 +984,94 @@
"Modified: 3.9.1995 / 12:55:42 / claus"
!
+codeOrIfOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
+ "generate code for (x or:[y]) ifxxx:[ ... ]"
+
+ |theByteCode optByteCode theReceiver theArg pos1 pos2 pos3 code here jmp|
+
+ theByteCode := #trueJump.
+ theReceiver := receiver receiver.
+
+ optByteCode := self optimizedConditionFor:theReceiver with:theByteCode.
+ optByteCode notNil ifTrue:[
+ ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
+ theArg := theReceiver arg1
+ ].
+ theReceiver := theReceiver receiver.
+ theByteCode := optByteCode
+ ].
+ theReceiver codeOn:aStream inBlock:b for:aCompiler.
+ theArg notNil ifTrue:[
+ theArg codeOn:aStream inBlock:b for:aCompiler
+ ].
+ aStream nextPut:theByteCode.
+ pos1 := aStream position.
+ aStream nextPut:0.
+
+
+ theReceiver := receiver arg1.
+
+"new:"
+ (selector == #ifTrue:) ifTrue:[
+ theByteCode := #falseJump
+ ] ifFalse:[
+ theByteCode := #trueJump
+ ].
+ optByteCode := self optimizedConditionFor:theReceiver with:theByteCode.
+ optByteCode notNil ifTrue:[
+ theReceiver isBlock ifTrue:[
+ theReceiver := theReceiver statements expression
+ ].
+ ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
+ theArg := theReceiver arg1
+ ].
+ theReceiver := theReceiver receiver.
+ theByteCode := optByteCode.
+
+ theReceiver codeOn:aStream inBlock:b for:aCompiler.
+ theArg notNil ifTrue:[
+ theArg codeOn:aStream inBlock:b for:aCompiler
+ ].
+ aStream nextPut:theByteCode.
+
+ ] ifFalse:[
+"org"
+ theReceiver codeInlineOn:aStream inBlock:b for:aCompiler.
+ (selector == #ifTrue:) ifTrue:[
+ jmp := #falseJump
+ ] ifFalse:[
+ jmp := #trueJump
+ ].
+ aStream nextPut:jmp
+ ].
+ pos2 := aStream position.
+ aStream nextPut:0.
+ (selector == #ifTrue:) ifTrue:[
+ (aStream contents) at:pos1 put:(aStream position)
+ ].
+ (argArray at: 1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+
+ code := aStream contents.
+ valueNeeded ifTrue:[
+ aStream nextPut:#jump.
+ pos3 := aStream position.
+ aStream nextPut:0.
+ here := aStream position.
+ (selector == #ifFalse:) ifTrue:[
+ code at:pos1 put:here
+ ].
+ code at:pos2 put:here.
+ aStream nextPut:#pushNil.
+ code at:pos3 put:(aStream position)
+ ] ifFalse:[
+ here := aStream position.
+ (selector == #ifFalse:) ifTrue:[
+ code at:pos1 put:here
+ ].
+ code at:pos2 put:here
+ ]
+!
+
codeSendOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
"like code on, but assumes that receiver has already been
coded onto stack - needed for cascade"
@@ -1441,85 +1185,342 @@
aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs
!
-codeForCascadeOn:aStream inBlock:b for:aCompiler
- "like codeOn, but always leave the receiver instead of the result"
+codeTimesRepeatOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
+ "generate code for n timesRepeat:[ ... ]"
+
+ |pos pos2 theReceiver|
+
+ theReceiver := receiver.
+ theReceiver codeOn:aStream inBlock:b for:aCompiler.
+ valueNeeded ifTrue:[aStream nextPut:#dup].
- |nargs isBuiltIn code litIndex|
+ pos := aStream position.
+"/ aStream nextPut:#dup; nextPut:#push0; nextPut:#>; nextPut:lineNr; nextPut:#falseJump.
+"/ aStream nextPut:#dup; nextPut:#gt0; nextPut:lineNr; nextPut:#falseJump.
+ aStream nextPut:#pushgt0; nextPut:lineNr; nextPut:#falseJump.
+ pos2 := aStream position.
+ aStream nextPut:0.
+
+ (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:false for:aCompiler.
+ aStream nextPut:#minus1; nextPut:lineNr; nextPut:#jump; nextPut:pos.
+
+ (aStream contents) at:pos2 put:(aStream position).
+ aStream nextPut:#drop.
+!
+
+codeWhileOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler
+ "generate code for [...] whilexxx:[ ... ]"
+
+ |pos pos2 theReceiver theArg theByteCode optByteCode|
- argArray isNil ifTrue:[
- nargs := 0
+ (selector == #whileTrue:) ifTrue:[
+ theByteCode := #falseJump
] ifFalse:[
- nargs := argArray size
+ theByteCode := #trueJump
+ ].
+
+ theReceiver := receiver.
+ optByteCode := self optimizedConditionFor:theReceiver with:theByteCode.
+ optByteCode notNil ifTrue:[
+ ((optByteCode == #eqJump) or:[optByteCode == #notEqJump]) ifTrue:[
+ theArg := receiver statements expression arg1
+ ].
+ theReceiver := receiver statements expression receiver.
+ theByteCode := optByteCode
+ ].
+
+"/ OLD:
+"/ valueNeeded ifTrue:[aStream nextPut:#pushNil].
+"/
+ pos := aStream position.
+ optByteCode notNil ifTrue:[
+ theReceiver codeOn:aStream inBlock:b for:aCompiler.
+ theArg notNil ifTrue:[
+ theArg codeOn:aStream inBlock:b for:aCompiler
+ ]
+ ] ifFalse:[
+ theReceiver codeInlineOn:aStream inBlock:b for:aCompiler
+ ].
+
+ (lineNr between:1 and:255) ifTrue:[
+ aStream nextPut:#lineno; nextPut:lineNr.
].
- isBuiltIn := false.
+ aStream nextPut:theByteCode.
+ pos2 := aStream position.
+ aStream nextPut:0.
+"/ OLD:
+"/ valueNeeded ifTrue:[aStream nextPut:#drop].
+"/
+"/ OLD:
+"/ (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:valueNeeded for:aCompiler.
+"/ NEW:
+ (argArray at:1) codeInlineOn:aStream inBlock:b valueNeeded:false for:aCompiler.
+ aStream nextPut:#jump; nextPut:pos.
+ (aStream contents) at:pos2 put:(aStream position).
+"/ NEW:
+ valueNeeded ifTrue:[aStream nextPut:#pushNil].
+!
+
+optimizedConditionFor:aReceiver with:aByteCode
+ |rec sel|
- (nargs == 0) ifTrue:[
- isBuiltIn := self class isBuiltInUnarySelector:selector
+ rec := aReceiver.
+ (rec isBlock) ifTrue:[
+ rec statements nextStatement isNil ifTrue:[
+ rec := rec statements expression
+ ]
+ ].
+ (rec isUnaryMessage) ifTrue:[
+ sel := rec selector.
+ (sel == #isNil) ifTrue:[
+ "/
+ "/ isNil trueJmp -> nilJump
+ "/ isNil falseJmp -> notNilJump
+ "/
+ (aByteCode == #trueJump) ifTrue:[^ #nilJump].
+ (aByteCode == #falseJump) ifTrue:[^ #notNilJump]
+ ].
+ (sel == #notNil) ifTrue:[
+ "/
+ "/ notNil trueJmp -> notNilJump
+ "/ notNil falseJmp -> nilJump
+ "/
+ (aByteCode == #trueJump) ifTrue:[^ #notNilJump].
+ (aByteCode == #falseJump) ifTrue:[^ #nilJump]
+ ].
+ (sel == #not) ifTrue:[
+ "/
+ "/ not trueJmp -> falseJump
+ "/ not falseJmp -> trueJump
+ "/
+ (aByteCode == #trueJump) ifTrue:[^ #falseJump].
+ (aByteCode == #falseJump) ifTrue:[^ #trueJump]
+ ].
+ ^ nil
].
+ (rec isBinaryMessage) ifTrue:[
+ sel := rec selector.
+ rec arg1 isConstant ifTrue:[
+ (rec arg1 value == 0) ifTrue:[
+ "/
+ "/ ==0 trueJmp -> zeroJump
+ "/ ==0 falseJmp -> notZeroJump
+ "/
+ (sel == #==) ifTrue:[
+ (aByteCode == #trueJump) ifTrue:[^ #zeroJump].
+ (aByteCode == #falseJump) ifTrue:[^ #notZeroJump]
+ ].
+ "/
+ "/ ~~0 trueJmp -> notZeroJump
+ "/ ~~0 falseJmp -> zeroJump
+ "/
+ (sel == #~~) ifTrue:[
+ (aByteCode == #falseJump) ifTrue:[^ #zeroJump].
+ (aByteCode == #trueJump) ifTrue:[^ #notZeroJump]
+ ].
+ ^ nil
+ ]
+ ].
+ (sel == #==) ifTrue:[
+ "/
+ "/ == trueJmp -> eqJump
+ "/ == falseJmp -> notEqJump
+ "/
+ (aByteCode == #trueJump) ifTrue:[^ #eqJump].
+ (aByteCode == #falseJump) ifTrue:[^ #notEqJump]
+ ].
+ (sel == #~~) ifTrue:[
+ "/
+ "/ ~~ trueJmp -> notEqJump
+ "/ ~~ falseJmp -> eqJump
+ "/
+ (aByteCode == #falseJump) ifTrue:[^ #eqJump].
+ (aByteCode == #trueJump) ifTrue:[^ #notEqJump]
+ ]
+ ].
+ ^ nil
+! !
+
+!MessageNode methodsFor:'evaluating'!
+
+evaluate
+ |r nargs argValueArray class|
+
+ receiver isSuper ifTrue:[
+ r := receiver value.
+ receiver isHere ifTrue:[
+ class := receiver definingClass.
+ ] ifFalse:[
+ class := receiver definingClass superclass.
+ ].
+ argArray notNil ifTrue:[
+ argValueArray := argArray collect:[:arg | arg evaluate].
+ ] ifFalse:[
+ argValueArray := #()
+ ].
+ ^ r perform:selector inClass:class withArguments:argValueArray
+ ].
+
+
+ argArray isNil ifTrue:[
+ ^ (receiver evaluate) perform:selector
+ ].
+ nargs := argArray size.
(nargs == 1) ifTrue:[
- isBuiltIn := self class isBuiltIn1ArgSelector:selector
+ ^ (receiver evaluate) perform:selector with:(argArray at:1) evaluate
].
(nargs == 2) ifTrue:[
- isBuiltIn := self class isBuiltIn2ArgSelector:selector
+ ^ (receiver evaluate) perform:selector
+ with:(argArray at:1) evaluate
+ with:(argArray at:2) evaluate
+ ].
+ (nargs == 3) ifTrue:[
+ ^ (receiver evaluate) perform:selector
+ with:(argArray at:1) evaluate
+ with:(argArray at:2) evaluate
+ with:(argArray at:3) evaluate
+ ].
+ r := receiver evaluate.
+ argValueArray := argArray collect:[:arg | arg evaluate].
+ ^ r perform:selector withArguments:argValueArray
+!
+
+evaluateForCascade
+ |r nargs argValueArray class|
+
+ receiver isSuper ifTrue:[
+ r := receiver value.
+ class := receiver definingClass.
+ receiver isHere ifFalse:[
+ class := class superclass.
+ ].
+ argArray notNil ifTrue:[
+ argValueArray := argArray collect:[:arg | arg evaluate].
+ ] ifFalse:[
+ argValueArray := #()
+ ].
+ r perform:selector inClass:class withArguments:argValueArray.
+ ^ r
].
- receiver codeOn:aStream inBlock:b for:aCompiler.
- aStream nextPut:#dup.
+ r := receiver evaluate.
+ argArray isNil ifTrue:[
+ r perform:selector.
+ ^ r
+ ].
+ nargs := argArray size.
+ (nargs == 1) ifTrue:[
+ r perform:selector with:(argArray at:1) evaluate.
+ ^ r
+ ].
+ (nargs == 2) ifTrue:[
+ r perform:selector with:(argArray at:1) evaluate
+ with:(argArray at:2) evaluate.
+ ^ r
+ ].
+ (nargs == 3) ifTrue:[
+ r perform:selector with:(argArray at:1) evaluate
+ with:(argArray at:2) evaluate
+ with:(argArray at:3) evaluate.
+ ^ r
+ ].
+ argValueArray := argArray collect:[:arg | arg evaluate].
+ r perform:selector withArguments:argValueArray.
+ ^ r
+! !
+
+!MessageNode methodsFor:'printing'!
+
+printOn:aStream indent:i
+ |needParen selectorParts index index2 arg|
+
+ (#(whileTrue: whileFalse:) includes:selector) ifTrue:[
+ receiver isBlock ifTrue:[
+ ^ self printWhileOn:aStream indent:i
+ ].
+ ].
- "can we use a send-bytecode ?"
- isBuiltIn ifTrue:[
- receiver isSuper ifFalse:[
- (nargs > 0) ifTrue:[
- (argArray at:1) codeOn:aStream inBlock:b for:aCompiler.
- (nargs > 1) ifTrue:[
- (argArray at:2) codeOn:aStream inBlock:b for:aCompiler
+ index := 1.
+ selectorParts := OrderedCollection new.
+ [index == 0] whileFalse:[
+ index2 := selector indexOf:$: startingAt:index.
+ index2 ~~ 0 ifTrue:[
+ selectorParts add:(selector copyFrom:index to:index2).
+ index2 := index2 + 1
+ ].
+ index := index2
+ ].
+
+ needParen := false.
+ receiver isMessage ifTrue:[
+ receiver isUnaryMessage ifFalse:[
+ receiver isBinaryMessage ifFalse:[
+ needParen := true
+ ].
+ ].
+ ].
+ needParen ifTrue:[
+ aStream nextPutAll:'('
+ ].
+ receiver printOn:aStream indent:i.
+ needParen ifTrue:[
+ aStream nextPutAll:')'
+ ].
+
+ 1 to:(argArray size) do:[:argIndex |
+ aStream space.
+ (selectorParts at:argIndex) printOn:aStream.
+ aStream space.
+ arg := argArray at:argIndex.
+ needParen := false.
+ arg isMessage ifTrue:[
+ arg isBinaryMessage ifFalse:[
+ arg isUnaryMessage ifFalse:[
+ needParen := true
]
].
- aStream nextPut:selector.
- (self class hasLineNumber:selector) ifTrue:[
- aStream nextPut:lineNr.
- ].
- aStream nextPut:#drop.
- ^ self
- ]
- ].
+ ].
+ needParen ifTrue:[
+ aStream nextPutAll:'('
+ ].
+ arg printOn:aStream indent:i.
+ needParen ifTrue:[
+ aStream nextPutAll:') '
+ ].
+ ]
+!
+
+printWhileOn:aStream indent:i
+ |needParen arg|
- "no - generate a send"
- argArray notNil ifTrue:[
- argArray do:[:arg |
- arg codeOn:aStream inBlock:b for:aCompiler
- ]
+ "special handling of whileTrue/whileFalse"
+
+ aStream nextPutAll:'['.
+ receiver statements printOn:aStream indent:i.
+ aStream nextPutAll:'] whileTrue: '.
+
+ arg := argArray at:1.
+ needParen := false.
+ arg isMessage ifTrue:[
+ arg isBinaryMessage ifFalse:[
+ arg isUnaryMessage ifFalse:[
+ needParen := true
+ ]
+ ].
].
- litIndex := aCompiler addLiteral:selector.
- litIndex <= 255 ifTrue:[
- receiver isSuper ifTrue:[
- receiver isHere ifTrue:[
- code := #hereSend
- ] ifFalse:[
- code := #superSend.
- ].
- aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:nargs; nextPut:nil; nextPut:#drop.
- ^ self
- ].
- (nargs <= 3) ifTrue:[
- code := #(sendDrop0 sendDrop1 sendDrop2 sendDrop3) at:(nargs+1).
- aStream nextPut:code; nextPut:lineNr; nextPut:litIndex.
- ^ self
- ].
+ needParen ifTrue:[
+ aStream nextPutAll:'('
+ ].
+ arg printOn:aStream indent:i.
+ needParen ifTrue:[
+ aStream nextPutAll:') '
+ ].
+! !
- aStream nextPut:#sendDrop; nextPut:lineNr; nextPut:litIndex; nextPut:nargs.
- ^ self
- ].
- "need 16bit litIndex"
- receiver isSuper ifTrue:[
- receiver isHere ifTrue:[
- code := #hereSendL
- ] ifFalse:[
- code := #superSendL.
- ].
- aStream nextPut:code; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs; nextPut:nil; nextPut:#drop.
- ^ self
- ].
- aStream nextPut:#sendDropL; nextPut:lineNr; nextPut:litIndex; nextPut:0; nextPut:nargs
+!MessageNode methodsFor:'queries'!
+
+isMessage
+ ^ true
! !
+