Compiler-Interpreter.js 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. smalltalk.addPackage('Compiler-Interpreter', {});
  2. smalltalk.addClass('AIContext', smalltalk.NodeVisitor, ['outerContext', 'pc', 'locals', 'selector'], 'Compiler-Interpreter');
  3. smalltalk.addMethod(
  4. "_initializeFromMethodContext_",
  5. smalltalk.method({
  6. selector: "initializeFromMethodContext:",
  7. category: 'accessing',
  8. fn: function (aMethodContext){
  9. var self=this;
  10. return smalltalk.withContext(function($ctx1) { var $1;
  11. _st(self)._pc_(_st(aMethodContext)._pc());
  12. _st(self)._receiver_(_st(aMethodContext)._receiver());
  13. _st(self)._selector_(_st(aMethodContext)._selector());
  14. $1=_st(aMethodContext)._outerContext();
  15. if(($receiver = $1) == nil || $receiver == undefined){
  16. $1;
  17. } else {
  18. _st(self)._outerContext_(_st(_st(self)._class())._fromMethodContext_(_st(aMethodContext)._outerContext()));
  19. };
  20. _st(_st(aMethodContext)._locals())._keysAndValuesDo_((function(key,value){
  21. return smalltalk.withContext(function($ctx2) { return _st(_st(self)._locals())._at_put_(key,value);
  22. }, function($ctx2) {$ctx2.fillBlock({key:key,value:value},$ctx1)})}));
  23. return self}, function($ctx1) {$ctx1.fill(self,"initializeFromMethodContext:",{aMethodContext:aMethodContext}, smalltalk.AIContext)})},
  24. args: ["aMethodContext"],
  25. source: "initializeFromMethodContext: aMethodContext\x0a\x09self pc: aMethodContext pc.\x0a self receiver: aMethodContext receiver.\x0a self selector: aMethodContext selector.\x0a aMethodContext outerContext ifNotNil: [\x0a\x09\x09self outerContext: (self class fromMethodContext: aMethodContext outerContext) ].\x0a aMethodContext locals keysAndValuesDo: [ :key :value |\x0a \x09self locals at: key put: value ]\x0a ",
  26. messageSends: ["pc:", "pc", "receiver:", "receiver", "selector:", "selector", "ifNotNil:", "outerContext:", "fromMethodContext:", "outerContext", "class", "keysAndValuesDo:", "at:put:", "locals"],
  27. referencedClasses: []
  28. }),
  29. smalltalk.AIContext);
  30. smalltalk.addMethod(
  31. "_localAt_",
  32. smalltalk.method({
  33. selector: "localAt:",
  34. category: 'accessing',
  35. fn: function (aString){
  36. var self=this;
  37. return smalltalk.withContext(function($ctx1) { var $1;
  38. $1=_st(_st(self)._locals())._at_ifAbsent_(aString,(function(){
  39. return smalltalk.withContext(function($ctx2) { return nil;
  40. }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
  41. return $1;
  42. }, function($ctx1) {$ctx1.fill(self,"localAt:",{aString:aString}, smalltalk.AIContext)})},
  43. args: ["aString"],
  44. source: "localAt: aString\x0a\x09^ self locals at: aString ifAbsent: [ nil ]",
  45. messageSends: ["at:ifAbsent:", "locals"],
  46. referencedClasses: []
  47. }),
  48. smalltalk.AIContext);
  49. smalltalk.addMethod(
  50. "_localAt_put_",
  51. smalltalk.method({
  52. selector: "localAt:put:",
  53. category: 'accessing',
  54. fn: function (aString,anObject){
  55. var self=this;
  56. return smalltalk.withContext(function($ctx1) { _st(_st(self)._locals())._at_put_(aString,anObject);
  57. return self}, function($ctx1) {$ctx1.fill(self,"localAt:put:",{aString:aString,anObject:anObject}, smalltalk.AIContext)})},
  58. args: ["aString", "anObject"],
  59. source: "localAt: aString put: anObject\x0a\x09self locals at: aString put: anObject",
  60. messageSends: ["at:put:", "locals"],
  61. referencedClasses: []
  62. }),
  63. smalltalk.AIContext);
  64. smalltalk.addMethod(
  65. "_locals",
  66. smalltalk.method({
  67. selector: "locals",
  68. category: 'accessing',
  69. fn: function (){
  70. var self=this;
  71. return smalltalk.withContext(function($ctx1) { var $2,$1;
  72. $2=self["@locals"];
  73. if(($receiver = $2) == nil || $receiver == undefined){
  74. self["@locals"]=_st((smalltalk.Dictionary || Dictionary))._new();
  75. $1=self["@locals"];
  76. } else {
  77. $1=$2;
  78. };
  79. return $1;
  80. }, function($ctx1) {$ctx1.fill(self,"locals",{}, smalltalk.AIContext)})},
  81. args: [],
  82. source: "locals\x0a\x09^ locals ifNil: [ locals := Dictionary new ]",
  83. messageSends: ["ifNil:", "new"],
  84. referencedClasses: ["Dictionary"]
  85. }),
  86. smalltalk.AIContext);
  87. smalltalk.addMethod(
  88. "_outerContext",
  89. smalltalk.method({
  90. selector: "outerContext",
  91. category: 'accessing',
  92. fn: function (){
  93. var self=this;
  94. return smalltalk.withContext(function($ctx1) { var $1;
  95. $1=self["@outerContext"];
  96. return $1;
  97. }, function($ctx1) {$ctx1.fill(self,"outerContext",{}, smalltalk.AIContext)})},
  98. args: [],
  99. source: "outerContext\x0a\x09^ outerContext",
  100. messageSends: [],
  101. referencedClasses: []
  102. }),
  103. smalltalk.AIContext);
  104. smalltalk.addMethod(
  105. "_outerContext_",
  106. smalltalk.method({
  107. selector: "outerContext:",
  108. category: 'accessing',
  109. fn: function (anAIContext){
  110. var self=this;
  111. return smalltalk.withContext(function($ctx1) { self["@outerContext"]=anAIContext;
  112. return self}, function($ctx1) {$ctx1.fill(self,"outerContext:",{anAIContext:anAIContext}, smalltalk.AIContext)})},
  113. args: ["anAIContext"],
  114. source: "outerContext: anAIContext\x0a\x09outerContext := anAIContext",
  115. messageSends: [],
  116. referencedClasses: []
  117. }),
  118. smalltalk.AIContext);
  119. smalltalk.addMethod(
  120. "_pc",
  121. smalltalk.method({
  122. selector: "pc",
  123. category: 'accessing',
  124. fn: function (){
  125. var self=this;
  126. return smalltalk.withContext(function($ctx1) { var $2,$1;
  127. $2=self["@pc"];
  128. if(($receiver = $2) == nil || $receiver == undefined){
  129. self["@pc"]=(0);
  130. $1=self["@pc"];
  131. } else {
  132. $1=$2;
  133. };
  134. return $1;
  135. }, function($ctx1) {$ctx1.fill(self,"pc",{}, smalltalk.AIContext)})},
  136. args: [],
  137. source: "pc\x0a\x09^ pc ifNil: [ pc := 0 ]",
  138. messageSends: ["ifNil:"],
  139. referencedClasses: []
  140. }),
  141. smalltalk.AIContext);
  142. smalltalk.addMethod(
  143. "_pc_",
  144. smalltalk.method({
  145. selector: "pc:",
  146. category: 'accessing',
  147. fn: function (anInteger){
  148. var self=this;
  149. return smalltalk.withContext(function($ctx1) { self["@pc"]=anInteger;
  150. return self}, function($ctx1) {$ctx1.fill(self,"pc:",{anInteger:anInteger}, smalltalk.AIContext)})},
  151. args: ["anInteger"],
  152. source: "pc: anInteger\x0a\x09pc := anInteger",
  153. messageSends: [],
  154. referencedClasses: []
  155. }),
  156. smalltalk.AIContext);
  157. smalltalk.addMethod(
  158. "_receiver",
  159. smalltalk.method({
  160. selector: "receiver",
  161. category: 'accessing',
  162. fn: function (){
  163. var self=this;
  164. return smalltalk.withContext(function($ctx1) { var $1;
  165. $1=_st(self)._localAt_("self");
  166. return $1;
  167. }, function($ctx1) {$ctx1.fill(self,"receiver",{}, smalltalk.AIContext)})},
  168. args: [],
  169. source: "receiver\x0a\x09^ self localAt: 'self'",
  170. messageSends: ["localAt:"],
  171. referencedClasses: []
  172. }),
  173. smalltalk.AIContext);
  174. smalltalk.addMethod(
  175. "_receiver_",
  176. smalltalk.method({
  177. selector: "receiver:",
  178. category: 'accessing',
  179. fn: function (anObject){
  180. var self=this;
  181. return smalltalk.withContext(function($ctx1) { _st(self)._localAt_put_("self",anObject);
  182. return self}, function($ctx1) {$ctx1.fill(self,"receiver:",{anObject:anObject}, smalltalk.AIContext)})},
  183. args: ["anObject"],
  184. source: "receiver: anObject\x0a\x09self localAt: 'self' put: anObject",
  185. messageSends: ["localAt:put:"],
  186. referencedClasses: []
  187. }),
  188. smalltalk.AIContext);
  189. smalltalk.addClass('ASTInterpreter', smalltalk.NodeVisitor, ['currentNode', 'context', 'shouldReturn', 'currentValue'], 'Compiler-Interpreter');
  190. smalltalk.addMethod(
  191. "_assign_to_",
  192. smalltalk.method({
  193. selector: "assign:to:",
  194. category: 'interpreting',
  195. fn: function (aNode,anObject){
  196. var self=this;
  197. return smalltalk.withContext(function($ctx1) { var $2,$1;
  198. $2=_st(_st(aNode)._binding())._isInstanceVar();
  199. if(smalltalk.assert($2)){
  200. $1=_st(_st(_st(self)._context())._receiver())._instVarAt_put_(_st(aNode)._value(),anObject);
  201. } else {
  202. $1=_st(_st(self)._context())._localAt_put_(_st(aNode)._value(),anObject);
  203. };
  204. return $1;
  205. }, function($ctx1) {$ctx1.fill(self,"assign:to:",{aNode:aNode,anObject:anObject}, smalltalk.ASTInterpreter)})},
  206. args: ["aNode", "anObject"],
  207. source: "assign: aNode to: anObject\x0a\x09^ aNode binding isInstanceVar \x0a \x09ifTrue: [ self context receiver instVarAt: aNode value put: anObject ]\x0a \x09ifFalse: [ self context localAt: aNode value put: anObject ]",
  208. messageSends: ["ifTrue:ifFalse:", "instVarAt:put:", "value", "receiver", "context", "localAt:put:", "isInstanceVar", "binding"],
  209. referencedClasses: []
  210. }),
  211. smalltalk.ASTInterpreter);
  212. smalltalk.addMethod(
  213. "_context",
  214. smalltalk.method({
  215. selector: "context",
  216. category: 'accessing',
  217. fn: function (){
  218. var self=this;
  219. return smalltalk.withContext(function($ctx1) { var $2,$1;
  220. $2=self["@context"];
  221. if(($receiver = $2) == nil || $receiver == undefined){
  222. self["@context"]=_st((smalltalk.AIContext || AIContext))._new();
  223. $1=self["@context"];
  224. } else {
  225. $1=$2;
  226. };
  227. return $1;
  228. }, function($ctx1) {$ctx1.fill(self,"context",{}, smalltalk.ASTInterpreter)})},
  229. args: [],
  230. source: "context\x0a\x09^ context ifNil: [ context := AIContext new ]",
  231. messageSends: ["ifNil:", "new"],
  232. referencedClasses: ["AIContext"]
  233. }),
  234. smalltalk.ASTInterpreter);
  235. smalltalk.addMethod(
  236. "_context_",
  237. smalltalk.method({
  238. selector: "context:",
  239. category: 'accessing',
  240. fn: function (anAIContext){
  241. var self=this;
  242. return smalltalk.withContext(function($ctx1) { self["@context"]=anAIContext;
  243. return self}, function($ctx1) {$ctx1.fill(self,"context:",{anAIContext:anAIContext}, smalltalk.ASTInterpreter)})},
  244. args: ["anAIContext"],
  245. source: "context: anAIContext\x0a\x09context := anAIContext",
  246. messageSends: [],
  247. referencedClasses: []
  248. }),
  249. smalltalk.ASTInterpreter);
  250. smalltalk.addMethod(
  251. "_continue_",
  252. smalltalk.method({
  253. selector: "continue:",
  254. category: 'interpreting',
  255. fn: function (anObject){
  256. var self=this;
  257. return smalltalk.withContext(function($ctx1) { self["@currentValue"]=anObject;
  258. return self}, function($ctx1) {$ctx1.fill(self,"continue:",{anObject:anObject}, smalltalk.ASTInterpreter)})},
  259. args: ["anObject"],
  260. source: "continue: anObject\x0a\x09currentValue := anObject",
  261. messageSends: [],
  262. referencedClasses: []
  263. }),
  264. smalltalk.ASTInterpreter);
  265. smalltalk.addMethod(
  266. "_currentValue",
  267. smalltalk.method({
  268. selector: "currentValue",
  269. category: 'accessing',
  270. fn: function (){
  271. var self=this;
  272. return smalltalk.withContext(function($ctx1) { var $1;
  273. $1=self["@currentValue"];
  274. return $1;
  275. }, function($ctx1) {$ctx1.fill(self,"currentValue",{}, smalltalk.ASTInterpreter)})},
  276. args: [],
  277. source: "currentValue\x0a\x09^ currentValue",
  278. messageSends: [],
  279. referencedClasses: []
  280. }),
  281. smalltalk.ASTInterpreter);
  282. smalltalk.addMethod(
  283. "_eval_",
  284. smalltalk.method({
  285. selector: "eval:",
  286. category: 'interpreting',
  287. fn: function (aString){
  288. var self=this;
  289. var source,function_;
  290. return smalltalk.withContext(function($ctx1) { var $1,$2,$3;
  291. source=_st((smalltalk.String || String))._streamContents_((function(str){
  292. return smalltalk.withContext(function($ctx2) { _st(str)._nextPutAll_("(function(");
  293. _st(_st(_st(_st(self)._context())._locals())._keys())._do_separatedBy_((function(each){
  294. return smalltalk.withContext(function($ctx3) { return _st(str)._nextPutAll_(each);
  295. }, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}),(function(){
  296. return smalltalk.withContext(function($ctx3) { return _st(str)._nextPutAll_(",");
  297. }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
  298. $1=str;
  299. _st($1)._nextPutAll_("){ return (function() {");
  300. _st($1)._nextPutAll_(aString);
  301. $2=_st($1)._nextPutAll_("})() })");
  302. return $2;
  303. }, function($ctx2) {$ctx2.fillBlock({str:str},$ctx1)})}));
  304. function_=_st(_st((smalltalk.Compiler || Compiler))._new())._eval_(source);
  305. $3=_st(function_)._valueWithPossibleArguments_(_st(_st(_st(self)._context())._locals())._values());
  306. return $3;
  307. }, function($ctx1) {$ctx1.fill(self,"eval:",{aString:aString,source:source,function_:function_}, smalltalk.ASTInterpreter)})},
  308. args: ["aString"],
  309. source: "eval: aString\x0a\x09\x22Evaluate aString as JS source inside an JS function. \x0a aString is not sandboxed.\x22\x0a \x0a | source function |\x0a \x0a source := String streamContents: [ :str |\x0a \x09str nextPutAll: '(function('.\x0a self context locals keys \x0a \x09do: [ :each | str nextPutAll: each ]\x0a \x09separatedBy: [ str nextPutAll: ',' ].\x0a str \x0a \x09nextPutAll: '){ return (function() {';\x0a \x09nextPutAll: aString;\x0a nextPutAll: '})() })' ].\x0a \x0a\x09function := Compiler new eval: source.\x0a \x0a\x09^ function valueWithPossibleArguments: self context locals values",
  310. messageSends: ["streamContents:", "nextPutAll:", "do:separatedBy:", "keys", "locals", "context", "eval:", "new", "valueWithPossibleArguments:", "values"],
  311. referencedClasses: ["String", "Compiler"]
  312. }),
  313. smalltalk.ASTInterpreter);
  314. smalltalk.addMethod(
  315. "_initialize",
  316. smalltalk.method({
  317. selector: "initialize",
  318. category: 'initialization',
  319. fn: function (){
  320. var self=this;
  321. return smalltalk.withContext(function($ctx1) { smalltalk.NodeVisitor.fn.prototype._initialize.apply(_st(self), []);
  322. self["@shouldReturn"]=false;
  323. return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.ASTInterpreter)})},
  324. args: [],
  325. source: "initialize\x0a\x09super initialize.\x0a shouldReturn := false",
  326. messageSends: ["initialize"],
  327. referencedClasses: []
  328. }),
  329. smalltalk.ASTInterpreter);
  330. smalltalk.addMethod(
  331. "_interpret_",
  332. smalltalk.method({
  333. selector: "interpret:",
  334. category: 'interpreting',
  335. fn: function (aNode){
  336. var self=this;
  337. return smalltalk.withContext(function($ctx1) { self["@shouldReturn"]=false;
  338. _st(self)._interpret_continue_(aNode,(function(value){
  339. return smalltalk.withContext(function($ctx2) { self["@currentValue"]=value;
  340. return self["@currentValue"];
  341. }, function($ctx2) {$ctx2.fillBlock({value:value},$ctx1)})}));
  342. return self}, function($ctx1) {$ctx1.fill(self,"interpret:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
  343. args: ["aNode"],
  344. source: "interpret: aNode\x0a\x09shouldReturn := false.\x0a self interpret: aNode continue: [ :value |\x0a \x09currentValue := value ]",
  345. messageSends: ["interpret:continue:"],
  346. referencedClasses: []
  347. }),
  348. smalltalk.ASTInterpreter);
  349. smalltalk.addMethod(
  350. "_interpret_continue_",
  351. smalltalk.method({
  352. selector: "interpret:continue:",
  353. category: 'interpreting',
  354. fn: function (aNode,aBlock){
  355. var self=this;
  356. return smalltalk.withContext(function($ctx1) { var $1,$2,$3;
  357. $1=self["@shouldReturn"];
  358. if(smalltalk.assert($1)){
  359. $2=self;
  360. return $2;
  361. };
  362. $3=_st(aNode)._isNode();
  363. if(smalltalk.assert($3)){
  364. _st(self)._visit_(aNode);
  365. } else {
  366. self["@currentValue"]=aNode;
  367. self["@currentValue"];
  368. };
  369. _st(aBlock)._value_(_st(self)._currentValue());
  370. return self}, function($ctx1) {$ctx1.fill(self,"interpret:continue:",{aNode:aNode,aBlock:aBlock}, smalltalk.ASTInterpreter)})},
  371. args: ["aNode", "aBlock"],
  372. source: "interpret: aNode continue: aBlock\x0a\x0a\x09shouldReturn ifTrue: [ ^ self ].\x0a\x0a\x09aNode isNode \x0a \x09ifTrue: [ self visit: aNode ]\x0a ifFalse: [ currentValue := aNode ].\x0a\x09aBlock value: self currentValue",
  373. messageSends: ["ifTrue:", "ifTrue:ifFalse:", "visit:", "isNode", "value:", "currentValue"],
  374. referencedClasses: []
  375. }),
  376. smalltalk.ASTInterpreter);
  377. smalltalk.addMethod(
  378. "_interpretAll_continue_",
  379. smalltalk.method({
  380. selector: "interpretAll:continue:",
  381. category: 'interpreting',
  382. fn: function (aCollection,aBlock){
  383. var self=this;
  384. return smalltalk.withContext(function($ctx1) { _st(self)._interpretAll_continue_result_(aCollection,aBlock,_st((smalltalk.OrderedCollection || OrderedCollection))._new());
  385. return self}, function($ctx1) {$ctx1.fill(self,"interpretAll:continue:",{aCollection:aCollection,aBlock:aBlock}, smalltalk.ASTInterpreter)})},
  386. args: ["aCollection", "aBlock"],
  387. source: "interpretAll: aCollection continue: aBlock\x0a\x09self \x0a \x09interpretAll: aCollection \x0a continue: aBlock \x0a result: OrderedCollection new",
  388. messageSends: ["interpretAll:continue:result:", "new"],
  389. referencedClasses: ["OrderedCollection"]
  390. }),
  391. smalltalk.ASTInterpreter);
  392. smalltalk.addMethod(
  393. "_interpretAll_continue_result_",
  394. smalltalk.method({
  395. selector: "interpretAll:continue:result:",
  396. category: 'interpreting',
  397. fn: function (nodes,aBlock,aCollection){
  398. var self=this;
  399. return smalltalk.withContext(function($ctx1) { var $1;
  400. $1=_st(nodes)._isEmpty();
  401. if(smalltalk.assert($1)){
  402. _st(aBlock)._value_(aCollection);
  403. } else {
  404. _st(self)._interpret_continue_(_st(nodes)._first(),(function(value){
  405. return smalltalk.withContext(function($ctx2) { return _st(self)._interpretAll_continue_result_(_st(nodes)._allButFirst(),aBlock,_st(aCollection).__comma([value]));
  406. }, function($ctx2) {$ctx2.fillBlock({value:value},$ctx1)})}));
  407. };
  408. return self}, function($ctx1) {$ctx1.fill(self,"interpretAll:continue:result:",{nodes:nodes,aBlock:aBlock,aCollection:aCollection}, smalltalk.ASTInterpreter)})},
  409. args: ["nodes", "aBlock", "aCollection"],
  410. source: "interpretAll: nodes continue: aBlock result: aCollection\x0a\x09nodes isEmpty \x0a \x09ifTrue: [ aBlock value: aCollection ]\x0a \x09ifFalse: [\x0a \x09\x09self interpret: nodes first continue: [:value |\x0a \x09\x09\x09self \x0a \x09interpretAll: nodes allButFirst \x0a continue: aBlock\x0a \x09\x09\x09\x09\x09result: aCollection, { value } ] ]",
  411. messageSends: ["ifTrue:ifFalse:", "value:", "interpret:continue:", "first", "interpretAll:continue:result:", "allButFirst", ",", "isEmpty"],
  412. referencedClasses: []
  413. }),
  414. smalltalk.ASTInterpreter);
  415. smalltalk.addMethod(
  416. "_messageFromSendNode_do_",
  417. smalltalk.method({
  418. selector: "messageFromSendNode:do:",
  419. category: 'interpreting',
  420. fn: function (aSendNode,aBlock){
  421. var self=this;
  422. return smalltalk.withContext(function($ctx1) { var $1,$2;
  423. _st(self)._interpretAll_continue_(_st(aSendNode)._arguments(),(function(args){
  424. return smalltalk.withContext(function($ctx2) { $1=_st((smalltalk.Message || Message))._new();
  425. _st($1)._selector_(_st(aSendNode)._selector());
  426. _st($1)._arguments_(args);
  427. $2=_st($1)._yourself();
  428. return _st(aBlock)._value_($2);
  429. }, function($ctx2) {$ctx2.fillBlock({args:args},$ctx1)})}));
  430. return self}, function($ctx1) {$ctx1.fill(self,"messageFromSendNode:do:",{aSendNode:aSendNode,aBlock:aBlock}, smalltalk.ASTInterpreter)})},
  431. args: ["aSendNode", "aBlock"],
  432. source: "messageFromSendNode: aSendNode do: aBlock\x0a\x09self interpretAll: aSendNode arguments continue: [ :args |\x0a \x09aBlock value: (Message new\x0a \x09\x09selector: aSendNode selector;\x0a \x09arguments: args;\x0a \x09yourself) ]",
  433. messageSends: ["interpretAll:continue:", "arguments", "value:", "selector:", "selector", "new", "arguments:", "yourself"],
  434. referencedClasses: ["Message"]
  435. }),
  436. smalltalk.ASTInterpreter);
  437. smalltalk.addMethod(
  438. "_visitAssignmentNode_",
  439. smalltalk.method({
  440. selector: "visitAssignmentNode:",
  441. category: 'visiting',
  442. fn: function (aNode){
  443. var self=this;
  444. return smalltalk.withContext(function($ctx1) { _st(self)._interpret_continue_(_st(aNode)._right(),(function(value){
  445. return smalltalk.withContext(function($ctx2) { return _st(self)._continue_(_st(self)._assign_to_(_st(aNode)._left(),value));
  446. }, function($ctx2) {$ctx2.fillBlock({value:value},$ctx1)})}));
  447. return self}, function($ctx1) {$ctx1.fill(self,"visitAssignmentNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
  448. args: ["aNode"],
  449. source: "visitAssignmentNode: aNode\x0a\x09self interpret: aNode right continue: [ :value |\x0a \x09self continue: (self assign: aNode left to: value) ]",
  450. messageSends: ["interpret:continue:", "right", "continue:", "assign:to:", "left"],
  451. referencedClasses: []
  452. }),
  453. smalltalk.ASTInterpreter);
  454. smalltalk.addMethod(
  455. "_visitBlockNode_",
  456. smalltalk.method({
  457. selector: "visitBlockNode:",
  458. category: 'visiting',
  459. fn: function (aNode){
  460. var self=this;
  461. return smalltalk.withContext(function($ctx1) { var $1,$2;
  462. _st(self)._continue_((function(){
  463. return smalltalk.withContext(function($ctx2) { $1=self;
  464. _st($1)._interpret_(_st(_st(aNode)._nodes())._first());
  465. $2=_st($1)._currentValue();
  466. return $2;
  467. }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
  468. return self}, function($ctx1) {$ctx1.fill(self,"visitBlockNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
  469. args: ["aNode"],
  470. source: "visitBlockNode: aNode\x0a\x09\x22TODO: Context should be set\x22\x0a self continue: [ self interpret: aNode nodes first; currentValue ]",
  471. messageSends: ["continue:", "interpret:", "first", "nodes", "currentValue"],
  472. referencedClasses: []
  473. }),
  474. smalltalk.ASTInterpreter);
  475. smalltalk.addMethod(
  476. "_visitCascadeNode_",
  477. smalltalk.method({
  478. selector: "visitCascadeNode:",
  479. category: 'visiting',
  480. fn: function (aNode){
  481. var self=this;
  482. return smalltalk.withContext(function($ctx1) { _st(self)._interpret_continue_(_st(aNode)._receiver(),(function(receiver){
  483. return smalltalk.withContext(function($ctx2) { _st(_st(aNode)._nodes())._do_((function(each){
  484. return smalltalk.withContext(function($ctx3) { return _st(each)._receiver_(receiver);
  485. }, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}));
  486. return _st(self)._interpretAll_continue_(_st(_st(aNode)._nodes())._allButLast(),(function(){
  487. return smalltalk.withContext(function($ctx3) { return _st(self)._interpret_continue_(_st(_st(aNode)._nodes())._last(),(function(val){
  488. return smalltalk.withContext(function($ctx4) { return _st(self)._continue_(val);
  489. }, function($ctx4) {$ctx4.fillBlock({val:val},$ctx1)})}));
  490. }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
  491. }, function($ctx2) {$ctx2.fillBlock({receiver:receiver},$ctx1)})}));
  492. return self}, function($ctx1) {$ctx1.fill(self,"visitCascadeNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
  493. args: ["aNode"],
  494. source: "visitCascadeNode: aNode\x0a\x09\x22TODO: Handle super sends\x22\x0a\x09\x0a self interpret: aNode receiver continue: [ :receiver |\x0a\x09\x09\x22Only interpret the receiver once\x22\x0a aNode nodes do: [ :each | each receiver: receiver ].\x0a \x0a \x09self \x0a \x09interpretAll: aNode nodes allButLast\x0a \x09\x09continue: [\x0a \x09self \x0a \x09interpret: aNode nodes last\x0a \x09continue: [ :val | self continue: val ] ] ]",
  495. messageSends: ["interpret:continue:", "receiver", "do:", "receiver:", "nodes", "interpretAll:continue:", "allButLast", "last", "continue:"],
  496. referencedClasses: []
  497. }),
  498. smalltalk.ASTInterpreter);
  499. smalltalk.addMethod(
  500. "_visitClassReferenceNode_",
  501. smalltalk.method({
  502. selector: "visitClassReferenceNode:",
  503. category: 'visiting',
  504. fn: function (aNode){
  505. var self=this;
  506. return smalltalk.withContext(function($ctx1) { _st(self)._continue_(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(_st(aNode)._value()));
  507. return self}, function($ctx1) {$ctx1.fill(self,"visitClassReferenceNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
  508. args: ["aNode"],
  509. source: "visitClassReferenceNode: aNode\x0a\x09self continue: (Smalltalk current at: aNode value)",
  510. messageSends: ["continue:", "at:", "value", "current"],
  511. referencedClasses: ["Smalltalk"]
  512. }),
  513. smalltalk.ASTInterpreter);
  514. smalltalk.addMethod(
  515. "_visitDynamicArrayNode_",
  516. smalltalk.method({
  517. selector: "visitDynamicArrayNode:",
  518. category: 'visiting',
  519. fn: function (aNode){
  520. var self=this;
  521. return smalltalk.withContext(function($ctx1) { _st(self)._interpretAll_continue_(_st(aNode)._nodes(),(function(array){
  522. return smalltalk.withContext(function($ctx2) { return _st(self)._continue_(array);
  523. }, function($ctx2) {$ctx2.fillBlock({array:array},$ctx1)})}));
  524. return self}, function($ctx1) {$ctx1.fill(self,"visitDynamicArrayNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
  525. args: ["aNode"],
  526. source: "visitDynamicArrayNode: aNode\x0a\x0a\x09self interpretAll: aNode nodes continue: [ :array |\x0a \x09self continue: array ]",
  527. messageSends: ["interpretAll:continue:", "nodes", "continue:"],
  528. referencedClasses: []
  529. }),
  530. smalltalk.ASTInterpreter);
  531. smalltalk.addMethod(
  532. "_visitDynamicDictionaryNode_",
  533. smalltalk.method({
  534. selector: "visitDynamicDictionaryNode:",
  535. category: 'visiting',
  536. fn: function (aNode){
  537. var self=this;
  538. return smalltalk.withContext(function($ctx1) { _st(self)._interpretAll_continue_(_st(aNode)._nodes(),(function(array){
  539. var hashedCollection;
  540. return smalltalk.withContext(function($ctx2) { hashedCollection=_st((smalltalk.HashedCollection || HashedCollection))._new();
  541. hashedCollection;
  542. _st(array)._do_((function(each){
  543. return smalltalk.withContext(function($ctx3) { return _st(hashedCollection)._add_(each);
  544. }, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}));
  545. return _st(self)._continue_(hashedCollection);
  546. }, function($ctx2) {$ctx2.fillBlock({array:array,hashedCollection:hashedCollection},$ctx1)})}));
  547. return self}, function($ctx1) {$ctx1.fill(self,"visitDynamicDictionaryNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
  548. args: ["aNode"],
  549. source: "visitDynamicDictionaryNode: aNode\x0a\x09\x0a self interpretAll: aNode nodes continue: [ :array | | hashedCollection |\x0a \x09hashedCollection := HashedCollection new.\x0a array do: [ :each | hashedCollection add: each ].\x0a self continue: hashedCollection ]",
  550. messageSends: ["interpretAll:continue:", "nodes", "new", "do:", "add:", "continue:"],
  551. referencedClasses: ["HashedCollection"]
  552. }),
  553. smalltalk.ASTInterpreter);
  554. smalltalk.addMethod(
  555. "_visitJSStatementNode_",
  556. smalltalk.method({
  557. selector: "visitJSStatementNode:",
  558. category: 'visiting',
  559. fn: function (aNode){
  560. var self=this;
  561. return smalltalk.withContext(function($ctx1) { self["@shouldReturn"]=true;
  562. _st(self)._continue_(_st(self)._eval_(_st(aNode)._source()));
  563. return self}, function($ctx1) {$ctx1.fill(self,"visitJSStatementNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
  564. args: ["aNode"],
  565. source: "visitJSStatementNode: aNode\x0a\x09shouldReturn := true.\x0a\x09self continue: (self eval: aNode source)",
  566. messageSends: ["continue:", "eval:", "source"],
  567. referencedClasses: []
  568. }),
  569. smalltalk.ASTInterpreter);
  570. smalltalk.addMethod(
  571. "_visitReturnNode_",
  572. smalltalk.method({
  573. selector: "visitReturnNode:",
  574. category: 'visiting',
  575. fn: function (aNode){
  576. var self=this;
  577. return smalltalk.withContext(function($ctx1) { _st(self)._interpret_continue_(_st(_st(aNode)._nodes())._first(),(function(value){
  578. return smalltalk.withContext(function($ctx2) { self["@shouldReturn"]=true;
  579. self["@shouldReturn"];
  580. return _st(self)._continue_(value);
  581. }, function($ctx2) {$ctx2.fillBlock({value:value},$ctx1)})}));
  582. return self}, function($ctx1) {$ctx1.fill(self,"visitReturnNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
  583. args: ["aNode"],
  584. source: "visitReturnNode: aNode\x0a self interpret: aNode nodes first continue: [ :value |\x0a \x09shouldReturn := true.\x0a\x09\x09self continue: value ]",
  585. messageSends: ["interpret:continue:", "first", "nodes", "continue:"],
  586. referencedClasses: []
  587. }),
  588. smalltalk.ASTInterpreter);
  589. smalltalk.addMethod(
  590. "_visitSendNode_",
  591. smalltalk.method({
  592. selector: "visitSendNode:",
  593. category: 'visiting',
  594. fn: function (aNode){
  595. var self=this;
  596. return smalltalk.withContext(function($ctx1) { _st(self)._interpret_continue_(_st(aNode)._receiver(),(function(receiver){
  597. return smalltalk.withContext(function($ctx2) { return _st(self)._messageFromSendNode_do_(aNode,(function(message){
  598. return smalltalk.withContext(function($ctx3) { _st(_st(self)._context())._pc_(_st(_st(_st(self)._context())._pc()).__plus((1)));
  599. return _st(self)._continue_(_st(message)._sendTo_(receiver));
  600. }, function($ctx3) {$ctx3.fillBlock({message:message},$ctx1)})}));
  601. }, function($ctx2) {$ctx2.fillBlock({receiver:receiver},$ctx1)})}));
  602. return self}, function($ctx1) {$ctx1.fill(self,"visitSendNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
  603. args: ["aNode"],
  604. source: "visitSendNode: aNode\x0a\x09\x22TODO: Handle super sends\x22\x0a \x0a self interpret: aNode receiver continue: [ :receiver |\x0a \x09self messageFromSendNode: aNode do: [ :message |\x0a \x09self context pc: self context pc + 1.\x0a \x09self continue: (message sendTo: receiver) ] ]",
  605. messageSends: ["interpret:continue:", "receiver", "messageFromSendNode:do:", "pc:", "+", "pc", "context", "continue:", "sendTo:"],
  606. referencedClasses: []
  607. }),
  608. smalltalk.ASTInterpreter);
  609. smalltalk.addMethod(
  610. "_visitSequenceNode_",
  611. smalltalk.method({
  612. selector: "visitSequenceNode:",
  613. category: 'visiting',
  614. fn: function (aNode){
  615. var self=this;
  616. return smalltalk.withContext(function($ctx1) { _st(self)._interpretAll_continue_(_st(aNode)._nodes(),(function(array){
  617. return smalltalk.withContext(function($ctx2) { return _st(self)._continue_(_st(array)._last());
  618. }, function($ctx2) {$ctx2.fillBlock({array:array},$ctx1)})}));
  619. return self}, function($ctx1) {$ctx1.fill(self,"visitSequenceNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
  620. args: ["aNode"],
  621. source: "visitSequenceNode: aNode\x0a\x09self interpretAll: aNode nodes continue: [ :array |\x0a \x09self continue: array last ]",
  622. messageSends: ["interpretAll:continue:", "nodes", "continue:", "last"],
  623. referencedClasses: []
  624. }),
  625. smalltalk.ASTInterpreter);
  626. smalltalk.addMethod(
  627. "_visitValueNode_",
  628. smalltalk.method({
  629. selector: "visitValueNode:",
  630. category: 'visiting',
  631. fn: function (aNode){
  632. var self=this;
  633. return smalltalk.withContext(function($ctx1) { _st(self)._continue_(_st(aNode)._value());
  634. return self}, function($ctx1) {$ctx1.fill(self,"visitValueNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
  635. args: ["aNode"],
  636. source: "visitValueNode: aNode\x0a\x09self continue: aNode value",
  637. messageSends: ["continue:", "value"],
  638. referencedClasses: []
  639. }),
  640. smalltalk.ASTInterpreter);
  641. smalltalk.addMethod(
  642. "_visitVariableNode_",
  643. smalltalk.method({
  644. selector: "visitVariableNode:",
  645. category: 'visiting',
  646. fn: function (aNode){
  647. var self=this;
  648. return smalltalk.withContext(function($ctx1) { var $1,$3,$2;
  649. $1=self;
  650. $3=_st(_st(aNode)._binding())._isInstanceVar();
  651. if(smalltalk.assert($3)){
  652. $2=_st(_st(_st(self)._context())._receiver())._instVarAt_(_st(aNode)._value());
  653. } else {
  654. $2=_st(_st(self)._context())._localAt_(_st(aNode)._value());
  655. };
  656. _st($1)._continue_($2);
  657. return self}, function($ctx1) {$ctx1.fill(self,"visitVariableNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
  658. args: ["aNode"],
  659. source: "visitVariableNode: aNode\x0a self continue: (aNode binding isInstanceVar\x0a\x09\x09ifTrue: [ self context receiver instVarAt: aNode value ]\x0a\x09\x09ifFalse: [ self context localAt: aNode value ])",
  660. messageSends: ["continue:", "ifTrue:ifFalse:", "instVarAt:", "value", "receiver", "context", "localAt:", "isInstanceVar", "binding"],
  661. referencedClasses: []
  662. }),
  663. smalltalk.ASTInterpreter);
  664. smalltalk.addClass('ASTDebugger', smalltalk.ASTInterpreter, ['continuation'], 'Compiler-Interpreter');
  665. smalltalk.addMethod(
  666. "_initialize",
  667. smalltalk.method({
  668. selector: "initialize",
  669. category: 'initialization',
  670. fn: function (){
  671. var self=this;
  672. return smalltalk.withContext(function($ctx1) { smalltalk.ASTInterpreter.fn.prototype._initialize.apply(_st(self), []);
  673. self["@continuation"]=(function(){
  674. return smalltalk.withContext(function($ctx2) { }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
  675. return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.ASTDebugger)})},
  676. args: [],
  677. source: "initialize\x0a\x09super initialize.\x0a continuation := [ ]",
  678. messageSends: ["initialize"],
  679. referencedClasses: []
  680. }),
  681. smalltalk.ASTDebugger);
  682. smalltalk.addMethod(
  683. "_interpret_continue_",
  684. smalltalk.method({
  685. selector: "interpret:continue:",
  686. category: 'interpreting',
  687. fn: function (aNode,aBlock){
  688. var self=this;
  689. return smalltalk.withContext(function($ctx1) { self["@continuation"]=(function(){
  690. return smalltalk.withContext(function($ctx2) { return smalltalk.ASTInterpreter.fn.prototype._interpret_continue_.apply(_st(self), [aNode,aBlock]);
  691. }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
  692. return self}, function($ctx1) {$ctx1.fill(self,"interpret:continue:",{aNode:aNode,aBlock:aBlock}, smalltalk.ASTDebugger)})},
  693. args: ["aNode", "aBlock"],
  694. source: "interpret: aNode continue: aBlock\x0a\x09continuation := [ super interpret: aNode continue: aBlock ]",
  695. messageSends: ["interpret:continue:"],
  696. referencedClasses: []
  697. }),
  698. smalltalk.ASTDebugger);
  699. smalltalk.addMethod(
  700. "_stepOver",
  701. smalltalk.method({
  702. selector: "stepOver",
  703. category: 'stepping',
  704. fn: function (){
  705. var self=this;
  706. return smalltalk.withContext(function($ctx1) { _st(self["@continuation"])._value();
  707. return self}, function($ctx1) {$ctx1.fill(self,"stepOver",{}, smalltalk.ASTDebugger)})},
  708. args: [],
  709. source: "stepOver\x0a\x09continuation value",
  710. messageSends: ["value"],
  711. referencedClasses: []
  712. }),
  713. smalltalk.ASTDebugger);