|  | @@ -155,8 +155,8 @@ exportMethodsOf: aClass on: aStream
 | 
											
												
													
														|  |  exportPackageDefinitionOf: package on: aStream
 |  |  exportPackageDefinitionOf: package on: aStream
 | 
											
												
													
														|  |  	aStream 
 |  |  	aStream 
 | 
											
												
													
														|  |  	    nextPutAll: 'smalltalk.addPackage(';
 |  |  	    nextPutAll: 'smalltalk.addPackage(';
 | 
											
												
													
														|  | -	    nextPutAll: '''', package name, ''', ', package propertiesAsJSON , ');'.
 |  | 
 | 
											
												
													
														|  | -	aStream lf
 |  | 
 | 
											
												
													
														|  | 
 |  | +	    nextPutAll: '''', package name, ''');';
 | 
											
												
													
														|  | 
 |  | +        lf
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  exportPackageExtensionsOf: package on: aStream
 |  |  exportPackageExtensionsOf: package on: aStream
 | 
											
										
											
												
													
														|  | @@ -262,8 +262,8 @@ exportPackageDefinitionOf: package on: aStream
 | 
											
												
													
														|  |  	"Chunk format."
 |  |  	"Chunk format."
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	aStream 
 |  |  	aStream 
 | 
											
												
													
														|  | -	    nextPutAll: 'Smalltalk current createPackage: ''', package name,
 |  | 
 | 
											
												
													
														|  | -		''' properties: ', package properties storeString, '!!'; lf.
 |  | 
 | 
											
												
													
														|  | 
 |  | +		nextPutAll: 'Smalltalk current createPackage: ''', package name, '''!!';
 | 
											
												
													
														|  | 
 |  | +		lf
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  exportPackageExtensionsOf: package on: aStream
 |  |  exportPackageExtensionsOf: package on: aStream
 | 
											
										
											
												
													
														|  | @@ -313,7 +313,8 @@ exportMethod: aMethod of: aClass on: aStream
 | 
											
												
													
														|  |  		nextPutAll: aMethod selector asSelector asJavascript, ',';lf;
 |  |  		nextPutAll: aMethod selector asSelector asJavascript, ',';lf;
 | 
											
												
													
														|  |  		nextPutAll: 'smalltalk.method({';lf;
 |  |  		nextPutAll: 'smalltalk.method({';lf;
 | 
											
												
													
														|  |  		nextPutAll: 'selector: ', aMethod selector asJavascript, ',';lf;
 |  |  		nextPutAll: 'selector: ', aMethod selector asJavascript, ',';lf;
 | 
											
												
													
														|  | -		nextPutAll: 'fn: ', aMethod fn compiledSource;lf;
 |  | 
 | 
											
												
													
														|  | 
 |  | +		nextPutAll: 'fn: ', aMethod fn compiledSource, ',';lf;
 | 
											
												
													
														|  | 
 |  | +		nextPutAll: 'messageSends: ', aMethod messageSends asJavascript;
 | 
											
												
													
														|  |  		nextPutAll: '}),';lf;
 |  |  		nextPutAll: '}),';lf;
 | 
											
												
													
														|  |  		nextPutAll: 'smalltalk.', (self classNameFor: aClass);
 |  |  		nextPutAll: 'smalltalk.', (self classNameFor: aClass);
 | 
											
												
													
														|  |  		nextPutAll: ');';lf;lf
 |  |  		nextPutAll: ');';lf;lf
 | 
											
										
											
												
													
														|  | @@ -459,6 +460,10 @@ The default behavior is to allow it, as this is how Amber currently is able to s
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  !UnknownVariableError methodsFor: '*Compiler'!
 |  |  !UnknownVariableError methodsFor: '*Compiler'!
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +messageText
 | 
											
												
													
														|  | 
 |  | +	^ 'Unknown Variable error: ', self variableName, ' is not defined'
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  variableName
 |  |  variableName
 | 
											
												
													
														|  |  	^ variableName
 |  |  	^ variableName
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
										
											
												
													
														|  | @@ -467,6 +472,25 @@ variableName: aString
 | 
											
												
													
														|  |  	variableName := aString
 |  |  	variableName := aString
 | 
											
												
													
														|  |  ! !
 |  |  ! !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +ErrorHandler subclass: #RethrowErrorHandler
 | 
											
												
													
														|  | 
 |  | +	instanceVariableNames: ''
 | 
											
												
													
														|  | 
 |  | +	package:'Compiler'!
 | 
											
												
													
														|  | 
 |  | +!RethrowErrorHandler commentStamp!
 | 
											
												
													
														|  | 
 |  | +This class is used in the commandline version of the compiler.
 | 
											
												
													
														|  | 
 |  | +It uses the handleError: message of ErrorHandler for printing the stacktrace and throws the error again as JS exception.
 | 
											
												
													
														|  | 
 |  | +As a result Smalltalk errors are not swallowd by the Amber runtime and compilation can be aborted.!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!RethrowErrorHandler methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +basicSignal: anError
 | 
											
												
													
														|  | 
 |  | +	<throw anError>
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +handleError: anError
 | 
											
												
													
														|  | 
 |  | +	super handleError: anError.
 | 
											
												
													
														|  | 
 |  | +    self basicSignal: anError
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  Object subclass: #Compiler
 |  |  Object subclass: #Compiler
 | 
											
												
													
														|  |  	instanceVariableNames: 'currentClass source unknownVariables codeGeneratorClass'
 |  |  	instanceVariableNames: 'currentClass source unknownVariables codeGeneratorClass'
 | 
											
												
													
														|  |  	package:'Compiler'!
 |  |  	package:'Compiler'!
 | 
											
										
											
												
													
														|  | @@ -553,12 +577,10 @@ evaluateExpression: aString
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  install: aString forClass: aBehavior category: anotherString
 |  |  install: aString forClass: aBehavior category: anotherString
 | 
											
												
													
														|  | -	| compiled |
 |  | 
 | 
											
												
													
														|  | -	compiled := self eval: (self compile: aString forClass: aBehavior).
 |  | 
 | 
											
												
													
														|  | -	compiled category: anotherString.
 |  | 
 | 
											
												
													
														|  | -	aBehavior addCompiledMethod: compiled.
 |  | 
 | 
											
												
													
														|  | -    self setupClass: aBehavior.
 |  | 
 | 
											
												
													
														|  | -	^compiled
 |  | 
 | 
											
												
													
														|  | 
 |  | +   	^ ClassBuilder new
 | 
											
												
													
														|  | 
 |  | +    	installMethod: (self eval: (self compile: aString forClass: aBehavior))
 | 
											
												
													
														|  | 
 |  | +        forClass: aBehavior
 | 
											
												
													
														|  | 
 |  | +        category: anotherString
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  parse: aString
 |  |  parse: aString
 | 
											
										
											
												
													
														|  | @@ -573,7 +595,7 @@ recompile: aClass
 | 
											
												
													
														|  |  	aClass methodDictionary do: [:each |
 |  |  	aClass methodDictionary do: [:each |
 | 
											
												
													
														|  |  		console log: aClass name, ' >> ', each selector.
 |  |  		console log: aClass name, ' >> ', each selector.
 | 
											
												
													
														|  |  		self install: each source forClass: aClass category: each category].
 |  |  		self install: each source forClass: aClass category: each category].
 | 
											
												
													
														|  | -	self setupClass: aClass.
 |  | 
 | 
											
												
													
														|  | 
 |  | +	"self setupClass: aClass."
 | 
											
												
													
														|  |  	aClass isMetaclass ifFalse: [self recompile: aClass class]
 |  |  	aClass isMetaclass ifFalse: [self recompile: aClass class]
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -581,10 +603,6 @@ recompileAll
 | 
											
												
													
														|  |  	Smalltalk current classes do: [:each |
 |  |  	Smalltalk current classes do: [:each |
 | 
											
												
													
														|  |  		Transcript show: each; cr.
 |  |  		Transcript show: each; cr.
 | 
											
												
													
														|  |  		[self recompile: each] valueWithTimeout: 100]
 |  |  		[self recompile: each] valueWithTimeout: 100]
 | 
											
												
													
														|  | -!
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -setupClass: aClass
 |  | 
 | 
											
												
													
														|  | -	<smalltalk.init(aClass)>
 |  | 
 | 
											
												
													
														|  |  ! !
 |  |  ! !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  !Compiler class methodsFor: '*Compiler'!
 |  |  !Compiler class methodsFor: '*Compiler'!
 | 
											
										
											
												
													
														|  | @@ -617,7 +635,7 @@ visit: aNode
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  visitAll: aCollection
 |  |  visitAll: aCollection
 | 
											
												
													
														|  | -	^ aCollection do: [ :each | self visit: each ]
 |  | 
 | 
											
												
													
														|  | 
 |  | +	^ aCollection collect: [ :each | self visit: each ]
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  visitAssignmentNode: aNode
 |  |  visitAssignmentNode: aNode
 | 
											
										
											
												
													
														|  | @@ -828,6 +846,10 @@ isImmutable
 | 
											
												
													
														|  |  	^false
 |  |  	^false
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +isNode
 | 
											
												
													
														|  | 
 |  | +	^ true
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  isReturnNode
 |  |  isReturnNode
 | 
											
												
													
														|  |  	^false
 |  |  	^false
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
										
											
												
													
														|  | @@ -915,6 +937,10 @@ scope: aLexicalScope
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  isBlockNode
 |  |  isBlockNode
 | 
											
												
													
														|  |  	^true
 |  |  	^true
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +subtreeNeedsAliasing
 | 
											
												
													
														|  | 
 |  | +    ^ self shouldBeAliased or: [ self shouldBeInlined ]
 | 
											
												
													
														|  |  ! !
 |  |  ! !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  !BlockNode methodsFor: '*Compiler'!
 |  |  !BlockNode methodsFor: '*Compiler'!
 | 
											
										
											
												
													
														|  | @@ -1303,6 +1329,12 @@ accept: aVisitor
 | 
											
												
													
														|  |  	^ aVisitor visitClassReferenceNode: self
 |  |  	^ aVisitor visitClassReferenceNode: self
 | 
											
												
													
														|  |  ! !
 |  |  ! !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +!Object methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +isNode
 | 
											
												
													
														|  | 
 |  | +	^ false
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  Object subclass: #LexicalScope
 |  |  Object subclass: #LexicalScope
 | 
											
												
													
														|  |  	instanceVariableNames: 'node instruction temps args outerScope'
 |  |  	instanceVariableNames: 'node instruction temps args outerScope'
 | 
											
												
													
														|  |  	package:'Compiler'!
 |  |  	package:'Compiler'!
 | 
											
										
											
												
													
														|  | @@ -1663,12 +1695,6 @@ I am an temporary variable of a method or block.!
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  !TempVar methodsFor: '*Compiler'!
 |  |  !TempVar methodsFor: '*Compiler'!
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -alias
 |  | 
 | 
											
												
													
														|  | -	^ self scope alias, '.locals.', super alias
 |  | 
 | 
											
												
													
														|  | -! !
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -!TempVar methodsFor: '*Compiler'!
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |  isTempVar
 |  |  isTempVar
 | 
											
												
													
														|  |  	^ true
 |  |  	^ true
 | 
											
												
													
														|  |  ! !
 |  |  ! !
 | 
											
										
											
												
													
														|  | @@ -1722,16 +1748,24 @@ errorShadowingVariable: aString
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  errorUnknownVariable: aNode
 |  |  errorUnknownVariable: aNode
 | 
											
												
													
														|  | -	"Throw an error if the variable is undeclared in the global JS scope (i.e. window)"
 |  | 
 | 
											
												
													
														|  | 
 |  | +	"Throw an error if the variable is undeclared in the global JS scope (i.e. window).
 | 
											
												
													
														|  | 
 |  | +    We allow four variable names in addition: `jQuery`, `window`, `process` and `global` 
 | 
											
												
													
														|  | 
 |  | +    for nodejs and browser environments. 
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +    This is only to make sure compilation works on both browser-based and nodejs environments.
 | 
											
												
													
														|  | 
 |  | +    The ideal solution would be to use a pragma instead"
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	| identifier |
 |  |  	| identifier |
 | 
											
												
													
														|  |      identifier := aNode value.
 |  |      identifier := aNode value.
 | 
											
												
													
														|  | -	((#('jQuery' 'window' 'process' 'global') includes: identifier) not and: [ self isVariableGloballyUndefined: identifier ]) ifTrue: [
 |  | 
 | 
											
												
													
														|  | -			UnknownVariableError new
 |  | 
 | 
											
												
													
														|  | -				variableName: aNode value;
 |  | 
 | 
											
												
													
														|  | -				signal ]
 |  | 
 | 
											
												
													
														|  | -		ifFalse: [
 |  | 
 | 
											
												
													
														|  | -			currentScope methodScope unknownVariables add: aNode value. ]
 |  | 
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +	((#('jQuery' 'window' 'document' 'process' 'global') includes: identifier) not 
 | 
											
												
													
														|  | 
 |  | +        and: [ self isVariableGloballyUndefined: identifier ]) 
 | 
											
												
													
														|  | 
 |  | +        	ifTrue: [
 | 
											
												
													
														|  | 
 |  | +				UnknownVariableError new
 | 
											
												
													
														|  | 
 |  | +					variableName: aNode value;
 | 
											
												
													
														|  | 
 |  | +					signal ]
 | 
											
												
													
														|  | 
 |  | +			ifFalse: [
 | 
											
												
													
														|  | 
 |  | +				currentScope methodScope unknownVariables add: aNode value ]
 | 
											
												
													
														|  |  ! !
 |  |  ! !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  !SemanticAnalyzer methodsFor: '*Compiler'!
 |  |  !SemanticAnalyzer methodsFor: '*Compiler'!
 | 
											
										
											
												
													
														|  | @@ -2148,6 +2182,10 @@ instructions
 | 
											
												
													
														|  |  	^ instructions ifNil: [ instructions := OrderedCollection new ]
 |  |  	^ instructions ifNil: [ instructions := OrderedCollection new ]
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +method
 | 
											
												
													
														|  | 
 |  | +	^ self parent method
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  parent
 |  |  parent
 | 
											
												
													
														|  |  	^ parent
 |  |  	^ parent
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
										
											
												
													
														|  | @@ -2200,6 +2238,10 @@ isLocalReturn
 | 
											
												
													
														|  |  	^ false
 |  |  	^ false
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +isMethod
 | 
											
												
													
														|  | 
 |  | +	^ false
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  isReturn
 |  |  isReturn
 | 
											
												
													
														|  |  	^ false
 |  |  	^ false
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
										
											
												
													
														|  | @@ -2278,11 +2320,11 @@ scope: aScope
 | 
											
												
													
														|  |  	scope := aScope
 |  |  	scope := aScope
 | 
											
												
													
														|  |  ! !
 |  |  ! !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -IRScopedInstruction subclass: #IRClosure
 |  | 
 | 
											
												
													
														|  | 
 |  | +IRScopedInstruction subclass: #IRClosureInstruction
 | 
											
												
													
														|  |  	instanceVariableNames: 'arguments'
 |  |  	instanceVariableNames: 'arguments'
 | 
											
												
													
														|  |  	package:'Compiler'!
 |  |  	package:'Compiler'!
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -!IRClosure methodsFor: '*Compiler'!
 |  | 
 | 
											
												
													
														|  | 
 |  | +!IRClosureInstruction methodsFor: '*Compiler'!
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  arguments
 |  |  arguments
 | 
											
												
													
														|  |  	^ arguments ifNil: [ #() ]
 |  |  	^ arguments ifNil: [ #() ]
 | 
											
										
											
												
													
														|  | @@ -2292,11 +2334,28 @@ arguments: aCollection
 | 
											
												
													
														|  |  	arguments := aCollection
 |  |  	arguments := aCollection
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +locals
 | 
											
												
													
														|  | 
 |  | +	^ self arguments copy
 | 
											
												
													
														|  | 
 |  | +    	addAll: (self tempDeclarations collect: [ :each | each name ]); 
 | 
											
												
													
														|  | 
 |  | +        yourself
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  scope: aScope
 |  |  scope: aScope
 | 
											
												
													
														|  |  	super scope: aScope.
 |  |  	super scope: aScope.
 | 
											
												
													
														|  |  	aScope instruction: self
 |  |  	aScope instruction: self
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +tempDeclarations
 | 
											
												
													
														|  | 
 |  | +	^ self instructions select: [ :each | 
 | 
											
												
													
														|  | 
 |  | +    	each isTempDeclaration ]
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +IRClosureInstruction subclass: #IRClosure
 | 
											
												
													
														|  | 
 |  | +	instanceVariableNames: ''
 | 
											
												
													
														|  | 
 |  | +	package:'Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!IRClosure methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  sequence
 |  |  sequence
 | 
											
												
													
														|  |  	^ self instructions last
 |  |  	^ self instructions last
 | 
											
												
													
														|  |  ! !
 |  |  ! !
 | 
											
										
											
												
													
														|  | @@ -2313,22 +2372,14 @@ accept: aVisitor
 | 
											
												
													
														|  |  	^ aVisitor visitIRClosure: self
 |  |  	^ aVisitor visitIRClosure: self
 | 
											
												
													
														|  |  ! !
 |  |  ! !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -IRScopedInstruction subclass: #IRMethod
 |  | 
 | 
											
												
													
														|  | -	instanceVariableNames: 'theClass source selector classReferences messageSends superSends arguments internalVariables'
 |  | 
 | 
											
												
													
														|  | 
 |  | +IRClosureInstruction subclass: #IRMethod
 | 
											
												
													
														|  | 
 |  | +	instanceVariableNames: 'theClass source selector classReferences messageSends superSends internalVariables'
 | 
											
												
													
														|  |  	package:'Compiler'!
 |  |  	package:'Compiler'!
 | 
											
												
													
														|  |  !IRMethod commentStamp!
 |  |  !IRMethod commentStamp!
 | 
											
												
													
														|  |  I am a method instruction!
 |  |  I am a method instruction!
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  !IRMethod methodsFor: '*Compiler'!
 |  |  !IRMethod methodsFor: '*Compiler'!
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -arguments
 |  | 
 | 
											
												
													
														|  | -	^ arguments
 |  | 
 | 
											
												
													
														|  | -!
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -arguments: aCollection
 |  | 
 | 
											
												
													
														|  | -	arguments := aCollection
 |  | 
 | 
											
												
													
														|  | -!
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |  classReferences
 |  |  classReferences
 | 
											
												
													
														|  |  	^ classReferences
 |  |  	^ classReferences
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
										
											
												
													
														|  | @@ -2341,6 +2392,10 @@ internalVariables
 | 
											
												
													
														|  |  	^ internalVariables ifNil: [ internalVariables := Set new ]
 |  |  	^ internalVariables ifNil: [ internalVariables := Set new ]
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +isMethod
 | 
											
												
													
														|  | 
 |  | +	^ true
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  messageSends
 |  |  messageSends
 | 
											
												
													
														|  |  	^ messageSends
 |  |  	^ messageSends
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
										
											
												
													
														|  | @@ -2349,9 +2404,8 @@ messageSends: aCollection
 | 
											
												
													
														|  |  	messageSends := aCollection
 |  |  	messageSends := aCollection
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -scope: aScope
 |  | 
 | 
											
												
													
														|  | -	super scope: aScope.
 |  | 
 | 
											
												
													
														|  | -	aScope instruction: self
 |  | 
 | 
											
												
													
														|  | 
 |  | +method
 | 
											
												
													
														|  | 
 |  | +	^ self
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  selector
 |  |  selector
 | 
											
										
											
												
													
														|  | @@ -2481,6 +2535,12 @@ name: aString
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  !IRTempDeclaration methodsFor: '*Compiler'!
 |  |  !IRTempDeclaration methodsFor: '*Compiler'!
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +isTempDeclaration
 | 
											
												
													
														|  | 
 |  | +	^ true
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!IRTempDeclaration methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  accept: aVisitor
 |  |  accept: aVisitor
 | 
											
												
													
														|  |  	^ aVisitor visitIRTempDeclaration: self
 |  |  	^ aVisitor visitIRTempDeclaration: self
 | 
											
												
													
														|  |  ! !
 |  |  ! !
 | 
											
										
											
												
													
														|  | @@ -2754,6 +2814,8 @@ visitIRAssignment: anIRAssignment
 | 
											
												
													
														|  |  visitIRClosure: anIRClosure
 |  |  visitIRClosure: anIRClosure
 | 
											
												
													
														|  |  	self stream 
 |  |  	self stream 
 | 
											
												
													
														|  |  		nextPutClosureWith: [ 
 |  |  		nextPutClosureWith: [ 
 | 
											
												
													
														|  | 
 |  | +        	self stream nextPutVars: (anIRClosure tempDeclarations collect: [ :each |
 | 
											
												
													
														|  | 
 |  | +    				each name asVariableName ]).
 | 
											
												
													
														|  |          	self stream 
 |  |          	self stream 
 | 
											
												
													
														|  |              	nextPutBlockContextFor: anIRClosure
 |  |              	nextPutBlockContextFor: anIRClosure
 | 
											
												
													
														|  |                  during: [ super visitIRClosure: anIRClosure ] ]
 |  |                  during: [ super visitIRClosure: anIRClosure ] ]
 | 
											
										
											
												
													
														|  | @@ -2777,10 +2839,13 @@ visitIRDynamicDictionary: anIRDynamicDictionary
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  visitIRMethod: anIRMethod
 |  |  visitIRMethod: anIRMethod
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  	self stream
 |  |  	self stream
 | 
											
												
													
														|  |  		nextPutMethodDeclaration: anIRMethod 
 |  |  		nextPutMethodDeclaration: anIRMethod 
 | 
											
												
													
														|  |  		with: [ self stream 
 |  |  		with: [ self stream 
 | 
											
												
													
														|  |  			nextPutFunctionWith: [ 
 |  |  			nextPutFunctionWith: [ 
 | 
											
												
													
														|  | 
 |  | +            	self stream nextPutVars: (anIRMethod tempDeclarations collect: [ :each |
 | 
											
												
													
														|  | 
 |  | +    				each name asVariableName ]).
 | 
											
												
													
														|  |              	self stream nextPutContextFor: anIRMethod during: [
 |  |              	self stream nextPutContextFor: anIRMethod during: [
 | 
											
												
													
														|  |  				anIRMethod internalVariables notEmpty ifTrue: [
 |  |  				anIRMethod internalVariables notEmpty ifTrue: [
 | 
											
												
													
														|  |  					self stream nextPutVars: (anIRMethod internalVariables asArray collect: [ :each |
 |  |  					self stream nextPutVars: (anIRMethod internalVariables asArray collect: [ :each |
 | 
											
										
											
												
													
														|  | @@ -2833,9 +2898,9 @@ visitIRSequence: anIRSequence
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  visitIRTempDeclaration: anIRTempDeclaration
 |  |  visitIRTempDeclaration: anIRTempDeclaration
 | 
											
												
													
														|  | -	self stream 
 |  | 
 | 
											
												
													
														|  | -    	nextPutAll: anIRTempDeclaration scope alias, '.locals.', anIRTempDeclaration name, '=nil;'; 
 |  | 
 | 
											
												
													
														|  | -        lf
 |  | 
 | 
											
												
													
														|  | 
 |  | +	"self stream 
 | 
											
												
													
														|  | 
 |  | +    	nextPutAll: 'var ', anIRTempDeclaration name asVariableName, ';'; 
 | 
											
												
													
														|  | 
 |  | +        lf"
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  visitIRValue: anIRValue
 |  |  visitIRValue: anIRValue
 | 
											
										
											
												
													
														|  | @@ -2890,10 +2955,26 @@ nextPutAssignment
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  nextPutBlockContextFor: anIRClosure during: aBlock
 |  |  nextPutBlockContextFor: anIRClosure during: aBlock
 | 
											
												
													
														|  |  	self 
 |  |  	self 
 | 
											
												
													
														|  | -    	nextPutAll: 'return smalltalk.withContext(function(', anIRClosure scope alias, ') { '; 
 |  | 
 | 
											
												
													
														|  | 
 |  | +    	nextPutAll: 'return smalltalk.withContext(function(', anIRClosure scope alias, ') {'; 
 | 
											
												
													
														|  |          nextPutAll: String cr.
 |  |          nextPutAll: String cr.
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  |      aBlock value.
 |  |      aBlock value.
 | 
											
												
													
														|  | -    self nextPutAll: '})'
 |  | 
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +    self 
 | 
											
												
													
														|  | 
 |  | +    	nextPutAll: '}, function(', anIRClosure scope alias, ') {';
 | 
											
												
													
														|  | 
 |  | +        nextPutAll: anIRClosure scope alias, '.fillBlock({'.
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +    anIRClosure locals 
 | 
											
												
													
														|  | 
 |  | +    	do: [ :each |
 | 
											
												
													
														|  | 
 |  | +    		self 
 | 
											
												
													
														|  | 
 |  | +        		nextPutAll: each asVariableName;
 | 
											
												
													
														|  | 
 |  | +           	 	nextPutAll: ':';
 | 
											
												
													
														|  | 
 |  | +        		nextPutAll: each asVariableName]
 | 
											
												
													
														|  | 
 |  | +		separatedBy: [ self nextPutAll: ',' ].
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +    self
 | 
											
												
													
														|  | 
 |  | +    	nextPutAll: '},';
 | 
											
												
													
														|  | 
 |  | +        nextPutAll:  anIRClosure method scope alias, ')})'
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  nextPutClosureWith: aBlock arguments: anArray
 |  |  nextPutClosureWith: aBlock arguments: anArray
 | 
											
										
											
												
													
														|  | @@ -2911,15 +2992,23 @@ nextPutContextFor: aMethod during: aBlock
 | 
											
												
													
														|  |      	nextPutAll: 'return smalltalk.withContext(function(', aMethod scope alias, ') { '; 
 |  |      	nextPutAll: 'return smalltalk.withContext(function(', aMethod scope alias, ') { '; 
 | 
											
												
													
														|  |          nextPutAll: String cr.
 |  |          nextPutAll: String cr.
 | 
											
												
													
														|  |      aBlock value.
 |  |      aBlock value.
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  |      self 
 |  |      self 
 | 
											
												
													
														|  | -    	nextPutAll: '}, self, ';
 |  | 
 | 
											
												
													
														|  | -        nextPutAll: aMethod selector asJavascript, ', ['.
 |  | 
 | 
											
												
													
														|  | -    aMethod arguments 
 |  | 
 | 
											
												
													
														|  | -    	do: [ :each | self nextPutAll: each asVariableName ]
 |  | 
 | 
											
												
													
														|  | -      	separatedBy: [ self nextPutAll: ','  ].
 |  | 
 | 
											
												
													
														|  | -    self nextPutAll: '], ';
 |  | 
 | 
											
												
													
														|  | 
 |  | +    	nextPutAll: '}, function(', aMethod scope alias, ') {', aMethod scope alias; 
 | 
											
												
													
														|  | 
 |  | +        nextPutAll: '.fill(self,', aMethod selector asJavascript, ',{'.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    aMethod locals 
 | 
											
												
													
														|  | 
 |  | +    	do: [ :each |
 | 
											
												
													
														|  | 
 |  | +    		self 
 | 
											
												
													
														|  | 
 |  | +        		nextPutAll: each asVariableName;
 | 
											
												
													
														|  | 
 |  | +           	 	nextPutAll: ':';
 | 
											
												
													
														|  | 
 |  | +        		nextPutAll: each asVariableName]
 | 
											
												
													
														|  | 
 |  | +		separatedBy: [ self nextPutAll: ',' ].
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +    self
 | 
											
												
													
														|  | 
 |  | +    	nextPutAll: '}, ';
 | 
											
												
													
														|  |          nextPutAll: aMethod theClass asJavascript;
 |  |          nextPutAll: aMethod theClass asJavascript;
 | 
											
												
													
														|  | -        nextPutAll: ')'
 |  | 
 | 
											
												
													
														|  | 
 |  | +        nextPutAll: ')})'
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  nextPutFunctionWith: aBlock arguments: anArray
 |  |  nextPutFunctionWith: aBlock arguments: anArray
 | 
											
										
											
												
													
														|  | @@ -3019,6 +3108,8 @@ nextPutVar: aString
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  nextPutVars: aCollection
 |  |  nextPutVars: aCollection
 | 
											
												
													
														|  | 
 |  | +	aCollection ifEmpty: [ ^self ].
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  |  	stream nextPutAll: 'var '.
 |  |  	stream nextPutAll: 'var '.
 | 
											
												
													
														|  |  	aCollection 
 |  |  	aCollection 
 | 
											
												
													
														|  |  		do: [ :each | stream nextPutAll: each ]
 |  |  		do: [ :each | stream nextPutAll: each ]
 | 
											
										
											
												
													
														|  | @@ -3690,25 +3781,36 @@ irTranslator
 | 
											
												
													
														|  |  ! !
 |  |  ! !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  NodeVisitor subclass: #AIContext
 |  |  NodeVisitor subclass: #AIContext
 | 
											
												
													
														|  | -	instanceVariableNames: 'outerContext pc locals receiver selector'
 |  | 
 | 
											
												
													
														|  | 
 |  | +	instanceVariableNames: 'outerContext pc locals method'
 | 
											
												
													
														|  |  	package:'Compiler'!
 |  |  	package:'Compiler'!
 | 
											
												
													
														|  | 
 |  | +!AIContext commentStamp!
 | 
											
												
													
														|  | 
 |  | +AIContext is like a `MethodContext`, used by the `ASTInterpreter`.
 | 
											
												
													
														|  | 
 |  | +Unlike a `MethodContext`, it is not read-only.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +When debugging, `AIContext` instances are created by copying the current `MethodContext` (thisContext)!
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  !AIContext methodsFor: '*Compiler'!
 |  |  !AIContext methodsFor: '*Compiler'!
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -initializeFromMethodContext: aMethodContext
 |  | 
 | 
											
												
													
														|  | -	self pc: aMethodContext pc.
 |  | 
 | 
											
												
													
														|  | -    self receiver: aMethodContext receiver.
 |  | 
 | 
											
												
													
														|  | -    self selector: aMethodContext selector.
 |  | 
 | 
											
												
													
														|  | -    aMethodContext outerContext ifNotNil: [
 |  | 
 | 
											
												
													
														|  | -		self outerContext: (self class fromMethodContext: aMethodContext outerContext) ].
 |  | 
 | 
											
												
													
														|  | -    aMethodContext locals keysAndValuesDo: [ :key :value |
 |  | 
 | 
											
												
													
														|  | -    	self locals at: key put: value ]
 |  | 
 | 
											
												
													
														|  | 
 |  | +localAt: aString
 | 
											
												
													
														|  | 
 |  | +	^ self locals at: aString ifAbsent: [ nil ]
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +localAt: aString put: anObject
 | 
											
												
													
														|  | 
 |  | +	self locals at: aString put: anObject
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  locals
 |  |  locals
 | 
											
												
													
														|  |  	^ locals ifNil: [ locals := Dictionary new ]
 |  |  	^ locals ifNil: [ locals := Dictionary new ]
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +method
 | 
											
												
													
														|  | 
 |  | +	^ method
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +method: aCompiledMethod
 | 
											
												
													
														|  | 
 |  | +	method := aCompiledMethod
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  outerContext
 |  |  outerContext
 | 
											
												
													
														|  |  	^ outerContext
 |  |  	^ outerContext
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
										
											
												
													
														|  | @@ -3726,41 +3828,177 @@ pc: anInteger
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  receiver
 |  |  receiver
 | 
											
												
													
														|  | -	^ receiver
 |  | 
 | 
											
												
													
														|  | 
 |  | +	^ self localAt: 'self'
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  receiver: anObject
 |  |  receiver: anObject
 | 
											
												
													
														|  | -	receiver := anObject
 |  | 
 | 
											
												
													
														|  | 
 |  | +	self localAt: 'self' put: anObject
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  selector
 |  |  selector
 | 
											
												
													
														|  | -	^ selector
 |  | 
 | 
											
												
													
														|  | -!
 |  | 
 | 
											
												
													
														|  | 
 |  | +	^ self metod
 | 
											
												
													
														|  | 
 |  | +    	ifNotNil: [ self method selector ]
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -selector: aString
 |  | 
 | 
											
												
													
														|  | -	selector := aString
 |  | 
 | 
											
												
													
														|  | 
 |  | +!AIContext methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +initializeFromMethodContext: aMethodContext
 | 
											
												
													
														|  | 
 |  | +	self pc: aMethodContext pc.
 | 
											
												
													
														|  | 
 |  | +    self receiver: aMethodContext receiver.
 | 
											
												
													
														|  | 
 |  | +    self method: aMethodContext method.
 | 
											
												
													
														|  | 
 |  | +    aMethodContext outerContext ifNotNil: [
 | 
											
												
													
														|  | 
 |  | +		self outerContext: (self class fromMethodContext: aMethodContext outerContext) ].
 | 
											
												
													
														|  | 
 |  | +    aMethodContext locals keysAndValuesDo: [ :key :value |
 | 
											
												
													
														|  | 
 |  | +    	self locals at: key put: value ]
 | 
											
												
													
														|  |  ! !
 |  |  ! !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  !AIContext class methodsFor: '*Compiler'!
 |  |  !AIContext class methodsFor: '*Compiler'!
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  fromMethodContext: aMethodContext
 |  |  fromMethodContext: aMethodContext
 | 
											
												
													
														|  | -	^ self new 
 |  | 
 | 
											
												
													
														|  | 
 |  | +	^ self new
 | 
											
												
													
														|  |      	initializeFromMethodContext: aMethodContext;
 |  |      	initializeFromMethodContext: aMethodContext;
 | 
											
												
													
														|  |          yourself
 |  |          yourself
 | 
											
												
													
														|  |  ! !
 |  |  ! !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -NodeVisitor subclass: #ASTInterpreter
 |  | 
 | 
											
												
													
														|  | -	instanceVariableNames: 'currentNode context shouldReturn'
 |  | 
 | 
											
												
													
														|  | 
 |  | +Object subclass: #ASTDebugger
 | 
											
												
													
														|  | 
 |  | +	instanceVariableNames: 'interpreter context'
 | 
											
												
													
														|  |  	package:'Compiler'!
 |  |  	package:'Compiler'!
 | 
											
												
													
														|  | 
 |  | +!ASTDebugger commentStamp!
 | 
											
												
													
														|  | 
 |  | +ASTDebugger is a debugger to Amber.
 | 
											
												
													
														|  | 
 |  | +It uses an AST interpreter to step through the code.
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -!ASTInterpreter methodsFor: '*Compiler'!
 |  | 
 | 
											
												
													
														|  | 
 |  | +ASTDebugger instances are created from a `MethodContext` with `ASTDebugger class >> context:`.
 | 
											
												
													
														|  | 
 |  | +They hold an `AIContext` instance internally, recursive copy of the `MethodContext`.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +Use the methods of the 'stepping' protocol to do stepping.!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!ASTDebugger methodsFor: '*Compiler'!
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  context
 |  |  context
 | 
											
												
													
														|  |  	^ context
 |  |  	^ context
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +context: aContext
 | 
											
												
													
														|  | 
 |  | +	context := AIContext new.
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter
 | 
											
												
													
														|  | 
 |  | +	^ interpreter ifNil: [ interpreter := self defaultInterpreterClass new ]
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter: anInterpreter
 | 
											
												
													
														|  | 
 |  | +	interpreter := anInterpreter
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +method
 | 
											
												
													
														|  | 
 |  | +	^ self context method
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!ASTDebugger methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +defaultInterpreterClass
 | 
											
												
													
														|  | 
 |  | +	^ ASTSteppingInterpreter
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!ASTDebugger methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +buildAST
 | 
											
												
													
														|  | 
 |  | +	"Build the AST tree from the method source code.
 | 
											
												
													
														|  | 
 |  | +    The AST is annotated with a SemanticAnalyzer, 
 | 
											
												
													
														|  | 
 |  | +    to know the semantics and bindings of each node needed for later debugging"
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +    | ast |
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +    ast := Smalltalk current parse: self method source.
 | 
											
												
													
														|  | 
 |  | +    (SemanticAnalyzer on: self context receiver class)
 | 
											
												
													
														|  | 
 |  | +    	visit: ast.    
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +    ^ ast
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +initializeInterpreter
 | 
											
												
													
														|  | 
 |  | +	self interpreter interpret: self buildAST nodes first
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +initializeWithContext: aMethodContext
 | 
											
												
													
														|  | 
 |  | +	"TODO: do we need to handle block contexts?"
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +    self context: (AIContext fromMethodContext: aMethodContext).
 | 
											
												
													
														|  | 
 |  | +    self initializeInterpreter
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!ASTDebugger methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +restart
 | 
											
												
													
														|  | 
 |  | +	self shouldBeImplemented
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +resume
 | 
											
												
													
														|  | 
 |  | +	self shouldBeImplemented
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +step
 | 
											
												
													
														|  | 
 |  | +	"The ASTSteppingInterpreter stops at each node interpretation. 
 | 
											
												
													
														|  | 
 |  | +    One step will interpret nodes until:
 | 
											
												
													
														|  | 
 |  | +    - we get at the end
 | 
											
												
													
														|  | 
 |  | +    - the next node is a stepping node (send, assignment, etc.)"
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +	[ (self interpreter nextNode notNil and: [ self interpreter nextNode stopOnStepping ])
 | 
											
												
													
														|  | 
 |  | +		or: [ self interpreter atEnd not ] ] 
 | 
											
												
													
														|  | 
 |  | + 			whileFalse: [
 | 
											
												
													
														|  | 
 |  | +				self interpreter step. 
 | 
											
												
													
														|  | 
 |  | +                self step ]
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +stepInto
 | 
											
												
													
														|  | 
 |  | +	self shouldBeImplemented
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +stepOver
 | 
											
												
													
														|  | 
 |  | +	self step
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!ASTDebugger class methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +context: aMethodContext
 | 
											
												
													
														|  | 
 |  | +	^ self new
 | 
											
												
													
														|  | 
 |  | +    	initializeWithContext: aMethodContext;
 | 
											
												
													
														|  | 
 |  | +        yourself
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +Object subclass: #ASTInterpreter
 | 
											
												
													
														|  | 
 |  | +	instanceVariableNames: 'currentNode context shouldReturn result'
 | 
											
												
													
														|  | 
 |  | +	package:'Compiler'!
 | 
											
												
													
														|  | 
 |  | +!ASTInterpreter commentStamp!
 | 
											
												
													
														|  | 
 |  | +ASTIntepreter is like a `NodeVisitor`, interpreting nodes one after each other.
 | 
											
												
													
														|  | 
 |  | +It is built using Continuation Passing Style for stepping purposes.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +Usage example:
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    | ast interpreter |
 | 
											
												
													
														|  | 
 |  | +    ast := Smalltalk current parse: 'foo 1+2+4'.
 | 
											
												
													
														|  | 
 |  | +    (SemanticAnalyzer on: Object) visit: ast.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    ASTInterpreter new
 | 
											
												
													
														|  | 
 |  | +        interpret: ast nodes first;
 | 
											
												
													
														|  | 
 |  | +        result "Answers 7"!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!ASTInterpreter methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +context
 | 
											
												
													
														|  | 
 |  | +	^ context ifNil: [ context := AIContext new ]
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  context: anAIContext
 |  |  context: anAIContext
 | 
											
												
													
														|  |  	context := anAIContext
 |  |  	context := anAIContext
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +currentNode
 | 
											
												
													
														|  | 
 |  | +	^ currentNode
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +result
 | 
											
												
													
														|  | 
 |  | +	^ result
 | 
											
												
													
														|  |  ! !
 |  |  ! !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  !ASTInterpreter methodsFor: '*Compiler'!
 |  |  !ASTInterpreter methodsFor: '*Compiler'!
 | 
											
										
											
												
													
														|  | @@ -3774,71 +4012,367 @@ initialize
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  interpret: aNode
 |  |  interpret: aNode
 | 
											
												
													
														|  |  	shouldReturn := false.
 |  |  	shouldReturn := false.
 | 
											
												
													
														|  | -    ^ self interpretNode: aNode
 |  | 
 | 
											
												
													
														|  | 
 |  | +    self interpret: aNode continue: [ :value |
 | 
											
												
													
														|  | 
 |  | +    	result := value ]
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -interpretNode: aNode
 |  | 
 | 
											
												
													
														|  | -	currentNode := aNode.
 |  | 
 | 
											
												
													
														|  | -    ^ self visit: aNode
 |  | 
 | 
											
												
													
														|  | 
 |  | +interpret: aNode continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	shouldReturn ifTrue: [ ^ self ].
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	aNode isNode 
 | 
											
												
													
														|  | 
 |  | +    	ifTrue: [ 	
 | 
											
												
													
														|  | 
 |  | +        	currentNode := aNode.
 | 
											
												
													
														|  | 
 |  | +            self interpretNode: aNode continue: [ :value |
 | 
											
												
													
														|  | 
 |  | +  				self continue: aBlock value: value ] ]
 | 
											
												
													
														|  | 
 |  | +        ifFalse: [ self continue: aBlock value: aNode ]
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -messageFromSendNode: aSendNode
 |  | 
 | 
											
												
													
														|  | -	^ Message new
 |  | 
 | 
											
												
													
														|  | -    	selector: aSendNode selector;
 |  | 
 | 
											
												
													
														|  | -        arguments: (aSendNode arguments collect: [ :each |
 |  | 
 | 
											
												
													
														|  | -        	self interpretNode: each ]);
 |  | 
 | 
											
												
													
														|  | -        yourself
 |  | 
 | 
											
												
													
														|  | -! !
 |  | 
 | 
											
												
													
														|  | 
 |  | +interpretAssignmentNode: aNode continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	self interpret: aNode right continue: [ :value |
 | 
											
												
													
														|  | 
 |  | +    	self 
 | 
											
												
													
														|  | 
 |  | +        	continue: aBlock
 | 
											
												
													
														|  | 
 |  | +            value: (self assign: aNode left to: value) ]
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -!ASTInterpreter methodsFor: '*Compiler'!
 |  | 
 | 
											
												
													
														|  | 
 |  | +interpretBlockNode: aNode continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	"TODO: Context should be set"
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +    self 
 | 
											
												
													
														|  | 
 |  | +    	continue: aBlock 
 | 
											
												
													
														|  | 
 |  | +        value: [ self interpret: aNode nodes first; result ]
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -visitBlockNode: aNode
 |  | 
 | 
											
												
													
														|  | -    ^ [ self interpretNode: aNode nodes first ]
 |  | 
 | 
											
												
													
														|  | 
 |  | +interpretBlockSequenceNode: aNode continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	self interpretSequenceNode: aNode continue: aBlock
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -visitCascadeNode: aNode
 |  | 
 | 
											
												
													
														|  | 
 |  | +interpretCascadeNode: aNode continue: aBlock
 | 
											
												
													
														|  |  	"TODO: Handle super sends"
 |  |  	"TODO: Handle super sends"
 | 
											
												
													
														|  | -	| receiver |
 |  | 
 | 
											
												
													
														|  | -    
 |  | 
 | 
											
												
													
														|  | -    receiver := self interpretNode: aNode receiver.
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -    aNode nodes allButLast
 |  | 
 | 
											
												
													
														|  | -    	do: [ :each | 
 |  | 
 | 
											
												
													
														|  | -        	(self messageFromSendNode: each)
 |  | 
 | 
											
												
													
														|  | -            	sendTo: receiver ].
 |  | 
 | 
											
												
													
														|  | 
 |  | +	
 | 
											
												
													
														|  | 
 |  | +    self interpret: aNode receiver continue: [ :receiver |
 | 
											
												
													
														|  | 
 |  | +		"Only interpret the receiver once"
 | 
											
												
													
														|  | 
 |  | +        aNode nodes do: [ :each | each receiver: receiver ].
 | 
											
												
													
														|  | 
 |  | +  
 | 
											
												
													
														|  | 
 |  | +    	self 
 | 
											
												
													
														|  | 
 |  | +        	interpretAll: aNode nodes allButLast
 | 
											
												
													
														|  | 
 |  | +    		continue: [
 | 
											
												
													
														|  | 
 |  | +              	self 
 | 
											
												
													
														|  | 
 |  | +                	interpret: aNode nodes last
 | 
											
												
													
														|  | 
 |  | +                	continue: [ :val | self continue: aBlock value: val ] ] ]
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    ^ (self messageFromSendNode: aNode nodes last)
 |  | 
 | 
											
												
													
														|  | -            	sendTo: receiver
 |  | 
 | 
											
												
													
														|  | 
 |  | +interpretClassReferenceNode: aNode continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	self continue: aBlock value: (Smalltalk current at: aNode value)
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -visitClassReferenceNode: aNode
 |  | 
 | 
											
												
													
														|  | -	^ Smalltalk current at: aNode value
 |  | 
 | 
											
												
													
														|  | 
 |  | +interpretDynamicArrayNode: aNode continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	self interpretAll: aNode nodes continue: [ :array |
 | 
											
												
													
														|  | 
 |  | +    	self 
 | 
											
												
													
														|  | 
 |  | +        	continue: aBlock
 | 
											
												
													
														|  | 
 |  | +			value: array ]
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -visitJSStatementNode: aNode
 |  | 
 | 
											
												
													
														|  | -	self halt
 |  | 
 | 
											
												
													
														|  | 
 |  | +interpretDynamicDictionaryNode: aNode continue: aBlock
 | 
											
												
													
														|  | 
 |  | +    self interpretAll: aNode nodes continue: [ :array | | hashedCollection |
 | 
											
												
													
														|  | 
 |  | +    	hashedCollection := HashedCollection new.
 | 
											
												
													
														|  | 
 |  | +        array do: [ :each | hashedCollection add: each ].
 | 
											
												
													
														|  | 
 |  | +        self 	
 | 
											
												
													
														|  | 
 |  | +        	continue: aBlock
 | 
											
												
													
														|  | 
 |  | +            value: hashedCollection ]
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -visitReturnNode: aNode
 |  | 
 | 
											
												
													
														|  | 
 |  | +interpretJSStatementNode: aNode continue: aBlock
 | 
											
												
													
														|  |  	shouldReturn := true.
 |  |  	shouldReturn := true.
 | 
											
												
													
														|  | -    ^ self interpretNode: aNode nodes first
 |  | 
 | 
											
												
													
														|  | 
 |  | +	self continue: aBlock value: (self eval: aNode source)
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -visitSendNode: aNode
 |  | 
 | 
											
												
													
														|  | 
 |  | +interpretMethodNode: aNode continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	self interpretAll: aNode nodes continue: [ :array |
 | 
											
												
													
														|  | 
 |  | +    	self continue: aBlock value: array first ]
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpretNode: aNode continue: aBlock
 | 
											
												
													
														|  | 
 |  | +    aNode interpreter: self continue: aBlock
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpretReturnNode: aNode continue: aBlock
 | 
											
												
													
														|  | 
 |  | +    self interpret: aNode nodes first continue: [ :value |
 | 
											
												
													
														|  | 
 |  | +    	shouldReturn := true.
 | 
											
												
													
														|  | 
 |  | +		self continue: aBlock value: value ]
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpretSendNode: aNode continue: aBlock
 | 
											
												
													
														|  |  	"TODO: Handle super sends"
 |  |  	"TODO: Handle super sends"
 | 
											
												
													
														|  |      
 |  |      
 | 
											
												
													
														|  | -    ^ (self messageFromSendNode: aNode)
 |  | 
 | 
											
												
													
														|  | -    	sendTo: (self interpretNode: aNode receiver)
 |  | 
 | 
											
												
													
														|  | 
 |  | +    self interpret: aNode receiver continue: [ :receiver |
 | 
											
												
													
														|  | 
 |  | +    	self interpretAll: aNode arguments continue: [ :args |
 | 
											
												
													
														|  | 
 |  | +    		self 
 | 
											
												
													
														|  | 
 |  | +            	messageFromSendNode: aNode 
 | 
											
												
													
														|  | 
 |  | +                arguments: args
 | 
											
												
													
														|  | 
 |  | +                do: [ :message |
 | 
											
												
													
														|  | 
 |  | +        			self context pc: self context pc + 1.
 | 
											
												
													
														|  | 
 |  | +        			self 
 | 
											
												
													
														|  | 
 |  | +            			continue: aBlock 
 | 
											
												
													
														|  | 
 |  | +                		value: (message sendTo: receiver) ] ] ]
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -visitSequenceNode: aNode
 |  | 
 | 
											
												
													
														|  | -	aNode nodes allButLast do: [ :each | | value |
 |  | 
 | 
											
												
													
														|  | -        value := self interpretNode: each.
 |  | 
 | 
											
												
													
														|  | -		shouldReturn ifTrue: [ ^ value ] ].
 |  | 
 | 
											
												
													
														|  | -    ^ self interpretNode: aNode nodes last
 |  | 
 | 
											
												
													
														|  | 
 |  | +interpretSequenceNode: aNode continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	self interpretAll: aNode nodes continue: [ :array |
 | 
											
												
													
														|  | 
 |  | +    	self continue: aBlock value: array last ]
 | 
											
												
													
														|  |  !
 |  |  !
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -visitValueNode: aNode
 |  | 
 | 
											
												
													
														|  | -	^ aNode value
 |  | 
 | 
											
												
													
														|  | 
 |  | +interpretValueNode: aNode continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	self continue: aBlock value: aNode value
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpretVariableNode: aNode continue: aBlock
 | 
											
												
													
														|  | 
 |  | +    self 
 | 
											
												
													
														|  | 
 |  | +    	continue: aBlock
 | 
											
												
													
														|  | 
 |  | +        value: (aNode binding isInstanceVar
 | 
											
												
													
														|  | 
 |  | +			ifTrue: [ self context receiver instVarAt: aNode value ]
 | 
											
												
													
														|  | 
 |  | +			ifFalse: [ self context localAt: aNode value ])
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!ASTInterpreter methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +assign: aNode to: anObject
 | 
											
												
													
														|  | 
 |  | +	^ aNode binding isInstanceVar 
 | 
											
												
													
														|  | 
 |  | +    	ifTrue: [ self context receiver instVarAt: aNode value put: anObject ]
 | 
											
												
													
														|  | 
 |  | +      	ifFalse: [ self context localAt: aNode value put: anObject ]
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +continue: aBlock value: anObject
 | 
											
												
													
														|  | 
 |  | +	result := anObject.
 | 
											
												
													
														|  | 
 |  | +    aBlock value: anObject
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +eval: aString
 | 
											
												
													
														|  | 
 |  | +	"Evaluate aString as JS source inside an JS function. 
 | 
											
												
													
														|  | 
 |  | +    aString is not sandboxed."
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +    | source function |
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +    source := String streamContents: [ :str |
 | 
											
												
													
														|  | 
 |  | +    	str nextPutAll: '(function('.
 | 
											
												
													
														|  | 
 |  | +        self context locals keys 
 | 
											
												
													
														|  | 
 |  | +        	do: [ :each | str nextPutAll: each ]
 | 
											
												
													
														|  | 
 |  | +          	separatedBy: [ str nextPutAll: ',' ].
 | 
											
												
													
														|  | 
 |  | +        str 
 | 
											
												
													
														|  | 
 |  | +        	nextPutAll: '){ return (function() {';
 | 
											
												
													
														|  | 
 |  | +        	nextPutAll: aString;
 | 
											
												
													
														|  | 
 |  | +            nextPutAll: '})() })' ].
 | 
											
												
													
														|  | 
 |  | +            
 | 
											
												
													
														|  | 
 |  | +	function := Compiler new eval: source.
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +	^ function valueWithPossibleArguments: self context locals values
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpretAll: aCollection continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	self 
 | 
											
												
													
														|  | 
 |  | +    	interpretAll: aCollection 
 | 
											
												
													
														|  | 
 |  | +        continue: aBlock 
 | 
											
												
													
														|  | 
 |  | +        result: OrderedCollection new
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpretAll: nodes continue: aBlock result: aCollection
 | 
											
												
													
														|  | 
 |  | +	nodes isEmpty 
 | 
											
												
													
														|  | 
 |  | +    	ifTrue: [ self continue: aBlock value: aCollection ]
 | 
											
												
													
														|  | 
 |  | +    	ifFalse: [
 | 
											
												
													
														|  | 
 |  | +    		self interpret: nodes first continue: [:value |
 | 
											
												
													
														|  | 
 |  | +    			self 
 | 
											
												
													
														|  | 
 |  | +                	interpretAll: nodes allButFirst 
 | 
											
												
													
														|  | 
 |  | +                    continue: aBlock
 | 
											
												
													
														|  | 
 |  | +  					result: aCollection, { value } ] ]
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +messageFromSendNode: aSendNode arguments: aCollection do: aBlock
 | 
											
												
													
														|  | 
 |  | +    self 
 | 
											
												
													
														|  | 
 |  | +        continue: aBlock
 | 
											
												
													
														|  | 
 |  | +        value: (Message new
 | 
											
												
													
														|  | 
 |  | +    		selector: aSendNode selector;
 | 
											
												
													
														|  | 
 |  | +        	arguments: aCollection;
 | 
											
												
													
														|  | 
 |  | +        	yourself)
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!ASTInterpreter methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +shouldReturn
 | 
											
												
													
														|  | 
 |  | +	^ shouldReturn ifNil: [ false ]
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +ASTInterpreter subclass: #ASTSteppingInterpreter
 | 
											
												
													
														|  | 
 |  | +	instanceVariableNames: 'continuation nextNode'
 | 
											
												
													
														|  | 
 |  | +	package:'Compiler'!
 | 
											
												
													
														|  | 
 |  | +!ASTSteppingInterpreter commentStamp!
 | 
											
												
													
														|  | 
 |  | +ASTSteppingInterpreter is an interpreter with stepping capabilities.
 | 
											
												
													
														|  | 
 |  | +Use `#step` to actually interpret the next node.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +Usage example:
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    | ast interpreter |
 | 
											
												
													
														|  | 
 |  | +    ast := Smalltalk current parse: 'foo 1+2+4'.
 | 
											
												
													
														|  | 
 |  | +    (SemanticAnalyzer on: Object) visit: ast.
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    interpreter := ASTSteppingInterpreter new
 | 
											
												
													
														|  | 
 |  | +        interpret: ast nodes first;
 | 
											
												
													
														|  | 
 |  | +        yourself.
 | 
											
												
													
														|  | 
 |  | +        
 | 
											
												
													
														|  | 
 |  | +    debugger step; step.
 | 
											
												
													
														|  | 
 |  | +    debugger step; step.
 | 
											
												
													
														|  | 
 |  | +    debugger result."Answers 1"
 | 
											
												
													
														|  | 
 |  | +    debugger step.
 | 
											
												
													
														|  | 
 |  | +    debugger result. "Answers 3"
 | 
											
												
													
														|  | 
 |  | +    debugger step.
 | 
											
												
													
														|  | 
 |  | +    debugger result. "Answers 7"!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!ASTSteppingInterpreter methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +nextNode
 | 
											
												
													
														|  | 
 |  | +	^ nextNode
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!ASTSteppingInterpreter methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +initialize
 | 
											
												
													
														|  | 
 |  | +	super initialize.
 | 
											
												
													
														|  | 
 |  | +    continuation := [  ]
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!ASTSteppingInterpreter methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpret: aNode continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	nextNode := aNode.
 | 
											
												
													
														|  | 
 |  | +	continuation := [ 
 | 
											
												
													
														|  | 
 |  | +    	super interpret: aNode continue: aBlock ]
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!ASTSteppingInterpreter methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +step
 | 
											
												
													
														|  | 
 |  | +	continuation value
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!ASTSteppingInterpreter methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +atEnd
 | 
											
												
													
														|  | 
 |  | +	^ self shouldReturn or: [ self nextNode == self currentNode ]
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!Node methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter: anInterpreter continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	^ anInterpreter interpretNode: self continue: aBlock
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +isSteppingNode
 | 
											
												
													
														|  | 
 |  | +	^ false
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!AssignmentNode methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter: anInterpreter continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	^ anInterpreter interpretAssignmentNode: self continue: aBlock
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +isSteppingNode
 | 
											
												
													
														|  | 
 |  | +	^ true
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!BlockNode methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter: anInterpreter continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	^ anInterpreter interpretBlockNode: self continue: aBlock
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +isSteppingNode
 | 
											
												
													
														|  | 
 |  | +	^ true
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!CascadeNode methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter: anInterpreter continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	^ anInterpreter interpretCascadeNode: self continue: aBlock
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!DynamicArrayNode methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter: anInterpreter continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	^ anInterpreter interpretDynamicArrayNode: self continue: aBlock
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +isSteppingNode
 | 
											
												
													
														|  | 
 |  | +	^ true
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!DynamicDictionaryNode methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter: anInterpreter continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	^ anInterpreter interpretDynamicDictionaryNode: self continue: aBlock
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +isSteppingNode
 | 
											
												
													
														|  | 
 |  | +	^ true
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!JSStatementNode methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter: anInterpreter continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	^ anInterpreter interpretJSStatementNode: self continue: aBlock
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +isSteppingNode
 | 
											
												
													
														|  | 
 |  | +	^ true
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!MethodNode methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter: anInterpreter continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	^ anInterpreter interpretMethodNode: self continue: aBlock
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!ReturnNode methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter: anInterpreter continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	^ anInterpreter interpretReturnNode: self continue: aBlock
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!SendNode methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter: anInterpreter continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	^ anInterpreter interpretSendNode: self continue: aBlock
 | 
											
												
													
														|  | 
 |  | +!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +isSteppingNode
 | 
											
												
													
														|  | 
 |  | +	^ true
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!SequenceNode methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter: anInterpreter continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	^ anInterpreter interpretSequenceNode: self continue: aBlock
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!BlockSequenceNode methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter: anInterpreter continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	^ anInterpreter interpretBlockSequenceNode: self continue: aBlock
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!ValueNode methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter: anInterpreter continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	^ anInterpreter interpretValueNode: self continue: aBlock
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!VariableNode methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter: anInterpreter continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	^ anInterpreter interpretVariableNode: self continue: aBlock
 | 
											
												
													
														|  | 
 |  | +! !
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +!ClassReferenceNode methodsFor: '*Compiler'!
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +interpreter: anInterpreter continue: aBlock
 | 
											
												
													
														|  | 
 |  | +	^ anInterpreter interpretClassReferenceNode: self continue: aBlock
 | 
											
												
													
														|  |  ! !
 |  |  ! !
 | 
											
												
													
														|  |  
 |  |  
 |