| 
					
				 | 
			
			
				@@ -1,5 +1,5 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.addPackage('Compiler-Interpreter'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-smalltalk.addClass('AIContext', smalltalk.NodeVisitor, ['outerContext', 'innerContext', 'pc', 'locals', 'method', 'ast', 'interpreter'], 'Compiler-Interpreter'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+smalltalk.addClass('AIContext', smalltalk.NodeVisitor, ['outerContext', 'innerContext', 'pc', 'locals', 'method', 'ast', 'interpreter', 'methodContext'], 'Compiler-Interpreter'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.AIContext.comment="I am like a `MethodContext`, used by the `ASTInterpreter`.\x0aUnlike a `MethodContext`, my instances are not read-only.\x0a\x0aWhen debugging, my instances are created by copying the current `MethodContext` (thisContext)"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.addMethod( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.method({ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -17,7 +17,7 @@ return $1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }, function($ctx1) {$ctx1.fill(self,"arguments",{},smalltalk.AIContext)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 source: "arguments\x0a\x09^ self ast arguments collect: [ :each |\x0a\x09\x09self localAt: each ]", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["collect:", "localAt:", "arguments", "ast"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["collect:", "arguments", "ast", "localAt:"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.AIContext); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -593,7 +593,7 @@ return $1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }, function($ctx1) {$ctx1.fill(self,"buildAST",{ast:ast},smalltalk.ASTDebugger)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 source: "buildAST\x0a\x09\x22Build the AST tree from the method source code.\x0a\x09The AST is annotated with a SemanticAnalyzer,\x0a\x09to know the semantics and bindings of each node needed for later debugging\x22\x0a\x09\x0a\x09| ast |\x0a\x09\x0a\x09ast := Smalltalk current parse: self method source.\x0a\x09(SemanticAnalyzer on: self context receiver class)\x0a\x09\x09visit: ast.\x0a\x09\x0a\x09^ ast", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["parse:", "source", "method", "current", "visit:", "on:", "class", "receiver", "context"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["parse:", "current", "source", "method", "visit:", "on:", "class", "receiver", "context"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: ["Smalltalk", "SemanticAnalyzer"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.ASTDebugger); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -671,7 +671,7 @@ _st(self._interpreter())._interpret_(next); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return self}, function($ctx1) {$ctx1.fill(self,"initializeInterpreter",{ast:ast,next:next},smalltalk.ASTDebugger)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 source: "initializeInterpreter\x0a\x09| ast next |\x0a\x09ast := self buildAST.\x0a\x09next := ASTPCNodeVisitor new\x0a\x09\x09context: self context;\x0a\x09\x09visit: ast;\x0a\x09\x09currentNode.\x0a\x09self interpreter interpret: next", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["buildAST", "context:", "context", "new", "visit:", "currentNode", "interpret:", "interpreter"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["buildAST", "context:", "new", "context", "visit:", "currentNode", "interpret:", "interpreter"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: ["ASTPCNodeVisitor"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.ASTDebugger); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -825,7 +825,7 @@ return self._step(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return self}, function($ctx1) {$ctx1.fill(self,"step",{},smalltalk.ASTDebugger)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 source: "step\x0a\x09\x22The ASTSteppingInterpreter stops at each node interpretation.\x0a\x09One step will interpret nodes until:\x0a\x09- we get at the end\x0a\x09- the next node is a stepping node (send, assignment, etc.)\x22\x0a\x09\x0a\x09[ (self interpreter nextNode notNil and: [ self interpreter nextNode stopOnStepping ])\x0a\x09\x09or: [ self interpreter atEnd not ] ]\x0a\x09\x09\x09whileFalse: [\x0a\x09\x09\x09\x09self interpreter step.\x0a\x09\x09\x09\x09self step ]", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["whileFalse:", "step", "interpreter", "or:", "not", "atEnd", "and:", "stopOnStepping", "nextNode", "notNil"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["whileFalse:", "or:", "and:", "notNil", "nextNode", "interpreter", "stopOnStepping", "not", "atEnd", "step"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.ASTDebugger); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -905,7 +905,7 @@ return $1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }, function($ctx1) {$ctx1.fill(self,"assign:to:",{aNode:aNode,anObject:anObject},smalltalk.ASTInterpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: ["aNode", "anObject"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 source: "assign: aNode to: anObject\x0a\x09^ aNode binding isInstanceVar\x0a\x09\x09ifTrue: [ self context receiver instVarAt: aNode value put: anObject ]\x0a\x09\x09ifFalse: [ self context localAt: aNode value put: anObject ]", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["ifTrue:ifFalse:", "instVarAt:put:", "value", "receiver", "context", "localAt:put:", "isInstanceVar", "binding"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["ifTrue:ifFalse:", "isInstanceVar", "binding", "instVarAt:put:", "receiver", "context", "value", "localAt:put:"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.ASTInterpreter); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1089,7 +1089,7 @@ self._continue_value_(aBlock,aNode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return self}, function($ctx1) {$ctx1.fill(self,"interpret:continue:",{aNode:aNode,aBlock:aBlock},smalltalk.ASTInterpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: ["aNode", "aBlock"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 source: "interpret: aNode continue: aBlock\x0a\x09shouldReturn ifTrue: [ ^ self ].\x0a\x0a\x09aNode isNode\x0a\x09\x09ifTrue: [\x0a\x09\x09\x09currentNode := aNode.\x0a\x09\x09\x09self interpretNode: aNode continue: [ :value |\x0a\x09\x09\x09\x09self continue: aBlock value: value ] ]\x0a\x09\x09ifFalse: [ self continue: aBlock value: aNode ]", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["ifTrue:", "ifTrue:ifFalse:", "interpretNode:continue:", "continue:value:", "isNode"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["ifTrue:", "ifTrue:ifFalse:", "isNode", "interpretNode:continue:", "continue:value:"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.ASTInterpreter); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1131,7 +1131,7 @@ return self._interpretAll_continue_result_(_st(nodes)._allButFirst(),aBlock,_st( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return self}, function($ctx1) {$ctx1.fill(self,"interpretAll:continue:result:",{nodes:nodes,aBlock:aBlock,aCollection:aCollection},smalltalk.ASTInterpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: ["nodes", "aBlock", "aCollection"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 source: "interpretAll: nodes continue: aBlock result: aCollection\x0a\x09nodes isEmpty\x0a\x09\x09ifTrue: [ self continue: aBlock value: aCollection ]\x0a\x09\x09ifFalse: [\x0a\x09\x09\x09self interpret: nodes first continue: [:value |\x0a\x09\x09\x09\x09self\x0a\x09\x09\x09\x09\x09interpretAll: nodes allButFirst\x0a\x09\x09\x09\x09\x09continue: aBlock\x0a\x09\x09\x09\x09\x09result: aCollection, { value } ] ]", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["ifTrue:ifFalse:", "continue:value:", "interpret:continue:", "first", "interpretAll:continue:result:", "allButFirst", ",", "isEmpty"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["ifTrue:ifFalse:", "isEmpty", "continue:value:", "interpret:continue:", "first", "interpretAll:continue:result:", "allButFirst", ","], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.ASTInterpreter); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1221,7 +1221,7 @@ return self._continue_value_(aBlock,val); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return self}, function($ctx1) {$ctx1.fill(self,"interpretCascadeNode:continue:",{aNode:aNode,aBlock:aBlock},smalltalk.ASTInterpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: ["aNode", "aBlock"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 source: "interpretCascadeNode: aNode continue: aBlock\x0a\x09\x22TODO: Handle super sends\x22\x0a\x09\x0a\x09self interpret: aNode receiver continue: [ :receiver |\x0a\x09\x09\x22Only interpret the receiver once\x22\x0a\x09\x09aNode nodes do: [ :each | each receiver: receiver ].\x0a\x0a\x09\x09self\x0a\x09\x09\x09interpretAll: aNode nodes allButLast\x0a\x09\x09\x09continue: [\x0a\x09\x09\x09\x09self\x0a\x09\x09\x09\x09\x09interpret: aNode nodes last\x0a\x09\x09\x09\x09\x09continue: [ :val | self continue: aBlock value: val ] ] ]", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["interpret:continue:", "receiver", "do:", "receiver:", "nodes", "interpretAll:continue:", "allButLast", "last", "continue:value:"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["interpret:continue:", "receiver", "do:", "nodes", "receiver:", "interpretAll:continue:", "allButLast", "last", "continue:value:"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.ASTInterpreter); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1238,7 +1238,7 @@ self._continue_value_(aBlock,_st(_st($Smalltalk())._current())._at_(_st(aNode)._ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return self}, function($ctx1) {$ctx1.fill(self,"interpretClassReferenceNode:continue:",{aNode:aNode,aBlock:aBlock},smalltalk.ASTInterpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: ["aNode", "aBlock"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 source: "interpretClassReferenceNode: aNode continue: aBlock\x0a\x09self continue: aBlock value: (Smalltalk current at: aNode value)", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["continue:value:", "at:", "value", "current"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["continue:value:", "at:", "current", "value"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: ["Smalltalk"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.ASTInterpreter); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1383,7 +1383,7 @@ return self._continue_value_(aBlock,self._sendMessage_to_superSend_(message,rece 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return self}, function($ctx1) {$ctx1.fill(self,"interpretSendNode:continue:",{aNode:aNode,aBlock:aBlock},smalltalk.ASTInterpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: ["aNode", "aBlock"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 source: "interpretSendNode: aNode continue: aBlock\x0a\x09self interpret: aNode receiver continue: [ :receiver |\x0a\x09\x09self interpretAll: aNode arguments continue: [ :args |\x0a\x09\x09\x09self\x0a\x09\x09\x09\x09messageFromSendNode: aNode\x0a\x09\x09\x09\x09arguments: args\x0a\x09\x09\x09\x09do: [ :message |\x0a\x09\x09\x09\x09\x09self context pc: self context pc + 1.\x0a\x09\x09\x09\x09\x09self\x0a\x09\x09\x09\x09\x09\x09continue: aBlock\x0a\x09\x09\x09\x09\x09\x09value: (self sendMessage: message to: receiver superSend: aNode superSend) ] ] ]", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["interpret:continue:", "receiver", "interpretAll:continue:", "arguments", "messageFromSendNode:arguments:do:", "pc:", "+", "pc", "context", "continue:value:", "sendMessage:to:superSend:", "superSend"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["interpret:continue:", "receiver", "interpretAll:continue:", "arguments", "messageFromSendNode:arguments:do:", "pc:", "context", "+", "pc", "continue:value:", "sendMessage:to:superSend:", "superSend"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.ASTInterpreter); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1443,7 +1443,7 @@ _st($1)._continue_value_($2,$3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return self}, function($ctx1) {$ctx1.fill(self,"interpretVariableNode:continue:",{aNode:aNode,aBlock:aBlock},smalltalk.ASTInterpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: ["aNode", "aBlock"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 source: "interpretVariableNode: aNode continue: aBlock\x0a\x09self\x0a\x09\x09continue: aBlock\x0a\x09\x09value: (aNode binding isInstanceVar\x0a\x09\x09\x09ifTrue: [ self context receiver instVarAt: aNode value ]\x0a\x09\x09\x09ifFalse: [ self context localAt: aNode value ])", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["continue:value:", "ifTrue:ifFalse:", "instVarAt:", "value", "receiver", "context", "localAt:", "isInstanceVar", "binding"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["continue:value:", "ifTrue:ifFalse:", "isInstanceVar", "binding", "instVarAt:", "receiver", "context", "value", "localAt:"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.ASTInterpreter); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1465,7 +1465,7 @@ self._continue_value_(aBlock,$2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return self}, function($ctx1) {$ctx1.fill(self,"messageFromSendNode:arguments:do:",{aSendNode:aSendNode,aCollection:aCollection,aBlock:aBlock},smalltalk.ASTInterpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: ["aSendNode", "aCollection", "aBlock"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 source: "messageFromSendNode: aSendNode arguments: aCollection do: aBlock\x0a\x09self\x0a\x09\x09continue: aBlock\x0a\x09\x09value: (Message new\x0a\x09\x09\x09selector: aSendNode selector;\x0a\x09\x09\x09arguments: aCollection;\x0a\x09\x09\x09yourself)", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["continue:value:", "selector:", "selector", "new", "arguments:", "yourself"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["continue:value:", "selector:", "new", "selector", "arguments:", "yourself"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: ["Message"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.ASTInterpreter); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1562,7 +1562,7 @@ catch(e) {if(e===$early)return e[0]; throw e} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }, function($ctx1) {$ctx1.fill(self,"sendMessage:to:superSend:",{aMessage:aMessage,anObject:anObject,aBoolean:aBoolean,method:method},smalltalk.ASTInterpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: ["aMessage", "anObject", "aBoolean"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 source: "sendMessage: aMessage to: anObject superSend: aBoolean\x0a\x09| method |\x0a\x09\x0a\x09aBoolean ifFalse: [ ^ aMessage sendTo: anObject ].\x0a\x09anObject class superclass ifNil: [ ^ self messageNotUnderstood: aMessage receiver: anObject ].\x0a\x09\x0a\x09method := anObject class superclass methodDictionary\x0a\x09\x09at: aMessage selector\x0a\x09\x09ifAbsent: [ ^ self messageNotUnderstood: aMessage receiver: anObject ].\x0a\x09\x09\x0a\x09^ method fn applyTo: anObject arguments: aMessage arguments\x0a\x09\x09\x0a\x09\x0a\x09", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["ifFalse:", "sendTo:", "ifNil:", "messageNotUnderstood:receiver:", "superclass", "class", "at:ifAbsent:", "selector", "methodDictionary", "applyTo:arguments:", "arguments", "fn"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["ifFalse:", "sendTo:", "ifNil:", "superclass", "class", "messageNotUnderstood:receiver:", "at:ifAbsent:", "methodDictionary", "selector", "applyTo:arguments:", "fn", "arguments"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.ASTInterpreter); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1611,7 +1611,7 @@ return $3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }, function($ctx1) {$ctx1.fill(self,"withBlockContext:",{aBlock:aBlock,blockResult:blockResult},smalltalk.ASTInterpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: ["aBlock"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 source: "withBlockContext: aBlock\x0a\x09\x22Evaluate aBlock with a BlockContext:\x0a\x09- a context is pushed before aBlock evaluation.\x0a\x09- the context is poped after aBlock evaluation\x0a\x09- the result of aBlock evaluation is answered\x22\x0a\x09\x0a\x09| blockResult |\x0a\x09\x09\x09\x0a\x09self context: (AIContext new\x0a\x09\x09outerContext: self context;\x0a\x09\x09yourself).\x0a\x09\x0a\x09blockResult := aBlock value.\x0a\x09\x0a\x09self context: self context outerContext.\x0a\x09^ blockResult", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["context:", "outerContext:", "context", "new", "yourself", "value", "outerContext"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["context:", "outerContext:", "new", "context", "yourself", "value", "outerContext"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: ["AIContext"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.ASTInterpreter); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1636,7 +1636,7 @@ return $1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }, function($ctx1) {$ctx1.fill(self,"atEnd",{},smalltalk.ASTSteppingInterpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 source: "atEnd\x0a\x09^ self shouldReturn or: [ self nextNode == self currentNode ]", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["or:", "==", "currentNode", "nextNode", "shouldReturn"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["or:", "shouldReturn", "==", "nextNode", "currentNode"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.ASTSteppingInterpreter); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2024,6 +2024,23 @@ referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.Interpreter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+smalltalk.addMethod( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+smalltalk.method({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+selector: "interpret:", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+category: 'interpreting', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+fn: function (aNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var self=this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return smalltalk.withContext(function($ctx1) {  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+self._node_(aNode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+self._interpret(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return self}, function($ctx1) {$ctx1.fill(self,"interpret:",{aNode:aNode},smalltalk.Interpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+args: ["aNode"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+source: "interpret: aNode\x0a\x09self node: aNode.\x0a\x09self interpret", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["node:", "interpret"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+smalltalk.Interpreter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.addMethod( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.method({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 selector: "messageFromSendNode:arguments:", 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2166,15 +2183,15 @@ var self=this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return smalltalk.withContext(function($ctx1) {  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 _st((function(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return smalltalk.withContext(function($ctx2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-return _st(self._node())._notNil(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileTrue_((function(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return self._atEnd(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileFalse_((function(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return smalltalk.withContext(function($ctx2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return self._step(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return self}, function($ctx1) {$ctx1.fill(self,"proceed",{},smalltalk.Interpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-source: "proceed\x0a\x09\x22Eagerly evaluate the ast\x22\x0a\x09\x0a\x09[ self node notNil ] whileTrue: [ \x0a\x09\x09self step ]", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["whileTrue:", "step", "notNil", "node"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+source: "proceed\x0a\x09\x22Eagerly evaluate the ast\x22\x0a\x09\x0a\x09[ self atEnd ] whileFalse: [ \x0a\x09\x09self step ]", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["whileFalse:", "atEnd", "step"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.Interpreter); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2199,23 +2216,41 @@ smalltalk.Interpreter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.addMethod( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.method({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-selector: "returnValue", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+selector: "result", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 category: 'accessing', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 fn: function (){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 var self=this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return smalltalk.withContext(function($ctx1) {  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 var $2,$1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-$2=self["@returnValue"]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+$2=self._returnValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 if(($receiver = $2) == nil || $receiver == undefined){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 $1=_st(self._context())._receiver(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 $1=$2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return $1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}, function($ctx1) {$ctx1.fill(self,"result",{},smalltalk.Interpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+args: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+source: "result\x0a\x09^ self returnValue ifNil: [ self context receiver ]", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["ifNil:", "returnValue", "receiver", "context"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+smalltalk.Interpreter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+smalltalk.addMethod( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+smalltalk.method({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+selector: "returnValue", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+category: 'accessing', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+fn: function (){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var self=this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return smalltalk.withContext(function($ctx1) {  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var $1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+$1=self["@returnValue"]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return $1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }, function($ctx1) {$ctx1.fill(self,"returnValue",{},smalltalk.Interpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-source: "returnValue\x0a\x09^ returnValue ifNil: [ self context receiver ]", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["ifNil:", "receiver", "context"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+source: "returnValue\x0a\x09^ returnValue", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.Interpreter); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2284,12 +2319,12 @@ fn: function (){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 var self=this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return smalltalk.withContext(function($ctx1) {  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 var $1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-$1=_st(self["@returnValue"])._notNil(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+$1=_st(self._returnValue())._notNil(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return $1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }, function($ctx1) {$ctx1.fill(self,"shouldReturn",{},smalltalk.Interpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-source: "shouldReturn\x0a\x09^ returnValue notNil", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["notNil"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+source: "shouldReturn\x0a\x09^ self returnValue notNil", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["notNil", "returnValue"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.Interpreter); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2380,12 +2415,57 @@ selector: "visitAssignmentNode:", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 category: 'visiting', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 fn: function (aNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 var self=this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return smalltalk.withContext(function($ctx1) {  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+value=self._pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+self._pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+self._push_(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+self._assign_to_(_st(aNode)._left(),value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return self}, function($ctx1) {$ctx1.fill(self,"visitAssignmentNode:",{aNode:aNode,value:value},smalltalk.Interpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+args: ["aNode"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+source: "visitAssignmentNode: aNode\x0a\x09| value |\x0a\x09\x0a\x09value := self pop.\x0a\x09\x0a\x09\x22Pop the left side of the assignment.\x0a\x09It already has been visited, and we don't need its value.\x22\x0a\x09self pop.\x0a\x09\x0a\x09self push: value.\x0a\x09self assign: aNode left to: value", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["pop", "push:", "assign:to:", "left"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+smalltalk.Interpreter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+smalltalk.addMethod( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+smalltalk.method({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+selector: "visitBlockNode:", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+category: 'visiting', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+fn: function (aNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var self=this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var blockNode,blockContext,block,interpreter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return smalltalk.withContext(function($ctx1) {  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-self._assign_to_(_st(aNode)._left(),self._peek()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-return self}, function($ctx1) {$ctx1.fill(self,"visitAssignmentNode:",{aNode:aNode},smalltalk.Interpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var $1,$2,$3,$4,$5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+blockNode=_st(_st(_st(aNode)._nodes())._first())._copy(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+_st(blockNode)._parent_(nil); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+$1=_st(_st(self._context())._class())._new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+_st($1)._outerContext_(self._context()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+$2=_st($1)._yourself(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+blockContext=$2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+block=(function(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return smalltalk.withContext(function($ctx2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+interpreter=_st(self._class())._new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+interpreter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+$3=interpreter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+_st($3)._context_(blockContext); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+_st($3)._node_(_st(blockNode)._nextChild()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+$4=_st($3)._proceed(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+$4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+self._returnValue_(_st(interpreter)._returnValue()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+$5=_st(_st(interpreter)._stack())._isEmpty(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+if(smalltalk.assert($5)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return nil; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return _st(interpreter)._pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+self._push_(block); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return self}, function($ctx1) {$ctx1.fill(self,"visitBlockNode:",{aNode:aNode,blockNode:blockNode,blockContext:blockContext,block:block,interpreter:interpreter},smalltalk.Interpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: ["aNode"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-source: "visitAssignmentNode: aNode\x0a\x09\x22Do not pop as the pushed value would be the right node\x22\x0a\x09\x0a\x09self assign: aNode left to: self peek", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["assign:to:", "left", "peek"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+source: "visitBlockNode: aNode\x0a\x09\x22Do not evaluate the block node.\x0a\x09Instead, put all instructions into a block that we push to the stack for later evaluation\x22\x0a\x09\x0a\x09| blockNode blockContext block interpreter |\x0a\x09\x0a\x09\x22Copy the sequence node without the parent to avoid evaluating nodes up the block. \x0a\x09#nextNode should not go anymore up than the block itself\x22\x0a\x09blockNode := aNode nodes first copy.\x0a\x09blockNode parent: nil.\x0a\x09\x09\x0a\x09blockContext := self context class new\x0a\x09\x09outerContext: self context;\x0a\x09\x09yourself.\x0a\x09\x0a\x09block := [\x0a\x09\x09interpreter := self class new.\x0a\x09\x09interpreter\x0a\x09\x09\x09context: blockContext;\x0a\x09\x09\x09node: blockNode nextChild;\x0a\x09\x09\x09proceed.\x0a\x09\x09\x0a\x09\x09\x22Non local returns hanlding\x22\x0a\x09\x09self returnValue: interpreter returnValue.\x0a\x09\x09\x0a\x09\x09\x22Answer the last evaluation of the block or nil\x22\x0a\x09\x09interpreter stack isEmpty\x0a\x09\x09\x09ifTrue: [ nil ]\x0a\x09\x09\x09ifFalse: [ interpreter pop ] ].\x0a\x09\x0a\x09self push: block", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["copy", "first", "nodes", "parent:", "outerContext:", "new", "class", "context", "yourself", "context:", "node:", "nextChild", "proceed", "returnValue:", "returnValue", "ifTrue:ifFalse:", "isEmpty", "stack", "pop", "push:"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.Interpreter); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2407,6 +2487,51 @@ referencedClasses: ["Smalltalk"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.Interpreter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+smalltalk.addMethod( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+smalltalk.method({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+selector: "visitDynamicArrayNode:", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+category: 'visiting', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+fn: function (aNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var self=this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var array; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return smalltalk.withContext(function($ctx1) {  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+array=[]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+_st(_st(aNode)._nodes())._do_((function(each){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return smalltalk.withContext(function($ctx2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return _st(array)._addFirst_(self._pop()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})})); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+self._push_(array); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return self}, function($ctx1) {$ctx1.fill(self,"visitDynamicArrayNode:",{aNode:aNode,array:array},smalltalk.Interpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+args: ["aNode"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+source: "visitDynamicArrayNode: aNode\x0a\x09| array |\x0a\x09\x0a\x09array := #().\x0a\x09aNode nodes do: [ :each |\x0a\x09\x09array addFirst: self pop ].\x0a\x09\x0a\x09self push: array", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["do:", "nodes", "addFirst:", "pop", "push:"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+smalltalk.Interpreter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+smalltalk.addMethod( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+smalltalk.method({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+selector: "visitDynamicDictionaryNode:", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+category: 'visiting', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+fn: function (aNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var self=this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var hashedCollection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function $HashedCollection(){return smalltalk.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return smalltalk.withContext(function($ctx1) {  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+hashedCollection=_st($HashedCollection())._new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+_st(_st(aNode)._nodes())._do_((function(each){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return smalltalk.withContext(function($ctx2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return _st(hashedCollection)._add_(self._pop()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})})); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+self._push_(hashedCollection); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return self}, function($ctx1) {$ctx1.fill(self,"visitDynamicDictionaryNode:",{aNode:aNode,hashedCollection:hashedCollection},smalltalk.Interpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+args: ["aNode"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+source: "visitDynamicDictionaryNode: aNode\x0a\x09| hashedCollection |\x0a\x09\x0a\x09hashedCollection := HashedCollection new.\x0a\x09aNode nodes do: [ :each | \x0a\x09\x09hashedCollection add: self pop ].\x0a\x09\x0a\x09self push: hashedCollection", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["new", "do:", "nodes", "add:", "pop", "push:"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+referencedClasses: ["HashedCollection"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+smalltalk.Interpreter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.addMethod( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.method({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 selector: "visitJSStatementNode:", 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -2462,18 +2587,28 @@ fn: function (aNode){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 var self=this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 var receiver,args,message,result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return smalltalk.withContext(function($ctx1) {  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var $1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args=_st(_st(aNode)._arguments())._collect_((function(each){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return smalltalk.withContext(function($ctx2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return self._pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})})); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 receiver=self._pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-message=self._messageFromSendNode_arguments_(aNode,args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+message=self._messageFromSendNode_arguments_(aNode,_st(args)._reversed()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 result=self._sendMessage_to_superSend_(message,receiver,_st(aNode)._superSend()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+_st(self._context())._pc_(_st(_st(self._context())._pc()).__plus((1))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+$1=_st(_st(aNode)._isCascadeSendNode())._and_((function(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return smalltalk.withContext(function($ctx2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+return _st(_st(aNode)._isLastChild())._not(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+if(smalltalk.assert($1)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+self._push_(receiver); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 self._push_(result); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 return self}, function($ctx1) {$ctx1.fill(self,"visitSendNode:",{aNode:aNode,receiver:receiver,args:args,message:message,result:result},smalltalk.Interpreter)})}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 args: ["aNode"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-source: "visitSendNode: aNode\x0a\x09| receiver args message result |\x0a\x09\x0a\x09args := aNode arguments collect: [ :each |\x0a\x09\x09self pop ].\x0a\x09receiver := self pop.\x0a\x09\x0a\x09message := self\x0a\x09\x09messageFromSendNode: aNode\x0a\x09\x09arguments: args.\x0a\x09\x0a\x09result := self sendMessage: message to: receiver superSend: aNode superSend.\x0a\x09\x0a\x09self push: result", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-messageSends: ["collect:", "pop", "arguments", "messageFromSendNode:arguments:", "sendMessage:to:superSend:", "superSend", "push:"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+source: "visitSendNode: aNode\x0a\x09| receiver args message result |\x0a\x09\x0a\x09args := aNode arguments collect: [ :each | self pop ].\x0a\x09receiver := self pop.\x0a\x09\x0a\x09message := self\x0a\x09\x09messageFromSendNode: aNode\x0a\x09\x09arguments: args reversed.\x0a\x09\x0a\x09result := self sendMessage: message to: receiver superSend: aNode superSend.\x0a\x09\x0a\x09self context pc: self context pc + 1.\x0a\x09\x0a\x09\x22For cascade sends, push the reciever if the send is not the last one\x22\x0a\x09(aNode isCascadeSendNode and: [ aNode isLastChild not ])\x0a\x09\x09ifTrue: [ self push: receiver ]\x0a\x09\x09ifFalse: [ self push: result ]", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+messageSends: ["collect:", "arguments", "pop", "messageFromSendNode:arguments:", "reversed", "sendMessage:to:superSend:", "superSend", "pc:", "context", "+", "pc", "ifTrue:ifFalse:", "and:", "isCascadeSendNode", "not", "isLastChild", "push:"], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 referencedClasses: [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 smalltalk.Interpreter); 
			 |