|
@@ -1,5 +1,5 @@
|
|
smalltalk.addPackage('Compiler-Interpreter');
|
|
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.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.addMethod(
|
|
smalltalk.method({
|
|
smalltalk.method({
|
|
@@ -17,7 +17,7 @@ return $1;
|
|
}, function($ctx1) {$ctx1.fill(self,"arguments",{},smalltalk.AIContext)})},
|
|
}, function($ctx1) {$ctx1.fill(self,"arguments",{},smalltalk.AIContext)})},
|
|
args: [],
|
|
args: [],
|
|
source: "arguments\x0a\x09^ self ast arguments collect: [ :each |\x0a\x09\x09self localAt: each ]",
|
|
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: []
|
|
referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.AIContext);
|
|
smalltalk.AIContext);
|
|
@@ -593,7 +593,7 @@ return $1;
|
|
}, function($ctx1) {$ctx1.fill(self,"buildAST",{ast:ast},smalltalk.ASTDebugger)})},
|
|
}, function($ctx1) {$ctx1.fill(self,"buildAST",{ast:ast},smalltalk.ASTDebugger)})},
|
|
args: [],
|
|
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",
|
|
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"]
|
|
referencedClasses: ["Smalltalk", "SemanticAnalyzer"]
|
|
}),
|
|
}),
|
|
smalltalk.ASTDebugger);
|
|
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)})},
|
|
return self}, function($ctx1) {$ctx1.fill(self,"initializeInterpreter",{ast:ast,next:next},smalltalk.ASTDebugger)})},
|
|
args: [],
|
|
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",
|
|
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"]
|
|
referencedClasses: ["ASTPCNodeVisitor"]
|
|
}),
|
|
}),
|
|
smalltalk.ASTDebugger);
|
|
smalltalk.ASTDebugger);
|
|
@@ -825,7 +825,7 @@ return self._step();
|
|
return self}, function($ctx1) {$ctx1.fill(self,"step",{},smalltalk.ASTDebugger)})},
|
|
return self}, function($ctx1) {$ctx1.fill(self,"step",{},smalltalk.ASTDebugger)})},
|
|
args: [],
|
|
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 ]",
|
|
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: []
|
|
referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.ASTDebugger);
|
|
smalltalk.ASTDebugger);
|
|
@@ -905,7 +905,7 @@ return $1;
|
|
}, function($ctx1) {$ctx1.fill(self,"assign:to:",{aNode:aNode,anObject:anObject},smalltalk.ASTInterpreter)})},
|
|
}, function($ctx1) {$ctx1.fill(self,"assign:to:",{aNode:aNode,anObject:anObject},smalltalk.ASTInterpreter)})},
|
|
args: ["aNode", "anObject"],
|
|
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 ]",
|
|
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: []
|
|
referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.ASTInterpreter);
|
|
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)})},
|
|
return self}, function($ctx1) {$ctx1.fill(self,"interpret:continue:",{aNode:aNode,aBlock:aBlock},smalltalk.ASTInterpreter)})},
|
|
args: ["aNode", "aBlock"],
|
|
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 ]",
|
|
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: []
|
|
referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.ASTInterpreter);
|
|
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)})},
|
|
return self}, function($ctx1) {$ctx1.fill(self,"interpretAll:continue:result:",{nodes:nodes,aBlock:aBlock,aCollection:aCollection},smalltalk.ASTInterpreter)})},
|
|
args: ["nodes", "aBlock", "aCollection"],
|
|
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 } ] ]",
|
|
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: []
|
|
referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.ASTInterpreter);
|
|
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)})},
|
|
return self}, function($ctx1) {$ctx1.fill(self,"interpretCascadeNode:continue:",{aNode:aNode,aBlock:aBlock},smalltalk.ASTInterpreter)})},
|
|
args: ["aNode", "aBlock"],
|
|
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 ] ] ]",
|
|
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: []
|
|
referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.ASTInterpreter);
|
|
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)})},
|
|
return self}, function($ctx1) {$ctx1.fill(self,"interpretClassReferenceNode:continue:",{aNode:aNode,aBlock:aBlock},smalltalk.ASTInterpreter)})},
|
|
args: ["aNode", "aBlock"],
|
|
args: ["aNode", "aBlock"],
|
|
source: "interpretClassReferenceNode: aNode continue: aBlock\x0a\x09self continue: aBlock value: (Smalltalk current at: aNode value)",
|
|
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"]
|
|
referencedClasses: ["Smalltalk"]
|
|
}),
|
|
}),
|
|
smalltalk.ASTInterpreter);
|
|
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)})},
|
|
return self}, function($ctx1) {$ctx1.fill(self,"interpretSendNode:continue:",{aNode:aNode,aBlock:aBlock},smalltalk.ASTInterpreter)})},
|
|
args: ["aNode", "aBlock"],
|
|
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) ] ] ]",
|
|
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: []
|
|
referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.ASTInterpreter);
|
|
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)})},
|
|
return self}, function($ctx1) {$ctx1.fill(self,"interpretVariableNode:continue:",{aNode:aNode,aBlock:aBlock},smalltalk.ASTInterpreter)})},
|
|
args: ["aNode", "aBlock"],
|
|
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 ])",
|
|
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: []
|
|
referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.ASTInterpreter);
|
|
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)})},
|
|
return self}, function($ctx1) {$ctx1.fill(self,"messageFromSendNode:arguments:do:",{aSendNode:aSendNode,aCollection:aCollection,aBlock:aBlock},smalltalk.ASTInterpreter)})},
|
|
args: ["aSendNode", "aCollection", "aBlock"],
|
|
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)",
|
|
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"]
|
|
referencedClasses: ["Message"]
|
|
}),
|
|
}),
|
|
smalltalk.ASTInterpreter);
|
|
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)})},
|
|
}, function($ctx1) {$ctx1.fill(self,"sendMessage:to:superSend:",{aMessage:aMessage,anObject:anObject,aBoolean:aBoolean,method:method},smalltalk.ASTInterpreter)})},
|
|
args: ["aMessage", "anObject", "aBoolean"],
|
|
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",
|
|
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: []
|
|
referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.ASTInterpreter);
|
|
smalltalk.ASTInterpreter);
|
|
@@ -1611,7 +1611,7 @@ return $3;
|
|
}, function($ctx1) {$ctx1.fill(self,"withBlockContext:",{aBlock:aBlock,blockResult:blockResult},smalltalk.ASTInterpreter)})},
|
|
}, function($ctx1) {$ctx1.fill(self,"withBlockContext:",{aBlock:aBlock,blockResult:blockResult},smalltalk.ASTInterpreter)})},
|
|
args: ["aBlock"],
|
|
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",
|
|
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"]
|
|
referencedClasses: ["AIContext"]
|
|
}),
|
|
}),
|
|
smalltalk.ASTInterpreter);
|
|
smalltalk.ASTInterpreter);
|
|
@@ -1636,7 +1636,7 @@ return $1;
|
|
}, function($ctx1) {$ctx1.fill(self,"atEnd",{},smalltalk.ASTSteppingInterpreter)})},
|
|
}, function($ctx1) {$ctx1.fill(self,"atEnd",{},smalltalk.ASTSteppingInterpreter)})},
|
|
args: [],
|
|
args: [],
|
|
source: "atEnd\x0a\x09^ self shouldReturn or: [ self nextNode == self currentNode ]",
|
|
source: "atEnd\x0a\x09^ self shouldReturn or: [ self nextNode == self currentNode ]",
|
|
-messageSends: ["or:", "==", "currentNode", "nextNode", "shouldReturn"],
|
|
|
|
|
|
+messageSends: ["or:", "shouldReturn", "==", "nextNode", "currentNode"],
|
|
referencedClasses: []
|
|
referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.ASTSteppingInterpreter);
|
|
smalltalk.ASTSteppingInterpreter);
|
|
@@ -2024,6 +2024,23 @@ referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.Interpreter);
|
|
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.addMethod(
|
|
smalltalk.method({
|
|
smalltalk.method({
|
|
selector: "messageFromSendNode:arguments:",
|
|
selector: "messageFromSendNode:arguments:",
|
|
@@ -2166,15 +2183,15 @@ var self=this;
|
|
return smalltalk.withContext(function($ctx1) {
|
|
return smalltalk.withContext(function($ctx1) {
|
|
_st((function(){
|
|
_st((function(){
|
|
return smalltalk.withContext(function($ctx2) {
|
|
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 smalltalk.withContext(function($ctx2) {
|
|
return self._step();
|
|
return self._step();
|
|
}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
|
|
}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
|
|
return self}, function($ctx1) {$ctx1.fill(self,"proceed",{},smalltalk.Interpreter)})},
|
|
return self}, function($ctx1) {$ctx1.fill(self,"proceed",{},smalltalk.Interpreter)})},
|
|
args: [],
|
|
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: []
|
|
referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.Interpreter);
|
|
smalltalk.Interpreter);
|
|
@@ -2199,23 +2216,41 @@ smalltalk.Interpreter);
|
|
|
|
|
|
smalltalk.addMethod(
|
|
smalltalk.addMethod(
|
|
smalltalk.method({
|
|
smalltalk.method({
|
|
-selector: "returnValue",
|
|
|
|
|
|
+selector: "result",
|
|
category: 'accessing',
|
|
category: 'accessing',
|
|
fn: function (){
|
|
fn: function (){
|
|
var self=this;
|
|
var self=this;
|
|
return smalltalk.withContext(function($ctx1) {
|
|
return smalltalk.withContext(function($ctx1) {
|
|
var $2,$1;
|
|
var $2,$1;
|
|
-$2=self["@returnValue"];
|
|
|
|
|
|
+$2=self._returnValue();
|
|
if(($receiver = $2) == nil || $receiver == undefined){
|
|
if(($receiver = $2) == nil || $receiver == undefined){
|
|
$1=_st(self._context())._receiver();
|
|
$1=_st(self._context())._receiver();
|
|
} else {
|
|
} else {
|
|
$1=$2;
|
|
$1=$2;
|
|
};
|
|
};
|
|
return $1;
|
|
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)})},
|
|
}, function($ctx1) {$ctx1.fill(self,"returnValue",{},smalltalk.Interpreter)})},
|
|
args: [],
|
|
args: [],
|
|
-source: "returnValue\x0a\x09^ returnValue ifNil: [ self context receiver ]",
|
|
|
|
-messageSends: ["ifNil:", "receiver", "context"],
|
|
|
|
|
|
+source: "returnValue\x0a\x09^ returnValue",
|
|
|
|
+messageSends: [],
|
|
referencedClasses: []
|
|
referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.Interpreter);
|
|
smalltalk.Interpreter);
|
|
@@ -2284,12 +2319,12 @@ fn: function (){
|
|
var self=this;
|
|
var self=this;
|
|
return smalltalk.withContext(function($ctx1) {
|
|
return smalltalk.withContext(function($ctx1) {
|
|
var $1;
|
|
var $1;
|
|
-$1=_st(self["@returnValue"])._notNil();
|
|
|
|
|
|
+$1=_st(self._returnValue())._notNil();
|
|
return $1;
|
|
return $1;
|
|
}, function($ctx1) {$ctx1.fill(self,"shouldReturn",{},smalltalk.Interpreter)})},
|
|
}, function($ctx1) {$ctx1.fill(self,"shouldReturn",{},smalltalk.Interpreter)})},
|
|
args: [],
|
|
args: [],
|
|
-source: "shouldReturn\x0a\x09^ returnValue notNil",
|
|
|
|
-messageSends: ["notNil"],
|
|
|
|
|
|
+source: "shouldReturn\x0a\x09^ self returnValue notNil",
|
|
|
|
+messageSends: ["notNil", "returnValue"],
|
|
referencedClasses: []
|
|
referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.Interpreter);
|
|
smalltalk.Interpreter);
|
|
@@ -2380,12 +2415,57 @@ selector: "visitAssignmentNode:",
|
|
category: 'visiting',
|
|
category: 'visiting',
|
|
fn: function (aNode){
|
|
fn: function (aNode){
|
|
var self=this;
|
|
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) {
|
|
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"],
|
|
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: []
|
|
referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.Interpreter);
|
|
smalltalk.Interpreter);
|
|
@@ -2407,6 +2487,51 @@ referencedClasses: ["Smalltalk"]
|
|
}),
|
|
}),
|
|
smalltalk.Interpreter);
|
|
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.addMethod(
|
|
smalltalk.method({
|
|
smalltalk.method({
|
|
selector: "visitJSStatementNode:",
|
|
selector: "visitJSStatementNode:",
|
|
@@ -2462,18 +2587,28 @@ fn: function (aNode){
|
|
var self=this;
|
|
var self=this;
|
|
var receiver,args,message,result;
|
|
var receiver,args,message,result;
|
|
return smalltalk.withContext(function($ctx1) {
|
|
return smalltalk.withContext(function($ctx1) {
|
|
|
|
+var $1;
|
|
args=_st(_st(aNode)._arguments())._collect_((function(each){
|
|
args=_st(_st(aNode)._arguments())._collect_((function(each){
|
|
return smalltalk.withContext(function($ctx2) {
|
|
return smalltalk.withContext(function($ctx2) {
|
|
return self._pop();
|
|
return self._pop();
|
|
}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
|
|
}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
|
|
receiver=self._pop();
|
|
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());
|
|
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);
|
|
self._push_(result);
|
|
|
|
+};
|
|
return self}, function($ctx1) {$ctx1.fill(self,"visitSendNode:",{aNode:aNode,receiver:receiver,args:args,message:message,result:result},smalltalk.Interpreter)})},
|
|
return self}, function($ctx1) {$ctx1.fill(self,"visitSendNode:",{aNode:aNode,receiver:receiver,args:args,message:message,result:result},smalltalk.Interpreter)})},
|
|
args: ["aNode"],
|
|
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: []
|
|
referencedClasses: []
|
|
}),
|
|
}),
|
|
smalltalk.Interpreter);
|
|
smalltalk.Interpreter);
|