|  | @@ -1,58 +1,4 @@
 | 
	
		
			
				|  |  |  smalltalk.addPackage('Compiler-Interpreter', {});
 | 
	
		
			
				|  |  | -smalltalk.addClass('ASTBlockClosure', smalltalk.BlockClosure, ['astNode'], 'Compiler-Interpreter');
 | 
	
		
			
				|  |  | -smalltalk.ASTBlockClosure.comment="ASTBlockClosure is polymorph with BlockClosure. \x0aAn ASTBlockClosure is used to interpret a BlockNode, and override all \x22primitive\x22 methods (#value and co)."
 | 
	
		
			
				|  |  | -smalltalk.addMethod(
 | 
	
		
			
				|  |  | -"_astNode",
 | 
	
		
			
				|  |  | -smalltalk.method({
 | 
	
		
			
				|  |  | -selector: "astNode",
 | 
	
		
			
				|  |  | -category: 'accessing',
 | 
	
		
			
				|  |  | -fn: function (){
 | 
	
		
			
				|  |  | -var self=this;
 | 
	
		
			
				|  |  | -return self["@astNode"];
 | 
	
		
			
				|  |  | -},
 | 
	
		
			
				|  |  | -args: [],
 | 
	
		
			
				|  |  | -source: "astNode\x0a\x09^ astNode",
 | 
	
		
			
				|  |  | -messageSends: [],
 | 
	
		
			
				|  |  | -referencedClasses: []
 | 
	
		
			
				|  |  | -}),
 | 
	
		
			
				|  |  | -smalltalk.ASTBlockClosure);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -smalltalk.addMethod(
 | 
	
		
			
				|  |  | -"_astNode_",
 | 
	
		
			
				|  |  | -smalltalk.method({
 | 
	
		
			
				|  |  | -selector: "astNode:",
 | 
	
		
			
				|  |  | -category: 'accessing',
 | 
	
		
			
				|  |  | -fn: function (aNode){
 | 
	
		
			
				|  |  | -var self=this;
 | 
	
		
			
				|  |  | -self["@astNode"]=aNode;
 | 
	
		
			
				|  |  | -return self},
 | 
	
		
			
				|  |  | -args: ["aNode"],
 | 
	
		
			
				|  |  | -source: "astNode: aNode\x0a\x09astNode := aNode",
 | 
	
		
			
				|  |  | -messageSends: [],
 | 
	
		
			
				|  |  | -referencedClasses: []
 | 
	
		
			
				|  |  | -}),
 | 
	
		
			
				|  |  | -smalltalk.ASTBlockClosure);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -smalltalk.addMethod(
 | 
	
		
			
				|  |  | -"_value",
 | 
	
		
			
				|  |  | -smalltalk.method({
 | 
	
		
			
				|  |  | -selector: "value",
 | 
	
		
			
				|  |  | -category: 'evaluating',
 | 
	
		
			
				|  |  | -fn: function (){
 | 
	
		
			
				|  |  | -var self=this;
 | 
	
		
			
				|  |  | -var $1;
 | 
	
		
			
				|  |  | -$1=smalltalk.send(smalltalk.send((smalltalk.ASTInterpreter || ASTInterpreter),"_current",[]),"_blockValue_",[self]);
 | 
	
		
			
				|  |  | -return $1;
 | 
	
		
			
				|  |  | -},
 | 
	
		
			
				|  |  | -args: [],
 | 
	
		
			
				|  |  | -source: "value\x0a\x09^ ASTInterpreter current blockValue: self",
 | 
	
		
			
				|  |  | -messageSends: ["blockValue:", "current"],
 | 
	
		
			
				|  |  | -referencedClasses: ["ASTInterpreter"]
 | 
	
		
			
				|  |  | -}),
 | 
	
		
			
				|  |  | -smalltalk.ASTBlockClosure);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  smalltalk.addClass('ASTInterpreter', smalltalk.NodeVisitor, ['currentNode', 'context', 'shouldReturn'], 'Compiler-Interpreter');
 | 
	
		
			
				|  |  |  smalltalk.addMethod(
 | 
	
		
			
				|  |  |  "_blockValue_",
 | 
	
	
		
			
				|  | @@ -184,17 +130,16 @@ selector: "visitBlockNode:",
 | 
	
		
			
				|  |  |  category: 'visiting',
 | 
	
		
			
				|  |  |  fn: function (aNode){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  | -var $2,$3,$1;
 | 
	
		
			
				|  |  | -$2=smalltalk.send((smalltalk.ASTBlockClosure || ASTBlockClosure),"_new",[]);
 | 
	
		
			
				|  |  | -smalltalk.send($2,"_astNode_",[aNode]);
 | 
	
		
			
				|  |  | -$3=smalltalk.send($2,"_yourself",[]);
 | 
	
		
			
				|  |  | -$1=$3;
 | 
	
		
			
				|  |  | +var $1;
 | 
	
		
			
				|  |  | +$1=(function(){
 | 
	
		
			
				|  |  | +return _st(self)._interpretNode_(_st(_st(aNode)._nodes())._first());
 | 
	
		
			
				|  |  | +});
 | 
	
		
			
				|  |  |  return $1;
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  args: ["aNode"],
 | 
	
		
			
				|  |  | -source: "visitBlockNode: aNode\x0a\x09^ ASTBlockClosure new\x0a    \x09astNode: aNode;\x0a        yourself",
 | 
	
		
			
				|  |  | -messageSends: ["astNode:", "new", "yourself"],
 | 
	
		
			
				|  |  | -referencedClasses: ["ASTBlockClosure"]
 | 
	
		
			
				|  |  | +source: "visitBlockNode: aNode\x0a    ^ [ self interpretNode: aNode nodes first ]",
 | 
	
		
			
				|  |  | +messageSends: ["interpretNode:", "first", "nodes"],
 | 
	
		
			
				|  |  | +referencedClasses: []
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  |  smalltalk.ASTInterpreter);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -207,12 +152,12 @@ fn: function (aNode){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  |  var $1;
 | 
	
		
			
				|  |  |  self["@shouldReturn"]=true;
 | 
	
		
			
				|  |  | -$1=smalltalk.send(self,"_interpret_",[smalltalk.send(smalltalk.send(aNode,"_nodes",[]),"_first",[])]);
 | 
	
		
			
				|  |  | +$1=_st(self)._interpretNode_(_st(_st(aNode)._nodes())._first());
 | 
	
		
			
				|  |  |  return $1;
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  args: ["aNode"],
 | 
	
		
			
				|  |  | -source: "visitReturnNode: aNode\x0a\x09shouldReturn := true.\x0a    ^ self interpret: aNode nodes first",
 | 
	
		
			
				|  |  | -messageSends: ["interpret:", "first", "nodes"],
 | 
	
		
			
				|  |  | +source: "visitReturnNode: aNode\x0a\x09shouldReturn := true.\x0a    ^ self interpretNode: aNode nodes first",
 | 
	
		
			
				|  |  | +messageSends: ["interpretNode:", "first", "nodes"],
 | 
	
		
			
				|  |  |  referencedClasses: []
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  |  smalltalk.ASTInterpreter);
 | 
	
	
		
			
				|  | @@ -227,16 +172,16 @@ var self=this;
 | 
	
		
			
				|  |  |  var $1;
 | 
	
		
			
				|  |  |  var receiver;
 | 
	
		
			
				|  |  |  var arguments;
 | 
	
		
			
				|  |  | -receiver=smalltalk.send(self,"_interpret_",[smalltalk.send(aNode,"_receiver",[])]);
 | 
	
		
			
				|  |  | -arguments=smalltalk.send(smalltalk.send(aNode,"_arguments",[]),"_collect_",[(function(each){
 | 
	
		
			
				|  |  | -return smalltalk.send(self,"_interpret_",[each]);
 | 
	
		
			
				|  |  | -})]);
 | 
	
		
			
				|  |  | -$1=smalltalk.send(self,"_send_to_arguments_",[smalltalk.send(aNode,"_selector",[]),receiver,arguments]);
 | 
	
		
			
				|  |  | +receiver=_st(self)._interpretNode_(_st(aNode)._receiver());
 | 
	
		
			
				|  |  | +arguments=_st(_st(aNode)._arguments())._collect_((function(each){
 | 
	
		
			
				|  |  | +return _st(self)._interpretNode_(each);
 | 
	
		
			
				|  |  | +}));
 | 
	
		
			
				|  |  | +$1=_st(self)._send_to_arguments_(_st(aNode)._selector(),receiver,arguments);
 | 
	
		
			
				|  |  |  return $1;
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  args: ["aNode"],
 | 
	
		
			
				|  |  | -source: "visitSendNode: aNode\x0a\x09\x22TODO: Handle super sends\x22\x0a\x09| receiver arguments |\x0a    \x0a    receiver := self interpret: aNode receiver.\x0a    arguments := aNode arguments collect: [ :each |\x0a\x09\x09self interpret: each ].\x0a    \x0a    ^ self send: aNode selector to: receiver arguments: arguments",
 | 
	
		
			
				|  |  | -messageSends: ["interpret:", "receiver", "collect:", "arguments", "send:to:arguments:", "selector"],
 | 
	
		
			
				|  |  | +source: "visitSendNode: aNode\x0a\x09\x22TODO: Handle super sends\x22\x0a\x09| receiver arguments |\x0a    \x0a    receiver := self interpretNode: aNode receiver.\x0a    arguments := aNode arguments collect: [ :each |\x0a\x09\x09self interpretNode: each ].\x0a    \x0a    ^ self send: aNode selector to: receiver arguments: arguments",
 | 
	
		
			
				|  |  | +messageSends: ["interpretNode:", "receiver", "collect:", "arguments", "send:to:arguments:", "selector"],
 | 
	
		
			
				|  |  |  referencedClasses: []
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  |  smalltalk.ASTInterpreter);
 | 
	
	
		
			
				|  | @@ -251,22 +196,22 @@ var self=this;
 | 
	
		
			
				|  |  |  var $1;
 | 
	
		
			
				|  |  |  var $early={};
 | 
	
		
			
				|  |  |  try {
 | 
	
		
			
				|  |  | -smalltalk.send(smalltalk.send(smalltalk.send(aNode,"_nodes",[]),"_allButLast",[]),"_do_",[(function(each){
 | 
	
		
			
				|  |  | +_st(_st(_st(aNode)._nodes())._allButLast())._do_((function(each){
 | 
	
		
			
				|  |  |  var value;
 | 
	
		
			
				|  |  | -value=smalltalk.send(self,"_interpret_",[each]);
 | 
	
		
			
				|  |  | +value=_st(self)._interpretNode_(each);
 | 
	
		
			
				|  |  |  value;
 | 
	
		
			
				|  |  |  if(smalltalk.assert(self["@shouldReturn"])){
 | 
	
		
			
				|  |  |  throw $early=[value];
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  | -})]);
 | 
	
		
			
				|  |  | -$1=smalltalk.send(self,"_interpret_",[smalltalk.send(smalltalk.send(aNode,"_nodes",[]),"_last",[])]);
 | 
	
		
			
				|  |  | +}));
 | 
	
		
			
				|  |  | +$1=_st(self)._interpretNode_(_st(_st(aNode)._nodes())._last());
 | 
	
		
			
				|  |  |  return $1;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  catch(e) {if(e===$early)return e[0]; throw e}
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  |  args: ["aNode"],
 | 
	
		
			
				|  |  | -source: "visitSequenceNode: aNode\x0a\x09aNode nodes allButLast do: [ :each | | value |\x0a        value := self interpret: each.\x0a\x09\x09shouldReturn ifTrue: [ ^ value ] ].\x0a    ^ self interpret: aNode nodes last",
 | 
	
		
			
				|  |  | -messageSends: ["do:", "interpret:", "ifTrue:", "allButLast", "nodes", "last"],
 | 
	
		
			
				|  |  | +source: "visitSequenceNode: aNode\x0a\x09aNode nodes allButLast do: [ :each | | value |\x0a        value := self interpretNode: each.\x0a\x09\x09shouldReturn ifTrue: [ ^ value ] ].\x0a    ^ self interpretNode: aNode nodes last",
 | 
	
		
			
				|  |  | +messageSends: ["do:", "interpretNode:", "ifTrue:", "allButLast", "nodes", "last"],
 | 
	
		
			
				|  |  |  referencedClasses: []
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  |  smalltalk.ASTInterpreter);
 | 
	
	
		
			
				|  | @@ -290,44 +235,110 @@ referencedClasses: []
 | 
	
		
			
				|  |  |  smalltalk.ASTInterpreter);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -smalltalk.ASTInterpreter.klass.iVarNames = ['current'];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +smalltalk.addClass('ASTInterpretorTest', smalltalk.TestCase, [], 'Compiler-Interpreter');
 | 
	
		
			
				|  |  |  smalltalk.addMethod(
 | 
	
		
			
				|  |  | -"_current",
 | 
	
		
			
				|  |  | +"_analyze_forClass_",
 | 
	
		
			
				|  |  |  smalltalk.method({
 | 
	
		
			
				|  |  | -selector: "current",
 | 
	
		
			
				|  |  | -category: 'instance creation',
 | 
	
		
			
				|  |  | -fn: function (){
 | 
	
		
			
				|  |  | +selector: "analyze:forClass:",
 | 
	
		
			
				|  |  | +category: 'accessing',
 | 
	
		
			
				|  |  | +fn: function (aNode,aClass){
 | 
	
		
			
				|  |  | +var self=this;
 | 
	
		
			
				|  |  | +_st(_st((smalltalk.SemanticAnalyzer || SemanticAnalyzer))._on_(aClass))._visit_(aNode);
 | 
	
		
			
				|  |  | +return aNode;
 | 
	
		
			
				|  |  | +},
 | 
	
		
			
				|  |  | +args: ["aNode", "aClass"],
 | 
	
		
			
				|  |  | +source: "analyze: aNode forClass: aClass\x0a\x09(SemanticAnalyzer on: aClass) visit: aNode.\x0a    ^ aNode",
 | 
	
		
			
				|  |  | +messageSends: ["visit:", "on:"],
 | 
	
		
			
				|  |  | +referencedClasses: ["SemanticAnalyzer"]
 | 
	
		
			
				|  |  | +}),
 | 
	
		
			
				|  |  | +smalltalk.ASTInterpretorTest);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +smalltalk.addMethod(
 | 
	
		
			
				|  |  | +"_interpret_",
 | 
	
		
			
				|  |  | +smalltalk.method({
 | 
	
		
			
				|  |  | +selector: "interpret:",
 | 
	
		
			
				|  |  | +category: 'accessing',
 | 
	
		
			
				|  |  | +fn: function (aString){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  |  var $1;
 | 
	
		
			
				|  |  | -if(($receiver = self["@current"]) == nil || $receiver == undefined){
 | 
	
		
			
				|  |  | -self["@current"]=smalltalk.send(self,"_new",[],smalltalk.NodeVisitor.klass);
 | 
	
		
			
				|  |  | -$1=self["@current"];
 | 
	
		
			
				|  |  | -} else {
 | 
	
		
			
				|  |  | -$1=self["@current"];
 | 
	
		
			
				|  |  | -};
 | 
	
		
			
				|  |  | +$1=_st(_st((smalltalk.ASTInterpreter || ASTInterpreter))._new())._interpret_(_st(_st(_st(self)._parse_forClass_(aString,(smalltalk.Object || Object)))._nodes())._first());
 | 
	
		
			
				|  |  | +return $1;
 | 
	
		
			
				|  |  | +},
 | 
	
		
			
				|  |  | +args: ["aString"],
 | 
	
		
			
				|  |  | +source: "interpret: aString\x0a\x09\x22the food is a methodNode. Interpret the sequenceNode only\x22\x0a    ^ ASTInterpreter new\x0a    \x09interpret: (self parse: aString forClass: Object) \x0a        \x09nodes first",
 | 
	
		
			
				|  |  | +messageSends: ["interpret:", "first", "nodes", "parse:forClass:", "new"],
 | 
	
		
			
				|  |  | +referencedClasses: ["Object", "ASTInterpreter"]
 | 
	
		
			
				|  |  | +}),
 | 
	
		
			
				|  |  | +smalltalk.ASTInterpretorTest);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +smalltalk.addMethod(
 | 
	
		
			
				|  |  | +"_parse_",
 | 
	
		
			
				|  |  | +smalltalk.method({
 | 
	
		
			
				|  |  | +selector: "parse:",
 | 
	
		
			
				|  |  | +category: 'accessing',
 | 
	
		
			
				|  |  | +fn: function (aString){
 | 
	
		
			
				|  |  | +var self=this;
 | 
	
		
			
				|  |  | +var $1;
 | 
	
		
			
				|  |  | +$1=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._parse_(aString);
 | 
	
		
			
				|  |  | +return $1;
 | 
	
		
			
				|  |  | +},
 | 
	
		
			
				|  |  | +args: ["aString"],
 | 
	
		
			
				|  |  | +source: "parse: aString\x0a\x09^ Smalltalk current parse: aString",
 | 
	
		
			
				|  |  | +messageSends: ["parse:", "current"],
 | 
	
		
			
				|  |  | +referencedClasses: ["Smalltalk"]
 | 
	
		
			
				|  |  | +}),
 | 
	
		
			
				|  |  | +smalltalk.ASTInterpretorTest);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +smalltalk.addMethod(
 | 
	
		
			
				|  |  | +"_parse_forClass_",
 | 
	
		
			
				|  |  | +smalltalk.method({
 | 
	
		
			
				|  |  | +selector: "parse:forClass:",
 | 
	
		
			
				|  |  | +category: 'accessing',
 | 
	
		
			
				|  |  | +fn: function (aString,aClass){
 | 
	
		
			
				|  |  | +var self=this;
 | 
	
		
			
				|  |  | +var $1;
 | 
	
		
			
				|  |  | +$1=_st(self)._analyze_forClass_(_st(self)._parse_(aString),aClass);
 | 
	
		
			
				|  |  |  return $1;
 | 
	
		
			
				|  |  |  },
 | 
	
		
			
				|  |  | +args: ["aString", "aClass"],
 | 
	
		
			
				|  |  | +source: "parse: aString forClass: aClass\x0a\x09^ self analyze: (self parse: aString) forClass: aClass",
 | 
	
		
			
				|  |  | +messageSends: ["analyze:forClass:", "parse:"],
 | 
	
		
			
				|  |  | +referencedClasses: []
 | 
	
		
			
				|  |  | +}),
 | 
	
		
			
				|  |  | +smalltalk.ASTInterpretorTest);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +smalltalk.addMethod(
 | 
	
		
			
				|  |  | +"_testBinarySend",
 | 
	
		
			
				|  |  | +smalltalk.method({
 | 
	
		
			
				|  |  | +selector: "testBinarySend",
 | 
	
		
			
				|  |  | +category: 'tests',
 | 
	
		
			
				|  |  | +fn: function (){
 | 
	
		
			
				|  |  | +var self=this;
 | 
	
		
			
				|  |  | +_st(self)._assert_equals_(_st(self)._interpret_("foo 2+3+4"),(9));
 | 
	
		
			
				|  |  | +return self},
 | 
	
		
			
				|  |  |  args: [],
 | 
	
		
			
				|  |  | -source: "current\x0a\x09^ current ifNil: [ current := super new ]",
 | 
	
		
			
				|  |  | -messageSends: ["ifNil:", "new"],
 | 
	
		
			
				|  |  | +source: "testBinarySend\x0a\x09self assert: (self interpret: 'foo 2+3+4') equals: 9",
 | 
	
		
			
				|  |  | +messageSends: ["assert:equals:", "interpret:"],
 | 
	
		
			
				|  |  |  referencedClasses: []
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  | -smalltalk.ASTInterpreter.klass);
 | 
	
		
			
				|  |  | +smalltalk.ASTInterpretorTest);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  smalltalk.addMethod(
 | 
	
		
			
				|  |  | -"_new",
 | 
	
		
			
				|  |  | +"_testBlockLiteral",
 | 
	
		
			
				|  |  |  smalltalk.method({
 | 
	
		
			
				|  |  | -selector: "new",
 | 
	
		
			
				|  |  | -category: 'instance creation',
 | 
	
		
			
				|  |  | +selector: "testBlockLiteral",
 | 
	
		
			
				|  |  | +category: 'tests',
 | 
	
		
			
				|  |  |  fn: function (){
 | 
	
		
			
				|  |  |  var self=this;
 | 
	
		
			
				|  |  | -smalltalk.send(self,"_shouldNotImplement",[]);
 | 
	
		
			
				|  |  | +_st(self)._assert_(false);
 | 
	
		
			
				|  |  |  return self},
 | 
	
		
			
				|  |  |  args: [],
 | 
	
		
			
				|  |  | -source: "new\x0a\x09self shouldNotImplement",
 | 
	
		
			
				|  |  | -messageSends: ["shouldNotImplement"],
 | 
	
		
			
				|  |  | +source: "testBlockLiteral\x0a\x09self assert: false",
 | 
	
		
			
				|  |  | +messageSends: ["assert:"],
 | 
	
		
			
				|  |  |  referencedClasses: []
 | 
	
		
			
				|  |  |  }),
 | 
	
		
			
				|  |  | -smalltalk.ASTInterpreter.klass);
 | 
	
		
			
				|  |  | +smalltalk.ASTInterpretorTest);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 |