| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556 | 
							- Smalltalk current createPackage: 'Compiler-AST'!
 
- Object subclass: #Node
 
- 	instanceVariableNames: 'position nodes shouldBeInlined shouldBeAliased'
 
- 	package: 'Compiler-AST'!
 
- !Node commentStamp!
 
- I am the abstract root class of the abstract syntax tree.
 
- position: holds a point containing lline- and column number of the symbol location in the original source file!
 
- !Node methodsFor: 'accessing'!
 
- addNode: aNode
 
- 	self nodes add: aNode
 
- !
 
- nodes
 
- 	^nodes ifNil: [nodes := Array new]
 
- !
 
- position
 
- 	^position ifNil: [position := 0@0]
 
- !
 
- shouldBeAliased
 
- 	^ shouldBeAliased ifNil: [ false ]
 
- !
 
- shouldBeAliased: aBoolean
 
- 	shouldBeAliased := aBoolean
 
- !
 
- shouldBeInlined
 
- 	^ shouldBeInlined ifNil: [ false ]
 
- !
 
- shouldBeInlined: aBoolean
 
- 	shouldBeInlined := aBoolean
 
- ! !
 
- !Node methodsFor: 'building'!
 
- nodes: aCollection
 
- 	nodes := aCollection
 
- !
 
- position: aPosition
 
- 	position := aPosition
 
- ! !
 
- !Node methodsFor: 'testing'!
 
- isAssignmentNode
 
- 	^ false
 
- !
 
- isBlockNode
 
- 	^false
 
- !
 
- isBlockSequenceNode
 
- 	^false
 
- !
 
- isImmutable
 
- 	^false
 
- !
 
- isNode
 
- 	^ true
 
- !
 
- isReturnNode
 
- 	^false
 
- !
 
- isSendNode
 
- 	^false
 
- !
 
- isValueNode
 
- 	^false
 
- !
 
- subtreeNeedsAliasing
 
- 	^(self shouldBeAliased or: [ self shouldBeInlined ]) or: [
 
- 		(self nodes detect: [ :each | each subtreeNeedsAliasing ] ifNone: [ false ]) ~= false ]
 
- ! !
 
- !Node methodsFor: 'visiting'!
 
- accept: aVisitor
 
- 	^ aVisitor visitNode: self
 
- ! !
 
- Node subclass: #AssignmentNode
 
- 	instanceVariableNames: 'left right'
 
- 	package: 'Compiler-AST'!
 
- !AssignmentNode methodsFor: 'accessing'!
 
- left
 
- 	^left
 
- !
 
- left: aNode
 
- 	left := aNode
 
- !
 
- nodes
 
- 	^ Array with: self left with: self right
 
- !
 
- right
 
- 	^right
 
- !
 
- right: aNode
 
- 	right := aNode
 
- ! !
 
- !AssignmentNode methodsFor: 'testing'!
 
- isAssignmentNode
 
- 	^ true
 
- ! !
 
- !AssignmentNode methodsFor: 'visiting'!
 
- accept: aVisitor
 
- 	^ aVisitor visitAssignmentNode: self
 
- ! !
 
- Node subclass: #BlockNode
 
- 	instanceVariableNames: 'parameters scope'
 
- 	package: 'Compiler-AST'!
 
- !BlockNode methodsFor: 'accessing'!
 
- parameters
 
- 	^parameters ifNil: [parameters := Array new]
 
- !
 
- parameters: aCollection
 
- 	parameters := aCollection
 
- !
 
- scope
 
- 	^ scope
 
- !
 
- scope: aLexicalScope
 
- 	scope := aLexicalScope
 
- ! !
 
- !BlockNode methodsFor: 'testing'!
 
- isBlockNode
 
- 	^true
 
- !
 
- subtreeNeedsAliasing
 
- 	^ self shouldBeAliased or: [ self shouldBeInlined ]
 
- ! !
 
- !BlockNode methodsFor: 'visiting'!
 
- accept: aVisitor
 
- 	^ aVisitor visitBlockNode: self
 
- ! !
 
- Node subclass: #CascadeNode
 
- 	instanceVariableNames: 'receiver'
 
- 	package: 'Compiler-AST'!
 
- !CascadeNode methodsFor: 'accessing'!
 
- receiver
 
- 	^receiver
 
- !
 
- receiver: aNode
 
- 	receiver := aNode
 
- ! !
 
- !CascadeNode methodsFor: 'visiting'!
 
- accept: aVisitor
 
- 	^ aVisitor visitCascadeNode: self
 
- ! !
 
- Node subclass: #DynamicArrayNode
 
- 	instanceVariableNames: ''
 
- 	package: 'Compiler-AST'!
 
- !DynamicArrayNode methodsFor: 'visiting'!
 
- accept: aVisitor
 
- 	^ aVisitor visitDynamicArrayNode: self
 
- ! !
 
- Node subclass: #DynamicDictionaryNode
 
- 	instanceVariableNames: ''
 
- 	package: 'Compiler-AST'!
 
- !DynamicDictionaryNode methodsFor: 'visiting'!
 
- accept: aVisitor
 
- 	^ aVisitor visitDynamicDictionaryNode: self
 
- ! !
 
- Node subclass: #JSStatementNode
 
- 	instanceVariableNames: 'source'
 
- 	package: 'Compiler-AST'!
 
- !JSStatementNode methodsFor: 'accessing'!
 
- source
 
- 	^source ifNil: ['']
 
- !
 
- source: aString
 
- 	source := aString
 
- ! !
 
- !JSStatementNode methodsFor: 'visiting'!
 
- accept: aVisitor
 
- 	^ aVisitor visitJSStatementNode: self
 
- ! !
 
- Node subclass: #MethodNode
 
- 	instanceVariableNames: 'selector arguments source scope classReferences messageSends superSends'
 
- 	package: 'Compiler-AST'!
 
- !MethodNode methodsFor: 'accessing'!
 
- arguments
 
- 	^arguments ifNil: [#()]
 
- !
 
- arguments: aCollection
 
- 	arguments := aCollection
 
- !
 
- classReferences
 
- 	^ classReferences
 
- !
 
- classReferences: aCollection
 
- 	classReferences := aCollection
 
- !
 
- messageSends
 
- 	^ messageSends
 
- !
 
- messageSends: aCollection
 
- 	messageSends := aCollection
 
- !
 
- scope
 
- 	^ scope
 
- !
 
- scope: aMethodScope
 
- 	scope := aMethodScope
 
- !
 
- selector
 
- 	^selector
 
- !
 
- selector: aString
 
- 	selector := aString
 
- !
 
- source
 
- 	^source
 
- !
 
- source: aString
 
- 	source := aString
 
- !
 
- superSends
 
- 	^ superSends
 
- !
 
- superSends: aCollection
 
- 	superSends := aCollection
 
- ! !
 
- !MethodNode methodsFor: 'visiting'!
 
- accept: aVisitor
 
- 	^ aVisitor visitMethodNode: self
 
- ! !
 
- Node subclass: #ReturnNode
 
- 	instanceVariableNames: 'scope'
 
- 	package: 'Compiler-AST'!
 
- !ReturnNode methodsFor: 'accessing'!
 
- scope
 
- 	^ scope
 
- !
 
- scope: aLexicalScope
 
- 	scope := aLexicalScope
 
- ! !
 
- !ReturnNode methodsFor: 'testing'!
 
- isReturnNode
 
- 	^ true
 
- !
 
- nonLocalReturn
 
- 	^ self scope isMethodScope not
 
- ! !
 
- !ReturnNode methodsFor: 'visiting'!
 
- accept: aVisitor
 
- 	^ aVisitor visitReturnNode: self
 
- ! !
 
- Node subclass: #SendNode
 
- 	instanceVariableNames: 'selector arguments receiver superSend index'
 
- 	package: 'Compiler-AST'!
 
- !SendNode methodsFor: 'accessing'!
 
- arguments
 
- 	^arguments ifNil: [arguments := #()]
 
- !
 
- arguments: aCollection
 
- 	arguments := aCollection
 
- !
 
- cascadeNodeWithMessages: aCollection
 
- 	| first |
 
- 	first := SendNode new
 
- 		selector: self selector;
 
- 		arguments: self arguments;
 
- 		yourself.
 
- 	^CascadeNode new
 
- 		receiver: self receiver;
 
- 		nodes: (Array with: first), aCollection;
 
- 		yourself
 
- !
 
- index
 
- 	^ index
 
- !
 
- index: anInteger
 
- 	index := anInteger
 
- !
 
- nodes
 
- 	^ (Array withAll: self arguments)
 
- 		add: self receiver;
 
- 		yourself
 
- !
 
- receiver
 
- 	^receiver
 
- !
 
- receiver: aNode
 
- 	receiver := aNode
 
- !
 
- selector
 
- 	^selector
 
- !
 
- selector: aString
 
- 	selector := aString
 
- !
 
- superSend
 
- 	^ superSend ifNil: [ false ]
 
- !
 
- superSend: aBoolean
 
- 	superSend := aBoolean
 
- !
 
- valueForReceiver: anObject
 
- 	^SendNode new
 
- 		receiver: (self receiver
 
- 		ifNil: [anObject]
 
- 		ifNotNil: [self receiver valueForReceiver: anObject]);
 
- 		selector: self selector;
 
- 		arguments: self arguments;
 
- 		yourself
 
- ! !
 
- !SendNode methodsFor: 'testing'!
 
- isSendNode
 
- 	^ true
 
- ! !
 
- !SendNode methodsFor: 'visiting'!
 
- accept: aVisitor
 
- 	^ aVisitor visitSendNode: self
 
- ! !
 
- Node subclass: #SequenceNode
 
- 	instanceVariableNames: 'temps scope'
 
- 	package: 'Compiler-AST'!
 
- !SequenceNode methodsFor: 'accessing'!
 
- scope
 
- 	^ scope
 
- !
 
- scope: aLexicalScope
 
- 	scope := aLexicalScope
 
- !
 
- temps
 
- 	^temps ifNil: [#()]
 
- !
 
- temps: aCollection
 
- 	temps := aCollection
 
- ! !
 
- !SequenceNode methodsFor: 'testing'!
 
- asBlockSequenceNode
 
- 	^BlockSequenceNode new
 
- 		nodes: self nodes;
 
- 		temps: self temps;
 
- 		yourself
 
- ! !
 
- !SequenceNode methodsFor: 'visiting'!
 
- accept: aVisitor
 
- 	^ aVisitor visitSequenceNode: self
 
- ! !
 
- SequenceNode subclass: #BlockSequenceNode
 
- 	instanceVariableNames: ''
 
- 	package: 'Compiler-AST'!
 
- !BlockSequenceNode methodsFor: 'testing'!
 
- isBlockSequenceNode
 
- 	^true
 
- ! !
 
- !BlockSequenceNode methodsFor: 'visiting'!
 
- accept: aVisitor
 
- 	^ aVisitor visitBlockSequenceNode: self
 
- ! !
 
- Node subclass: #ValueNode
 
- 	instanceVariableNames: 'value'
 
- 	package: 'Compiler-AST'!
 
- !ValueNode methodsFor: 'accessing'!
 
- value
 
- 	^value
 
- !
 
- value: anObject
 
- 	value := anObject
 
- ! !
 
- !ValueNode methodsFor: 'testing'!
 
- isImmutable
 
- 	^ self value isImmutable
 
- !
 
- isValueNode
 
- 	^true
 
- ! !
 
- !ValueNode methodsFor: 'visiting'!
 
- accept: aVisitor
 
- 	^ aVisitor visitValueNode: self
 
- ! !
 
- ValueNode subclass: #VariableNode
 
- 	instanceVariableNames: 'assigned binding'
 
- 	package: 'Compiler-AST'!
 
- !VariableNode methodsFor: 'accessing'!
 
- alias
 
- 	^ self binding alias
 
- !
 
- assigned
 
- 	^assigned ifNil: [false]
 
- !
 
- assigned: aBoolean
 
- 	assigned := aBoolean
 
- !
 
- beAssigned
 
- 	self binding validateAssignment.
 
- 	assigned := true
 
- !
 
- binding
 
- 	^ binding
 
- !
 
- binding: aScopeVar
 
- 	binding := aScopeVar
 
- ! !
 
- !VariableNode methodsFor: 'testing'!
 
- isImmutable
 
- 	^false
 
- ! !
 
- !VariableNode methodsFor: 'visiting'!
 
- accept: aVisitor
 
- 	^ aVisitor visitVariableNode: self
 
- ! !
 
- VariableNode subclass: #ClassReferenceNode
 
- 	instanceVariableNames: ''
 
- 	package: 'Compiler-AST'!
 
- !ClassReferenceNode methodsFor: 'visiting'!
 
- accept: aVisitor
 
- 	^ aVisitor visitClassReferenceNode: self
 
- ! !
 
- !Object methodsFor: '*Compiler-AST'!
 
- isNode
 
- 	^ false
 
- ! !
 
 
  |