Parcourir la source

Merge branch 'master' into grunt-dev
fix conflicts in .gitignore and init.js to use latest master version

* master: (85 commits)
Use continuations in ASTInterpreter for future stepping
ASTInterpreter now handles assignments
Fixed inlined js node interpretation
Fixed ClassBuilder >> addSubclass:... with class migration
Updated MethodContext class comment
Moved MethodContext >> asString to protocol converting
Fixed MethodContext >> asString
Commented the (expected) failing test for now to make Travis happy
IRClosure/IRMethod refactoring
- Merged contexts locals and args into one object - Recompiled all .js files
Fixed block context home contexts
ClassCommentReader: update class comment
REPL: recompile
REPL.st: fix deprecation warning
ClassCommentReader: remove unused variable 'chunkParser'
ClassCategoryReader: remove unused variable 'chunkParser'
A way for block context to see parent context.
- Added MethodContext >> method - Fixed the debugger with block contexts
- improved MethodContext >> asString - fixed block context filling - recompiled all .js files
fillBlock() takes the args and locals as arguments
...

Conflicts:
.gitignore
js/init.js

Manfred Kroehnert il y a 11 ans
Parent
commit
c54c41e227
76 fichiers modifiés avec 18306 ajouts et 12986 suppressions
  1. 1 6
      .gitignore
  2. 80 89
      js/Benchfib.deploy.js
  3. 80 89
      js/Benchfib.js
  4. 219 217
      js/Canvas.deploy.js
  5. 219 217
      js/Canvas.js
  6. 287 188
      js/Compiler-AST.deploy.js
  7. 298 179
      js/Compiler-AST.js
  8. 208 969
      js/Compiler-Core.deploy.js
  9. 210 406
      js/Compiler-Core.js
  10. 37 18
      js/Compiler-Exceptions.deploy.js
  11. 42 18
      js/Compiler-Exceptions.js
  12. 343 285
      js/Compiler-IR.deploy.js
  13. 348 282
      js/Compiler-IR.js
  14. 290 281
      js/Compiler-Inlining.deploy.js
  15. 290 281
      js/Compiler-Inlining.js
  16. 592 0
      js/Compiler-Interpreter.deploy.js
  17. 787 0
      js/Compiler-Interpreter.js
  18. 366 318
      js/Compiler-Semantic.deploy.js
  19. 362 311
      js/Compiler-Semantic.js
  20. 472 288
      js/Compiler-Tests.deploy.js
  21. 520 248
      js/Compiler-Tests.js
  22. 350 0
      js/Compiler.deploy.js
  23. 436 0
      js/Compiler.js
  24. 29 29
      js/Examples.deploy.js
  25. 29 29
      js/Examples.js
  26. 381 340
      js/IDE.deploy.js
  27. 382 341
      js/IDE.js
  28. 393 349
      js/Importer-Exporter.deploy.js
  29. 398 354
      js/Importer-Exporter.js
  30. 53 44
      js/Kernel-Announcements.deploy.js
  31. 53 44
      js/Kernel-Announcements.js
  32. 367 256
      js/Kernel-Classes.deploy.js
  33. 316 233
      js/Kernel-Classes.js
  34. 279 256
      js/Kernel-Collections.deploy.js
  35. 281 258
      js/Kernel-Collections.js
  36. 91 75
      js/Kernel-Exceptions.deploy.js
  37. 98 77
      js/Kernel-Exceptions.js
  38. 355 290
      js/Kernel-Methods.deploy.js
  39. 388 298
      js/Kernel-Methods.js
  40. 333 324
      js/Kernel-Objects.deploy.js
  41. 332 311
      js/Kernel-Objects.js
  42. 380 315
      js/Kernel-Tests.deploy.js
  43. 385 315
      js/Kernel-Tests.js
  44. 23 24
      js/Kernel-Transcript.deploy.js
  45. 25 26
      js/Kernel-Transcript.js
  46. 169 175
      js/SUnit-Tests.deploy.js
  47. 182 188
      js/SUnit-Tests.js
  48. 249 213
      js/SUnit.deploy.js
  49. 265 219
      js/SUnit.js
  50. 1 0
      js/amber.js
  51. 413 240
      js/boot.js
  52. 1 4
      js/init.js
  53. 24 4
      js/parser.js
  54. 7 3
      js/parser.pegjs
  55. 1 1
      repl/REPL.st
  56. 511 165
      repl/amber.js
  57. 36 9
      st/Compiler-AST.st
  58. 1 540
      st/Compiler-Core.st
  59. 4 0
      st/Compiler-Exceptions.st
  60. 185 79
      st/Compiler-IR.st
  61. 266 0
      st/Compiler-Interpreter.st
  62. 45 20
      st/Compiler-Semantic.st
  63. 104 7
      st/Compiler-Tests.st
  64. 3172 1541
      st/Compiler.st
  65. 31 46
      st/IDE.st
  66. 4 7
      st/Importer-Exporter.st
  67. 116 31
      st/Kernel-Classes.st
  68. 21 27
      st/Kernel-Collections.st
  69. 7 1
      st/Kernel-Exceptions.st
  70. 45 9
      st/Kernel-Methods.st
  71. 149 144
      st/Kernel-Objects.st
  72. 43 22
      st/Kernel-Tests.st
  73. 1 3
      st/Kernel-Transcript.st
  74. 28 9
      st/Makefile
  75. 16 0
      st/SUnit.st
  76. 1 1
      test/run_build.sh

+ 1 - 6
.gitignore

@@ -16,9 +16,4 @@ test/run.js
 .svn
 
 # Ignoring local NPM modules
-node_modules
-
-# Ignoring folders - compiled versions of Amber
-# local NPM modules, tmp
-dist
-tmp
+/node_modules/*

+ 80 - 89
js/Benchfib.deploy.js

@@ -8,9 +8,9 @@ selector: "main",
 fn: function (){
 var self=this;
 var result;
-result=smalltalk.send((0),"_tinyBenchmarks",[]);
-smalltalk.send(console,"_log_",[smalltalk.send("0 tinyBenchmarks => ","__comma",[result])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
result=_st((0))._tinyBenchmarks();
+_st(console)._log_(_st("0 tinyBenchmarks => ").__comma(result));
+return self}, function($ctx1) {$ctx1.fill(self,"main",{result:result}, smalltalk.Benchfib.klass)})}
 }),
 smalltalk.Benchfib.klass);
 
@@ -21,15 +21,15 @@ smalltalk.method({
 selector: "benchFib",
 fn: function (){
 var self=this;
-var $2,$1;
-$2=smalltalk.send(self,"__lt",[(2)]);
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=_st(self).__lt((2));
 if(smalltalk.assert($2)){
 $1=(1);
 } else {
-$1=smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self,"__minus",[(1)]),"_benchFib",[]),"__plus",[smalltalk.send(smalltalk.send(self,"__minus",[(2)]),"_benchFib",[])]),"__plus",[(1)]);
+$1=_st(_st(_st(_st(self).__minus((1)))._benchFib()).__plus(_st(_st(self).__minus((2)))._benchFib())).__plus((1));
 };
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"benchFib",{}, smalltalk.Number)})}
 }),
 smalltalk.Number);
 
@@ -39,42 +39,43 @@ smalltalk.method({
 selector: "benchmark",
 fn: function (){
 var self=this;
-var $1;
-var size;
-var flags;
-var prime;
-var k;
-var count;
+var size,flags,prime,k,count;
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$5,$4,$2,$6;
 size=(8190);
-smalltalk.send((1),"_to_do_",[self,(function(iter){
-count=(0);
+$1=self;
+$2=(function(iter){
+return smalltalk.withContext(function($ctx2) {
count=(0);
 count;
-flags=smalltalk.send((smalltalk.Array || Array),"_new",[]);
+flags=_st((smalltalk.Array || Array))._new();
 flags;
-smalltalk.send(size,"_timesRepeat_",[(function(){
-return smalltalk.send(flags,"_add_",[true]);
-})]);
-return smalltalk.send((1),"_to_do_",[size,(function(i){
-$1=smalltalk.send(flags,"_at_",[i]);
-if(smalltalk.assert($1)){
-prime=smalltalk.send(i,"__plus",[(1)]);
+_st(size)._timesRepeat_((function(){
+return smalltalk.withContext(function($ctx3) {
return _st(flags)._add_(true);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+$3=size;
+$4=(function(i){
+return smalltalk.withContext(function($ctx3) {
$5=_st(flags)._at_(i);
+if(smalltalk.assert($5)){
+prime=_st(i).__plus((1));
 prime;
-k=smalltalk.send(i,"__plus",[prime]);
+k=_st(i).__plus(prime);
 k;
-smalltalk.send((function(){
-return smalltalk.send(k,"__lt_eq",[size]);
-}),"_whileTrue_",[(function(){
-smalltalk.send(flags,"_at_put_",[k,false]);
-k=smalltalk.send(k,"__plus",[prime]);
+_st((function(){
+return smalltalk.withContext(function($ctx4) {
return _st(k).__lt_eq(size);
+}, function($ctx4) {$ctx4.fillBlock({},$ctx1)})}))._whileTrue_((function(){
+return smalltalk.withContext(function($ctx4) {
_st(flags)._at_put_(k,false);
+k=_st(k).__plus(prime);
 return k;
-})]);
-count=smalltalk.send(count,"__plus",[(1)]);
+}, function($ctx4) {$ctx4.fillBlock({},$ctx1)})}));
+count=_st(count).__plus((1));
 return count;
 };
-})]);
-})]);
-return count;
-}
+}, function($ctx3) {$ctx3.fillBlock({i:i},$ctx1)})});
+return _st((1))._to_do_($3,$4);
+}, function($ctx2) {$ctx2.fillBlock({iter:iter},$ctx1)})});
+_st((1))._to_do_($1,$2);
+$6=count;
+return $6;
+}, function($ctx1) {$ctx1.fill(self,"benchmark",{size:size,flags:flags,prime:prime,k:k,count:count}, smalltalk.Number)})}
 }),
 smalltalk.Number);
 
@@ -84,12 +85,11 @@ smalltalk.method({
 selector: "jsbenchFib",
 fn: function (){
 var self=this;
-if (this < 2) {
+return smalltalk.withContext(function($ctx1) { 
if (this < 2) {
 return 1;
 } else {
 return (this-1)._jsbenchFib() + (this-2)._jsbenchFib() + 1;};
-;
-return self}
+return self}, function($ctx1) {$ctx1.fill(self,"jsbenchFib",{}, smalltalk.Number)})}
 }),
 smalltalk.Number);
 
@@ -99,7 +99,7 @@ smalltalk.method({
 selector: "jsbenchmark",
 fn: function (){
 var self=this;
-
+return smalltalk.withContext(function($ctx1) { 
 var size = 8190;
 var count;
 for (var z=0;z<this;z++) {
@@ -121,8 +121,7 @@ for (var z=0;z<this;z++) {
   }
 }
 return count;
-;
-return self}
+return self}, function($ctx1) {$ctx1.fill(self,"jsbenchmark",{}, smalltalk.Number)})}
 }),
 smalltalk.Number);
 
@@ -132,38 +131,34 @@ smalltalk.method({
 selector: "jstinyBenchmarks",
 fn: function (){
 var self=this;
-var $1;
-var t1;
-var t2;
-var r;
-var n1;
-var n2;
+var t1,t2,r,n1,n2;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 n1=(1);
-smalltalk.send((function(){
-t1=smalltalk.send((smalltalk.Date || Date),"_millisecondsToRun_",[(function(){
-return smalltalk.send(n1,"_jsbenchmark",[]);
-})]);
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
t1=_st((smalltalk.Date || Date))._millisecondsToRun_((function(){
+return smalltalk.withContext(function($ctx3) {
return _st(n1)._jsbenchmark();
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 t1;
-return smalltalk.send(t1,"__lt",[(1000)]);
-}),"_whileTrue_",[(function(){
-n1=smalltalk.send(n1,"__star",[(2)]);
+return _st(t1).__lt((1000));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileTrue_((function(){
+return smalltalk.withContext(function($ctx2) {
n1=_st(n1).__star((2));
 return n1;
-})]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 n2=(28);
-smalltalk.send((function(){
-t2=smalltalk.send((smalltalk.Date || Date),"_millisecondsToRun_",[(function(){
-r=smalltalk.send(n2,"_jsbenchFib",[]);
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
t2=_st((smalltalk.Date || Date))._millisecondsToRun_((function(){
+return smalltalk.withContext(function($ctx3) {
r=_st(n2)._jsbenchFib();
 return r;
-})]);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 t2;
-return smalltalk.send(t2,"__lt",[(1000)]);
-}),"_whileTrue_",[(function(){
-n2=smalltalk.send(n2,"__plus",[(1)]);
+return _st(t2).__lt((1000));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileTrue_((function(){
+return smalltalk.withContext(function($ctx2) {
n2=_st(n2).__plus((1));
 return n2;
-})]);
-$1=smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(n1,"__star",[(500000)]),"__star",[(1000)]),"__slash",[t1]),"_printString",[]),"__comma",[" bytecodes/sec; "]),"__comma",[smalltalk.send(smalltalk.send(smalltalk.send(r,"__star",[(1000)]),"__slash",[t2]),"_printString",[])]),"__comma",[" sends/sec"]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$1=_st(_st(_st(_st(_st(_st(_st(n1).__star((500000))).__star((1000))).__slash(t1))._printString()).__comma(" bytecodes/sec; ")).__comma(_st(_st(_st(r).__star((1000))).__slash(t2))._printString())).__comma(" sends/sec");
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"jstinyBenchmarks",{t1:t1,t2:t2,r:r,n1:n1,n2:n2}, smalltalk.Number)})}
 }),
 smalltalk.Number);
 
@@ -173,38 +168,34 @@ smalltalk.method({
 selector: "tinyBenchmarks",
 fn: function (){
 var self=this;
-var $1;
-var t1;
-var t2;
-var r;
-var n1;
-var n2;
+var t1,t2,r,n1,n2;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 n1=(1);
-smalltalk.send((function(){
-t1=smalltalk.send((smalltalk.Date || Date),"_millisecondsToRun_",[(function(){
-return smalltalk.send(n1,"_benchmark",[]);
-})]);
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
t1=_st((smalltalk.Date || Date))._millisecondsToRun_((function(){
+return smalltalk.withContext(function($ctx3) {
return _st(n1)._benchmark();
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 t1;
-return smalltalk.send(t1,"__lt",[(1000)]);
-}),"_whileTrue_",[(function(){
-n1=smalltalk.send(n1,"__star",[(2)]);
+return _st(t1).__lt((1000));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileTrue_((function(){
+return smalltalk.withContext(function($ctx2) {
n1=_st(n1).__star((2));
 return n1;
-})]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 n2=(16);
-smalltalk.send((function(){
-t2=smalltalk.send((smalltalk.Date || Date),"_millisecondsToRun_",[(function(){
-r=smalltalk.send(n2,"_benchFib",[]);
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
t2=_st((smalltalk.Date || Date))._millisecondsToRun_((function(){
+return smalltalk.withContext(function($ctx3) {
r=_st(n2)._benchFib();
 return r;
-})]);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 t2;
-return smalltalk.send(t2,"__lt",[(1000)]);
-}),"_whileTrue_",[(function(){
-n2=smalltalk.send(n2,"__plus",[(1)]);
+return _st(t2).__lt((1000));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileTrue_((function(){
+return smalltalk.withContext(function($ctx2) {
n2=_st(n2).__plus((1));
 return n2;
-})]);
-$1=smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(n1,"__star",[(500000)]),"__star",[(1000)]),"__slash",[t1]),"_printString",[]),"__comma",[" bytecodes/sec; "]),"__comma",[smalltalk.send(smalltalk.send(smalltalk.send(r,"__star",[(1000)]),"__slash",[t2]),"_printString",[])]),"__comma",[" sends/sec"]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$1=_st(_st(_st(_st(_st(_st(_st(n1).__star((500000))).__star((1000))).__slash(t1))._printString()).__comma(" bytecodes/sec; ")).__comma(_st(_st(_st(r).__star((1000))).__slash(t2))._printString())).__comma(" sends/sec");
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"tinyBenchmarks",{t1:t1,t2:t2,r:r,n1:n1,n2:n2}, smalltalk.Number)})}
 }),
 smalltalk.Number);
 

+ 80 - 89
js/Benchfib.js

@@ -9,9 +9,9 @@ category: 'not yet classified',
 fn: function (){
 var self=this;
 var result;
-result=smalltalk.send((0),"_tinyBenchmarks",[]);
-smalltalk.send(console,"_log_",[smalltalk.send("0 tinyBenchmarks => ","__comma",[result])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
result=_st((0))._tinyBenchmarks();
+_st(console)._log_(_st("0 tinyBenchmarks => ").__comma(result));
+return self}, function($ctx1) {$ctx1.fill(self,"main",{result:result}, smalltalk.Benchfib.klass)})},
 args: [],
 source: "main\x0a\x0a\x09| result |\x0a\x09result := 0 tinyBenchmarks.\x0a\x09console log: '0 tinyBenchmarks => ' , result",
 messageSends: ["tinyBenchmarks", "log:", ","],
@@ -27,15 +27,15 @@ selector: "benchFib",
 category: '*Benchfib',
 fn: function (){
 var self=this;
-var $2,$1;
-$2=smalltalk.send(self,"__lt",[(2)]);
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=_st(self).__lt((2));
 if(smalltalk.assert($2)){
 $1=(1);
 } else {
-$1=smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self,"__minus",[(1)]),"_benchFib",[]),"__plus",[smalltalk.send(smalltalk.send(self,"__minus",[(2)]),"_benchFib",[])]),"__plus",[(1)]);
+$1=_st(_st(_st(_st(self).__minus((1)))._benchFib()).__plus(_st(_st(self).__minus((2)))._benchFib())).__plus((1));
 };
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"benchFib",{}, smalltalk.Number)})},
 args: [],
 source: "benchFib \x0a\x09\x22Handy send-heavy benchmark\x22\x0a\x09\x22(result // seconds to run) = approx calls per second\x22\x0a\x09\x22 | r t |\x0a\x09  t := Time millisecondsToRun: [r := 26 benchFib].\x0a\x09  (r * 1000) // t\x22\x0a\x09\x22138000 on a Mac 8100/100\x22\x0a\x09^ self < 2 \x0a\x09\x09ifTrue: [1] \x0a\x09\x09ifFalse: [(self-1) benchFib + (self-2) benchFib + 1]",
 messageSends: ["ifTrue:ifFalse:", "+", "benchFib", "-", "<"],
@@ -50,42 +50,43 @@ selector: "benchmark",
 category: '*Benchfib',
 fn: function (){
 var self=this;
-var $1;
-var size;
-var flags;
-var prime;
-var k;
-var count;
+var size,flags,prime,k,count;
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$5,$4,$2,$6;
 size=(8190);
-smalltalk.send((1),"_to_do_",[self,(function(iter){
-count=(0);
+$1=self;
+$2=(function(iter){
+return smalltalk.withContext(function($ctx2) {
count=(0);
 count;
-flags=smalltalk.send((smalltalk.Array || Array),"_new",[]);
+flags=_st((smalltalk.Array || Array))._new();
 flags;
-smalltalk.send(size,"_timesRepeat_",[(function(){
-return smalltalk.send(flags,"_add_",[true]);
-})]);
-return smalltalk.send((1),"_to_do_",[size,(function(i){
-$1=smalltalk.send(flags,"_at_",[i]);
-if(smalltalk.assert($1)){
-prime=smalltalk.send(i,"__plus",[(1)]);
+_st(size)._timesRepeat_((function(){
+return smalltalk.withContext(function($ctx3) {
return _st(flags)._add_(true);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+$3=size;
+$4=(function(i){
+return smalltalk.withContext(function($ctx3) {
$5=_st(flags)._at_(i);
+if(smalltalk.assert($5)){
+prime=_st(i).__plus((1));
 prime;
-k=smalltalk.send(i,"__plus",[prime]);
+k=_st(i).__plus(prime);
 k;
-smalltalk.send((function(){
-return smalltalk.send(k,"__lt_eq",[size]);
-}),"_whileTrue_",[(function(){
-smalltalk.send(flags,"_at_put_",[k,false]);
-k=smalltalk.send(k,"__plus",[prime]);
+_st((function(){
+return smalltalk.withContext(function($ctx4) {
return _st(k).__lt_eq(size);
+}, function($ctx4) {$ctx4.fillBlock({},$ctx1)})}))._whileTrue_((function(){
+return smalltalk.withContext(function($ctx4) {
_st(flags)._at_put_(k,false);
+k=_st(k).__plus(prime);
 return k;
-})]);
-count=smalltalk.send(count,"__plus",[(1)]);
+}, function($ctx4) {$ctx4.fillBlock({},$ctx1)})}));
+count=_st(count).__plus((1));
 return count;
 };
-})]);
-})]);
-return count;
-},
+}, function($ctx3) {$ctx3.fillBlock({i:i},$ctx1)})});
+return _st((1))._to_do_($3,$4);
+}, function($ctx2) {$ctx2.fillBlock({iter:iter},$ctx1)})});
+_st((1))._to_do_($1,$2);
+$6=count;
+return $6;
+}, function($ctx1) {$ctx1.fill(self,"benchmark",{size:size,flags:flags,prime:prime,k:k,count:count}, smalltalk.Number)})},
 args: [],
 source: "benchmark \x0a\x09\x22Handy bytecode-heavy benchmark\x22\x0a\x09\x22(500000 // time to run) = approx bytecodes per second\x22\x0a\x09\x225000000 // (Time millisecondsToRun: [10 benchmark]) * 1000\x22\x0a\x09\x223059000 on a Mac 8100/100\x22\x0a    | size flags prime k count |\x0a    size := 8190.\x0a    1 to: self do:\x0a        [:iter |\x0a        count := 0.\x0a        flags := Array new.\x0a        size timesRepeat: [ flags add: true].\x0a        1 to: size do:\x0a            [:i | (flags at: i) ifTrue:\x0a                [prime := i+1.\x0a                k := i + prime.\x0a                [k <= size] whileTrue:\x0a                    [flags at: k put: false.\x0a                    k := k + prime].\x0a                count := count + 1]]].\x0a    ^ count",
 messageSends: ["to:do:", "new", "timesRepeat:", "add:", "ifTrue:", "+", "whileTrue:", "at:put:", "<=", "at:"],
@@ -100,12 +101,11 @@ selector: "jsbenchFib",
 category: '*Benchfib',
 fn: function (){
 var self=this;
-if (this < 2) {
+return smalltalk.withContext(function($ctx1) { 
if (this < 2) {
 return 1;
 } else {
 return (this-1)._jsbenchFib() + (this-2)._jsbenchFib() + 1;};
-;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"jsbenchFib",{}, smalltalk.Number)})},
 args: [],
 source: "jsbenchFib\x0a \x0a\x09<if (this < 2) {\x0areturn 1;\x0a} else {\x0areturn (this-1)._jsbenchFib() + (this-2)._jsbenchFib() + 1;}>",
 messageSends: [],
@@ -120,7 +120,7 @@ selector: "jsbenchmark",
 category: '*Benchfib',
 fn: function (){
 var self=this;
-
+return smalltalk.withContext(function($ctx1) { 
 var size = 8190;
 var count;
 for (var z=0;z<this;z++) {
@@ -142,8 +142,7 @@ for (var z=0;z<this;z++) {
   }
 }
 return count;
-;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"jsbenchmark",{}, smalltalk.Number)})},
 args: [],
 source: "jsbenchmark\x0a\x0a<\x0avar size = 8190;\x0avar count;\x0afor (var z=0;z<this;z++) {\x0a  count = 0;\x0a  var flags = new Array();\x0a  for (var p=0; p<size; p++) {\x0a    flags[p] = true;\x0a  }\x0a  for (var i=1;i<=size;i++) {\x0a    if (flags[i-1]) {\x0a      var prime = i+1;\x0a      var k = i + prime;\x0a      while (k <= size) {\x0a        flags[k-1] = false;\x0a        k = k + prime;\x0a      }\x0a      count = count + 1;\x0a    }\x0a  }\x0a}\x0areturn count>",
 messageSends: [],
@@ -158,38 +157,34 @@ selector: "jstinyBenchmarks",
 category: '*Benchfib',
 fn: function (){
 var self=this;
-var $1;
-var t1;
-var t2;
-var r;
-var n1;
-var n2;
+var t1,t2,r,n1,n2;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 n1=(1);
-smalltalk.send((function(){
-t1=smalltalk.send((smalltalk.Date || Date),"_millisecondsToRun_",[(function(){
-return smalltalk.send(n1,"_jsbenchmark",[]);
-})]);
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
t1=_st((smalltalk.Date || Date))._millisecondsToRun_((function(){
+return smalltalk.withContext(function($ctx3) {
return _st(n1)._jsbenchmark();
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 t1;
-return smalltalk.send(t1,"__lt",[(1000)]);
-}),"_whileTrue_",[(function(){
-n1=smalltalk.send(n1,"__star",[(2)]);
+return _st(t1).__lt((1000));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileTrue_((function(){
+return smalltalk.withContext(function($ctx2) {
n1=_st(n1).__star((2));
 return n1;
-})]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 n2=(28);
-smalltalk.send((function(){
-t2=smalltalk.send((smalltalk.Date || Date),"_millisecondsToRun_",[(function(){
-r=smalltalk.send(n2,"_jsbenchFib",[]);
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
t2=_st((smalltalk.Date || Date))._millisecondsToRun_((function(){
+return smalltalk.withContext(function($ctx3) {
r=_st(n2)._jsbenchFib();
 return r;
-})]);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 t2;
-return smalltalk.send(t2,"__lt",[(1000)]);
-}),"_whileTrue_",[(function(){
-n2=smalltalk.send(n2,"__plus",[(1)]);
+return _st(t2).__lt((1000));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileTrue_((function(){
+return smalltalk.withContext(function($ctx2) {
n2=_st(n2).__plus((1));
 return n2;
-})]);
-$1=smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(n1,"__star",[(500000)]),"__star",[(1000)]),"__slash",[t1]),"_printString",[]),"__comma",[" bytecodes/sec; "]),"__comma",[smalltalk.send(smalltalk.send(smalltalk.send(r,"__star",[(1000)]),"__slash",[t2]),"_printString",[])]),"__comma",[" sends/sec"]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$1=_st(_st(_st(_st(_st(_st(_st(n1).__star((500000))).__star((1000))).__slash(t1))._printString()).__comma(" bytecodes/sec; ")).__comma(_st(_st(_st(r).__star((1000))).__slash(t2))._printString())).__comma(" sends/sec");
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"jstinyBenchmarks",{t1:t1,t2:t2,r:r,n1:n1,n2:n2}, smalltalk.Number)})},
 args: [],
 source: "jstinyBenchmarks\x0a\x09\x220 jstinyBenchmarks\x22\x0a\x0a\x09| t1 t2 r n1 n2 |\x0a\x09n1 := 1.\x0a\x09[t1 := Date millisecondsToRun: [n1 jsbenchmark].\x0a\x09t1 < 1000] whileTrue:[n1 := n1 * 2]. \x22Note: #benchmark's runtime is about O(n)\x22\x0a\x0a\x09n2 := 28.\x0a\x09[t2 := Date millisecondsToRun: [r := n2 jsbenchFib].\x0a\x09t2 < 1000] whileTrue:[n2 := n2 + 1]. \x0a\x09\x22Note: #jsbenchFib's runtime is about O(k^n),\x0a\x09\x09where k is the golden number = (1 + 5 sqrt) / 2 = 1.618....\x22\x0a\x0a\x09^ ((n1 * 500000 * 1000) / t1) printString, ' bytecodes/sec; ',\x0a\x09  ((r * 1000) / t2) printString, ' sends/sec'",
 messageSends: ["whileTrue:", "*", "millisecondsToRun:", "jsbenchmark", "<", "+", "jsbenchFib", ",", "printString", "/"],
@@ -204,38 +199,34 @@ selector: "tinyBenchmarks",
 category: '*Benchfib',
 fn: function (){
 var self=this;
-var $1;
-var t1;
-var t2;
-var r;
-var n1;
-var n2;
+var t1,t2,r,n1,n2;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 n1=(1);
-smalltalk.send((function(){
-t1=smalltalk.send((smalltalk.Date || Date),"_millisecondsToRun_",[(function(){
-return smalltalk.send(n1,"_benchmark",[]);
-})]);
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
t1=_st((smalltalk.Date || Date))._millisecondsToRun_((function(){
+return smalltalk.withContext(function($ctx3) {
return _st(n1)._benchmark();
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 t1;
-return smalltalk.send(t1,"__lt",[(1000)]);
-}),"_whileTrue_",[(function(){
-n1=smalltalk.send(n1,"__star",[(2)]);
+return _st(t1).__lt((1000));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileTrue_((function(){
+return smalltalk.withContext(function($ctx2) {
n1=_st(n1).__star((2));
 return n1;
-})]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 n2=(16);
-smalltalk.send((function(){
-t2=smalltalk.send((smalltalk.Date || Date),"_millisecondsToRun_",[(function(){
-r=smalltalk.send(n2,"_benchFib",[]);
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
t2=_st((smalltalk.Date || Date))._millisecondsToRun_((function(){
+return smalltalk.withContext(function($ctx3) {
r=_st(n2)._benchFib();
 return r;
-})]);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 t2;
-return smalltalk.send(t2,"__lt",[(1000)]);
-}),"_whileTrue_",[(function(){
-n2=smalltalk.send(n2,"__plus",[(1)]);
+return _st(t2).__lt((1000));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileTrue_((function(){
+return smalltalk.withContext(function($ctx2) {
n2=_st(n2).__plus((1));
 return n2;
-})]);
-$1=smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(n1,"__star",[(500000)]),"__star",[(1000)]),"__slash",[t1]),"_printString",[]),"__comma",[" bytecodes/sec; "]),"__comma",[smalltalk.send(smalltalk.send(smalltalk.send(r,"__star",[(1000)]),"__slash",[t2]),"_printString",[])]),"__comma",[" sends/sec"]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$1=_st(_st(_st(_st(_st(_st(_st(n1).__star((500000))).__star((1000))).__slash(t1))._printString()).__comma(" bytecodes/sec; ")).__comma(_st(_st(_st(r).__star((1000))).__slash(t2))._printString())).__comma(" sends/sec");
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"tinyBenchmarks",{t1:t1,t2:t2,r:r,n1:n1,n2:n2}, smalltalk.Number)})},
 args: [],
 source: "tinyBenchmarks \x0a\x09\x22Report the results of running the two tiny Squeak benchmarks.\x0a\x09ar 9/10/1999: Adjusted to run at least 1 sec to get more stable results\x22\x0a\x09\x220 tinyBenchmarks\x22\x0a\x09\x22On a 292 MHz G3 Mac: 22727272 bytecodes/sec; 984169 sends/sec\x22\x0a\x09\x22On a 400 MHz PII/Win98:  18028169 bytecodes/sec; 1081272 sends/sec\x22\x0a\x09| t1 t2 r n1 n2 |\x0a\x09n1 := 1.\x0a\x09[t1 := Date millisecondsToRun: [n1 benchmark].\x0a\x09t1 < 1000] whileTrue:[n1 := n1 * 2]. \x22Note: #benchmark's runtime is about O(n)\x22\x0a\x0a\x09n2 := 16.\x0a\x09[t2 := Date millisecondsToRun: [r := n2 benchFib].\x0a\x09t2 < 1000] whileTrue:[n2 := n2 + 1]. \x0a\x09\x22Note: #benchFib's runtime is about O(k^n),\x0a\x09\x09where k is the golden number = (1 + 5 sqrt) / 2 = 1.618....\x22\x0a\x0a\x09^ ((n1 * 500000 * 1000) / t1) printString, ' bytecodes/sec; ',\x0a\x09  ((r * 1000) / t2) printString, ' sends/sec'",
 messageSends: ["whileTrue:", "*", "millisecondsToRun:", "benchmark", "<", "+", "benchFib", ",", "printString", "/"],

Fichier diff supprimé car celui-ci est trop grand
+ 219 - 217
js/Canvas.deploy.js


Fichier diff supprimé car celui-ci est trop grand
+ 219 - 217
js/Canvas.js


Fichier diff supprimé car celui-ci est trop grand
+ 287 - 188
js/Compiler-AST.deploy.js


Fichier diff supprimé car celui-ci est trop grand
+ 298 - 179
js/Compiler-AST.js


Fichier diff supprimé car celui-ci est trop grand
+ 208 - 969
js/Compiler-Core.deploy.js


Fichier diff supprimé car celui-ci est trop grand
+ 210 - 406
js/Compiler-Core.js


+ 37 - 18
js/Compiler-Exceptions.deploy.js

@@ -18,10 +18,10 @@ smalltalk.method({
 selector: "messageText",
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(" Invalid assignment to variable: ","__comma",[smalltalk.send(self,"_variableName",[])]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(" Invalid assignment to variable: ").__comma(_st(self)._variableName());
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"messageText",{}, smalltalk.InvalidAssignmentError)})}
 }),
 smalltalk.InvalidAssignmentError);
 
@@ -31,8 +31,10 @@ smalltalk.method({
 selector: "variableName",
 fn: function (){
 var self=this;
-return self["@variableName"];
-}
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@variableName"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"variableName",{}, smalltalk.InvalidAssignmentError)})}
 }),
 smalltalk.InvalidAssignmentError);
 
@@ -42,8 +44,8 @@ smalltalk.method({
 selector: "variableName:",
 fn: function (aString){
 var self=this;
-self["@variableName"]=aString;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@variableName"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"variableName:",{aString:aString}, smalltalk.InvalidAssignmentError)})}
 }),
 smalltalk.InvalidAssignmentError);
 
@@ -56,10 +58,10 @@ smalltalk.method({
 selector: "messageText",
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send("Variable shadowing error: ","__comma",[smalltalk.send(self,"_variableName",[])]),"__comma",[" is already defined"]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st("Variable shadowing error: ").__comma(_st(self)._variableName())).__comma(" is already defined");
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"messageText",{}, smalltalk.ShadowingVariableError)})}
 }),
 smalltalk.ShadowingVariableError);
 
@@ -69,8 +71,10 @@ smalltalk.method({
 selector: "variableName",
 fn: function (){
 var self=this;
-return self["@variableName"];
-}
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@variableName"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"variableName",{}, smalltalk.ShadowingVariableError)})}
 }),
 smalltalk.ShadowingVariableError);
 
@@ -80,22 +84,37 @@ smalltalk.method({
 selector: "variableName:",
 fn: function (aString){
 var self=this;
-self["@variableName"]=aString;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@variableName"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"variableName:",{aString:aString}, smalltalk.ShadowingVariableError)})}
 }),
 smalltalk.ShadowingVariableError);
 
 
 
 smalltalk.addClass('UnknownVariableError', smalltalk.SemanticError, ['variableName'], 'Compiler-Exceptions');
+smalltalk.addMethod(
+"_messageText",
+smalltalk.method({
+selector: "messageText",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st("Unknown Variable error: ").__comma(_st(self)._variableName())).__comma(" is not defined");
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"messageText",{}, smalltalk.UnknownVariableError)})}
+}),
+smalltalk.UnknownVariableError);
+
 smalltalk.addMethod(
 "_variableName",
 smalltalk.method({
 selector: "variableName",
 fn: function (){
 var self=this;
-return self["@variableName"];
-}
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@variableName"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"variableName",{}, smalltalk.UnknownVariableError)})}
 }),
 smalltalk.UnknownVariableError);
 
@@ -105,8 +124,8 @@ smalltalk.method({
 selector: "variableName:",
 fn: function (aString){
 var self=this;
-self["@variableName"]=aString;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@variableName"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"variableName:",{aString:aString}, smalltalk.UnknownVariableError)})}
 }),
 smalltalk.UnknownVariableError);
 

+ 42 - 18
js/Compiler-Exceptions.js

@@ -24,10 +24,10 @@ selector: "messageText",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(" Invalid assignment to variable: ","__comma",[smalltalk.send(self,"_variableName",[])]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(" Invalid assignment to variable: ").__comma(_st(self)._variableName());
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"messageText",{}, smalltalk.InvalidAssignmentError)})},
 args: [],
 source: "messageText\x0a\x09^ ' Invalid assignment to variable: ', self variableName",
 messageSends: [",", "variableName"],
@@ -42,8 +42,10 @@ selector: "variableName",
 category: 'accessing',
 fn: function (){
 var self=this;
-return self["@variableName"];
-},
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@variableName"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"variableName",{}, smalltalk.InvalidAssignmentError)})},
 args: [],
 source: "variableName\x0a\x09^ variableName",
 messageSends: [],
@@ -58,8 +60,8 @@ selector: "variableName:",
 category: 'accessing',
 fn: function (aString){
 var self=this;
-self["@variableName"]=aString;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@variableName"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"variableName:",{aString:aString}, smalltalk.InvalidAssignmentError)})},
 args: ["aString"],
 source: "variableName: aString\x0a\x09variableName := aString",
 messageSends: [],
@@ -78,10 +80,10 @@ selector: "messageText",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send("Variable shadowing error: ","__comma",[smalltalk.send(self,"_variableName",[])]),"__comma",[" is already defined"]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st("Variable shadowing error: ").__comma(_st(self)._variableName())).__comma(" is already defined");
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"messageText",{}, smalltalk.ShadowingVariableError)})},
 args: [],
 source: "messageText\x0a\x09^ 'Variable shadowing error: ', self variableName, ' is already defined'",
 messageSends: [",", "variableName"],
@@ -96,8 +98,10 @@ selector: "variableName",
 category: 'accessing',
 fn: function (){
 var self=this;
-return self["@variableName"];
-},
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@variableName"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"variableName",{}, smalltalk.ShadowingVariableError)})},
 args: [],
 source: "variableName\x0a\x09^ variableName",
 messageSends: [],
@@ -112,8 +116,8 @@ selector: "variableName:",
 category: 'accessing',
 fn: function (aString){
 var self=this;
-self["@variableName"]=aString;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@variableName"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"variableName:",{aString:aString}, smalltalk.ShadowingVariableError)})},
 args: ["aString"],
 source: "variableName: aString\x0a\x09variableName := aString",
 messageSends: [],
@@ -125,6 +129,24 @@ smalltalk.ShadowingVariableError);
 
 smalltalk.addClass('UnknownVariableError', smalltalk.SemanticError, ['variableName'], 'Compiler-Exceptions');
 smalltalk.UnknownVariableError.comment="I get signaled when a variable is not defined.\x0aThe default behavior is to allow it, as this is how Amber currently is able to seamlessly send messages to JavaScript objects."
+smalltalk.addMethod(
+"_messageText",
+smalltalk.method({
+selector: "messageText",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st("Unknown Variable error: ").__comma(_st(self)._variableName())).__comma(" is not defined");
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"messageText",{}, smalltalk.UnknownVariableError)})},
+args: [],
+source: "messageText\x0a\x09^ 'Unknown Variable error: ', self variableName, ' is not defined'",
+messageSends: [",", "variableName"],
+referencedClasses: []
+}),
+smalltalk.UnknownVariableError);
+
 smalltalk.addMethod(
 "_variableName",
 smalltalk.method({
@@ -132,8 +154,10 @@ selector: "variableName",
 category: 'accessing',
 fn: function (){
 var self=this;
-return self["@variableName"];
-},
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@variableName"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"variableName",{}, smalltalk.UnknownVariableError)})},
 args: [],
 source: "variableName\x0a\x09^ variableName",
 messageSends: [],
@@ -148,8 +172,8 @@ selector: "variableName:",
 category: 'accessing',
 fn: function (aString){
 var self=this;
-self["@variableName"]=aString;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@variableName"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"variableName:",{aString:aString}, smalltalk.UnknownVariableError)})},
 args: ["aString"],
 source: "variableName: aString\x0a\x09variableName := aString",
 messageSends: [],

Fichier diff supprimé car celui-ci est trop grand
+ 343 - 285
js/Compiler-IR.deploy.js


Fichier diff supprimé car celui-ci est trop grand
+ 348 - 282
js/Compiler-IR.js


Fichier diff supprimé car celui-ci est trop grand
+ 290 - 281
js/Compiler-Inlining.deploy.js


Fichier diff supprimé car celui-ci est trop grand
+ 290 - 281
js/Compiler-Inlining.js


+ 592 - 0
js/Compiler-Interpreter.deploy.js

@@ -0,0 +1,592 @@
+smalltalk.addPackage('Compiler-Interpreter', {});
+smalltalk.addClass('AIContext', smalltalk.NodeVisitor, ['outerContext', 'pc', 'locals', 'receiver', 'selector'], 'Compiler-Interpreter');
+smalltalk.addMethod(
+"_initializeFromMethodContext_",
+smalltalk.method({
+selector: "initializeFromMethodContext:",
+fn: function (aMethodContext){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+_st(self)._pc_(_st(aMethodContext)._pc());
+_st(self)._receiver_(_st(aMethodContext)._receiver());
+_st(self)._selector_(_st(aMethodContext)._selector());
+$1=_st(aMethodContext)._outerContext();
+if(($receiver = $1) == nil || $receiver == undefined){
+$1;
+} else {
+_st(self)._outerContext_(_st(_st(self)._class())._fromMethodContext_(_st(aMethodContext)._outerContext()));
+};
+_st(_st(aMethodContext)._locals())._keysAndValuesDo_((function(key,value){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(self)._locals())._at_put_(key,value);
+}, function($ctx2) {$ctx2.fillBlock({key:key,value:value},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"initializeFromMethodContext:",{aMethodContext:aMethodContext}, smalltalk.AIContext)})}
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_localAt_",
+smalltalk.method({
+selector: "localAt:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._locals())._at_ifAbsent_(aString,(function(){
+return smalltalk.withContext(function($ctx2) {
return nil;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"localAt:",{aString:aString}, smalltalk.AIContext)})}
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_localAt_put_",
+smalltalk.method({
+selector: "localAt:put:",
+fn: function (aString,anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._locals())._at_put_(aString,anObject);
+return self}, function($ctx1) {$ctx1.fill(self,"localAt:put:",{aString:aString,anObject:anObject}, smalltalk.AIContext)})}
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_locals",
+smalltalk.method({
+selector: "locals",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@locals"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@locals"]=_st((smalltalk.Dictionary || Dictionary))._new();
+$1=self["@locals"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"locals",{}, smalltalk.AIContext)})}
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_outerContext",
+smalltalk.method({
+selector: "outerContext",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@outerContext"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"outerContext",{}, smalltalk.AIContext)})}
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_outerContext_",
+smalltalk.method({
+selector: "outerContext:",
+fn: function (anAIContext){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@outerContext"]=anAIContext;
+return self}, function($ctx1) {$ctx1.fill(self,"outerContext:",{anAIContext:anAIContext}, smalltalk.AIContext)})}
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_pc",
+smalltalk.method({
+selector: "pc",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@pc"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@pc"]=(0);
+$1=self["@pc"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"pc",{}, smalltalk.AIContext)})}
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_pc_",
+smalltalk.method({
+selector: "pc:",
+fn: function (anInteger){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@pc"]=anInteger;
+return self}, function($ctx1) {$ctx1.fill(self,"pc:",{anInteger:anInteger}, smalltalk.AIContext)})}
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_receiver",
+smalltalk.method({
+selector: "receiver",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@receiver"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"receiver",{}, smalltalk.AIContext)})}
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_receiver_",
+smalltalk.method({
+selector: "receiver:",
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@receiver"]=anObject;
+return self}, function($ctx1) {$ctx1.fill(self,"receiver:",{anObject:anObject}, smalltalk.AIContext)})}
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_selector",
+smalltalk.method({
+selector: "selector",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@selector"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"selector",{}, smalltalk.AIContext)})}
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_selector_",
+smalltalk.method({
+selector: "selector:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@selector"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"selector:",{aString:aString}, smalltalk.AIContext)})}
+}),
+smalltalk.AIContext);
+
+
+smalltalk.addMethod(
+"_fromMethodContext_",
+smalltalk.method({
+selector: "fromMethodContext:",
+fn: function (aMethodContext){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
+$2=_st(self)._new();
+_st($2)._initializeFromMethodContext_(aMethodContext);
+$3=_st($2)._yourself();
+$1=$3;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"fromMethodContext:",{aMethodContext:aMethodContext}, smalltalk.AIContext.klass)})}
+}),
+smalltalk.AIContext.klass);
+
+
+smalltalk.addClass('ASTInterpreter', smalltalk.NodeVisitor, ['currentNode', 'context', 'shouldReturn', 'currentValue'], 'Compiler-Interpreter');
+smalltalk.addMethod(
+"_assign_to_",
+smalltalk.method({
+selector: "assign:to:",
+fn: function (aNode,anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=_st(_st(aNode)._binding())._isInstanceVar();
+if(smalltalk.assert($2)){
+$1=_st(_st(_st(self)._context())._receiver())._instVarAt_put_(_st(aNode)._value(),anObject);
+} else {
+$1=_st(_st(self)._context())._localAt_put_(_st(aNode)._value(),anObject);
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"assign:to:",{aNode:aNode,anObject:anObject}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_context",
+smalltalk.method({
+selector: "context",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@context"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@context"]=_st((smalltalk.AIContext || AIContext))._new();
+$1=self["@context"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"context",{}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_context_",
+smalltalk.method({
+selector: "context:",
+fn: function (anAIContext){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@context"]=anAIContext;
+return self}, function($ctx1) {$ctx1.fill(self,"context:",{anAIContext:anAIContext}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_continue_",
+smalltalk.method({
+selector: "continue:",
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@currentValue"]=anObject;
+return self}, function($ctx1) {$ctx1.fill(self,"continue:",{anObject:anObject}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_currentValue",
+smalltalk.method({
+selector: "currentValue",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@currentValue"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"currentValue",{}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_eval_",
+smalltalk.method({
+selector: "eval:",
+fn: function (aString){
+var self=this;
+var source,function_;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+source=_st((smalltalk.String || String))._streamContents_((function(str){
+return smalltalk.withContext(function($ctx2) {
_st(str)._nextPutAll_("(function(");
+_st(_st(_st(_st(self)._context())._locals())._keys())._do_separatedBy_((function(each){
+return smalltalk.withContext(function($ctx3) {
return _st(str)._nextPutAll_(each);
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx3) {
return _st(str)._nextPutAll_(",");
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+$1=str;
+_st($1)._nextPutAll_("){ return (function() {");
+_st($1)._nextPutAll_(aString);
+$2=_st($1)._nextPutAll_("})() })");
+return $2;
+}, function($ctx2) {$ctx2.fillBlock({str:str},$ctx1)})}));
+function_=_st(_st((smalltalk.Compiler || Compiler))._new())._eval_(source);
+$3=_st(function_)._valueWithPossibleArguments_(_st(_st(_st(self)._context())._locals())._values());
+return $3;
+}, function($ctx1) {$ctx1.fill(self,"eval:",{aString:aString,source:source,function_:function_}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
smalltalk.NodeVisitor.fn.prototype._initialize.apply(_st(self), []);
+self["@shouldReturn"]=false;
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_interpret_",
+smalltalk.method({
+selector: "interpret:",
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@shouldReturn"]=false;
+_st(self)._interpret_continue_(aNode,(function(value){
+return smalltalk.withContext(function($ctx2) {
self["@currentValue"]=value;
+return self["@currentValue"];
+}, function($ctx2) {$ctx2.fillBlock({value:value},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"interpret:",{aNode:aNode}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_interpret_continue_",
+smalltalk.method({
+selector: "interpret:continue:",
+fn: function (aNode,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+$1=self["@shouldReturn"];
+if(smalltalk.assert($1)){
+$2=self;
+return $2;
+};
+$3=_st(aNode)._isNode();
+if(smalltalk.assert($3)){
+_st(self)._visit_(aNode);
+} else {
+self["@currentValue"]=aNode;
+self["@currentValue"];
+};
+_st(aBlock)._value_(_st(self)._currentValue());
+return self}, function($ctx1) {$ctx1.fill(self,"interpret:continue:",{aNode:aNode,aBlock:aBlock}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_interpretAll_continue_",
+smalltalk.method({
+selector: "interpretAll:continue:",
+fn: function (aCollection,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._interpretAll_continue_result_(aCollection,aBlock,_st((smalltalk.OrderedCollection || OrderedCollection))._new());
+return self}, function($ctx1) {$ctx1.fill(self,"interpretAll:continue:",{aCollection:aCollection,aBlock:aBlock}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_interpretAll_continue_result_",
+smalltalk.method({
+selector: "interpretAll:continue:result:",
+fn: function (nodes,aBlock,aCollection){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(nodes)._isEmpty();
+if(smalltalk.assert($1)){
+_st(aBlock)._value_(aCollection);
+} else {
+_st(self)._interpret_continue_(_st(nodes)._first(),(function(value){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._interpretAll_continue_result_(_st(nodes)._allButFirst(),aBlock,_st(aCollection).__comma([value]));
+}, function($ctx2) {$ctx2.fillBlock({value:value},$ctx1)})}));
+};
+return self}, function($ctx1) {$ctx1.fill(self,"interpretAll:continue:result:",{nodes:nodes,aBlock:aBlock,aCollection:aCollection}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_messageFromSendNode_do_",
+smalltalk.method({
+selector: "messageFromSendNode:do:",
+fn: function (aSendNode,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+_st(self)._interpretAll_continue_(_st(aSendNode)._arguments(),(function(args){
+return smalltalk.withContext(function($ctx2) {
$1=_st((smalltalk.Message || Message))._new();
+_st($1)._selector_(_st(aSendNode)._selector());
+_st($1)._arguments_(args);
+$2=_st($1)._yourself();
+return _st(aBlock)._value_($2);
+}, function($ctx2) {$ctx2.fillBlock({args:args},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"messageFromSendNode:do:",{aSendNode:aSendNode,aBlock:aBlock}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitAssignmentNode_",
+smalltalk.method({
+selector: "visitAssignmentNode:",
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._interpret_continue_(_st(aNode)._right(),(function(value){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._continue_(_st(self)._assign_to_(_st(aNode)._left(),value));
+}, function($ctx2) {$ctx2.fillBlock({value:value},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"visitAssignmentNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitBlockNode_",
+smalltalk.method({
+selector: "visitBlockNode:",
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+_st(self)._continue_((function(){
+return smalltalk.withContext(function($ctx2) {
$1=self;
+_st($1)._interpret_(_st(_st(aNode)._nodes())._first());
+$2=_st($1)._currentValue();
+return $2;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"visitBlockNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitCascadeNode_",
+smalltalk.method({
+selector: "visitCascadeNode:",
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._interpret_continue_(_st(aNode)._receiver(),(function(receiver){
+return smalltalk.withContext(function($ctx2) {
_st(_st(aNode)._nodes())._do_((function(each){
+return smalltalk.withContext(function($ctx3) {
return _st(each)._receiver_(receiver);
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}));
+return _st(self)._interpretAll_continue_(_st(_st(aNode)._nodes())._allButLast(),(function(){
+return smalltalk.withContext(function($ctx3) {
return _st(self)._interpret_continue_(_st(_st(aNode)._nodes())._last(),(function(val){
+return smalltalk.withContext(function($ctx4) {
return _st(self)._continue_(val);
+}, function($ctx4) {$ctx4.fillBlock({val:val},$ctx1)})}));
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({receiver:receiver},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"visitCascadeNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitClassReferenceNode_",
+smalltalk.method({
+selector: "visitClassReferenceNode:",
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._continue_(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(_st(aNode)._value()));
+return self}, function($ctx1) {$ctx1.fill(self,"visitClassReferenceNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitDynamicArrayNode_",
+smalltalk.method({
+selector: "visitDynamicArrayNode:",
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._interpretAll_continue_(_st(aNode)._nodes(),(function(array){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._continue_(array);
+}, function($ctx2) {$ctx2.fillBlock({array:array},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"visitDynamicArrayNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitDynamicDictionaryNode_",
+smalltalk.method({
+selector: "visitDynamicDictionaryNode:",
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._interpretAll_continue_(_st(aNode)._nodes(),(function(array){
+var hashedCollection;
+return smalltalk.withContext(function($ctx2) {
hashedCollection=_st((smalltalk.HashedCollection || HashedCollection))._new();
+hashedCollection;
+_st(array)._do_((function(each){
+return smalltalk.withContext(function($ctx3) {
return _st(hashedCollection)._add_(each);
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}));
+return _st(self)._continue_(hashedCollection);
+}, function($ctx2) {$ctx2.fillBlock({array:array,hashedCollection:hashedCollection},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"visitDynamicDictionaryNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitJSStatementNode_",
+smalltalk.method({
+selector: "visitJSStatementNode:",
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@shouldReturn"]=true;
+_st(self)._continue_(_st(self)._eval_(_st(aNode)._source()));
+return self}, function($ctx1) {$ctx1.fill(self,"visitJSStatementNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitReturnNode_",
+smalltalk.method({
+selector: "visitReturnNode:",
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._interpret_continue_(_st(_st(aNode)._nodes())._first(),(function(value){
+return smalltalk.withContext(function($ctx2) {
self["@shouldReturn"]=true;
+self["@shouldReturn"];
+return _st(self)._continue_(value);
+}, function($ctx2) {$ctx2.fillBlock({value:value},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"visitReturnNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitSendNode_",
+smalltalk.method({
+selector: "visitSendNode:",
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._interpret_continue_(_st(aNode)._receiver(),(function(receiver){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._messageFromSendNode_do_(aNode,(function(message){
+return smalltalk.withContext(function($ctx3) {
_st(_st(self)._context())._pc_(_st(_st(_st(self)._context())._pc()).__plus((1)));
+return _st(self)._continue_(_st(message)._sendTo_(receiver));
+}, function($ctx3) {$ctx3.fillBlock({message:message},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({receiver:receiver},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"visitSendNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitSequenceNode_",
+smalltalk.method({
+selector: "visitSequenceNode:",
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._interpretAll_continue_(_st(aNode)._nodes(),(function(array){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._continue_(_st(array)._last());
+}, function($ctx2) {$ctx2.fillBlock({array:array},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"visitSequenceNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitValueNode_",
+smalltalk.method({
+selector: "visitValueNode:",
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._continue_(_st(aNode)._value());
+return self}, function($ctx1) {$ctx1.fill(self,"visitValueNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
+
+
+smalltalk.addClass('ASTDebugger', smalltalk.ASTInterpreter, ['continuation'], 'Compiler-Interpreter');
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
smalltalk.ASTInterpreter.fn.prototype._initialize.apply(_st(self), []);
+self["@continuation"]=(function(){
+return smalltalk.withContext(function($ctx2) {
}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.ASTDebugger)})}
+}),
+smalltalk.ASTDebugger);
+
+smalltalk.addMethod(
+"_interpret_continue_",
+smalltalk.method({
+selector: "interpret:continue:",
+fn: function (aNode,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@continuation"]=(function(){
+return smalltalk.withContext(function($ctx2) {
return smalltalk.ASTInterpreter.fn.prototype._interpret_continue_.apply(_st(self), [aNode,aBlock]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+return self}, function($ctx1) {$ctx1.fill(self,"interpret:continue:",{aNode:aNode,aBlock:aBlock}, smalltalk.ASTDebugger)})}
+}),
+smalltalk.ASTDebugger);
+
+smalltalk.addMethod(
+"_stepOver",
+smalltalk.method({
+selector: "stepOver",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self["@continuation"])._value();
+return self}, function($ctx1) {$ctx1.fill(self,"stepOver",{}, smalltalk.ASTDebugger)})}
+}),
+smalltalk.ASTDebugger);
+
+
+

+ 787 - 0
js/Compiler-Interpreter.js

@@ -0,0 +1,787 @@
+smalltalk.addPackage('Compiler-Interpreter', {});
+smalltalk.addClass('AIContext', smalltalk.NodeVisitor, ['outerContext', 'pc', 'locals', 'receiver', 'selector'], 'Compiler-Interpreter');
+smalltalk.addMethod(
+"_initializeFromMethodContext_",
+smalltalk.method({
+selector: "initializeFromMethodContext:",
+category: 'accessing',
+fn: function (aMethodContext){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+_st(self)._pc_(_st(aMethodContext)._pc());
+_st(self)._receiver_(_st(aMethodContext)._receiver());
+_st(self)._selector_(_st(aMethodContext)._selector());
+$1=_st(aMethodContext)._outerContext();
+if(($receiver = $1) == nil || $receiver == undefined){
+$1;
+} else {
+_st(self)._outerContext_(_st(_st(self)._class())._fromMethodContext_(_st(aMethodContext)._outerContext()));
+};
+_st(_st(aMethodContext)._locals())._keysAndValuesDo_((function(key,value){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(self)._locals())._at_put_(key,value);
+}, function($ctx2) {$ctx2.fillBlock({key:key,value:value},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"initializeFromMethodContext:",{aMethodContext:aMethodContext}, smalltalk.AIContext)})},
+args: ["aMethodContext"],
+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    ",
+messageSends: ["pc:", "pc", "receiver:", "receiver", "selector:", "selector", "ifNotNil:", "outerContext:", "fromMethodContext:", "outerContext", "class", "keysAndValuesDo:", "at:put:", "locals"],
+referencedClasses: []
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_localAt_",
+smalltalk.method({
+selector: "localAt:",
+category: 'accessing',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._locals())._at_ifAbsent_(aString,(function(){
+return smalltalk.withContext(function($ctx2) {
return nil;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"localAt:",{aString:aString}, smalltalk.AIContext)})},
+args: ["aString"],
+source: "localAt: aString\x0a\x09^ self locals at: aString ifAbsent: [ nil ]",
+messageSends: ["at:ifAbsent:", "locals"],
+referencedClasses: []
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_localAt_put_",
+smalltalk.method({
+selector: "localAt:put:",
+category: 'accessing',
+fn: function (aString,anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._locals())._at_put_(aString,anObject);
+return self}, function($ctx1) {$ctx1.fill(self,"localAt:put:",{aString:aString,anObject:anObject}, smalltalk.AIContext)})},
+args: ["aString", "anObject"],
+source: "localAt: aString put: anObject\x0a\x09self locals at: aString put: anObject",
+messageSends: ["at:put:", "locals"],
+referencedClasses: []
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_locals",
+smalltalk.method({
+selector: "locals",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@locals"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@locals"]=_st((smalltalk.Dictionary || Dictionary))._new();
+$1=self["@locals"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"locals",{}, smalltalk.AIContext)})},
+args: [],
+source: "locals\x0a\x09^ locals ifNil: [ locals := Dictionary new ]",
+messageSends: ["ifNil:", "new"],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_outerContext",
+smalltalk.method({
+selector: "outerContext",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@outerContext"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"outerContext",{}, smalltalk.AIContext)})},
+args: [],
+source: "outerContext\x0a\x09^ outerContext",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_outerContext_",
+smalltalk.method({
+selector: "outerContext:",
+category: 'accessing',
+fn: function (anAIContext){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@outerContext"]=anAIContext;
+return self}, function($ctx1) {$ctx1.fill(self,"outerContext:",{anAIContext:anAIContext}, smalltalk.AIContext)})},
+args: ["anAIContext"],
+source: "outerContext: anAIContext\x0a\x09outerContext := anAIContext",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_pc",
+smalltalk.method({
+selector: "pc",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@pc"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@pc"]=(0);
+$1=self["@pc"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"pc",{}, smalltalk.AIContext)})},
+args: [],
+source: "pc\x0a\x09^ pc ifNil: [ pc := 0 ]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_pc_",
+smalltalk.method({
+selector: "pc:",
+category: 'accessing',
+fn: function (anInteger){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@pc"]=anInteger;
+return self}, function($ctx1) {$ctx1.fill(self,"pc:",{anInteger:anInteger}, smalltalk.AIContext)})},
+args: ["anInteger"],
+source: "pc: anInteger\x0a\x09pc := anInteger",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_receiver",
+smalltalk.method({
+selector: "receiver",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@receiver"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"receiver",{}, smalltalk.AIContext)})},
+args: [],
+source: "receiver\x0a\x09^ receiver",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_receiver_",
+smalltalk.method({
+selector: "receiver:",
+category: 'accessing',
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@receiver"]=anObject;
+return self}, function($ctx1) {$ctx1.fill(self,"receiver:",{anObject:anObject}, smalltalk.AIContext)})},
+args: ["anObject"],
+source: "receiver: anObject\x0a\x09receiver := anObject",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_selector",
+smalltalk.method({
+selector: "selector",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@selector"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"selector",{}, smalltalk.AIContext)})},
+args: [],
+source: "selector\x0a\x09^ selector",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+"_selector_",
+smalltalk.method({
+selector: "selector:",
+category: 'accessing',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@selector"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"selector:",{aString:aString}, smalltalk.AIContext)})},
+args: ["aString"],
+source: "selector: aString\x0a\x09selector := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.AIContext);
+
+
+smalltalk.addMethod(
+"_fromMethodContext_",
+smalltalk.method({
+selector: "fromMethodContext:",
+category: 'instance creation',
+fn: function (aMethodContext){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
+$2=_st(self)._new();
+_st($2)._initializeFromMethodContext_(aMethodContext);
+$3=_st($2)._yourself();
+$1=$3;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"fromMethodContext:",{aMethodContext:aMethodContext}, smalltalk.AIContext.klass)})},
+args: ["aMethodContext"],
+source: "fromMethodContext: aMethodContext\x0a\x09^ self new \x0a    \x09initializeFromMethodContext: aMethodContext;\x0a        yourself",
+messageSends: ["initializeFromMethodContext:", "new", "yourself"],
+referencedClasses: []
+}),
+smalltalk.AIContext.klass);
+
+
+smalltalk.addClass('ASTInterpreter', smalltalk.NodeVisitor, ['currentNode', 'context', 'shouldReturn', 'currentValue'], 'Compiler-Interpreter');
+smalltalk.addMethod(
+"_assign_to_",
+smalltalk.method({
+selector: "assign:to:",
+category: 'interpreting',
+fn: function (aNode,anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=_st(_st(aNode)._binding())._isInstanceVar();
+if(smalltalk.assert($2)){
+$1=_st(_st(_st(self)._context())._receiver())._instVarAt_put_(_st(aNode)._value(),anObject);
+} else {
+$1=_st(_st(self)._context())._localAt_put_(_st(aNode)._value(),anObject);
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"assign:to:",{aNode:aNode,anObject:anObject}, smalltalk.ASTInterpreter)})},
+args: ["aNode", "anObject"],
+source: "assign: aNode to: anObject\x0a\x09^ aNode binding isInstanceVar \x0a    \x09ifTrue: [ self context receiver instVarAt: aNode value put: anObject ]\x0a      \x09ifFalse: [ self context localAt: aNode value put: anObject ]",
+messageSends: ["ifTrue:ifFalse:", "instVarAt:put:", "value", "receiver", "context", "localAt:put:", "isInstanceVar", "binding"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_context",
+smalltalk.method({
+selector: "context",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@context"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@context"]=_st((smalltalk.AIContext || AIContext))._new();
+$1=self["@context"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"context",{}, smalltalk.ASTInterpreter)})},
+args: [],
+source: "context\x0a\x09^ context ifNil: [ context := AIContext new ]",
+messageSends: ["ifNil:", "new"],
+referencedClasses: ["AIContext"]
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_context_",
+smalltalk.method({
+selector: "context:",
+category: 'accessing',
+fn: function (anAIContext){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@context"]=anAIContext;
+return self}, function($ctx1) {$ctx1.fill(self,"context:",{anAIContext:anAIContext}, smalltalk.ASTInterpreter)})},
+args: ["anAIContext"],
+source: "context: anAIContext\x0a\x09context := anAIContext",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_continue_",
+smalltalk.method({
+selector: "continue:",
+category: 'interpreting',
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@currentValue"]=anObject;
+return self}, function($ctx1) {$ctx1.fill(self,"continue:",{anObject:anObject}, smalltalk.ASTInterpreter)})},
+args: ["anObject"],
+source: "continue: anObject\x0a\x09currentValue := anObject",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_currentValue",
+smalltalk.method({
+selector: "currentValue",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@currentValue"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"currentValue",{}, smalltalk.ASTInterpreter)})},
+args: [],
+source: "currentValue\x0a\x09^ currentValue",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_eval_",
+smalltalk.method({
+selector: "eval:",
+category: 'interpreting',
+fn: function (aString){
+var self=this;
+var source,function_;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+source=_st((smalltalk.String || String))._streamContents_((function(str){
+return smalltalk.withContext(function($ctx2) {
_st(str)._nextPutAll_("(function(");
+_st(_st(_st(_st(self)._context())._locals())._keys())._do_separatedBy_((function(each){
+return smalltalk.withContext(function($ctx3) {
return _st(str)._nextPutAll_(each);
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx3) {
return _st(str)._nextPutAll_(",");
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+$1=str;
+_st($1)._nextPutAll_("){ return (function() {");
+_st($1)._nextPutAll_(aString);
+$2=_st($1)._nextPutAll_("})() })");
+return $2;
+}, function($ctx2) {$ctx2.fillBlock({str:str},$ctx1)})}));
+function_=_st(_st((smalltalk.Compiler || Compiler))._new())._eval_(source);
+$3=_st(function_)._valueWithPossibleArguments_(_st(_st(_st(self)._context())._locals())._values());
+return $3;
+}, function($ctx1) {$ctx1.fill(self,"eval:",{aString:aString,source:source,function_:function_}, smalltalk.ASTInterpreter)})},
+args: ["aString"],
+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",
+messageSends: ["streamContents:", "nextPutAll:", "do:separatedBy:", "keys", "locals", "context", "eval:", "new", "valueWithPossibleArguments:", "values"],
+referencedClasses: ["String", "Compiler"]
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+category: 'initialization',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
smalltalk.NodeVisitor.fn.prototype._initialize.apply(_st(self), []);
+self["@shouldReturn"]=false;
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.ASTInterpreter)})},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a    shouldReturn := false",
+messageSends: ["initialize"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_interpret_",
+smalltalk.method({
+selector: "interpret:",
+category: 'interpreting',
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@shouldReturn"]=false;
+_st(self)._interpret_continue_(aNode,(function(value){
+return smalltalk.withContext(function($ctx2) {
self["@currentValue"]=value;
+return self["@currentValue"];
+}, function($ctx2) {$ctx2.fillBlock({value:value},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"interpret:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
+args: ["aNode"],
+source: "interpret: aNode\x0a\x09shouldReturn := false.\x0a    self interpret: aNode continue: [ :value |\x0a    \x09currentValue := value ]",
+messageSends: ["interpret:continue:"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_interpret_continue_",
+smalltalk.method({
+selector: "interpret:continue:",
+category: 'interpreting',
+fn: function (aNode,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+$1=self["@shouldReturn"];
+if(smalltalk.assert($1)){
+$2=self;
+return $2;
+};
+$3=_st(aNode)._isNode();
+if(smalltalk.assert($3)){
+_st(self)._visit_(aNode);
+} else {
+self["@currentValue"]=aNode;
+self["@currentValue"];
+};
+_st(aBlock)._value_(_st(self)._currentValue());
+return self}, function($ctx1) {$ctx1.fill(self,"interpret:continue:",{aNode:aNode,aBlock:aBlock}, smalltalk.ASTInterpreter)})},
+args: ["aNode", "aBlock"],
+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",
+messageSends: ["ifTrue:", "ifTrue:ifFalse:", "visit:", "isNode", "value:", "currentValue"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_interpretAll_continue_",
+smalltalk.method({
+selector: "interpretAll:continue:",
+category: 'interpreting',
+fn: function (aCollection,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._interpretAll_continue_result_(aCollection,aBlock,_st((smalltalk.OrderedCollection || OrderedCollection))._new());
+return self}, function($ctx1) {$ctx1.fill(self,"interpretAll:continue:",{aCollection:aCollection,aBlock:aBlock}, smalltalk.ASTInterpreter)})},
+args: ["aCollection", "aBlock"],
+source: "interpretAll: aCollection continue: aBlock\x0a\x09self \x0a    \x09interpretAll: aCollection \x0a        continue: aBlock \x0a        result: OrderedCollection new",
+messageSends: ["interpretAll:continue:result:", "new"],
+referencedClasses: ["OrderedCollection"]
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_interpretAll_continue_result_",
+smalltalk.method({
+selector: "interpretAll:continue:result:",
+category: 'interpreting',
+fn: function (nodes,aBlock,aCollection){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(nodes)._isEmpty();
+if(smalltalk.assert($1)){
+_st(aBlock)._value_(aCollection);
+} else {
+_st(self)._interpret_continue_(_st(nodes)._first(),(function(value){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._interpretAll_continue_result_(_st(nodes)._allButFirst(),aBlock,_st(aCollection).__comma([value]));
+}, function($ctx2) {$ctx2.fillBlock({value:value},$ctx1)})}));
+};
+return self}, function($ctx1) {$ctx1.fill(self,"interpretAll:continue:result:",{nodes:nodes,aBlock:aBlock,aCollection:aCollection}, smalltalk.ASTInterpreter)})},
+args: ["nodes", "aBlock", "aCollection"],
+source: "interpretAll: nodes continue: aBlock result: aCollection\x0a\x09nodes isEmpty \x0a    \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 } ] ]",
+messageSends: ["ifTrue:ifFalse:", "value:", "interpret:continue:", "first", "interpretAll:continue:result:", "allButFirst", ",", "isEmpty"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_messageFromSendNode_do_",
+smalltalk.method({
+selector: "messageFromSendNode:do:",
+category: 'interpreting',
+fn: function (aSendNode,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+_st(self)._interpretAll_continue_(_st(aSendNode)._arguments(),(function(args){
+return smalltalk.withContext(function($ctx2) {
$1=_st((smalltalk.Message || Message))._new();
+_st($1)._selector_(_st(aSendNode)._selector());
+_st($1)._arguments_(args);
+$2=_st($1)._yourself();
+return _st(aBlock)._value_($2);
+}, function($ctx2) {$ctx2.fillBlock({args:args},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"messageFromSendNode:do:",{aSendNode:aSendNode,aBlock:aBlock}, smalltalk.ASTInterpreter)})},
+args: ["aSendNode", "aBlock"],
+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) ]",
+messageSends: ["interpretAll:continue:", "arguments", "value:", "selector:", "selector", "new", "arguments:", "yourself"],
+referencedClasses: ["Message"]
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitAssignmentNode_",
+smalltalk.method({
+selector: "visitAssignmentNode:",
+category: 'visiting',
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._interpret_continue_(_st(aNode)._right(),(function(value){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._continue_(_st(self)._assign_to_(_st(aNode)._left(),value));
+}, function($ctx2) {$ctx2.fillBlock({value:value},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"visitAssignmentNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
+args: ["aNode"],
+source: "visitAssignmentNode: aNode\x0a\x09self interpret: aNode right continue: [ :value |\x0a    \x09self continue: (self assign: aNode left to: value) ]",
+messageSends: ["interpret:continue:", "right", "continue:", "assign:to:", "left"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitBlockNode_",
+smalltalk.method({
+selector: "visitBlockNode:",
+category: 'visiting',
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+_st(self)._continue_((function(){
+return smalltalk.withContext(function($ctx2) {
$1=self;
+_st($1)._interpret_(_st(_st(aNode)._nodes())._first());
+$2=_st($1)._currentValue();
+return $2;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"visitBlockNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
+args: ["aNode"],
+source: "visitBlockNode: aNode\x0a\x09\x22TODO: Context should be set\x22\x0a    self continue: [ self interpret: aNode nodes first; currentValue ]",
+messageSends: ["continue:", "interpret:", "first", "nodes", "currentValue"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitCascadeNode_",
+smalltalk.method({
+selector: "visitCascadeNode:",
+category: 'visiting',
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._interpret_continue_(_st(aNode)._receiver(),(function(receiver){
+return smalltalk.withContext(function($ctx2) {
_st(_st(aNode)._nodes())._do_((function(each){
+return smalltalk.withContext(function($ctx3) {
return _st(each)._receiver_(receiver);
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}));
+return _st(self)._interpretAll_continue_(_st(_st(aNode)._nodes())._allButLast(),(function(){
+return smalltalk.withContext(function($ctx3) {
return _st(self)._interpret_continue_(_st(_st(aNode)._nodes())._last(),(function(val){
+return smalltalk.withContext(function($ctx4) {
return _st(self)._continue_(val);
+}, function($ctx4) {$ctx4.fillBlock({val:val},$ctx1)})}));
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({receiver:receiver},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"visitCascadeNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
+args: ["aNode"],
+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 ] ] ]",
+messageSends: ["interpret:continue:", "receiver", "do:", "receiver:", "nodes", "interpretAll:continue:", "allButLast", "last", "continue:"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitClassReferenceNode_",
+smalltalk.method({
+selector: "visitClassReferenceNode:",
+category: 'visiting',
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._continue_(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(_st(aNode)._value()));
+return self}, function($ctx1) {$ctx1.fill(self,"visitClassReferenceNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
+args: ["aNode"],
+source: "visitClassReferenceNode: aNode\x0a\x09self continue: (Smalltalk current at: aNode value)",
+messageSends: ["continue:", "at:", "value", "current"],
+referencedClasses: ["Smalltalk"]
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitDynamicArrayNode_",
+smalltalk.method({
+selector: "visitDynamicArrayNode:",
+category: 'visiting',
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._interpretAll_continue_(_st(aNode)._nodes(),(function(array){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._continue_(array);
+}, function($ctx2) {$ctx2.fillBlock({array:array},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"visitDynamicArrayNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
+args: ["aNode"],
+source: "visitDynamicArrayNode: aNode\x0a\x0a\x09self interpretAll: aNode nodes continue: [ :array |\x0a    \x09self continue: array ]",
+messageSends: ["interpretAll:continue:", "nodes", "continue:"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitDynamicDictionaryNode_",
+smalltalk.method({
+selector: "visitDynamicDictionaryNode:",
+category: 'visiting',
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._interpretAll_continue_(_st(aNode)._nodes(),(function(array){
+var hashedCollection;
+return smalltalk.withContext(function($ctx2) {
hashedCollection=_st((smalltalk.HashedCollection || HashedCollection))._new();
+hashedCollection;
+_st(array)._do_((function(each){
+return smalltalk.withContext(function($ctx3) {
return _st(hashedCollection)._add_(each);
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}));
+return _st(self)._continue_(hashedCollection);
+}, function($ctx2) {$ctx2.fillBlock({array:array,hashedCollection:hashedCollection},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"visitDynamicDictionaryNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
+args: ["aNode"],
+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 ]",
+messageSends: ["interpretAll:continue:", "nodes", "new", "do:", "add:", "continue:"],
+referencedClasses: ["HashedCollection"]
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitJSStatementNode_",
+smalltalk.method({
+selector: "visitJSStatementNode:",
+category: 'visiting',
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@shouldReturn"]=true;
+_st(self)._continue_(_st(self)._eval_(_st(aNode)._source()));
+return self}, function($ctx1) {$ctx1.fill(self,"visitJSStatementNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
+args: ["aNode"],
+source: "visitJSStatementNode: aNode\x0a\x09shouldReturn := true.\x0a\x09self continue: (self eval: aNode source)",
+messageSends: ["continue:", "eval:", "source"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitReturnNode_",
+smalltalk.method({
+selector: "visitReturnNode:",
+category: 'visiting',
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._interpret_continue_(_st(_st(aNode)._nodes())._first(),(function(value){
+return smalltalk.withContext(function($ctx2) {
self["@shouldReturn"]=true;
+self["@shouldReturn"];
+return _st(self)._continue_(value);
+}, function($ctx2) {$ctx2.fillBlock({value:value},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"visitReturnNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
+args: ["aNode"],
+source: "visitReturnNode: aNode\x0a    self interpret: aNode nodes first continue: [ :value |\x0a    \x09shouldReturn := true.\x0a\x09\x09self continue: value ]",
+messageSends: ["interpret:continue:", "first", "nodes", "continue:"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitSendNode_",
+smalltalk.method({
+selector: "visitSendNode:",
+category: 'visiting',
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._interpret_continue_(_st(aNode)._receiver(),(function(receiver){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._messageFromSendNode_do_(aNode,(function(message){
+return smalltalk.withContext(function($ctx3) {
_st(_st(self)._context())._pc_(_st(_st(_st(self)._context())._pc()).__plus((1)));
+return _st(self)._continue_(_st(message)._sendTo_(receiver));
+}, function($ctx3) {$ctx3.fillBlock({message:message},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({receiver:receiver},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"visitSendNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
+args: ["aNode"],
+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) ] ]",
+messageSends: ["interpret:continue:", "receiver", "messageFromSendNode:do:", "pc:", "+", "pc", "context", "continue:", "sendTo:"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitSequenceNode_",
+smalltalk.method({
+selector: "visitSequenceNode:",
+category: 'visiting',
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._interpretAll_continue_(_st(aNode)._nodes(),(function(array){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._continue_(_st(array)._last());
+}, function($ctx2) {$ctx2.fillBlock({array:array},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"visitSequenceNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
+args: ["aNode"],
+source: "visitSequenceNode: aNode\x0a\x09self interpretAll: aNode nodes continue: [ :array |\x0a    \x09self continue: array last ]",
+messageSends: ["interpretAll:continue:", "nodes", "continue:", "last"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+smalltalk.addMethod(
+"_visitValueNode_",
+smalltalk.method({
+selector: "visitValueNode:",
+category: 'visiting',
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._continue_(_st(aNode)._value());
+return self}, function($ctx1) {$ctx1.fill(self,"visitValueNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
+args: ["aNode"],
+source: "visitValueNode: aNode\x0a\x09self continue: aNode value",
+messageSends: ["continue:", "value"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
+
+
+smalltalk.addClass('ASTDebugger', smalltalk.ASTInterpreter, ['continuation'], 'Compiler-Interpreter');
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+category: 'initialization',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
smalltalk.ASTInterpreter.fn.prototype._initialize.apply(_st(self), []);
+self["@continuation"]=(function(){
+return smalltalk.withContext(function($ctx2) {
}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.ASTDebugger)})},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a    continuation := [  ]",
+messageSends: ["initialize"],
+referencedClasses: []
+}),
+smalltalk.ASTDebugger);
+
+smalltalk.addMethod(
+"_interpret_continue_",
+smalltalk.method({
+selector: "interpret:continue:",
+category: 'interpreting',
+fn: function (aNode,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@continuation"]=(function(){
+return smalltalk.withContext(function($ctx2) {
return smalltalk.ASTInterpreter.fn.prototype._interpret_continue_.apply(_st(self), [aNode,aBlock]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+return self}, function($ctx1) {$ctx1.fill(self,"interpret:continue:",{aNode:aNode,aBlock:aBlock}, smalltalk.ASTDebugger)})},
+args: ["aNode", "aBlock"],
+source: "interpret: aNode continue: aBlock\x0a\x09continuation := [ super interpret: aNode continue: aBlock ]",
+messageSends: ["interpret:continue:"],
+referencedClasses: []
+}),
+smalltalk.ASTDebugger);
+
+smalltalk.addMethod(
+"_stepOver",
+smalltalk.method({
+selector: "stepOver",
+category: 'stepping',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self["@continuation"])._value();
+return self}, function($ctx1) {$ctx1.fill(self,"stepOver",{}, smalltalk.ASTDebugger)})},
+args: [],
+source: "stepOver\x0a\x09continuation value",
+messageSends: ["value"],
+referencedClasses: []
+}),
+smalltalk.ASTDebugger);
+
+
+

Fichier diff supprimé car celui-ci est trop grand
+ 366 - 318
js/Compiler-Semantic.deploy.js


Fichier diff supprimé car celui-ci est trop grand
+ 362 - 311
js/Compiler-Semantic.js


Fichier diff supprimé car celui-ci est trop grand
+ 472 - 288
js/Compiler-Tests.deploy.js


Fichier diff supprimé car celui-ci est trop grand
+ 520 - 248
js/Compiler-Tests.js


Fichier diff supprimé car celui-ci est trop grand
+ 350 - 0
js/Compiler.deploy.js


Fichier diff supprimé car celui-ci est trop grand
+ 436 - 0
js/Compiler.js


+ 29 - 29
js/Examples.deploy.js

@@ -6,11 +6,11 @@ smalltalk.method({
 selector: "decrease",
 fn: function (){
 var self=this;
-self["@count"]=smalltalk.send(self["@count"],"__minus",[(1)]);
-smalltalk.send(self["@header"],"_contents_",[(function(html){
-return smalltalk.send(html,"_with_",[smalltalk.send(self["@count"],"_asString",[])]);
-})]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@count"]=_st(self["@count"]).__minus((1));
+_st(self["@header"])._contents_((function(html){
+return smalltalk.withContext(function($ctx2) {
return _st(html)._with_(_st(self["@count"])._asString());
+}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"decrease",{}, smalltalk.Counter)})}
 }),
 smalltalk.Counter);
 
@@ -20,11 +20,11 @@ smalltalk.method({
 selector: "increase",
 fn: function (){
 var self=this;
-self["@count"]=smalltalk.send(self["@count"],"__plus",[(1)]);
-smalltalk.send(self["@header"],"_contents_",[(function(html){
-return smalltalk.send(html,"_with_",[smalltalk.send(self["@count"],"_asString",[])]);
-})]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@count"]=_st(self["@count"]).__plus((1));
+_st(self["@header"])._contents_((function(html){
+return smalltalk.withContext(function($ctx2) {
return _st(html)._with_(_st(self["@count"])._asString());
+}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"increase",{}, smalltalk.Counter)})}
 }),
 smalltalk.Counter);
 
@@ -34,9 +34,9 @@ smalltalk.method({
 selector: "initialize",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_initialize",[],smalltalk.Widget);
+return smalltalk.withContext(function($ctx1) { 
smalltalk.Widget.fn.prototype._initialize.apply(_st(self), []);
 self["@count"]=(0);
-return self}
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.Counter)})}
 }),
 smalltalk.Counter);
 
@@ -46,22 +46,22 @@ smalltalk.method({
 selector: "renderOn:",
 fn: function (html){
 var self=this;
-var $1,$2,$3,$4,$5,$6;
-$1=smalltalk.send(html,"_h1",[]);
-smalltalk.send($1,"_with_",[smalltalk.send(self["@count"],"_asString",[])]);
-$2=smalltalk.send($1,"_yourself",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6;
+$1=_st(html)._h1();
+_st($1)._with_(_st(self["@count"])._asString());
+$2=_st($1)._yourself();
 self["@header"]=$2;
-$3=smalltalk.send(html,"_button",[]);
-smalltalk.send($3,"_with_",["++"]);
-$4=smalltalk.send($3,"_onClick_",[(function(){
-return smalltalk.send(self,"_increase",[]);
-})]);
-$5=smalltalk.send(html,"_button",[]);
-smalltalk.send($5,"_with_",["--"]);
-$6=smalltalk.send($5,"_onClick_",[(function(){
-return smalltalk.send(self,"_decrease",[]);
-})]);
-return self}
+$3=_st(html)._button();
+_st($3)._with_("++");
+$4=_st($3)._onClick_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._increase();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$5=_st(html)._button();
+_st($5)._with_("--");
+$6=_st($5)._onClick_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._decrease();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"renderOn:",{html:html}, smalltalk.Counter)})}
 }),
 smalltalk.Counter);
 
@@ -72,8 +72,8 @@ smalltalk.method({
 selector: "tryExample",
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send(self,"_new",[]),"_appendToJQuery_",[smalltalk.send("body","_asJQuery",[])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._new())._appendToJQuery_(_st("body")._asJQuery());
+return self}, function($ctx1) {$ctx1.fill(self,"tryExample",{}, smalltalk.Counter.klass)})}
 }),
 smalltalk.Counter.klass);
 

+ 29 - 29
js/Examples.js

@@ -8,11 +8,11 @@ selector: "decrease",
 category: 'actions',
 fn: function (){
 var self=this;
-self["@count"]=smalltalk.send(self["@count"],"__minus",[(1)]);
-smalltalk.send(self["@header"],"_contents_",[(function(html){
-return smalltalk.send(html,"_with_",[smalltalk.send(self["@count"],"_asString",[])]);
-})]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@count"]=_st(self["@count"]).__minus((1));
+_st(self["@header"])._contents_((function(html){
+return smalltalk.withContext(function($ctx2) {
return _st(html)._with_(_st(self["@count"])._asString());
+}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"decrease",{}, smalltalk.Counter)})},
 args: [],
 source: "decrease\x0a    count := count - 1.\x0a    header contents: [:html | html with: count asString]",
 messageSends: ["-", "contents:", "with:", "asString"],
@@ -27,11 +27,11 @@ selector: "increase",
 category: 'actions',
 fn: function (){
 var self=this;
-self["@count"]=smalltalk.send(self["@count"],"__plus",[(1)]);
-smalltalk.send(self["@header"],"_contents_",[(function(html){
-return smalltalk.send(html,"_with_",[smalltalk.send(self["@count"],"_asString",[])]);
-})]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@count"]=_st(self["@count"]).__plus((1));
+_st(self["@header"])._contents_((function(html){
+return smalltalk.withContext(function($ctx2) {
return _st(html)._with_(_st(self["@count"])._asString());
+}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"increase",{}, smalltalk.Counter)})},
 args: [],
 source: "increase\x0a    count := count + 1.\x0a    header contents: [:html | html with: count asString]",
 messageSends: ["+", "contents:", "with:", "asString"],
@@ -46,9 +46,9 @@ selector: "initialize",
 category: 'initialization',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_initialize",[],smalltalk.Widget);
+return smalltalk.withContext(function($ctx1) { 
smalltalk.Widget.fn.prototype._initialize.apply(_st(self), []);
 self["@count"]=(0);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.Counter)})},
 args: [],
 source: "initialize\x0a    super initialize.\x0a    count := 0",
 messageSends: ["initialize"],
@@ -63,22 +63,22 @@ selector: "renderOn:",
 category: 'rendering',
 fn: function (html){
 var self=this;
-var $1,$2,$3,$4,$5,$6;
-$1=smalltalk.send(html,"_h1",[]);
-smalltalk.send($1,"_with_",[smalltalk.send(self["@count"],"_asString",[])]);
-$2=smalltalk.send($1,"_yourself",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6;
+$1=_st(html)._h1();
+_st($1)._with_(_st(self["@count"])._asString());
+$2=_st($1)._yourself();
 self["@header"]=$2;
-$3=smalltalk.send(html,"_button",[]);
-smalltalk.send($3,"_with_",["++"]);
-$4=smalltalk.send($3,"_onClick_",[(function(){
-return smalltalk.send(self,"_increase",[]);
-})]);
-$5=smalltalk.send(html,"_button",[]);
-smalltalk.send($5,"_with_",["--"]);
-$6=smalltalk.send($5,"_onClick_",[(function(){
-return smalltalk.send(self,"_decrease",[]);
-})]);
-return self},
+$3=_st(html)._button();
+_st($3)._with_("++");
+$4=_st($3)._onClick_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._increase();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$5=_st(html)._button();
+_st($5)._with_("--");
+$6=_st($5)._onClick_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._decrease();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"renderOn:",{html:html}, smalltalk.Counter)})},
 args: ["html"],
 source: "renderOn: html\x0a    header := html h1 \x0a\x09with: count asString;\x0a\x09yourself.\x0a    html button\x0a\x09with: '++';\x0a\x09onClick: [self increase].\x0a    html button\x0a\x09with: '--';\x0a\x09onClick: [self decrease]",
 messageSends: ["with:", "asString", "h1", "yourself", "button", "onClick:", "increase", "decrease"],
@@ -94,8 +94,8 @@ selector: "tryExample",
 category: 'example',
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send(self,"_new",[]),"_appendToJQuery_",[smalltalk.send("body","_asJQuery",[])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._new())._appendToJQuery_(_st("body")._asJQuery());
+return self}, function($ctx1) {$ctx1.fill(self,"tryExample",{}, smalltalk.Counter.klass)})},
 args: [],
 source: "tryExample\x0a\x09\x22In order to play with the Counter, just select the\x0a\x09doit below and press the Do it button. Then take a\x0a\x09look in the HTML document above the IDE.\x22\x0a\x0a\x09\x22Counter tryExample\x22\x0a        self new appendToJQuery: 'body' asJQuery",
 messageSends: ["appendToJQuery:", "asJQuery", "new"],

Fichier diff supprimé car celui-ci est trop grand
+ 381 - 340
js/IDE.deploy.js


Fichier diff supprimé car celui-ci est trop grand
+ 382 - 341
js/IDE.js


+ 393 - 349
js/Importer-Exporter.deploy.js

@@ -6,34 +6,35 @@ smalltalk.method({
 selector: "nextChunk",
 fn: function (){
 var self=this;
-var $1,$2,$3;
+var char,result,chunk;
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$5,$6,$4,$2;
 var $early={};
 try {
-var char_;
-var result;
-var chunk;
-result=smalltalk.send("","_writeStream",[]);
-smalltalk.send((function(){
-char_=smalltalk.send(self["@stream"],"_next",[]);
-char_;
-return smalltalk.send(char_,"_notNil",[]);
-}),"_whileTrue_",[(function(){
-$1=smalltalk.send(char_,"__eq",["!"]);
-if(smalltalk.assert($1)){
-$2=smalltalk.send(smalltalk.send(self["@stream"],"_peek",[]),"__eq",["!"]);
-if(smalltalk.assert($2)){
-smalltalk.send(self["@stream"],"_next",[]);
+result=_st("")._writeStream();
+$1=(function(){
+return smalltalk.withContext(function($ctx2) {
char=_st(self["@stream"])._next();
+char;
+return _st(char)._notNil();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+$2=(function(){
+return smalltalk.withContext(function($ctx2) {
$3=_st(char).__eq("!");
+$4=(function(){
+return smalltalk.withContext(function($ctx3) {
$5=_st(_st(self["@stream"])._peek()).__eq("!");
+if(smalltalk.assert($5)){
+return _st(self["@stream"])._next();
 } else {
-$3=smalltalk.send(smalltalk.send(result,"_contents",[]),"_trimBoth",[]);
-throw $early=[$3];
+$6=_st(_st(result)._contents())._trimBoth();
+throw $early=[$6];
 };
-};
-return smalltalk.send(result,"_nextPut_",[char_]);
-})]);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
+_st($3)._ifTrue_($4);
+return _st(result)._nextPut_(char);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+_st($1)._whileTrue_($2);
 return nil;
 }
 catch(e) {if(e===$early)return e[0]; throw e}
-}
+}, function($ctx1) {$ctx1.fill(self,"nextChunk",{char:char,result:result,chunk:chunk}, smalltalk.ChunkParser)})}
 }),
 smalltalk.ChunkParser);
 
@@ -43,8 +44,8 @@ smalltalk.method({
 selector: "stream:",
 fn: function (aStream){
 var self=this;
-self["@stream"]=aStream;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@stream"]=aStream;
+return self}, function($ctx1) {$ctx1.fill(self,"stream:",{aStream:aStream}, smalltalk.ChunkParser)})}
 }),
 smalltalk.ChunkParser);
 
@@ -55,10 +56,10 @@ smalltalk.method({
 selector: "on:",
 fn: function (aStream){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(self,"_new",[]),"_stream_",[aStream]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._new())._stream_(aStream);
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"on:",{aStream:aStream}, smalltalk.ChunkParser.klass)})}
 }),
 smalltalk.ChunkParser.klass);
 
@@ -70,20 +71,22 @@ smalltalk.method({
 selector: "classNameFor:",
 fn: function (aClass){
 var self=this;
-var $2,$3,$1;
-$2=smalltalk.send(aClass,"_isMetaclass",[]);
-if(smalltalk.assert($2)){
-$1=smalltalk.send(smalltalk.send(smalltalk.send(aClass,"_instanceClass",[]),"_name",[]),"__comma",[".klass"]);
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$4,$1;
+$2=_st(aClass)._isMetaclass();
+$3=(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(_st(aClass)._instanceClass())._name()).__comma(".klass");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+$4=(function(){
+return smalltalk.withContext(function($ctx2) {
$5=_st(aClass)._isNil();
+if(smalltalk.assert($5)){
+return "nil";
 } else {
-$3=smalltalk.send(aClass,"_isNil",[]);
-if(smalltalk.assert($3)){
-$1="nil";
-} else {
-$1=smalltalk.send(aClass,"_name",[]);
-};
+return _st(aClass)._name();
 };
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+$1=_st($2)._ifTrue_ifFalse_($3,$4);
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass}, smalltalk.Exporter)})}
 }),
 smalltalk.Exporter);
 
@@ -93,14 +96,14 @@ smalltalk.method({
 selector: "exportAll",
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send((smalltalk.String || String),"_streamContents_",[(function(stream){
-return smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk),"_current",[]),"_packages",[]),"_do_",[(function(pkg){
-return smalltalk.send(stream,"_nextPutAll_",[smalltalk.send(self,"_exportPackage_",[smalltalk.send(pkg,"_name",[])])]);
-})]);
-})]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st((smalltalk.String || String))._streamContents_((function(stream){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._packages())._do_((function(pkg){
+return smalltalk.withContext(function($ctx3) {
return _st(stream)._nextPutAll_(_st(self)._exportPackage_(_st(pkg)._name()));
+}, function($ctx3) {$ctx3.fillBlock({pkg:pkg},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"exportAll",{}, smalltalk.Exporter)})}
 }),
 smalltalk.Exporter);
 
@@ -110,15 +113,15 @@ smalltalk.method({
 selector: "exportClass:",
 fn: function (aClass){
 var self=this;
-var $1;
-$1=smalltalk.send((smalltalk.String || String),"_streamContents_",[(function(stream){
-smalltalk.send(self,"_exportDefinitionOf_on_",[aClass,stream]);
-smalltalk.send(self,"_exportMethodsOf_on_",[aClass,stream]);
-smalltalk.send(self,"_exportMetaDefinitionOf_on_",[aClass,stream]);
-return smalltalk.send(self,"_exportMethodsOf_on_",[smalltalk.send(aClass,"_class",[]),stream]);
-})]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st((smalltalk.String || String))._streamContents_((function(stream){
+return smalltalk.withContext(function($ctx2) {
_st(self)._exportDefinitionOf_on_(aClass,stream);
+_st(self)._exportMethodsOf_on_(aClass,stream);
+_st(self)._exportMetaDefinitionOf_on_(aClass,stream);
+return _st(self)._exportMethodsOf_on_(_st(aClass)._class(),stream);
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"exportClass:",{aClass:aClass}, smalltalk.Exporter)})}
 }),
 smalltalk.Exporter);
 
@@ -128,30 +131,33 @@ smalltalk.method({
 selector: "exportDefinitionOf:on:",
 fn: function (aClass,aStream){
 var self=this;
-var $1,$2,$3,$4;
-smalltalk.send(aStream,"_nextPutAll_",["smalltalk.addClass("]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("'","__comma",[smalltalk.send(self,"_classNameFor_",[aClass])]),"__comma",["', "])]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("smalltalk.","__comma",[smalltalk.send(self,"_classNameFor_",[smalltalk.send(aClass,"_superclass",[])])])]);
-$1=smalltalk.send(aStream,"_nextPutAll_",[", ["]);
-smalltalk.send(smalltalk.send(aClass,"_instanceVariableNames",[]),"_do_separatedBy_",[(function(each){
-return smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("'","__comma",[each]),"__comma",["'"])]);
-}),(function(){
-return smalltalk.send(aStream,"_nextPutAll_",[", "]);
-})]);
-smalltalk.send(aStream,"_nextPutAll_",["], '"]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(aClass,"_category",[]),"__comma",["'"])]);
-$2=smalltalk.send(aStream,"_nextPutAll_",[");"]);
-$3=smalltalk.send(smalltalk.send(aClass,"_comment",[]),"_notEmpty",[]);
-if(smalltalk.assert($3)){
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",["smalltalk."]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(self,"_classNameFor_",[aClass])]);
-smalltalk.send(aStream,"_nextPutAll_",[".comment="]);
-$4=smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(aClass,"_comment",[]),"_asJavascript",[])]);
-$4;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6,$7;
+$1=aStream;
+_st($1)._nextPutAll_("smalltalk.addClass(");
+_st($1)._nextPutAll_(_st(_st("'").__comma(_st(self)._classNameFor_(aClass))).__comma("', "));
+_st($1)._nextPutAll_(_st("smalltalk.").__comma(_st(self)._classNameFor_(_st(aClass)._superclass())));
+$2=_st($1)._nextPutAll_(", [");
+_st(_st(aClass)._instanceVariableNames())._do_separatedBy_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(", ");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$3=aStream;
+_st($3)._nextPutAll_("], '");
+_st($3)._nextPutAll_(_st(_st(aClass)._category()).__comma("'"));
+$4=_st($3)._nextPutAll_(");");
+$5=_st(_st(aClass)._comment())._notEmpty();
+if(smalltalk.assert($5)){
+$6=aStream;
+_st($6)._lf();
+_st($6)._nextPutAll_("smalltalk.");
+_st($6)._nextPutAll_(_st(self)._classNameFor_(aClass));
+_st($6)._nextPutAll_(".comment=");
+$7=_st($6)._nextPutAll_(_st(_st(aClass)._comment())._asJavascript());
+$7;
 };
-smalltalk.send(aStream,"_lf",[]);
-return self}
+_st(aStream)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportDefinitionOf:on:",{aClass:aClass,aStream:aStream}, smalltalk.Exporter)})}
 }),
 smalltalk.Exporter);
 
@@ -161,20 +167,21 @@ smalltalk.method({
 selector: "exportMetaDefinitionOf:on:",
 fn: function (aClass,aStream){
 var self=this;
-var $1,$2;
-$1=smalltalk.send(smalltalk.send(smalltalk.send(aClass,"_class",[]),"_instanceVariableNames",[]),"_isEmpty",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+$1=_st(_st(_st(aClass)._class())._instanceVariableNames())._isEmpty();
 if(! smalltalk.assert($1)){
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("smalltalk.","__comma",[smalltalk.send(self,"_classNameFor_",[smalltalk.send(aClass,"_class",[])])])]);
-$2=smalltalk.send(aStream,"_nextPutAll_",[".iVarNames = ["]);
-$2;
-smalltalk.send(smalltalk.send(smalltalk.send(aClass,"_class",[]),"_instanceVariableNames",[]),"_do_separatedBy_",[(function(each){
-return smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("'","__comma",[each]),"__comma",["'"])]);
-}),(function(){
-return smalltalk.send(aStream,"_nextPutAll_",[","]);
-})]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("];","__comma",[smalltalk.send((smalltalk.String || String),"_lf",[])])]);
+$2=aStream;
+_st($2)._nextPutAll_(_st("smalltalk.").__comma(_st(self)._classNameFor_(_st(aClass)._class())));
+$3=_st($2)._nextPutAll_(".iVarNames = [");
+$3;
+_st(_st(_st(aClass)._class())._instanceVariableNames())._do_separatedBy_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(",");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st(aStream)._nextPutAll_(_st("];").__comma(_st((smalltalk.String || String))._lf()));
 };
-return self}
+return self}, function($ctx1) {$ctx1.fill(self,"exportMetaDefinitionOf:on:",{aClass:aClass,aStream:aStream}, smalltalk.Exporter)})}
 }),
 smalltalk.Exporter);
 
@@ -184,34 +191,36 @@ smalltalk.method({
 selector: "exportMethod:of:on:",
 fn: function (aMethod,aClass,aStream){
 var self=this;
-var $1,$2;
-smalltalk.send(aStream,"_nextPutAll_",["smalltalk.addMethod("]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aMethod,"_selector",[]),"_asSelector",[]),"_asJavascript",[]),"__comma",[","])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",["smalltalk.method({"]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("selector: ","__comma",[smalltalk.send(smalltalk.send(aMethod,"_selector",[]),"_asJavascript",[])]),"__comma",[","])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("category: '","__comma",[smalltalk.send(aMethod,"_category",[])]),"__comma",["',"])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("fn: ","__comma",[smalltalk.send(smalltalk.send(aMethod,"_fn",[]),"_compiledSource",[])]),"__comma",[","])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("args: ","__comma",[smalltalk.send(smalltalk.send(aMethod,"_arguments",[]),"_asJavascript",[])]),"__comma",[","])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("source: ","__comma",[smalltalk.send(smalltalk.send(aMethod,"_source",[]),"_asJavascript",[])]),"__comma",[","])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("messageSends: ","__comma",[smalltalk.send(smalltalk.send(aMethod,"_messageSends",[]),"_asJavascript",[])]),"__comma",[","])]);
-smalltalk.send(aStream,"_lf",[]);
-$1=smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("referencedClasses: ","__comma",[smalltalk.send(smalltalk.send(aMethod,"_referencedClasses",[]),"_asJavascript",[])])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",["}),"]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("smalltalk.","__comma",[smalltalk.send(self,"_classNameFor_",[aClass])])]);
-smalltalk.send(aStream,"_nextPutAll_",[");"]);
-smalltalk.send(aStream,"_lf",[]);
-$2=smalltalk.send(aStream,"_lf",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+$1=aStream;
+_st($1)._nextPutAll_("smalltalk.addMethod(");
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st(_st(_st(aMethod)._selector())._asSelector())._asJavascript()).__comma(","));
+_st($1)._lf();
+_st($1)._nextPutAll_("smalltalk.method({");
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st("selector: ").__comma(_st(_st(aMethod)._selector())._asJavascript())).__comma(","));
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st("category: '").__comma(_st(aMethod)._category())).__comma("',"));
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st("fn: ").__comma(_st(_st(aMethod)._fn())._compiledSource())).__comma(","));
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st("args: ").__comma(_st(_st(aMethod)._arguments())._asJavascript())).__comma(","));
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st("source: ").__comma(_st(_st(aMethod)._source())._asJavascript())).__comma(","));
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st("messageSends: ").__comma(_st(_st(aMethod)._messageSends())._asJavascript())).__comma(","));
+_st($1)._lf();
+$2=_st($1)._nextPutAll_(_st("referencedClasses: ").__comma(_st(_st(aMethod)._referencedClasses())._asJavascript()));
+$3=aStream;
+_st($3)._lf();
+_st($3)._nextPutAll_("}),");
+_st($3)._lf();
+_st($3)._nextPutAll_(_st("smalltalk.").__comma(_st(self)._classNameFor_(aClass)));
+_st($3)._nextPutAll_(");");
+_st($3)._lf();
+$4=_st($3)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportMethod:of:on:",{aMethod:aMethod,aClass:aClass,aStream:aStream}, smalltalk.Exporter)})}
 }),
 smalltalk.Exporter);
 
@@ -221,17 +230,19 @@ smalltalk.method({
 selector: "exportMethodsOf:on:",
 fn: function (aClass,aStream){
 var self=this;
-var $1;
-smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aClass,"_methodDictionary",[]),"_values",[]),"_sorted_",[(function(a,b){
-return smalltalk.send(smalltalk.send(a,"_selector",[]),"__lt_eq",[smalltalk.send(b,"_selector",[])]);
-})]),"_do_",[(function(each){
-$1=smalltalk.send(smalltalk.send(each,"_category",[]),"_match_",["^\x5c*"]);
-if(! smalltalk.assert($1)){
-return smalltalk.send(self,"_exportMethod_of_on_",[each,aClass,aStream]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
+$1=_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
+}, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})}));
+$2=(function(each){
+return smalltalk.withContext(function($ctx2) {
$3=_st(_st(each)._category())._match_("^\x5c*");
+if(! smalltalk.assert($3)){
+return _st(self)._exportMethod_of_on_(each,aClass,aStream);
 };
-})]);
-smalltalk.send(aStream,"_lf",[]);
-return self}
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
+_st($1)._do_($2);
+_st(aStream)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportMethodsOf:on:",{aClass:aClass,aStream:aStream}, smalltalk.Exporter)})}
 }),
 smalltalk.Exporter);
 
@@ -241,19 +252,19 @@ smalltalk.method({
 selector: "exportPackage:",
 fn: function (packageName){
 var self=this;
-var $1;
-var package;
-$1=smalltalk.send((smalltalk.String || String),"_streamContents_",[(function(stream){
-package=smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk),"_current",[]),"_packageAt_",[packageName]);
-package;
-smalltalk.send(self,"_exportPackageDefinitionOf_on_",[package,stream]);
-smalltalk.send(smalltalk.send(smalltalk.send(package,"_sortedClasses",[]),"_asSet",[]),"_do_",[(function(each){
-return smalltalk.send(stream,"_nextPutAll_",[smalltalk.send(self,"_exportClass_",[each])]);
-})]);
-return smalltalk.send(self,"_exportPackageExtensionsOf_on_",[package,stream]);
-})]);
+var package_;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st((smalltalk.String || String))._streamContents_((function(stream){
+return smalltalk.withContext(function($ctx2) {
package_=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._packageAt_(packageName);
+package_;
+_st(self)._exportPackageDefinitionOf_on_(package_,stream);
+_st(_st(_st(package_)._sortedClasses())._asSet())._do_((function(each){
+return smalltalk.withContext(function($ctx3) {
return _st(stream)._nextPutAll_(_st(self)._exportClass_(each));
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}));
+return _st(self)._exportPackageExtensionsOf_on_(package_,stream);
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"exportPackage:",{packageName:packageName,package_:package_}, smalltalk.Exporter)})}
 }),
 smalltalk.Exporter);
 
@@ -261,13 +272,14 @@ smalltalk.addMethod(
 "_exportPackageDefinitionOf_on_",
 smalltalk.method({
 selector: "exportPackageDefinitionOf:on:",
-fn: function (package,aStream){
+fn: function (package_,aStream){
 var self=this;
-var $1;
-smalltalk.send(aStream,"_nextPutAll_",["smalltalk.addPackage("]);
-$1=smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send("'","__comma",[smalltalk.send(package,"_name",[])]),"__comma",["', "]),"__comma",[smalltalk.send(package,"_propertiesAsJSON",[])]),"__comma",[");"])]);
-smalltalk.send(aStream,"_lf",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=aStream;
+_st($1)._nextPutAll_("smalltalk.addPackage(");
+$2=_st($1)._nextPutAll_(_st(_st(_st(_st("'").__comma(_st(package_)._name())).__comma("', ")).__comma(_st(package_)._propertiesAsJSON())).__comma(");"));
+_st(aStream)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackageDefinitionOf:on:",{package_:package_,aStream:aStream}, smalltalk.Exporter)})}
 }),
 smalltalk.Exporter);
 
@@ -275,24 +287,30 @@ smalltalk.addMethod(
 "_exportPackageExtensionsOf_on_",
 smalltalk.method({
 selector: "exportPackageExtensionsOf:on:",
-fn: function (package,aStream){
+fn: function (package_,aStream){
 var self=this;
-var $1;
 var name;
-name=smalltalk.send(package,"_name",[]);
-smalltalk.send(smalltalk.send((smalltalk.Package || Package),"_sortedClasses_",[smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk),"_current",[]),"_classes",[])]),"_do_",[(function(each){
-return smalltalk.send([each,smalltalk.send(each,"_class",[])],"_do_",[(function(aClass){
-return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aClass,"_methodDictionary",[]),"_values",[]),"_sorted_",[(function(a,b){
-return smalltalk.send(smalltalk.send(a,"_selector",[]),"__lt_eq",[smalltalk.send(b,"_selector",[])]);
-})]),"_do_",[(function(method){
-$1=smalltalk.send(smalltalk.send(method,"_category",[]),"_match_",[smalltalk.send("^\x5c*","__comma",[name])]);
-if(smalltalk.assert($1)){
-return smalltalk.send(self,"_exportMethod_of_on_",[method,aClass,aStream]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$5,$7,$6,$4,$2;
+name=_st(package_)._name();
+$1=_st((smalltalk.Package || Package))._sortedClasses_(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._classes());
+$2=(function(each){
+return smalltalk.withContext(function($ctx2) {
$3=[each,_st(each)._class()];
+$4=(function(aClass){
+return smalltalk.withContext(function($ctx3) {
$5=_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
+return smalltalk.withContext(function($ctx4) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
+}, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx1)})}));
+$6=(function(method){
+return smalltalk.withContext(function($ctx4) {
$7=_st(_st(method)._category())._match_(_st("^\x5c*").__comma(name));
+if(smalltalk.assert($7)){
+return _st(self)._exportMethod_of_on_(method,aClass,aStream);
 };
-})]);
-})]);
-})]);
-return self}
+}, function($ctx4) {$ctx4.fillBlock({method:method},$ctx1)})});
+return _st($5)._do_($6);
+}, function($ctx3) {$ctx3.fillBlock({aClass:aClass},$ctx1)})});
+return _st($3)._do_($4);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
+_st($1)._do_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackageExtensionsOf:on:",{package_:package_,aStream:aStream,name:name}, smalltalk.Exporter)})}
 }),
 smalltalk.Exporter);
 
@@ -305,10 +323,10 @@ smalltalk.method({
 selector: "chunkEscape:",
 fn: function (aString){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(aString,"_replace_with_",["!","!!"]),"_trimBoth",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(aString)._replace_with_("!","!!"))._trimBoth();
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"chunkEscape:",{aString:aString}, smalltalk.ChunkExporter)})}
 }),
 smalltalk.ChunkExporter);
 
@@ -318,20 +336,22 @@ smalltalk.method({
 selector: "classNameFor:",
 fn: function (aClass){
 var self=this;
-var $2,$3,$1;
-$2=smalltalk.send(aClass,"_isMetaclass",[]);
-if(smalltalk.assert($2)){
-$1=smalltalk.send(smalltalk.send(smalltalk.send(aClass,"_instanceClass",[]),"_name",[]),"__comma",[" class"]);
-} else {
-$3=smalltalk.send(aClass,"_isNil",[]);
-if(smalltalk.assert($3)){
-$1="nil";
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$4,$1;
+$2=_st(aClass)._isMetaclass();
+$3=(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(_st(aClass)._instanceClass())._name()).__comma(" class");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+$4=(function(){
+return smalltalk.withContext(function($ctx2) {
$5=_st(aClass)._isNil();
+if(smalltalk.assert($5)){
+return "nil";
 } else {
-$1=smalltalk.send(aClass,"_name",[]);
-};
+return _st(aClass)._name();
 };
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+$1=_st($2)._ifTrue_ifFalse_($3,$4);
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass}, smalltalk.ChunkExporter)})}
 }),
 smalltalk.ChunkExporter);
 
@@ -341,30 +361,33 @@ smalltalk.method({
 selector: "exportDefinitionOf:on:",
 fn: function (aClass,aStream){
 var self=this;
-var $1,$2,$3,$4;
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(self,"_classNameFor_",[smalltalk.send(aClass,"_superclass",[])])]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(" subclass: #","__comma",[smalltalk.send(self,"_classNameFor_",[aClass])])]);
-smalltalk.send(aStream,"_lf",[]);
-$1=smalltalk.send(aStream,"_nextPutAll_",["\x09instanceVariableNames: '"]);
-smalltalk.send(smalltalk.send(aClass,"_instanceVariableNames",[]),"_do_separatedBy_",[(function(each){
-return smalltalk.send(aStream,"_nextPutAll_",[each]);
-}),(function(){
-return smalltalk.send(aStream,"_nextPutAll_",[" "]);
-})]);
-smalltalk.send(aStream,"_nextPutAll_",["'"]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("\x09package: '","__comma",[smalltalk.send(aClass,"_category",[])]),"__comma",["'!"])]);
-$2=smalltalk.send(aStream,"_lf",[]);
-$3=smalltalk.send(smalltalk.send(aClass,"_comment",[]),"_notEmpty",[]);
-if(smalltalk.assert($3)){
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("!","__comma",[smalltalk.send(self,"_classNameFor_",[aClass])]),"__comma",[" commentStamp!"])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(self,"_chunkEscape_",[smalltalk.send(aClass,"_comment",[])]),"__comma",["!"])]);
-$4=smalltalk.send(aStream,"_lf",[]);
-$4;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6,$7;
+$1=aStream;
+_st($1)._nextPutAll_(_st(self)._classNameFor_(_st(aClass)._superclass()));
+_st($1)._nextPutAll_(_st(" subclass: #").__comma(_st(self)._classNameFor_(aClass)));
+_st($1)._lf();
+$2=_st($1)._nextPutAll_("\x09instanceVariableNames: '");
+_st(_st(aClass)._instanceVariableNames())._do_separatedBy_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(each);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(" ");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$3=aStream;
+_st($3)._nextPutAll_("'");
+_st($3)._lf();
+_st($3)._nextPutAll_(_st(_st("\x09package: '").__comma(_st(aClass)._category())).__comma("'!"));
+$4=_st($3)._lf();
+$5=_st(_st(aClass)._comment())._notEmpty();
+if(smalltalk.assert($5)){
+$6=aStream;
+_st($6)._nextPutAll_(_st(_st("!").__comma(_st(self)._classNameFor_(aClass))).__comma(" commentStamp!"));
+_st($6)._lf();
+_st($6)._nextPutAll_(_st(_st(self)._chunkEscape_(_st(aClass)._comment())).__comma("!"));
+$7=_st($6)._lf();
+$7;
 };
-smalltalk.send(aStream,"_lf",[]);
-return self}
+_st(aStream)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportDefinitionOf:on:",{aClass:aClass,aStream:aStream}, smalltalk.ChunkExporter)})}
 }),
 smalltalk.ChunkExporter);
 
@@ -374,23 +397,25 @@ smalltalk.method({
 selector: "exportMetaDefinitionOf:on:",
 fn: function (aClass,aStream){
 var self=this;
-var $1,$2,$3;
-$1=smalltalk.send(smalltalk.send(smalltalk.send(aClass,"_class",[]),"_instanceVariableNames",[]),"_isEmpty",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5;
+$1=_st(_st(_st(aClass)._class())._instanceVariableNames())._isEmpty();
 if(! smalltalk.assert($1)){
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(self,"_classNameFor_",[smalltalk.send(aClass,"_class",[])])]);
-$2=smalltalk.send(aStream,"_nextPutAll_",[" instanceVariableNames: '"]);
-$2;
-smalltalk.send(smalltalk.send(smalltalk.send(aClass,"_class",[]),"_instanceVariableNames",[]),"_do_separatedBy_",[(function(each){
-return smalltalk.send(aStream,"_nextPutAll_",[each]);
-}),(function(){
-return smalltalk.send(aStream,"_nextPutAll_",[" "]);
-})]);
-smalltalk.send(aStream,"_nextPutAll_",["'!"]);
-smalltalk.send(aStream,"_lf",[]);
-$3=smalltalk.send(aStream,"_lf",[]);
+$2=aStream;
+_st($2)._nextPutAll_(_st(self)._classNameFor_(_st(aClass)._class()));
+$3=_st($2)._nextPutAll_(" instanceVariableNames: '");
 $3;
+_st(_st(_st(aClass)._class())._instanceVariableNames())._do_separatedBy_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(each);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(" ");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$4=aStream;
+_st($4)._nextPutAll_("'!");
+_st($4)._lf();
+$5=_st($4)._lf();
+$5;
 };
-return self}
+return self}, function($ctx1) {$ctx1.fill(self,"exportMetaDefinitionOf:on:",{aClass:aClass,aStream:aStream}, smalltalk.ChunkExporter)})}
 }),
 smalltalk.ChunkExporter);
 
@@ -400,13 +425,14 @@ smalltalk.method({
 selector: "exportMethod:of:on:",
 fn: function (aMethod,aClass,aStream){
 var self=this;
-var $1;
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(self,"_chunkEscape_",[smalltalk.send(aMethod,"_source",[])])]);
-smalltalk.send(aStream,"_lf",[]);
-$1=smalltalk.send(aStream,"_nextPutAll_",["!"]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=aStream;
+_st($1)._lf();
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(self)._chunkEscape_(_st(aMethod)._source()));
+_st($1)._lf();
+$2=_st($1)._nextPutAll_("!");
+return self}, function($ctx1) {$ctx1.fill(self,"exportMethod:of:on:",{aMethod:aMethod,aClass:aClass,aStream:aStream}, smalltalk.ChunkExporter)})}
 }),
 smalltalk.ChunkExporter);
 
@@ -416,18 +442,20 @@ smalltalk.method({
 selector: "exportMethods:category:of:on:",
 fn: function (methods,category,aClass,aStream){
 var self=this;
-var $1,$2;
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("!","__comma",[smalltalk.send(self,"_classNameFor_",[aClass])])]);
-$1=smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(" methodsFor: '","__comma",[category]),"__comma",["'!"])]);
-smalltalk.send(smalltalk.send(methods,"_sorted_",[(function(a,b){
-return smalltalk.send(smalltalk.send(a,"_selector",[]),"__lt_eq",[smalltalk.send(b,"_selector",[])]);
-})]),"_do_",[(function(each){
-return smalltalk.send(self,"_exportMethod_of_on_",[each,aClass,aStream]);
-})]);
-smalltalk.send(aStream,"_nextPutAll_",[" !"]);
-smalltalk.send(aStream,"_lf",[]);
-$2=smalltalk.send(aStream,"_lf",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+$1=aStream;
+_st($1)._nextPutAll_(_st("!").__comma(_st(self)._classNameFor_(aClass)));
+$2=_st($1)._nextPutAll_(_st(_st(" methodsFor: '").__comma(category)).__comma("'!"));
+_st(_st(methods)._sorted_((function(a,b){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
+}, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._exportMethod_of_on_(each,aClass,aStream);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+$3=aStream;
+_st($3)._nextPutAll_(" !");
+_st($3)._lf();
+$4=_st($3)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportMethods:category:of:on:",{methods:methods,category:category,aClass:aClass,aStream:aStream}, smalltalk.ChunkExporter)})}
 }),
 smalltalk.ChunkExporter);
 
@@ -437,24 +465,26 @@ smalltalk.method({
 selector: "exportMethodsOf:on:",
 fn: function (aClass,aStream){
 var self=this;
-var $1;
 var map;
-map=smalltalk.send((smalltalk.Dictionary || Dictionary),"_new",[]);
-smalltalk.send(aClass,"_protocolsDo_",[(function(category,methods){
-$1=smalltalk.send(category,"_match_",["^\x5c*"]);
-if(! smalltalk.assert($1)){
-return smalltalk.send(map,"_at_put_",[category,methods]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
+map=_st((smalltalk.Dictionary || Dictionary))._new();
+$1=aClass;
+$2=(function(category,methods){
+return smalltalk.withContext(function($ctx2) {
$3=_st(category)._match_("^\x5c*");
+if(! smalltalk.assert($3)){
+return _st(map)._at_put_(category,methods);
 };
-})]);
-smalltalk.send(smalltalk.send(smalltalk.send(map,"_keys",[]),"_sorted_",[(function(a,b){
-return smalltalk.send(a,"__lt_eq",[b]);
-})]),"_do_",[(function(category){
+}, function($ctx2) {$ctx2.fillBlock({category:category,methods:methods},$ctx1)})});
+_st($1)._protocolsDo_($2);
+_st(_st(_st(map)._keys())._sorted_((function(a,b){
+return smalltalk.withContext(function($ctx2) {
return _st(a).__lt_eq(b);
+}, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(category){
 var methods;
-methods=smalltalk.send(map,"_at_",[category]);
+return smalltalk.withContext(function($ctx2) {
methods=_st(map)._at_(category);
 methods;
-return smalltalk.send(self,"_exportMethods_category_of_on_",[methods,category,aClass,aStream]);
-})]);
-return self}
+return _st(self)._exportMethods_category_of_on_(methods,category,aClass,aStream);
+}, function($ctx2) {$ctx2.fillBlock({category:category,methods:methods},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"exportMethodsOf:on:",{aClass:aClass,aStream:aStream,map:map}, smalltalk.ChunkExporter)})}
 }),
 smalltalk.ChunkExporter);
 
@@ -462,12 +492,13 @@ smalltalk.addMethod(
 "_exportPackageDefinitionOf_on_",
 smalltalk.method({
 selector: "exportPackageDefinitionOf:on:",
-fn: function (package,aStream){
+fn: function (package_,aStream){
 var self=this;
-var $1;
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send("Smalltalk current createPackage: '","__comma",[smalltalk.send(package,"_name",[])]),"__comma",["' properties: "]),"__comma",[smalltalk.send(smalltalk.send(package,"_properties",[]),"_storeString",[])]),"__comma",["!"])]);
-$1=smalltalk.send(aStream,"_lf",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=aStream;
+_st($1)._nextPutAll_(_st(_st(_st(_st("Smalltalk current createPackage: '").__comma(_st(package_)._name())).__comma("' properties: ")).__comma(_st(_st(package_)._properties())._storeString())).__comma("!"));
+$2=_st($1)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackageDefinitionOf:on:",{package_:package_,aStream:aStream}, smalltalk.ChunkExporter)})}
 }),
 smalltalk.ChunkExporter);
 
@@ -475,33 +506,38 @@ smalltalk.addMethod(
 "_exportPackageExtensionsOf_on_",
 smalltalk.method({
 selector: "exportPackageExtensionsOf:on:",
-fn: function (package,aStream){
+fn: function (package_,aStream){
 var self=this;
-var $1;
-var name;
-var map;
-name=smalltalk.send(package,"_name",[]);
-smalltalk.send(smalltalk.send((smalltalk.Package || Package),"_sortedClasses_",[smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk),"_current",[]),"_classes",[])]),"_do_",[(function(each){
-return smalltalk.send([each,smalltalk.send(each,"_class",[])],"_do_",[(function(aClass){
-map=smalltalk.send((smalltalk.Dictionary || Dictionary),"_new",[]);
+var name,map;
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$5,$7,$6,$4,$2;
+name=_st(package_)._name();
+$1=_st((smalltalk.Package || Package))._sortedClasses_(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._classes());
+$2=(function(each){
+return smalltalk.withContext(function($ctx2) {
$3=[each,_st(each)._class()];
+$4=(function(aClass){
+return smalltalk.withContext(function($ctx3) {
map=_st((smalltalk.Dictionary || Dictionary))._new();
 map;
-smalltalk.send(aClass,"_protocolsDo_",[(function(category,methods){
-$1=smalltalk.send(category,"_match_",[smalltalk.send("^\x5c*","__comma",[name])]);
-if(smalltalk.assert($1)){
-return smalltalk.send(map,"_at_put_",[category,methods]);
+$5=aClass;
+$6=(function(category,methods){
+return smalltalk.withContext(function($ctx4) {
$7=_st(category)._match_(_st("^\x5c*").__comma(name));
+if(smalltalk.assert($7)){
+return _st(map)._at_put_(category,methods);
 };
-})]);
-return smalltalk.send(smalltalk.send(smalltalk.send(map,"_keys",[]),"_sorted_",[(function(a,b){
-return smalltalk.send(a,"__lt_eq",[b]);
-})]),"_do_",[(function(category){
+}, function($ctx4) {$ctx4.fillBlock({category:category,methods:methods},$ctx1)})});
+_st($5)._protocolsDo_($6);
+return _st(_st(_st(map)._keys())._sorted_((function(a,b){
+return smalltalk.withContext(function($ctx4) {
return _st(a).__lt_eq(b);
+}, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(category){
 var methods;
-methods=smalltalk.send(map,"_at_",[category]);
+return smalltalk.withContext(function($ctx4) {
methods=_st(map)._at_(category);
 methods;
-return smalltalk.send(self,"_exportMethods_category_of_on_",[methods,category,aClass,aStream]);
-})]);
-})]);
-})]);
-return self}
+return _st(self)._exportMethods_category_of_on_(methods,category,aClass,aStream);
+}, function($ctx4) {$ctx4.fillBlock({category:category,methods:methods},$ctx1)})}));
+}, function($ctx3) {$ctx3.fillBlock({aClass:aClass},$ctx1)})});
+return _st($3)._do_($4);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
+_st($1)._do_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackageExtensionsOf:on:",{package_:package_,aStream:aStream,name:name,map:map}, smalltalk.ChunkExporter)})}
 }),
 smalltalk.ChunkExporter);
 
@@ -514,21 +550,23 @@ smalltalk.method({
 selector: "exportDefinitionOf:on:",
 fn: function (aClass,aStream){
 var self=this;
-var $1,$2;
-smalltalk.send(aStream,"_nextPutAll_",["smalltalk.addClass("]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("'","__comma",[smalltalk.send(self,"_classNameFor_",[aClass])]),"__comma",["', "])]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("smalltalk.","__comma",[smalltalk.send(self,"_classNameFor_",[smalltalk.send(aClass,"_superclass",[])])])]);
-$1=smalltalk.send(aStream,"_nextPutAll_",[", ["]);
-smalltalk.send(smalltalk.send(aClass,"_instanceVariableNames",[]),"_do_separatedBy_",[(function(each){
-return smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("'","__comma",[each]),"__comma",["'"])]);
-}),(function(){
-return smalltalk.send(aStream,"_nextPutAll_",[", "]);
-})]);
-smalltalk.send(aStream,"_nextPutAll_",["], '"]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(aClass,"_category",[]),"__comma",["'"])]);
-$2=smalltalk.send(aStream,"_nextPutAll_",[");"]);
-smalltalk.send(aStream,"_lf",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+$1=aStream;
+_st($1)._nextPutAll_("smalltalk.addClass(");
+_st($1)._nextPutAll_(_st(_st("'").__comma(_st(self)._classNameFor_(aClass))).__comma("', "));
+_st($1)._nextPutAll_(_st("smalltalk.").__comma(_st(self)._classNameFor_(_st(aClass)._superclass())));
+$2=_st($1)._nextPutAll_(", [");
+_st(_st(aClass)._instanceVariableNames())._do_separatedBy_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(", ");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$3=aStream;
+_st($3)._nextPutAll_("], '");
+_st($3)._nextPutAll_(_st(_st(aClass)._category()).__comma("'"));
+$4=_st($3)._nextPutAll_(");");
+_st(aStream)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportDefinitionOf:on:",{aClass:aClass,aStream:aStream}, smalltalk.StrippedExporter)})}
 }),
 smalltalk.StrippedExporter);
 
@@ -538,24 +576,25 @@ smalltalk.method({
 selector: "exportMethod:of:on:",
 fn: function (aMethod,aClass,aStream){
 var self=this;
-var $1;
-smalltalk.send(aStream,"_nextPutAll_",["smalltalk.addMethod("]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aMethod,"_selector",[]),"_asSelector",[]),"_asJavascript",[]),"__comma",[","])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",["smalltalk.method({"]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("selector: ","__comma",[smalltalk.send(smalltalk.send(aMethod,"_selector",[]),"_asJavascript",[])]),"__comma",[","])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("fn: ","__comma",[smalltalk.send(smalltalk.send(aMethod,"_fn",[]),"_compiledSource",[])])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",["}),"]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("smalltalk.","__comma",[smalltalk.send(self,"_classNameFor_",[aClass])])]);
-smalltalk.send(aStream,"_nextPutAll_",[");"]);
-smalltalk.send(aStream,"_lf",[]);
-$1=smalltalk.send(aStream,"_lf",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=aStream;
+_st($1)._nextPutAll_("smalltalk.addMethod(");
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st(_st(_st(aMethod)._selector())._asSelector())._asJavascript()).__comma(","));
+_st($1)._lf();
+_st($1)._nextPutAll_("smalltalk.method({");
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st("selector: ").__comma(_st(_st(aMethod)._selector())._asJavascript())).__comma(","));
+_st($1)._lf();
+_st($1)._nextPutAll_(_st("fn: ").__comma(_st(_st(aMethod)._fn())._compiledSource()));
+_st($1)._lf();
+_st($1)._nextPutAll_("}),");
+_st($1)._lf();
+_st($1)._nextPutAll_(_st("smalltalk.").__comma(_st(self)._classNameFor_(aClass)));
+_st($1)._nextPutAll_(");");
+_st($1)._lf();
+$2=_st($1)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportMethod:of:on:",{aMethod:aMethod,aClass:aClass,aStream:aStream}, smalltalk.StrippedExporter)})}
 }),
 smalltalk.StrippedExporter);
 
@@ -568,33 +607,35 @@ smalltalk.method({
 selector: "import:",
 fn: function (aStream){
 var self=this;
-var $1;
-var chunk;
-var result;
-var parser;
-var lastEmpty;
-parser=smalltalk.send((smalltalk.ChunkParser || ChunkParser),"_on_",[aStream]);
+var chunk,result,parser,lastEmpty;
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$4,$6,$5,$2;
+parser=_st((smalltalk.ChunkParser || ChunkParser))._on_(aStream);
 lastEmpty=false;
-smalltalk.send((function(){
-chunk=smalltalk.send(parser,"_nextChunk",[]);
+$1=(function(){
+return smalltalk.withContext(function($ctx2) {
chunk=_st(parser)._nextChunk();
 chunk;
-return smalltalk.send(chunk,"_isNil",[]);
-}),"_whileFalse_",[(function(){
-$1=smalltalk.send(chunk,"_isEmpty",[]);
-if(smalltalk.assert($1)){
-lastEmpty=true;
+return _st(chunk)._isNil();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+$2=(function(){
+return smalltalk.withContext(function($ctx2) {
$3=_st(chunk)._isEmpty();
+$4=(function(){
+return smalltalk.withContext(function($ctx3) {
lastEmpty=true;
 return lastEmpty;
-} else {
-result=smalltalk.send(smalltalk.send((smalltalk.Compiler || Compiler),"_new",[]),"_evaluateExpression_",[chunk]);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
+$5=(function(){
+return smalltalk.withContext(function($ctx3) {
result=_st(_st((smalltalk.Compiler || Compiler))._new())._evaluateExpression_(chunk);
 result;
-if(smalltalk.assert(lastEmpty)){
+$6=lastEmpty;
+if(smalltalk.assert($6)){
 lastEmpty=false;
 lastEmpty;
-return smalltalk.send(result,"_scanFrom_",[parser]);
+return _st(result)._scanFrom_(parser);
 };
-};
-})]);
-return self}
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
+return _st($3)._ifTrue_ifFalse_($4,$5);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+_st($1)._whileFalse_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"import:",{aStream:aStream,chunk:chunk,result:result,parser:parser,lastEmpty:lastEmpty}, smalltalk.Importer)})}
 }),
 smalltalk.Importer);
 
@@ -607,16 +648,12 @@ smalltalk.method({
 selector: "initializePackageNamed:prefix:",
 fn: function (packageName,aString){
 var self=this;
-var $1,$2;
-smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Package || Package),"_named_",[packageName]),"_classes",[]),"_do_",[(function(each){
-smalltalk.init(each);
-;
-return smalltalk.send(each,"_initialize",[]);
-})]);
-$1=smalltalk.send((smalltalk.Package || Package),"_named_",[packageName]);
-smalltalk.send($1,"_commitPathJs_",[smalltalk.send(smalltalk.send("/","__comma",[aString]),"__comma",["/js"])]);
-$2=smalltalk.send($1,"_commitPathSt_",[smalltalk.send(smalltalk.send("/","__comma",[aString]),"__comma",["/st"])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st((smalltalk.Package || Package))._named_(packageName);
+_st($1)._setupClasses();
+_st($1)._commitPathJs_(_st(_st("/").__comma(aString)).__comma("/js"));
+$2=_st($1)._commitPathSt_(_st(_st("/").__comma(aString)).__comma("/st"));
+return self}, function($ctx1) {$ctx1.fill(self,"initializePackageNamed:prefix:",{packageName:packageName,aString:aString}, smalltalk.PackageLoader)})}
 }),
 smalltalk.PackageLoader);
 
@@ -626,18 +663,25 @@ smalltalk.method({
 selector: "loadPackage:prefix:",
 fn: function (packageName,aString){
 var self=this;
-var $1;
 var url;
-url=smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send("/","__comma",[aString]),"__comma",["/js/"]),"__comma",[packageName]),"__comma",[".js"]);
-smalltalk.send(jQuery,"_ajax_options_",[url,smalltalk.HashedCollection._fromPairs_([smalltalk.send("type","__minus_gt",["GET"]),smalltalk.send("dataType","__minus_gt",["script"]),smalltalk.send("complete","__minus_gt",[(function(jqXHR,textStatus){
-$1=smalltalk.send(smalltalk.send(jqXHR,"_readyState",[]),"__eq",[(4)]);
-if(smalltalk.assert($1)){
-return smalltalk.send(self,"_initializePackageNamed_prefix_",[packageName,aString]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$5,$8,$7,$6,$3;
+url=_st(_st(_st(_st("/").__comma(aString)).__comma("/js/")).__comma(packageName)).__comma(".js");
+$1=jQuery;
+$2=url;
+$4=_st("type").__minus_gt("GET");
+$5=_st("dataType").__minus_gt("script");
+$7=(function(jqXHR,textStatus){
+return smalltalk.withContext(function($ctx2) {
$8=_st(_st(jqXHR)._readyState()).__eq((4));
+if(smalltalk.assert($8)){
+return _st(self)._initializePackageNamed_prefix_(packageName,aString);
 };
-})]),smalltalk.send("error","__minus_gt",[(function(){
-return smalltalk.send(window,"_alert_",[smalltalk.send("Could not load package at:  ","__comma",[url])]);
-})])])]);
-return self}
+}, function($ctx2) {$ctx2.fillBlock({jqXHR:jqXHR,textStatus:textStatus},$ctx1)})});
+$6=_st("complete").__minus_gt($7);
+$3=smalltalk.HashedCollection._fromPairs_([$4,$5,$6,_st("error").__minus_gt((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(window)._alert_(_st("Could not load package at:  ").__comma(url));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))]);
+_st($1)._ajax_options_($2,$3);
+return self}, function($ctx1) {$ctx1.fill(self,"loadPackage:prefix:",{packageName:packageName,aString:aString,url:url}, smalltalk.PackageLoader)})}
 }),
 smalltalk.PackageLoader);
 
@@ -647,10 +691,10 @@ smalltalk.method({
 selector: "loadPackages:prefix:",
 fn: function (aCollection,aString){
 var self=this;
-smalltalk.send(aCollection,"_do_",[(function(each){
-return smalltalk.send(self,"_loadPackage_prefix_",[each,aString]);
-})]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(aCollection)._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._loadPackage_prefix_(each,aString);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"loadPackages:prefix:",{aCollection:aCollection,aString:aString}, smalltalk.PackageLoader)})}
 }),
 smalltalk.PackageLoader);
 
@@ -661,10 +705,10 @@ smalltalk.method({
 selector: "loadPackages:prefix:",
 fn: function (aCollection,aString){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(self,"_new",[]),"_loadPackages_prefix_",[aCollection,aString]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._new())._loadPackages_prefix_(aCollection,aString);
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"loadPackages:prefix:",{aCollection:aCollection,aString:aString}, smalltalk.PackageLoader.klass)})}
 }),
 smalltalk.PackageLoader.klass);
 

+ 398 - 354
js/Importer-Exporter.js

@@ -7,34 +7,35 @@ selector: "nextChunk",
 category: 'reading',
 fn: function (){
 var self=this;
-var $1,$2,$3;
+var char,result,chunk;
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$5,$6,$4,$2;
 var $early={};
 try {
-var char_;
-var result;
-var chunk;
-result=smalltalk.send("","_writeStream",[]);
-smalltalk.send((function(){
-char_=smalltalk.send(self["@stream"],"_next",[]);
-char_;
-return smalltalk.send(char_,"_notNil",[]);
-}),"_whileTrue_",[(function(){
-$1=smalltalk.send(char_,"__eq",["!"]);
-if(smalltalk.assert($1)){
-$2=smalltalk.send(smalltalk.send(self["@stream"],"_peek",[]),"__eq",["!"]);
-if(smalltalk.assert($2)){
-smalltalk.send(self["@stream"],"_next",[]);
+result=_st("")._writeStream();
+$1=(function(){
+return smalltalk.withContext(function($ctx2) {
char=_st(self["@stream"])._next();
+char;
+return _st(char)._notNil();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+$2=(function(){
+return smalltalk.withContext(function($ctx2) {
$3=_st(char).__eq("!");
+$4=(function(){
+return smalltalk.withContext(function($ctx3) {
$5=_st(_st(self["@stream"])._peek()).__eq("!");
+if(smalltalk.assert($5)){
+return _st(self["@stream"])._next();
 } else {
-$3=smalltalk.send(smalltalk.send(result,"_contents",[]),"_trimBoth",[]);
-throw $early=[$3];
+$6=_st(_st(result)._contents())._trimBoth();
+throw $early=[$6];
 };
-};
-return smalltalk.send(result,"_nextPut_",[char_]);
-})]);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
+_st($3)._ifTrue_($4);
+return _st(result)._nextPut_(char);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+_st($1)._whileTrue_($2);
 return nil;
 }
 catch(e) {if(e===$early)return e[0]; throw e}
-},
+}, function($ctx1) {$ctx1.fill(self,"nextChunk",{char:char,result:result,chunk:chunk}, smalltalk.ChunkParser)})},
 args: [],
 source: "nextChunk\x0a\x09\x22The chunk format (Smalltalk Interchange Format or Fileout format)\x0a\x09is a trivial format but can be a bit tricky to understand:\x0a\x09\x09- Uses the exclamation mark as delimiter of chunks.\x0a\x09\x09- Inside a chunk a normal exclamation mark must be doubled.\x0a\x09\x09- A non empty chunk must be a valid Smalltalk expression.\x0a\x09\x09- A chunk on top level with a preceding empty chunk is an instruction chunk:\x0a\x09\x09\x09- The object created by the expression then takes over reading chunks.\x0a\x0a\x09This metod returns next chunk as a String (trimmed), empty String (all whitespace) or nil.\x22\x0a\x0a\x09| char result chunk |\x0a\x09result := '' writeStream.\x0a        [char := stream next.\x0a        char notNil] whileTrue: [\x0a                 char = '!' ifTrue: [\x0a                         stream peek = '!'\x0a                                ifTrue: [stream next \x22skipping the escape double\x22]\x0a                                ifFalse: [^result contents trimBoth  \x22chunk end marker found\x22]].\x0a                 result nextPut: char].\x0a\x09^nil \x22a chunk needs to end with !\x22",
 messageSends: ["writeStream", "whileTrue:", "ifTrue:", "ifTrue:ifFalse:", "next", "trimBoth", "contents", "=", "peek", "nextPut:", "notNil"],
@@ -49,8 +50,8 @@ selector: "stream:",
 category: 'accessing',
 fn: function (aStream){
 var self=this;
-self["@stream"]=aStream;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@stream"]=aStream;
+return self}, function($ctx1) {$ctx1.fill(self,"stream:",{aStream:aStream}, smalltalk.ChunkParser)})},
 args: ["aStream"],
 source: "stream: aStream\x0a\x09stream := aStream",
 messageSends: [],
@@ -66,10 +67,10 @@ selector: "on:",
 category: 'not yet classified',
 fn: function (aStream){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(self,"_new",[]),"_stream_",[aStream]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._new())._stream_(aStream);
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"on:",{aStream:aStream}, smalltalk.ChunkParser.klass)})},
 args: ["aStream"],
 source: "on: aStream\x0a\x09^self new stream: aStream",
 messageSends: ["stream:", "new"],
@@ -86,20 +87,22 @@ selector: "classNameFor:",
 category: 'private',
 fn: function (aClass){
 var self=this;
-var $2,$3,$1;
-$2=smalltalk.send(aClass,"_isMetaclass",[]);
-if(smalltalk.assert($2)){
-$1=smalltalk.send(smalltalk.send(smalltalk.send(aClass,"_instanceClass",[]),"_name",[]),"__comma",[".klass"]);
-} else {
-$3=smalltalk.send(aClass,"_isNil",[]);
-if(smalltalk.assert($3)){
-$1="nil";
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$4,$1;
+$2=_st(aClass)._isMetaclass();
+$3=(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(_st(aClass)._instanceClass())._name()).__comma(".klass");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+$4=(function(){
+return smalltalk.withContext(function($ctx2) {
$5=_st(aClass)._isNil();
+if(smalltalk.assert($5)){
+return "nil";
 } else {
-$1=smalltalk.send(aClass,"_name",[]);
-};
+return _st(aClass)._name();
 };
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+$1=_st($2)._ifTrue_ifFalse_($3,$4);
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass}, smalltalk.Exporter)})},
 args: ["aClass"],
 source: "classNameFor: aClass\x0a\x09^aClass isMetaclass\x0a\x09    ifTrue: [aClass instanceClass name, '.klass']\x0a\x09    ifFalse: [\x0a\x09\x09aClass isNil\x0a\x09\x09    ifTrue: ['nil']\x0a\x09\x09    ifFalse: [aClass name]]",
 messageSends: ["ifTrue:ifFalse:", ",", "name", "instanceClass", "isNil", "isMetaclass"],
@@ -114,14 +117,14 @@ selector: "exportAll",
 category: 'fileOut',
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send((smalltalk.String || String),"_streamContents_",[(function(stream){
-return smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk),"_current",[]),"_packages",[]),"_do_",[(function(pkg){
-return smalltalk.send(stream,"_nextPutAll_",[smalltalk.send(self,"_exportPackage_",[smalltalk.send(pkg,"_name",[])])]);
-})]);
-})]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st((smalltalk.String || String))._streamContents_((function(stream){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._packages())._do_((function(pkg){
+return smalltalk.withContext(function($ctx3) {
return _st(stream)._nextPutAll_(_st(self)._exportPackage_(_st(pkg)._name()));
+}, function($ctx3) {$ctx3.fillBlock({pkg:pkg},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"exportAll",{}, smalltalk.Exporter)})},
 args: [],
 source: "exportAll\x0a    \x22Export all packages in the system.\x22\x0a\x0a    ^String streamContents: [:stream |\x0a    \x09Smalltalk current packages do: [:pkg |\x0a\x09\x09stream nextPutAll: (self exportPackage: pkg name)]]",
 messageSends: ["streamContents:", "do:", "nextPutAll:", "exportPackage:", "name", "packages", "current"],
@@ -136,15 +139,15 @@ selector: "exportClass:",
 category: 'fileOut',
 fn: function (aClass){
 var self=this;
-var $1;
-$1=smalltalk.send((smalltalk.String || String),"_streamContents_",[(function(stream){
-smalltalk.send(self,"_exportDefinitionOf_on_",[aClass,stream]);
-smalltalk.send(self,"_exportMethodsOf_on_",[aClass,stream]);
-smalltalk.send(self,"_exportMetaDefinitionOf_on_",[aClass,stream]);
-return smalltalk.send(self,"_exportMethodsOf_on_",[smalltalk.send(aClass,"_class",[]),stream]);
-})]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st((smalltalk.String || String))._streamContents_((function(stream){
+return smalltalk.withContext(function($ctx2) {
_st(self)._exportDefinitionOf_on_(aClass,stream);
+_st(self)._exportMethodsOf_on_(aClass,stream);
+_st(self)._exportMetaDefinitionOf_on_(aClass,stream);
+return _st(self)._exportMethodsOf_on_(_st(aClass)._class(),stream);
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"exportClass:",{aClass:aClass}, smalltalk.Exporter)})},
 args: ["aClass"],
 source: "exportClass: aClass\x0a\x09\x22Export a single class. Subclasses override these methods.\x22\x0a\x0a\x09^String streamContents: [:stream |\x0a\x09\x09self exportDefinitionOf: aClass on: stream.\x0a\x09\x09self exportMethodsOf: aClass on: stream.\x0a\x09\x09self exportMetaDefinitionOf: aClass on: stream.\x0a\x09\x09self exportMethodsOf: aClass class on: stream]",
 messageSends: ["streamContents:", "exportDefinitionOf:on:", "exportMethodsOf:on:", "exportMetaDefinitionOf:on:", "class"],
@@ -159,30 +162,33 @@ selector: "exportDefinitionOf:on:",
 category: 'private',
 fn: function (aClass,aStream){
 var self=this;
-var $1,$2,$3,$4;
-smalltalk.send(aStream,"_nextPutAll_",["smalltalk.addClass("]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("'","__comma",[smalltalk.send(self,"_classNameFor_",[aClass])]),"__comma",["', "])]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("smalltalk.","__comma",[smalltalk.send(self,"_classNameFor_",[smalltalk.send(aClass,"_superclass",[])])])]);
-$1=smalltalk.send(aStream,"_nextPutAll_",[", ["]);
-smalltalk.send(smalltalk.send(aClass,"_instanceVariableNames",[]),"_do_separatedBy_",[(function(each){
-return smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("'","__comma",[each]),"__comma",["'"])]);
-}),(function(){
-return smalltalk.send(aStream,"_nextPutAll_",[", "]);
-})]);
-smalltalk.send(aStream,"_nextPutAll_",["], '"]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(aClass,"_category",[]),"__comma",["'"])]);
-$2=smalltalk.send(aStream,"_nextPutAll_",[");"]);
-$3=smalltalk.send(smalltalk.send(aClass,"_comment",[]),"_notEmpty",[]);
-if(smalltalk.assert($3)){
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",["smalltalk."]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(self,"_classNameFor_",[aClass])]);
-smalltalk.send(aStream,"_nextPutAll_",[".comment="]);
-$4=smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(aClass,"_comment",[]),"_asJavascript",[])]);
-$4;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6,$7;
+$1=aStream;
+_st($1)._nextPutAll_("smalltalk.addClass(");
+_st($1)._nextPutAll_(_st(_st("'").__comma(_st(self)._classNameFor_(aClass))).__comma("', "));
+_st($1)._nextPutAll_(_st("smalltalk.").__comma(_st(self)._classNameFor_(_st(aClass)._superclass())));
+$2=_st($1)._nextPutAll_(", [");
+_st(_st(aClass)._instanceVariableNames())._do_separatedBy_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(", ");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$3=aStream;
+_st($3)._nextPutAll_("], '");
+_st($3)._nextPutAll_(_st(_st(aClass)._category()).__comma("'"));
+$4=_st($3)._nextPutAll_(");");
+$5=_st(_st(aClass)._comment())._notEmpty();
+if(smalltalk.assert($5)){
+$6=aStream;
+_st($6)._lf();
+_st($6)._nextPutAll_("smalltalk.");
+_st($6)._nextPutAll_(_st(self)._classNameFor_(aClass));
+_st($6)._nextPutAll_(".comment=");
+$7=_st($6)._nextPutAll_(_st(_st(aClass)._comment())._asJavascript());
+$7;
 };
-smalltalk.send(aStream,"_lf",[]);
-return self},
+_st(aStream)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportDefinitionOf:on:",{aClass:aClass,aStream:aStream}, smalltalk.Exporter)})},
 args: ["aClass", "aStream"],
 source: "exportDefinitionOf: aClass on: aStream\x0a\x09aStream \x0a\x09    nextPutAll: 'smalltalk.addClass(';\x0a\x09    nextPutAll: '''', (self classNameFor: aClass), ''', ';\x0a\x09    nextPutAll: 'smalltalk.', (self classNameFor: aClass superclass);\x0a\x09    nextPutAll: ', ['.\x0a\x09aClass instanceVariableNames \x0a\x09    do: [:each | aStream nextPutAll: '''', each, '''']\x0a\x09    separatedBy: [aStream nextPutAll: ', '].\x0a\x09aStream\x09\x0a\x09    nextPutAll: '], ''';\x0a\x09    nextPutAll: aClass category, '''';\x0a\x09    nextPutAll: ');'.\x0a\x09aClass comment notEmpty ifTrue: [\x0a\x09    aStream \x0a\x09    \x09lf;\x0a\x09\x09nextPutAll: 'smalltalk.';\x0a\x09\x09nextPutAll: (self classNameFor: aClass);\x0a\x09\x09nextPutAll: '.comment=';\x0a\x09\x09nextPutAll: aClass comment asJavascript].\x0a\x09aStream lf",
 messageSends: ["nextPutAll:", ",", "classNameFor:", "superclass", "do:separatedBy:", "instanceVariableNames", "category", "ifTrue:", "lf", "asJavascript", "comment", "notEmpty"],
@@ -197,20 +203,21 @@ selector: "exportMetaDefinitionOf:on:",
 category: 'private',
 fn: function (aClass,aStream){
 var self=this;
-var $1,$2;
-$1=smalltalk.send(smalltalk.send(smalltalk.send(aClass,"_class",[]),"_instanceVariableNames",[]),"_isEmpty",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+$1=_st(_st(_st(aClass)._class())._instanceVariableNames())._isEmpty();
 if(! smalltalk.assert($1)){
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("smalltalk.","__comma",[smalltalk.send(self,"_classNameFor_",[smalltalk.send(aClass,"_class",[])])])]);
-$2=smalltalk.send(aStream,"_nextPutAll_",[".iVarNames = ["]);
-$2;
-smalltalk.send(smalltalk.send(smalltalk.send(aClass,"_class",[]),"_instanceVariableNames",[]),"_do_separatedBy_",[(function(each){
-return smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("'","__comma",[each]),"__comma",["'"])]);
-}),(function(){
-return smalltalk.send(aStream,"_nextPutAll_",[","]);
-})]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("];","__comma",[smalltalk.send((smalltalk.String || String),"_lf",[])])]);
+$2=aStream;
+_st($2)._nextPutAll_(_st("smalltalk.").__comma(_st(self)._classNameFor_(_st(aClass)._class())));
+$3=_st($2)._nextPutAll_(".iVarNames = [");
+$3;
+_st(_st(_st(aClass)._class())._instanceVariableNames())._do_separatedBy_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(",");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st(aStream)._nextPutAll_(_st("];").__comma(_st((smalltalk.String || String))._lf()));
 };
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"exportMetaDefinitionOf:on:",{aClass:aClass,aStream:aStream}, smalltalk.Exporter)})},
 args: ["aClass", "aStream"],
 source: "exportMetaDefinitionOf: aClass on: aStream\x0a\x09aClass class instanceVariableNames isEmpty ifFalse: [\x0a\x09    aStream \x0a\x09\x09nextPutAll: 'smalltalk.', (self classNameFor: aClass class);\x0a\x09\x09nextPutAll: '.iVarNames = ['.\x0a\x09    aClass class instanceVariableNames\x0a\x09\x09do: [:each | aStream nextPutAll: '''', each, '''']\x0a\x09\x09separatedBy: [aStream nextPutAll: ','].\x0a\x09    aStream nextPutAll: '];', String lf]",
 messageSends: ["ifFalse:", "nextPutAll:", ",", "classNameFor:", "class", "do:separatedBy:", "instanceVariableNames", "lf", "isEmpty"],
@@ -225,34 +232,36 @@ selector: "exportMethod:of:on:",
 category: 'private',
 fn: function (aMethod,aClass,aStream){
 var self=this;
-var $1,$2;
-smalltalk.send(aStream,"_nextPutAll_",["smalltalk.addMethod("]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aMethod,"_selector",[]),"_asSelector",[]),"_asJavascript",[]),"__comma",[","])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",["smalltalk.method({"]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("selector: ","__comma",[smalltalk.send(smalltalk.send(aMethod,"_selector",[]),"_asJavascript",[])]),"__comma",[","])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("category: '","__comma",[smalltalk.send(aMethod,"_category",[])]),"__comma",["',"])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("fn: ","__comma",[smalltalk.send(smalltalk.send(aMethod,"_fn",[]),"_compiledSource",[])]),"__comma",[","])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("args: ","__comma",[smalltalk.send(smalltalk.send(aMethod,"_arguments",[]),"_asJavascript",[])]),"__comma",[","])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("source: ","__comma",[smalltalk.send(smalltalk.send(aMethod,"_source",[]),"_asJavascript",[])]),"__comma",[","])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("messageSends: ","__comma",[smalltalk.send(smalltalk.send(aMethod,"_messageSends",[]),"_asJavascript",[])]),"__comma",[","])]);
-smalltalk.send(aStream,"_lf",[]);
-$1=smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("referencedClasses: ","__comma",[smalltalk.send(smalltalk.send(aMethod,"_referencedClasses",[]),"_asJavascript",[])])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",["}),"]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("smalltalk.","__comma",[smalltalk.send(self,"_classNameFor_",[aClass])])]);
-smalltalk.send(aStream,"_nextPutAll_",[");"]);
-smalltalk.send(aStream,"_lf",[]);
-$2=smalltalk.send(aStream,"_lf",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+$1=aStream;
+_st($1)._nextPutAll_("smalltalk.addMethod(");
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st(_st(_st(aMethod)._selector())._asSelector())._asJavascript()).__comma(","));
+_st($1)._lf();
+_st($1)._nextPutAll_("smalltalk.method({");
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st("selector: ").__comma(_st(_st(aMethod)._selector())._asJavascript())).__comma(","));
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st("category: '").__comma(_st(aMethod)._category())).__comma("',"));
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st("fn: ").__comma(_st(_st(aMethod)._fn())._compiledSource())).__comma(","));
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st("args: ").__comma(_st(_st(aMethod)._arguments())._asJavascript())).__comma(","));
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st("source: ").__comma(_st(_st(aMethod)._source())._asJavascript())).__comma(","));
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st("messageSends: ").__comma(_st(_st(aMethod)._messageSends())._asJavascript())).__comma(","));
+_st($1)._lf();
+$2=_st($1)._nextPutAll_(_st("referencedClasses: ").__comma(_st(_st(aMethod)._referencedClasses())._asJavascript()));
+$3=aStream;
+_st($3)._lf();
+_st($3)._nextPutAll_("}),");
+_st($3)._lf();
+_st($3)._nextPutAll_(_st("smalltalk.").__comma(_st(self)._classNameFor_(aClass)));
+_st($3)._nextPutAll_(");");
+_st($3)._lf();
+$4=_st($3)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportMethod:of:on:",{aMethod:aMethod,aClass:aClass,aStream:aStream}, smalltalk.Exporter)})},
 args: ["aMethod", "aClass", "aStream"],
 source: "exportMethod: aMethod of: aClass on: aStream\x0a\x09aStream \x0a\x09\x09nextPutAll: 'smalltalk.addMethod(';lf;\x0a\x09\x09nextPutAll: aMethod selector asSelector asJavascript, ',';lf;\x0a\x09\x09nextPutAll: 'smalltalk.method({';lf;\x0a\x09\x09nextPutAll: 'selector: ', aMethod selector asJavascript, ',';lf;\x0a\x09\x09nextPutAll: 'category: ''', aMethod category, ''',';lf;\x0a\x09\x09nextPutAll: 'fn: ', aMethod fn compiledSource, ',';lf;\x0a\x09\x09nextPutAll: 'args: ', aMethod arguments asJavascript, ','; lf;\x0a\x09\x09nextPutAll: 'source: ', aMethod source asJavascript, ',';lf;\x0a\x09\x09nextPutAll: 'messageSends: ', aMethod messageSends asJavascript, ',';lf;\x0a\x09\x09nextPutAll: 'referencedClasses: ', aMethod referencedClasses asJavascript.\x0a\x09aStream\x0a\x09\x09lf;\x0a\x09\x09nextPutAll: '}),';lf;\x0a\x09\x09nextPutAll: 'smalltalk.', (self classNameFor: aClass);\x0a\x09\x09nextPutAll: ');';lf;lf",
 messageSends: ["nextPutAll:", "lf", ",", "asJavascript", "asSelector", "selector", "category", "compiledSource", "fn", "arguments", "source", "messageSends", "referencedClasses", "classNameFor:"],
@@ -267,17 +276,19 @@ selector: "exportMethodsOf:on:",
 category: 'private',
 fn: function (aClass,aStream){
 var self=this;
-var $1;
-smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aClass,"_methodDictionary",[]),"_values",[]),"_sorted_",[(function(a,b){
-return smalltalk.send(smalltalk.send(a,"_selector",[]),"__lt_eq",[smalltalk.send(b,"_selector",[])]);
-})]),"_do_",[(function(each){
-$1=smalltalk.send(smalltalk.send(each,"_category",[]),"_match_",["^\x5c*"]);
-if(! smalltalk.assert($1)){
-return smalltalk.send(self,"_exportMethod_of_on_",[each,aClass,aStream]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
+$1=_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
+}, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})}));
+$2=(function(each){
+return smalltalk.withContext(function($ctx2) {
$3=_st(_st(each)._category())._match_("^\x5c*");
+if(! smalltalk.assert($3)){
+return _st(self)._exportMethod_of_on_(each,aClass,aStream);
 };
-})]);
-smalltalk.send(aStream,"_lf",[]);
-return self},
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
+_st($1)._do_($2);
+_st(aStream)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportMethodsOf:on:",{aClass:aClass,aStream:aStream}, smalltalk.Exporter)})},
 args: ["aClass", "aStream"],
 source: "exportMethodsOf: aClass on: aStream\x0a\x09\x22Issue #143: sort methods alphabetically\x22\x0a\x0a\x09((aClass methodDictionary values) sorted: [:a :b | a selector <= b selector]) do: [:each |\x0a\x09\x09(each category match: '^\x5c*') ifFalse: [\x0a\x09\x09\x09self exportMethod: each of: aClass on: aStream]].\x0a\x09aStream lf",
 messageSends: ["do:", "ifFalse:", "exportMethod:of:on:", "match:", "category", "sorted:", "<=", "selector", "values", "methodDictionary", "lf"],
@@ -292,19 +303,19 @@ selector: "exportPackage:",
 category: 'fileOut',
 fn: function (packageName){
 var self=this;
-var $1;
-var package;
-$1=smalltalk.send((smalltalk.String || String),"_streamContents_",[(function(stream){
-package=smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk),"_current",[]),"_packageAt_",[packageName]);
-package;
-smalltalk.send(self,"_exportPackageDefinitionOf_on_",[package,stream]);
-smalltalk.send(smalltalk.send(smalltalk.send(package,"_sortedClasses",[]),"_asSet",[]),"_do_",[(function(each){
-return smalltalk.send(stream,"_nextPutAll_",[smalltalk.send(self,"_exportClass_",[each])]);
-})]);
-return smalltalk.send(self,"_exportPackageExtensionsOf_on_",[package,stream]);
-})]);
+var package_;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st((smalltalk.String || String))._streamContents_((function(stream){
+return smalltalk.withContext(function($ctx2) {
package_=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._packageAt_(packageName);
+package_;
+_st(self)._exportPackageDefinitionOf_on_(package_,stream);
+_st(_st(_st(package_)._sortedClasses())._asSet())._do_((function(each){
+return smalltalk.withContext(function($ctx3) {
return _st(stream)._nextPutAll_(_st(self)._exportClass_(each));
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}));
+return _st(self)._exportPackageExtensionsOf_on_(package_,stream);
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"exportPackage:",{packageName:packageName,package_:package_}, smalltalk.Exporter)})},
 args: ["packageName"],
 source: "exportPackage: packageName\x0a\x09\x22Export a given package by name.\x22\x0a\x0a\x09| package |\x0a\x09^String streamContents: [:stream |\x0a                package := Smalltalk current packageAt: packageName.\x0a                self exportPackageDefinitionOf: package on: stream.\x0a\x0a\x09\x09\x22Export classes in dependency order.\x0a\x09\x09Update (issue #171): Remove duplicates for export\x22\x0a\x09    \x09package sortedClasses asSet do: [:each |\x0a                        stream nextPutAll: (self exportClass: each)].\x0a\x09\x09self exportPackageExtensionsOf: package on: stream]",
 messageSends: ["streamContents:", "packageAt:", "current", "exportPackageDefinitionOf:on:", "do:", "nextPutAll:", "exportClass:", "asSet", "sortedClasses", "exportPackageExtensionsOf:on:"],
@@ -317,13 +328,14 @@ smalltalk.addMethod(
 smalltalk.method({
 selector: "exportPackageDefinitionOf:on:",
 category: 'private',
-fn: function (package,aStream){
+fn: function (package_,aStream){
 var self=this;
-var $1;
-smalltalk.send(aStream,"_nextPutAll_",["smalltalk.addPackage("]);
-$1=smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send("'","__comma",[smalltalk.send(package,"_name",[])]),"__comma",["', "]),"__comma",[smalltalk.send(package,"_propertiesAsJSON",[])]),"__comma",[");"])]);
-smalltalk.send(aStream,"_lf",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=aStream;
+_st($1)._nextPutAll_("smalltalk.addPackage(");
+$2=_st($1)._nextPutAll_(_st(_st(_st(_st("'").__comma(_st(package_)._name())).__comma("', ")).__comma(_st(package_)._propertiesAsJSON())).__comma(");"));
+_st(aStream)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackageDefinitionOf:on:",{package_:package_,aStream:aStream}, smalltalk.Exporter)})},
 args: ["package", "aStream"],
 source: "exportPackageDefinitionOf: package on: aStream\x0a\x09aStream \x0a\x09    nextPutAll: 'smalltalk.addPackage(';\x0a\x09    nextPutAll: '''', package name, ''', ', package propertiesAsJSON , ');'.\x0a\x09aStream lf",
 messageSends: ["nextPutAll:", ",", "propertiesAsJSON", "name", "lf"],
@@ -336,24 +348,30 @@ smalltalk.addMethod(
 smalltalk.method({
 selector: "exportPackageExtensionsOf:on:",
 category: 'private',
-fn: function (package,aStream){
+fn: function (package_,aStream){
 var self=this;
-var $1;
 var name;
-name=smalltalk.send(package,"_name",[]);
-smalltalk.send(smalltalk.send((smalltalk.Package || Package),"_sortedClasses_",[smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk),"_current",[]),"_classes",[])]),"_do_",[(function(each){
-return smalltalk.send([each,smalltalk.send(each,"_class",[])],"_do_",[(function(aClass){
-return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aClass,"_methodDictionary",[]),"_values",[]),"_sorted_",[(function(a,b){
-return smalltalk.send(smalltalk.send(a,"_selector",[]),"__lt_eq",[smalltalk.send(b,"_selector",[])]);
-})]),"_do_",[(function(method){
-$1=smalltalk.send(smalltalk.send(method,"_category",[]),"_match_",[smalltalk.send("^\x5c*","__comma",[name])]);
-if(smalltalk.assert($1)){
-return smalltalk.send(self,"_exportMethod_of_on_",[method,aClass,aStream]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$5,$7,$6,$4,$2;
+name=_st(package_)._name();
+$1=_st((smalltalk.Package || Package))._sortedClasses_(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._classes());
+$2=(function(each){
+return smalltalk.withContext(function($ctx2) {
$3=[each,_st(each)._class()];
+$4=(function(aClass){
+return smalltalk.withContext(function($ctx3) {
$5=_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
+return smalltalk.withContext(function($ctx4) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
+}, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx1)})}));
+$6=(function(method){
+return smalltalk.withContext(function($ctx4) {
$7=_st(_st(method)._category())._match_(_st("^\x5c*").__comma(name));
+if(smalltalk.assert($7)){
+return _st(self)._exportMethod_of_on_(method,aClass,aStream);
 };
-})]);
-})]);
-})]);
-return self},
+}, function($ctx4) {$ctx4.fillBlock({method:method},$ctx1)})});
+return _st($5)._do_($6);
+}, function($ctx3) {$ctx3.fillBlock({aClass:aClass},$ctx1)})});
+return _st($3)._do_($4);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
+_st($1)._do_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackageExtensionsOf:on:",{package_:package_,aStream:aStream,name:name}, smalltalk.Exporter)})},
 args: ["package", "aStream"],
 source: "exportPackageExtensionsOf: package on: aStream\x0a\x09\x22Issue #143: sort classes and methods alphabetically\x22\x0a\x0a\x09| name |\x0a\x09name := package name.\x0a\x09(Package sortedClasses: Smalltalk current classes) do: [:each |\x0a\x09\x09{each. each class} do: [:aClass | \x0a\x09\x09\x09((aClass methodDictionary values) sorted: [:a :b | a selector <= b selector]) do: [:method |\x0a\x09\x09\x09\x09(method category match: '^\x5c*', name) ifTrue: [\x0a\x09\x09\x09\x09\x09self exportMethod: method of: aClass on: aStream ]]]]",
 messageSends: ["name", "do:", "ifTrue:", "exportMethod:of:on:", "match:", ",", "category", "sorted:", "<=", "selector", "values", "methodDictionary", "class", "sortedClasses:", "classes", "current"],
@@ -371,10 +389,10 @@ selector: "chunkEscape:",
 category: 'not yet classified',
 fn: function (aString){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(aString,"_replace_with_",["!","!!"]),"_trimBoth",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(aString)._replace_with_("!","!!"))._trimBoth();
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"chunkEscape:",{aString:aString}, smalltalk.ChunkExporter)})},
 args: ["aString"],
 source: "chunkEscape: aString\x0a\x09\x22Replace all occurrences of ! with !! and trim at both ends.\x22\x0a\x0a\x09^(aString replace: '!' with: '!!') trimBoth",
 messageSends: ["trimBoth", "replace:with:"],
@@ -389,20 +407,22 @@ selector: "classNameFor:",
 category: 'not yet classified',
 fn: function (aClass){
 var self=this;
-var $2,$3,$1;
-$2=smalltalk.send(aClass,"_isMetaclass",[]);
-if(smalltalk.assert($2)){
-$1=smalltalk.send(smalltalk.send(smalltalk.send(aClass,"_instanceClass",[]),"_name",[]),"__comma",[" class"]);
-} else {
-$3=smalltalk.send(aClass,"_isNil",[]);
-if(smalltalk.assert($3)){
-$1="nil";
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$4,$1;
+$2=_st(aClass)._isMetaclass();
+$3=(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(_st(aClass)._instanceClass())._name()).__comma(" class");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+$4=(function(){
+return smalltalk.withContext(function($ctx2) {
$5=_st(aClass)._isNil();
+if(smalltalk.assert($5)){
+return "nil";
 } else {
-$1=smalltalk.send(aClass,"_name",[]);
-};
+return _st(aClass)._name();
 };
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+$1=_st($2)._ifTrue_ifFalse_($3,$4);
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass}, smalltalk.ChunkExporter)})},
 args: ["aClass"],
 source: "classNameFor: aClass\x0a\x09^aClass isMetaclass\x0a\x09    ifTrue: [aClass instanceClass name, ' class']\x0a\x09    ifFalse: [\x0a\x09\x09aClass isNil\x0a\x09\x09    ifTrue: ['nil']\x0a\x09\x09    ifFalse: [aClass name]]",
 messageSends: ["ifTrue:ifFalse:", ",", "name", "instanceClass", "isNil", "isMetaclass"],
@@ -417,30 +437,33 @@ selector: "exportDefinitionOf:on:",
 category: 'not yet classified',
 fn: function (aClass,aStream){
 var self=this;
-var $1,$2,$3,$4;
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(self,"_classNameFor_",[smalltalk.send(aClass,"_superclass",[])])]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(" subclass: #","__comma",[smalltalk.send(self,"_classNameFor_",[aClass])])]);
-smalltalk.send(aStream,"_lf",[]);
-$1=smalltalk.send(aStream,"_nextPutAll_",["\x09instanceVariableNames: '"]);
-smalltalk.send(smalltalk.send(aClass,"_instanceVariableNames",[]),"_do_separatedBy_",[(function(each){
-return smalltalk.send(aStream,"_nextPutAll_",[each]);
-}),(function(){
-return smalltalk.send(aStream,"_nextPutAll_",[" "]);
-})]);
-smalltalk.send(aStream,"_nextPutAll_",["'"]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("\x09package: '","__comma",[smalltalk.send(aClass,"_category",[])]),"__comma",["'!"])]);
-$2=smalltalk.send(aStream,"_lf",[]);
-$3=smalltalk.send(smalltalk.send(aClass,"_comment",[]),"_notEmpty",[]);
-if(smalltalk.assert($3)){
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("!","__comma",[smalltalk.send(self,"_classNameFor_",[aClass])]),"__comma",[" commentStamp!"])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(self,"_chunkEscape_",[smalltalk.send(aClass,"_comment",[])]),"__comma",["!"])]);
-$4=smalltalk.send(aStream,"_lf",[]);
-$4;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6,$7;
+$1=aStream;
+_st($1)._nextPutAll_(_st(self)._classNameFor_(_st(aClass)._superclass()));
+_st($1)._nextPutAll_(_st(" subclass: #").__comma(_st(self)._classNameFor_(aClass)));
+_st($1)._lf();
+$2=_st($1)._nextPutAll_("\x09instanceVariableNames: '");
+_st(_st(aClass)._instanceVariableNames())._do_separatedBy_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(each);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(" ");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$3=aStream;
+_st($3)._nextPutAll_("'");
+_st($3)._lf();
+_st($3)._nextPutAll_(_st(_st("\x09package: '").__comma(_st(aClass)._category())).__comma("'!"));
+$4=_st($3)._lf();
+$5=_st(_st(aClass)._comment())._notEmpty();
+if(smalltalk.assert($5)){
+$6=aStream;
+_st($6)._nextPutAll_(_st(_st("!").__comma(_st(self)._classNameFor_(aClass))).__comma(" commentStamp!"));
+_st($6)._lf();
+_st($6)._nextPutAll_(_st(_st(self)._chunkEscape_(_st(aClass)._comment())).__comma("!"));
+$7=_st($6)._lf();
+$7;
 };
-smalltalk.send(aStream,"_lf",[]);
-return self},
+_st(aStream)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportDefinitionOf:on:",{aClass:aClass,aStream:aStream}, smalltalk.ChunkExporter)})},
 args: ["aClass", "aStream"],
 source: "exportDefinitionOf: aClass on: aStream\x0a    \x22Chunk format.\x22\x0a\x0a    aStream \x0a        nextPutAll: (self classNameFor: aClass superclass);\x0a        nextPutAll: ' subclass: #', (self classNameFor: aClass); lf;\x0a        nextPutAll: '\x09instanceVariableNames: '''.\x0a    aClass instanceVariableNames \x0a        do: [:each | aStream nextPutAll: each]\x0a        separatedBy: [aStream nextPutAll: ' '].\x0a    aStream \x0a        nextPutAll: ''''; lf;\x0a        nextPutAll: '\x09package: ''', aClass category, '''!'; lf.\x0a    aClass comment notEmpty ifTrue: [\x0a        aStream \x0a        nextPutAll: '!', (self classNameFor: aClass), ' commentStamp!';lf;\x0a        nextPutAll: (self chunkEscape: aClass comment), '!';lf].\x0a    aStream lf",
 messageSends: ["nextPutAll:", "classNameFor:", "superclass", ",", "lf", "do:separatedBy:", "instanceVariableNames", "category", "ifTrue:", "chunkEscape:", "comment", "notEmpty"],
@@ -455,23 +478,25 @@ selector: "exportMetaDefinitionOf:on:",
 category: 'not yet classified',
 fn: function (aClass,aStream){
 var self=this;
-var $1,$2,$3;
-$1=smalltalk.send(smalltalk.send(smalltalk.send(aClass,"_class",[]),"_instanceVariableNames",[]),"_isEmpty",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5;
+$1=_st(_st(_st(aClass)._class())._instanceVariableNames())._isEmpty();
 if(! smalltalk.assert($1)){
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(self,"_classNameFor_",[smalltalk.send(aClass,"_class",[])])]);
-$2=smalltalk.send(aStream,"_nextPutAll_",[" instanceVariableNames: '"]);
-$2;
-smalltalk.send(smalltalk.send(smalltalk.send(aClass,"_class",[]),"_instanceVariableNames",[]),"_do_separatedBy_",[(function(each){
-return smalltalk.send(aStream,"_nextPutAll_",[each]);
-}),(function(){
-return smalltalk.send(aStream,"_nextPutAll_",[" "]);
-})]);
-smalltalk.send(aStream,"_nextPutAll_",["'!"]);
-smalltalk.send(aStream,"_lf",[]);
-$3=smalltalk.send(aStream,"_lf",[]);
+$2=aStream;
+_st($2)._nextPutAll_(_st(self)._classNameFor_(_st(aClass)._class()));
+$3=_st($2)._nextPutAll_(" instanceVariableNames: '");
 $3;
+_st(_st(_st(aClass)._class())._instanceVariableNames())._do_separatedBy_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(each);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(" ");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$4=aStream;
+_st($4)._nextPutAll_("'!");
+_st($4)._lf();
+$5=_st($4)._lf();
+$5;
 };
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"exportMetaDefinitionOf:on:",{aClass:aClass,aStream:aStream}, smalltalk.ChunkExporter)})},
 args: ["aClass", "aStream"],
 source: "exportMetaDefinitionOf: aClass on: aStream\x0a\x0a\x09aClass class instanceVariableNames isEmpty ifFalse: [\x0a\x09\x09aStream \x0a\x09\x09    nextPutAll: (self classNameFor: aClass class);\x0a\x09\x09    nextPutAll: ' instanceVariableNames: '''.\x0a\x09\x09aClass class instanceVariableNames \x0a\x09\x09    do: [:each | aStream nextPutAll: each]\x0a\x09\x09    separatedBy: [aStream nextPutAll: ' '].\x0a\x09\x09aStream\x09\x0a\x09\x09    nextPutAll: '''!'; lf; lf]",
 messageSends: ["ifFalse:", "nextPutAll:", "classNameFor:", "class", "do:separatedBy:", "instanceVariableNames", "lf", "isEmpty"],
@@ -486,13 +511,14 @@ selector: "exportMethod:of:on:",
 category: 'not yet classified',
 fn: function (aMethod,aClass,aStream){
 var self=this;
-var $1;
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(self,"_chunkEscape_",[smalltalk.send(aMethod,"_source",[])])]);
-smalltalk.send(aStream,"_lf",[]);
-$1=smalltalk.send(aStream,"_nextPutAll_",["!"]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=aStream;
+_st($1)._lf();
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(self)._chunkEscape_(_st(aMethod)._source()));
+_st($1)._lf();
+$2=_st($1)._nextPutAll_("!");
+return self}, function($ctx1) {$ctx1.fill(self,"exportMethod:of:on:",{aMethod:aMethod,aClass:aClass,aStream:aStream}, smalltalk.ChunkExporter)})},
 args: ["aMethod", "aClass", "aStream"],
 source: "exportMethod: aMethod of: aClass on: aStream\x0a\x09aStream \x0a\x09\x09lf; lf; nextPutAll: (self chunkEscape: aMethod source); lf;\x0a\x09\x09nextPutAll: '!'",
 messageSends: ["lf", "nextPutAll:", "chunkEscape:", "source"],
@@ -507,18 +533,20 @@ selector: "exportMethods:category:of:on:",
 category: 'not yet classified',
 fn: function (methods,category,aClass,aStream){
 var self=this;
-var $1,$2;
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("!","__comma",[smalltalk.send(self,"_classNameFor_",[aClass])])]);
-$1=smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(" methodsFor: '","__comma",[category]),"__comma",["'!"])]);
-smalltalk.send(smalltalk.send(methods,"_sorted_",[(function(a,b){
-return smalltalk.send(smalltalk.send(a,"_selector",[]),"__lt_eq",[smalltalk.send(b,"_selector",[])]);
-})]),"_do_",[(function(each){
-return smalltalk.send(self,"_exportMethod_of_on_",[each,aClass,aStream]);
-})]);
-smalltalk.send(aStream,"_nextPutAll_",[" !"]);
-smalltalk.send(aStream,"_lf",[]);
-$2=smalltalk.send(aStream,"_lf",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+$1=aStream;
+_st($1)._nextPutAll_(_st("!").__comma(_st(self)._classNameFor_(aClass)));
+$2=_st($1)._nextPutAll_(_st(_st(" methodsFor: '").__comma(category)).__comma("'!"));
+_st(_st(methods)._sorted_((function(a,b){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
+}, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._exportMethod_of_on_(each,aClass,aStream);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+$3=aStream;
+_st($3)._nextPutAll_(" !");
+_st($3)._lf();
+$4=_st($3)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportMethods:category:of:on:",{methods:methods,category:category,aClass:aClass,aStream:aStream}, smalltalk.ChunkExporter)})},
 args: ["methods", "category", "aClass", "aStream"],
 source: "exportMethods: methods category: category of: aClass on: aStream\x0a\x09\x22Issue #143: sort methods alphabetically\x22\x0a\x0a\x09aStream\x0a\x09\x09nextPutAll: '!', (self classNameFor: aClass);\x0a\x09\x09nextPutAll: ' methodsFor: ''', category, '''!'.\x0a\x09\x09(methods sorted: [:a :b | a selector <= b selector]) do: [:each |\x0a\x09\x09\x09\x09self exportMethod: each of: aClass on: aStream].\x0a\x09aStream nextPutAll: ' !'; lf; lf",
 messageSends: ["nextPutAll:", ",", "classNameFor:", "do:", "exportMethod:of:on:", "sorted:", "<=", "selector", "lf"],
@@ -533,24 +561,26 @@ selector: "exportMethodsOf:on:",
 category: 'not yet classified',
 fn: function (aClass,aStream){
 var self=this;
-var $1;
 var map;
-map=smalltalk.send((smalltalk.Dictionary || Dictionary),"_new",[]);
-smalltalk.send(aClass,"_protocolsDo_",[(function(category,methods){
-$1=smalltalk.send(category,"_match_",["^\x5c*"]);
-if(! smalltalk.assert($1)){
-return smalltalk.send(map,"_at_put_",[category,methods]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
+map=_st((smalltalk.Dictionary || Dictionary))._new();
+$1=aClass;
+$2=(function(category,methods){
+return smalltalk.withContext(function($ctx2) {
$3=_st(category)._match_("^\x5c*");
+if(! smalltalk.assert($3)){
+return _st(map)._at_put_(category,methods);
 };
-})]);
-smalltalk.send(smalltalk.send(smalltalk.send(map,"_keys",[]),"_sorted_",[(function(a,b){
-return smalltalk.send(a,"__lt_eq",[b]);
-})]),"_do_",[(function(category){
+}, function($ctx2) {$ctx2.fillBlock({category:category,methods:methods},$ctx1)})});
+_st($1)._protocolsDo_($2);
+_st(_st(_st(map)._keys())._sorted_((function(a,b){
+return smalltalk.withContext(function($ctx2) {
return _st(a).__lt_eq(b);
+}, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(category){
 var methods;
-methods=smalltalk.send(map,"_at_",[category]);
+return smalltalk.withContext(function($ctx2) {
methods=_st(map)._at_(category);
 methods;
-return smalltalk.send(self,"_exportMethods_category_of_on_",[methods,category,aClass,aStream]);
-})]);
-return self},
+return _st(self)._exportMethods_category_of_on_(methods,category,aClass,aStream);
+}, function($ctx2) {$ctx2.fillBlock({category:category,methods:methods},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"exportMethodsOf:on:",{aClass:aClass,aStream:aStream,map:map}, smalltalk.ChunkExporter)})},
 args: ["aClass", "aStream"],
 source: "exportMethodsOf: aClass on: aStream\x0a\x09\x22Issue #143: sort protocol alphabetically\x22\x0a\x0a\x09| map |\x0a\x09map := Dictionary new.\x0a\x09aClass protocolsDo: [:category :methods | \x0a\x09\x09(category match: '^\x5c*') ifFalse: [ map at: category put: methods ]].\x0a\x09(map keys sorted: [:a :b | a <= b ]) do: [:category | | methods |\x0a\x09\x09methods := map at: category.\x0a\x09\x09self\x0a\x09\x09\x09exportMethods: methods\x0a\x09\x09\x09category: category\x0a\x09\x09\x09of: aClass\x0a\x09\x09\x09on: aStream ]",
 messageSends: ["new", "protocolsDo:", "ifFalse:", "at:put:", "match:", "do:", "at:", "exportMethods:category:of:on:", "sorted:", "<=", "keys"],
@@ -563,12 +593,13 @@ smalltalk.addMethod(
 smalltalk.method({
 selector: "exportPackageDefinitionOf:on:",
 category: 'not yet classified',
-fn: function (package,aStream){
+fn: function (package_,aStream){
 var self=this;
-var $1;
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send("Smalltalk current createPackage: '","__comma",[smalltalk.send(package,"_name",[])]),"__comma",["' properties: "]),"__comma",[smalltalk.send(smalltalk.send(package,"_properties",[]),"_storeString",[])]),"__comma",["!"])]);
-$1=smalltalk.send(aStream,"_lf",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=aStream;
+_st($1)._nextPutAll_(_st(_st(_st(_st("Smalltalk current createPackage: '").__comma(_st(package_)._name())).__comma("' properties: ")).__comma(_st(_st(package_)._properties())._storeString())).__comma("!"));
+$2=_st($1)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackageDefinitionOf:on:",{package_:package_,aStream:aStream}, smalltalk.ChunkExporter)})},
 args: ["package", "aStream"],
 source: "exportPackageDefinitionOf: package on: aStream\x0a\x09\x22Chunk format.\x22\x0a\x0a\x09aStream \x0a\x09    nextPutAll: 'Smalltalk current createPackage: ''', package name,\x0a\x09\x09''' properties: ', package properties storeString, '!'; lf.",
 messageSends: ["nextPutAll:", ",", "storeString", "properties", "name", "lf"],
@@ -581,33 +612,38 @@ smalltalk.addMethod(
 smalltalk.method({
 selector: "exportPackageExtensionsOf:on:",
 category: 'not yet classified',
-fn: function (package,aStream){
+fn: function (package_,aStream){
 var self=this;
-var $1;
-var name;
-var map;
-name=smalltalk.send(package,"_name",[]);
-smalltalk.send(smalltalk.send((smalltalk.Package || Package),"_sortedClasses_",[smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk),"_current",[]),"_classes",[])]),"_do_",[(function(each){
-return smalltalk.send([each,smalltalk.send(each,"_class",[])],"_do_",[(function(aClass){
-map=smalltalk.send((smalltalk.Dictionary || Dictionary),"_new",[]);
+var name,map;
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$5,$7,$6,$4,$2;
+name=_st(package_)._name();
+$1=_st((smalltalk.Package || Package))._sortedClasses_(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._classes());
+$2=(function(each){
+return smalltalk.withContext(function($ctx2) {
$3=[each,_st(each)._class()];
+$4=(function(aClass){
+return smalltalk.withContext(function($ctx3) {
map=_st((smalltalk.Dictionary || Dictionary))._new();
 map;
-smalltalk.send(aClass,"_protocolsDo_",[(function(category,methods){
-$1=smalltalk.send(category,"_match_",[smalltalk.send("^\x5c*","__comma",[name])]);
-if(smalltalk.assert($1)){
-return smalltalk.send(map,"_at_put_",[category,methods]);
+$5=aClass;
+$6=(function(category,methods){
+return smalltalk.withContext(function($ctx4) {
$7=_st(category)._match_(_st("^\x5c*").__comma(name));
+if(smalltalk.assert($7)){
+return _st(map)._at_put_(category,methods);
 };
-})]);
-return smalltalk.send(smalltalk.send(smalltalk.send(map,"_keys",[]),"_sorted_",[(function(a,b){
-return smalltalk.send(a,"__lt_eq",[b]);
-})]),"_do_",[(function(category){
+}, function($ctx4) {$ctx4.fillBlock({category:category,methods:methods},$ctx1)})});
+_st($5)._protocolsDo_($6);
+return _st(_st(_st(map)._keys())._sorted_((function(a,b){
+return smalltalk.withContext(function($ctx4) {
return _st(a).__lt_eq(b);
+}, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(category){
 var methods;
-methods=smalltalk.send(map,"_at_",[category]);
+return smalltalk.withContext(function($ctx4) {
methods=_st(map)._at_(category);
 methods;
-return smalltalk.send(self,"_exportMethods_category_of_on_",[methods,category,aClass,aStream]);
-})]);
-})]);
-})]);
-return self},
+return _st(self)._exportMethods_category_of_on_(methods,category,aClass,aStream);
+}, function($ctx4) {$ctx4.fillBlock({category:category,methods:methods},$ctx1)})}));
+}, function($ctx3) {$ctx3.fillBlock({aClass:aClass},$ctx1)})});
+return _st($3)._do_($4);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
+_st($1)._do_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackageExtensionsOf:on:",{package_:package_,aStream:aStream,name:name,map:map}, smalltalk.ChunkExporter)})},
 args: ["package", "aStream"],
 source: "exportPackageExtensionsOf: package on: aStream\x0a\x09\x22We need to override this one too since we need to group\x0a\x09all methods in a given protocol under a leading methodsFor: chunk\x0a\x09for that class.\x22\x0a\x0a\x09\x22Issue #143: sort protocol alphabetically\x22\x0a\x0a\x09| name map |\x0a\x09name := package name.\x0a\x09(Package sortedClasses: Smalltalk current classes) do: [:each |\x0a\x09\x09{each. each class} do: [:aClass |\x0a\x09\x09\x09map := Dictionary new.\x0a\x09\x09\x09aClass protocolsDo: [:category :methods | \x0a\x09\x09\x09\x09(category match: '^\x5c*', name) ifTrue: [ map at: category put: methods ]].\x0a\x09\x09\x09(map keys sorted: [:a :b | a <= b ]) do: [:category | | methods |\x0a\x09\x09\x09\x09methods := map at: category.\x09\x0a\x09\x09\x09\x09self exportMethods: methods category: category of: aClass on: aStream ]]]",
 messageSends: ["name", "do:", "new", "protocolsDo:", "ifTrue:", "at:put:", "match:", ",", "at:", "exportMethods:category:of:on:", "sorted:", "<=", "keys", "class", "sortedClasses:", "classes", "current"],
@@ -625,21 +661,23 @@ selector: "exportDefinitionOf:on:",
 category: 'private',
 fn: function (aClass,aStream){
 var self=this;
-var $1,$2;
-smalltalk.send(aStream,"_nextPutAll_",["smalltalk.addClass("]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("'","__comma",[smalltalk.send(self,"_classNameFor_",[aClass])]),"__comma",["', "])]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("smalltalk.","__comma",[smalltalk.send(self,"_classNameFor_",[smalltalk.send(aClass,"_superclass",[])])])]);
-$1=smalltalk.send(aStream,"_nextPutAll_",[", ["]);
-smalltalk.send(smalltalk.send(aClass,"_instanceVariableNames",[]),"_do_separatedBy_",[(function(each){
-return smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("'","__comma",[each]),"__comma",["'"])]);
-}),(function(){
-return smalltalk.send(aStream,"_nextPutAll_",[", "]);
-})]);
-smalltalk.send(aStream,"_nextPutAll_",["], '"]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(aClass,"_category",[]),"__comma",["'"])]);
-$2=smalltalk.send(aStream,"_nextPutAll_",[");"]);
-smalltalk.send(aStream,"_lf",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+$1=aStream;
+_st($1)._nextPutAll_("smalltalk.addClass(");
+_st($1)._nextPutAll_(_st(_st("'").__comma(_st(self)._classNameFor_(aClass))).__comma("', "));
+_st($1)._nextPutAll_(_st("smalltalk.").__comma(_st(self)._classNameFor_(_st(aClass)._superclass())));
+$2=_st($1)._nextPutAll_(", [");
+_st(_st(aClass)._instanceVariableNames())._do_separatedBy_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(_st(_st("'").__comma(each)).__comma("'"));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(aStream)._nextPutAll_(", ");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$3=aStream;
+_st($3)._nextPutAll_("], '");
+_st($3)._nextPutAll_(_st(_st(aClass)._category()).__comma("'"));
+$4=_st($3)._nextPutAll_(");");
+_st(aStream)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportDefinitionOf:on:",{aClass:aClass,aStream:aStream}, smalltalk.StrippedExporter)})},
 args: ["aClass", "aStream"],
 source: "exportDefinitionOf: aClass on: aStream\x0a\x09aStream \x0a\x09    nextPutAll: 'smalltalk.addClass(';\x0a\x09    nextPutAll: '''', (self classNameFor: aClass), ''', ';\x0a\x09    nextPutAll: 'smalltalk.', (self classNameFor: aClass superclass);\x0a\x09    nextPutAll: ', ['.\x0a\x09aClass instanceVariableNames \x0a\x09    do: [:each | aStream nextPutAll: '''', each, '''']\x0a\x09    separatedBy: [aStream nextPutAll: ', '].\x0a\x09aStream\x09\x0a\x09    nextPutAll: '], ''';\x0a\x09    nextPutAll: aClass category, '''';\x0a\x09    nextPutAll: ');'.\x0a\x09aStream lf",
 messageSends: ["nextPutAll:", ",", "classNameFor:", "superclass", "do:separatedBy:", "instanceVariableNames", "category", "lf"],
@@ -654,24 +692,25 @@ selector: "exportMethod:of:on:",
 category: 'private',
 fn: function (aMethod,aClass,aStream){
 var self=this;
-var $1;
-smalltalk.send(aStream,"_nextPutAll_",["smalltalk.addMethod("]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aMethod,"_selector",[]),"_asSelector",[]),"_asJavascript",[]),"__comma",[","])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",["smalltalk.method({"]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send(smalltalk.send("selector: ","__comma",[smalltalk.send(smalltalk.send(aMethod,"_selector",[]),"_asJavascript",[])]),"__comma",[","])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("fn: ","__comma",[smalltalk.send(smalltalk.send(aMethod,"_fn",[]),"_compiledSource",[])])]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",["}),"]);
-smalltalk.send(aStream,"_lf",[]);
-smalltalk.send(aStream,"_nextPutAll_",[smalltalk.send("smalltalk.","__comma",[smalltalk.send(self,"_classNameFor_",[aClass])])]);
-smalltalk.send(aStream,"_nextPutAll_",[");"]);
-smalltalk.send(aStream,"_lf",[]);
-$1=smalltalk.send(aStream,"_lf",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=aStream;
+_st($1)._nextPutAll_("smalltalk.addMethod(");
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st(_st(_st(aMethod)._selector())._asSelector())._asJavascript()).__comma(","));
+_st($1)._lf();
+_st($1)._nextPutAll_("smalltalk.method({");
+_st($1)._lf();
+_st($1)._nextPutAll_(_st(_st("selector: ").__comma(_st(_st(aMethod)._selector())._asJavascript())).__comma(","));
+_st($1)._lf();
+_st($1)._nextPutAll_(_st("fn: ").__comma(_st(_st(aMethod)._fn())._compiledSource()));
+_st($1)._lf();
+_st($1)._nextPutAll_("}),");
+_st($1)._lf();
+_st($1)._nextPutAll_(_st("smalltalk.").__comma(_st(self)._classNameFor_(aClass)));
+_st($1)._nextPutAll_(");");
+_st($1)._lf();
+$2=_st($1)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportMethod:of:on:",{aMethod:aMethod,aClass:aClass,aStream:aStream}, smalltalk.StrippedExporter)})},
 args: ["aMethod", "aClass", "aStream"],
 source: "exportMethod: aMethod of: aClass on: aStream\x0a\x09aStream \x0a\x09\x09nextPutAll: 'smalltalk.addMethod(';lf;\x0a\x09\x09nextPutAll: aMethod selector asSelector asJavascript, ',';lf;\x0a\x09\x09nextPutAll: 'smalltalk.method({';lf;\x0a\x09\x09nextPutAll: 'selector: ', aMethod selector asJavascript, ',';lf;\x0a\x09\x09nextPutAll: 'fn: ', aMethod fn compiledSource;lf;\x0a\x09\x09nextPutAll: '}),';lf;\x0a\x09\x09nextPutAll: 'smalltalk.', (self classNameFor: aClass);\x0a\x09\x09nextPutAll: ');';lf;lf",
 messageSends: ["nextPutAll:", "lf", ",", "asJavascript", "asSelector", "selector", "compiledSource", "fn", "classNameFor:"],
@@ -689,33 +728,35 @@ selector: "import:",
 category: 'fileIn',
 fn: function (aStream){
 var self=this;
-var $1;
-var chunk;
-var result;
-var parser;
-var lastEmpty;
-parser=smalltalk.send((smalltalk.ChunkParser || ChunkParser),"_on_",[aStream]);
+var chunk,result,parser,lastEmpty;
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$4,$6,$5,$2;
+parser=_st((smalltalk.ChunkParser || ChunkParser))._on_(aStream);
 lastEmpty=false;
-smalltalk.send((function(){
-chunk=smalltalk.send(parser,"_nextChunk",[]);
+$1=(function(){
+return smalltalk.withContext(function($ctx2) {
chunk=_st(parser)._nextChunk();
 chunk;
-return smalltalk.send(chunk,"_isNil",[]);
-}),"_whileFalse_",[(function(){
-$1=smalltalk.send(chunk,"_isEmpty",[]);
-if(smalltalk.assert($1)){
-lastEmpty=true;
+return _st(chunk)._isNil();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+$2=(function(){
+return smalltalk.withContext(function($ctx2) {
$3=_st(chunk)._isEmpty();
+$4=(function(){
+return smalltalk.withContext(function($ctx3) {
lastEmpty=true;
 return lastEmpty;
-} else {
-result=smalltalk.send(smalltalk.send((smalltalk.Compiler || Compiler),"_new",[]),"_evaluateExpression_",[chunk]);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
+$5=(function(){
+return smalltalk.withContext(function($ctx3) {
result=_st(_st((smalltalk.Compiler || Compiler))._new())._evaluateExpression_(chunk);
 result;
-if(smalltalk.assert(lastEmpty)){
+$6=lastEmpty;
+if(smalltalk.assert($6)){
 lastEmpty=false;
 lastEmpty;
-return smalltalk.send(result,"_scanFrom_",[parser]);
-};
+return _st(result)._scanFrom_(parser);
 };
-})]);
-return self},
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
+return _st($3)._ifTrue_ifFalse_($4,$5);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+_st($1)._whileFalse_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"import:",{aStream:aStream,chunk:chunk,result:result,parser:parser,lastEmpty:lastEmpty}, smalltalk.Importer)})},
 args: ["aStream"],
 source: "import: aStream\x0a    | chunk result parser lastEmpty |\x0a    parser := ChunkParser on: aStream.\x0a    lastEmpty := false.\x0a    [chunk := parser nextChunk.\x0a     chunk isNil] whileFalse: [\x0a        chunk isEmpty\x0a       \x09\x09ifTrue: [lastEmpty := true]\x0a       \x09\x09ifFalse: [\x0a        \x09\x09result := Compiler new evaluateExpression: chunk.\x0a        \x09\x09lastEmpty \x0a            \x09\x09\x09ifTrue: [\x0a                                  \x09lastEmpty := false.\x0a                                  \x09result scanFrom: parser]]]",
 messageSends: ["on:", "whileFalse:", "ifTrue:ifFalse:", "evaluateExpression:", "new", "ifTrue:", "scanFrom:", "isEmpty", "nextChunk", "isNil"],
@@ -730,22 +771,18 @@ smalltalk.addMethod(
 "_initializePackageNamed_prefix_",
 smalltalk.method({
 selector: "initializePackageNamed:prefix:",
-category: 'not yet classified',
+category: 'laoding',
 fn: function (packageName,aString){
 var self=this;
-var $1,$2;
-smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Package || Package),"_named_",[packageName]),"_classes",[]),"_do_",[(function(each){
-smalltalk.init(each);
-;
-return smalltalk.send(each,"_initialize",[]);
-})]);
-$1=smalltalk.send((smalltalk.Package || Package),"_named_",[packageName]);
-smalltalk.send($1,"_commitPathJs_",[smalltalk.send(smalltalk.send("/","__comma",[aString]),"__comma",["/js"])]);
-$2=smalltalk.send($1,"_commitPathSt_",[smalltalk.send(smalltalk.send("/","__comma",[aString]),"__comma",["/st"])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st((smalltalk.Package || Package))._named_(packageName);
+_st($1)._setupClasses();
+_st($1)._commitPathJs_(_st(_st("/").__comma(aString)).__comma("/js"));
+$2=_st($1)._commitPathSt_(_st(_st("/").__comma(aString)).__comma("/st"));
+return self}, function($ctx1) {$ctx1.fill(self,"initializePackageNamed:prefix:",{packageName:packageName,aString:aString}, smalltalk.PackageLoader)})},
 args: ["packageName", "aString"],
-source: "initializePackageNamed: packageName prefix: aString\x0a\x0a\x09(Package named: packageName) classes do: [ :each |\x0a    \x09<smalltalk.init(each)>.\x0a        each initialize. ].\x0a        \x0a    (Package named: packageName) \x0a    \x09commitPathJs: '/', aString, '/js';\x0a        commitPathSt: '/', aString, '/st'",
-messageSends: ["do:", "initialize", "classes", "named:", "commitPathJs:", ",", "commitPathSt:"],
+source: "initializePackageNamed: packageName prefix: aString\x0a\x0a\x09(Package named: packageName) \x0a    \x09setupClasses;\x0a        commitPathJs: '/', aString, '/js';\x0a        commitPathSt: '/', aString, '/st'",
+messageSends: ["setupClasses", "named:", "commitPathJs:", ",", "commitPathSt:"],
 referencedClasses: ["Package"]
 }),
 smalltalk.PackageLoader);
@@ -754,21 +791,28 @@ smalltalk.addMethod(
 "_loadPackage_prefix_",
 smalltalk.method({
 selector: "loadPackage:prefix:",
-category: 'not yet classified',
+category: 'laoding',
 fn: function (packageName,aString){
 var self=this;
-var $1;
 var url;
-url=smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send("/","__comma",[aString]),"__comma",["/js/"]),"__comma",[packageName]),"__comma",[".js"]);
-smalltalk.send(jQuery,"_ajax_options_",[url,smalltalk.HashedCollection._fromPairs_([smalltalk.send("type","__minus_gt",["GET"]),smalltalk.send("dataType","__minus_gt",["script"]),smalltalk.send("complete","__minus_gt",[(function(jqXHR,textStatus){
-$1=smalltalk.send(smalltalk.send(jqXHR,"_readyState",[]),"__eq",[(4)]);
-if(smalltalk.assert($1)){
-return smalltalk.send(self,"_initializePackageNamed_prefix_",[packageName,aString]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$5,$8,$7,$6,$3;
+url=_st(_st(_st(_st("/").__comma(aString)).__comma("/js/")).__comma(packageName)).__comma(".js");
+$1=jQuery;
+$2=url;
+$4=_st("type").__minus_gt("GET");
+$5=_st("dataType").__minus_gt("script");
+$7=(function(jqXHR,textStatus){
+return smalltalk.withContext(function($ctx2) {
$8=_st(_st(jqXHR)._readyState()).__eq((4));
+if(smalltalk.assert($8)){
+return _st(self)._initializePackageNamed_prefix_(packageName,aString);
 };
-})]),smalltalk.send("error","__minus_gt",[(function(){
-return smalltalk.send(window,"_alert_",[smalltalk.send("Could not load package at:  ","__comma",[url])]);
-})])])]);
-return self},
+}, function($ctx2) {$ctx2.fillBlock({jqXHR:jqXHR,textStatus:textStatus},$ctx1)})});
+$6=_st("complete").__minus_gt($7);
+$3=smalltalk.HashedCollection._fromPairs_([$4,$5,$6,_st("error").__minus_gt((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(window)._alert_(_st("Could not load package at:  ").__comma(url));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))]);
+_st($1)._ajax_options_($2,$3);
+return self}, function($ctx1) {$ctx1.fill(self,"loadPackage:prefix:",{packageName:packageName,aString:aString,url:url}, smalltalk.PackageLoader)})},
 args: ["packageName", "aString"],
 source: "loadPackage: packageName prefix: aString\x09\x0a\x09| url |\x0a    url := '/', aString, '/js/', packageName, '.js'.\x0a\x09jQuery \x0a\x09\x09ajax: url\x0a        options: #{\x0a\x09\x09\x09'type' -> 'GET'.\x0a\x09\x09\x09'dataType' -> 'script'.\x0a    \x09\x09'complete' -> [ :jqXHR :textStatus | \x0a\x09\x09\x09\x09jqXHR readyState = 4 \x0a                \x09ifTrue: [ self initializePackageNamed: packageName prefix: aString ] ].\x0a\x09\x09\x09'error' -> [ window alert: 'Could not load package at:  ', url ]\x0a\x09\x09}",
 messageSends: [",", "ajax:options:", "->", "ifTrue:", "initializePackageNamed:prefix:", "=", "readyState", "alert:"],
@@ -780,13 +824,13 @@ smalltalk.addMethod(
 "_loadPackages_prefix_",
 smalltalk.method({
 selector: "loadPackages:prefix:",
-category: 'not yet classified',
+category: 'laoding',
 fn: function (aCollection,aString){
 var self=this;
-smalltalk.send(aCollection,"_do_",[(function(each){
-return smalltalk.send(self,"_loadPackage_prefix_",[each,aString]);
-})]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(aCollection)._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._loadPackage_prefix_(each,aString);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"loadPackages:prefix:",{aCollection:aCollection,aString:aString}, smalltalk.PackageLoader)})},
 args: ["aCollection", "aString"],
 source: "loadPackages: aCollection prefix: aString\x0a\x09aCollection do: [ :each |\x0a    \x09self loadPackage: each prefix: aString ]",
 messageSends: ["do:", "loadPackage:prefix:"],
@@ -802,10 +846,10 @@ selector: "loadPackages:prefix:",
 category: 'not yet classified',
 fn: function (aCollection,aString){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(self,"_new",[]),"_loadPackages_prefix_",[aCollection,aString]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._new())._loadPackages_prefix_(aCollection,aString);
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"loadPackages:prefix:",{aCollection:aCollection,aString:aString}, smalltalk.PackageLoader.klass)})},
 args: ["aCollection", "aString"],
 source: "loadPackages: aCollection prefix: aString\x0a\x09^ self new loadPackages: aCollection prefix: aString",
 messageSends: ["loadPackages:prefix:", "new"],

+ 53 - 44
js/Kernel-Announcements.deploy.js

@@ -6,8 +6,10 @@ smalltalk.method({
 selector: "announcementClass",
 fn: function (){
 var self=this;
-return self["@announcementClass"];
-}
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@announcementClass"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"announcementClass",{}, smalltalk.AnnouncementSubscription)})}
 }),
 smalltalk.AnnouncementSubscription);
 
@@ -17,8 +19,8 @@ smalltalk.method({
 selector: "announcementClass:",
 fn: function (aClass){
 var self=this;
-self["@announcementClass"]=aClass;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@announcementClass"]=aClass;
+return self}, function($ctx1) {$ctx1.fill(self,"announcementClass:",{aClass:aClass}, smalltalk.AnnouncementSubscription)})}
 }),
 smalltalk.AnnouncementSubscription);
 
@@ -28,8 +30,10 @@ smalltalk.method({
 selector: "block",
 fn: function (){
 var self=this;
-return self["@block"];
-}
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@block"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"block",{}, smalltalk.AnnouncementSubscription)})}
 }),
 smalltalk.AnnouncementSubscription);
 
@@ -39,8 +43,8 @@ smalltalk.method({
 selector: "block:",
 fn: function (aBlock){
 var self=this;
-self["@block"]=aBlock;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@block"]=aBlock;
+return self}, function($ctx1) {$ctx1.fill(self,"block:",{aBlock:aBlock}, smalltalk.AnnouncementSubscription)})}
 }),
 smalltalk.AnnouncementSubscription);
 
@@ -50,12 +54,12 @@ smalltalk.method({
 selector: "deliver:",
 fn: function (anAnnouncement){
 var self=this;
-var $1;
-$1=smalltalk.send(self,"_handlesAnnouncement_",[anAnnouncement]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(self)._handlesAnnouncement_(anAnnouncement);
 if(smalltalk.assert($1)){
-smalltalk.send(smalltalk.send(self,"_block",[]),"_value_",[anAnnouncement]);
+_st(_st(self)._block())._value_(anAnnouncement);
 };
-return self}
+return self}, function($ctx1) {$ctx1.fill(self,"deliver:",{anAnnouncement:anAnnouncement}, smalltalk.AnnouncementSubscription)})}
 }),
 smalltalk.AnnouncementSubscription);
 
@@ -65,10 +69,10 @@ smalltalk.method({
 selector: "handlesAnnouncement:",
 fn: function (anAnnouncement){
 var self=this;
-var $1;
-$1=smalltalk.send(anAnnouncement,"_isKindOf_",[smalltalk.send(self,"_announcementClass",[])]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(anAnnouncement)._isKindOf_(_st(self)._announcementClass());
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"handlesAnnouncement:",{anAnnouncement:anAnnouncement}, smalltalk.AnnouncementSubscription)})}
 }),
 smalltalk.AnnouncementSubscription);
 
@@ -81,10 +85,10 @@ smalltalk.method({
 selector: "announce:",
 fn: function (anAnnouncement){
 var self=this;
-smalltalk.send(self["@subscriptions"],"_do_",[(function(each){
-return smalltalk.send(each,"_deliver_",[anAnnouncement]);
-})]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self["@subscriptions"])._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(each)._deliver_(anAnnouncement);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"announce:",{anAnnouncement:anAnnouncement}, smalltalk.Announcer)})}
 }),
 smalltalk.Announcer);
 
@@ -94,9 +98,9 @@ smalltalk.method({
 selector: "initialize",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_initialize",[],smalltalk.Object);
-self["@subscriptions"]=smalltalk.send((smalltalk.Array || Array),"_new",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+self["@subscriptions"]=_st((smalltalk.Array || Array))._new();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.Announcer)})}
 }),
 smalltalk.Announcer);
 
@@ -106,13 +110,13 @@ smalltalk.method({
 selector: "on:do:",
 fn: function (aClass,aBlock){
 var self=this;
-var $1,$2;
-$1=smalltalk.send((smalltalk.AnnouncementSubscription || AnnouncementSubscription),"_new",[]);
-smalltalk.send($1,"_block_",[aBlock]);
-smalltalk.send($1,"_announcementClass_",[aClass]);
-$2=smalltalk.send($1,"_yourself",[]);
-smalltalk.send(self["@subscriptions"],"_add_",[$2]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st((smalltalk.AnnouncementSubscription || AnnouncementSubscription))._new();
+_st($1)._block_(aBlock);
+_st($1)._announcementClass_(aClass);
+$2=_st($1)._yourself();
+_st(self["@subscriptions"])._add_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"on:do:",{aClass:aClass,aBlock:aBlock}, smalltalk.Announcer)})}
 }),
 smalltalk.Announcer);
 
@@ -127,15 +131,16 @@ smalltalk.method({
 selector: "current",
 fn: function (){
 var self=this;
-var $1;
-if(($receiver = self["@current"]) == nil || $receiver == undefined){
-self["@current"]=smalltalk.send(self,"_new",[],smalltalk.Announcer.klass);
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@current"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@current"]=smalltalk.Announcer.klass.fn.prototype._new.apply(_st(self), []);
 $1=self["@current"];
 } else {
-$1=self["@current"];
+$1=$2;
 };
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"current",{}, smalltalk.SystemAnnouncer.klass)})}
 }),
 smalltalk.SystemAnnouncer.klass);
 
@@ -145,8 +150,8 @@ smalltalk.method({
 selector: "new",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_shouldNotImplement",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._shouldNotImplement();
+return self}, function($ctx1) {$ctx1.fill(self,"new",{}, smalltalk.SystemAnnouncer.klass)})}
 }),
 smalltalk.SystemAnnouncer.klass);
 
@@ -158,8 +163,10 @@ smalltalk.method({
 selector: "theClass",
 fn: function (){
 var self=this;
-return self["@theClass"];
-}
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@theClass"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"theClass",{}, smalltalk.SystemAnnouncement)})}
 }),
 smalltalk.SystemAnnouncement);
 
@@ -169,8 +176,8 @@ smalltalk.method({
 selector: "theClass:",
 fn: function (aClass){
 var self=this;
-self["@theClass"]=aClass;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@theClass"]=aClass;
+return self}, function($ctx1) {$ctx1.fill(self,"theClass:",{aClass:aClass}, smalltalk.SystemAnnouncement)})}
 }),
 smalltalk.SystemAnnouncement);
 
@@ -198,8 +205,10 @@ smalltalk.method({
 selector: "method",
 fn: function (){
 var self=this;
-return self["@method"];
-}
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@method"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"method",{}, smalltalk.MethodAnnouncement)})}
 }),
 smalltalk.MethodAnnouncement);
 
@@ -209,8 +218,8 @@ smalltalk.method({
 selector: "method:",
 fn: function (aCompiledMethod){
 var self=this;
-self["@method"]=aCompiledMethod;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@method"]=aCompiledMethod;
+return self}, function($ctx1) {$ctx1.fill(self,"method:",{aCompiledMethod:aCompiledMethod}, smalltalk.MethodAnnouncement)})}
 }),
 smalltalk.MethodAnnouncement);
 

+ 53 - 44
js/Kernel-Announcements.js

@@ -7,8 +7,10 @@ selector: "announcementClass",
 category: 'accessing',
 fn: function (){
 var self=this;
-return self["@announcementClass"];
-},
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@announcementClass"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"announcementClass",{}, smalltalk.AnnouncementSubscription)})},
 args: [],
 source: "announcementClass\x0a\x09^announcementClass",
 messageSends: [],
@@ -23,8 +25,8 @@ selector: "announcementClass:",
 category: 'accessing',
 fn: function (aClass){
 var self=this;
-self["@announcementClass"]=aClass;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@announcementClass"]=aClass;
+return self}, function($ctx1) {$ctx1.fill(self,"announcementClass:",{aClass:aClass}, smalltalk.AnnouncementSubscription)})},
 args: ["aClass"],
 source: "announcementClass: aClass\x0a\x09announcementClass := aClass",
 messageSends: [],
@@ -39,8 +41,10 @@ selector: "block",
 category: 'accessing',
 fn: function (){
 var self=this;
-return self["@block"];
-},
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@block"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"block",{}, smalltalk.AnnouncementSubscription)})},
 args: [],
 source: "block\x0a\x09^block",
 messageSends: [],
@@ -55,8 +59,8 @@ selector: "block:",
 category: 'accessing',
 fn: function (aBlock){
 var self=this;
-self["@block"]=aBlock;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@block"]=aBlock;
+return self}, function($ctx1) {$ctx1.fill(self,"block:",{aBlock:aBlock}, smalltalk.AnnouncementSubscription)})},
 args: ["aBlock"],
 source: "block: aBlock\x0a\x09block := aBlock",
 messageSends: [],
@@ -71,12 +75,12 @@ selector: "deliver:",
 category: 'announcing',
 fn: function (anAnnouncement){
 var self=this;
-var $1;
-$1=smalltalk.send(self,"_handlesAnnouncement_",[anAnnouncement]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(self)._handlesAnnouncement_(anAnnouncement);
 if(smalltalk.assert($1)){
-smalltalk.send(smalltalk.send(self,"_block",[]),"_value_",[anAnnouncement]);
+_st(_st(self)._block())._value_(anAnnouncement);
 };
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"deliver:",{anAnnouncement:anAnnouncement}, smalltalk.AnnouncementSubscription)})},
 args: ["anAnnouncement"],
 source: "deliver: anAnnouncement\x0a\x09(self handlesAnnouncement: anAnnouncement)\x0a\x09\x09ifTrue: [self block value: anAnnouncement]",
 messageSends: ["ifTrue:", "value:", "block", "handlesAnnouncement:"],
@@ -91,10 +95,10 @@ selector: "handlesAnnouncement:",
 category: 'announcing',
 fn: function (anAnnouncement){
 var self=this;
-var $1;
-$1=smalltalk.send(anAnnouncement,"_isKindOf_",[smalltalk.send(self,"_announcementClass",[])]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(anAnnouncement)._isKindOf_(_st(self)._announcementClass());
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"handlesAnnouncement:",{anAnnouncement:anAnnouncement}, smalltalk.AnnouncementSubscription)})},
 args: ["anAnnouncement"],
 source: "handlesAnnouncement: anAnnouncement\x0a\x09^anAnnouncement isKindOf: self announcementClass",
 messageSends: ["isKindOf:", "announcementClass"],
@@ -112,10 +116,10 @@ selector: "announce:",
 category: 'announcing',
 fn: function (anAnnouncement){
 var self=this;
-smalltalk.send(self["@subscriptions"],"_do_",[(function(each){
-return smalltalk.send(each,"_deliver_",[anAnnouncement]);
-})]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self["@subscriptions"])._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(each)._deliver_(anAnnouncement);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"announce:",{anAnnouncement:anAnnouncement}, smalltalk.Announcer)})},
 args: ["anAnnouncement"],
 source: "announce: anAnnouncement\x0a\x09subscriptions do: [:each |\x0a\x09\x09each deliver: anAnnouncement]",
 messageSends: ["do:", "deliver:"],
@@ -130,9 +134,9 @@ selector: "initialize",
 category: 'initialization',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_initialize",[],smalltalk.Object);
-self["@subscriptions"]=smalltalk.send((smalltalk.Array || Array),"_new",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+self["@subscriptions"]=_st((smalltalk.Array || Array))._new();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.Announcer)})},
 args: [],
 source: "initialize\x0a\x09super initialize.\x0a\x09subscriptions := Array new",
 messageSends: ["initialize", "new"],
@@ -147,13 +151,13 @@ selector: "on:do:",
 category: 'subscribing',
 fn: function (aClass,aBlock){
 var self=this;
-var $1,$2;
-$1=smalltalk.send((smalltalk.AnnouncementSubscription || AnnouncementSubscription),"_new",[]);
-smalltalk.send($1,"_block_",[aBlock]);
-smalltalk.send($1,"_announcementClass_",[aClass]);
-$2=smalltalk.send($1,"_yourself",[]);
-smalltalk.send(self["@subscriptions"],"_add_",[$2]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st((smalltalk.AnnouncementSubscription || AnnouncementSubscription))._new();
+_st($1)._block_(aBlock);
+_st($1)._announcementClass_(aClass);
+$2=_st($1)._yourself();
+_st(self["@subscriptions"])._add_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"on:do:",{aClass:aClass,aBlock:aBlock}, smalltalk.Announcer)})},
 args: ["aClass", "aBlock"],
 source: "on: aClass do: aBlock\x0a\x09subscriptions add: (AnnouncementSubscription new\x0a\x09\x09block: aBlock;\x0a\x09\x09announcementClass: aClass;\x0a\x09\x09yourself)",
 messageSends: ["add:", "block:", "new", "announcementClass:", "yourself"],
@@ -174,15 +178,16 @@ selector: "current",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
-if(($receiver = self["@current"]) == nil || $receiver == undefined){
-self["@current"]=smalltalk.send(self,"_new",[],smalltalk.Announcer.klass);
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@current"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@current"]=smalltalk.Announcer.klass.fn.prototype._new.apply(_st(self), []);
 $1=self["@current"];
 } else {
-$1=self["@current"];
+$1=$2;
 };
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"current",{}, smalltalk.SystemAnnouncer.klass)})},
 args: [],
 source: "current\x0a\x09^ current ifNil: [ current := super new ]",
 messageSends: ["ifNil:", "new"],
@@ -197,8 +202,8 @@ selector: "new",
 category: 'instance creation',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_shouldNotImplement",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._shouldNotImplement();
+return self}, function($ctx1) {$ctx1.fill(self,"new",{}, smalltalk.SystemAnnouncer.klass)})},
 args: [],
 source: "new\x0a\x09self shouldNotImplement",
 messageSends: ["shouldNotImplement"],
@@ -216,8 +221,10 @@ selector: "theClass",
 category: 'accessing',
 fn: function (){
 var self=this;
-return self["@theClass"];
-},
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@theClass"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"theClass",{}, smalltalk.SystemAnnouncement)})},
 args: [],
 source: "theClass\x0a\x09^ theClass",
 messageSends: [],
@@ -232,8 +239,8 @@ selector: "theClass:",
 category: 'accessing',
 fn: function (aClass){
 var self=this;
-self["@theClass"]=aClass;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@theClass"]=aClass;
+return self}, function($ctx1) {$ctx1.fill(self,"theClass:",{aClass:aClass}, smalltalk.SystemAnnouncement)})},
 args: ["aClass"],
 source: "theClass: aClass\x0a\x09theClass := aClass",
 messageSends: [],
@@ -271,8 +278,10 @@ selector: "method",
 category: 'accessing',
 fn: function (){
 var self=this;
-return self["@method"];
-},
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@method"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"method",{}, smalltalk.MethodAnnouncement)})},
 args: [],
 source: "method\x0a\x09^ method",
 messageSends: [],
@@ -287,8 +296,8 @@ selector: "method:",
 category: 'accessing',
 fn: function (aCompiledMethod){
 var self=this;
-self["@method"]=aCompiledMethod;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@method"]=aCompiledMethod;
+return self}, function($ctx1) {$ctx1.fill(self,"method:",{aCompiledMethod:aCompiledMethod}, smalltalk.MethodAnnouncement)})},
 args: ["aCompiledMethod"],
 source: "method: aCompiledMethod\x0a\x09method := aCompiledMethod",
 messageSends: [],

Fichier diff supprimé car celui-ci est trop grand
+ 367 - 256
js/Kernel-Classes.deploy.js


Fichier diff supprimé car celui-ci est trop grand
+ 316 - 233
js/Kernel-Classes.js


Fichier diff supprimé car celui-ci est trop grand
+ 279 - 256
js/Kernel-Collections.deploy.js


Fichier diff supprimé car celui-ci est trop grand
+ 281 - 258
js/Kernel-Collections.js


+ 91 - 75
js/Kernel-Exceptions.deploy.js

@@ -6,9 +6,19 @@ smalltalk.method({
 selector: "context",
 fn: function (){
 var self=this;
-return self.context;
-;
-return self}
+return smalltalk.withContext(function($ctx1) { 
return self.context;
+return self}, function($ctx1) {$ctx1.fill(self,"context",{}, smalltalk.Error)})}
+}),
+smalltalk.Error);
+
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._messageText_(_st("Errorclass: ").__comma(_st(_st(self)._class())._name()));
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.Error)})}
 }),
 smalltalk.Error);
 
@@ -18,9 +28,8 @@ smalltalk.method({
 selector: "isSmalltalkError",
 fn: function (){
 var self=this;
-return self.smalltalkError === true;
-;
-return self}
+return smalltalk.withContext(function($ctx1) { 
return self.smalltalkError === true;
+return self}, function($ctx1) {$ctx1.fill(self,"isSmalltalkError",{}, smalltalk.Error)})}
 }),
 smalltalk.Error);
 
@@ -30,9 +39,8 @@ smalltalk.method({
 selector: "jsStack",
 fn: function (){
 var self=this;
-return self.stack;
-;
-return self}
+return smalltalk.withContext(function($ctx1) { 
return self.stack;
+return self}, function($ctx1) {$ctx1.fill(self,"jsStack",{}, smalltalk.Error)})}
 }),
 smalltalk.Error);
 
@@ -42,8 +50,10 @@ smalltalk.method({
 selector: "messageText",
 fn: function (){
 var self=this;
-return self["@messageText"];
-}
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@messageText"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"messageText",{}, smalltalk.Error)})}
 }),
 smalltalk.Error);
 
@@ -53,8 +63,8 @@ smalltalk.method({
 selector: "messageText:",
 fn: function (aString){
 var self=this;
-self["@messageText"]=aString;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@messageText"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"messageText:",{aString:aString}, smalltalk.Error)})}
 }),
 smalltalk.Error);
 
@@ -64,9 +74,8 @@ smalltalk.method({
 selector: "signal",
 fn: function (){
 var self=this;
-self.context = smalltalk.getThisContext(); self.smalltalkError = true; throw(self);
-;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self.context = smalltalk.getThisContext(); self.smalltalkError = true; throw(self);
+return self}, function($ctx1) {$ctx1.fill(self,"signal",{}, smalltalk.Error)})}
 }),
 smalltalk.Error);
 
@@ -76,9 +85,9 @@ smalltalk.method({
 selector: "signal:",
 fn: function (aString){
 var self=this;
-smalltalk.send(self,"_messageText_",[aString]);
-smalltalk.send(self,"_signal",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._messageText_(aString);
+_st(self)._signal();
+return self}, function($ctx1) {$ctx1.fill(self,"signal:",{aString:aString}, smalltalk.Error)})}
 }),
 smalltalk.Error);
 
@@ -89,10 +98,10 @@ smalltalk.method({
 selector: "signal",
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(self,"_new",[]),"_signal",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._new())._signal();
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"signal",{}, smalltalk.Error.klass)})}
 }),
 smalltalk.Error.klass);
 
@@ -102,10 +111,10 @@ smalltalk.method({
 selector: "signal:",
 fn: function (aString){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(self,"_new",[]),"_signal_",[aString]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._new())._signal_(aString);
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"signal:",{aString:aString}, smalltalk.Error.klass)})}
 }),
 smalltalk.Error.klass);
 
@@ -117,8 +126,10 @@ smalltalk.method({
 selector: "message",
 fn: function (){
 var self=this;
-return self["@message"];
-}
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@message"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"message",{}, smalltalk.MessageNotUnderstood)})}
 }),
 smalltalk.MessageNotUnderstood);
 
@@ -128,8 +139,8 @@ smalltalk.method({
 selector: "message:",
 fn: function (aMessage){
 var self=this;
-self["@message"]=aMessage;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@message"]=aMessage;
+return self}, function($ctx1) {$ctx1.fill(self,"message:",{aMessage:aMessage}, smalltalk.MessageNotUnderstood)})}
 }),
 smalltalk.MessageNotUnderstood);
 
@@ -139,10 +150,10 @@ smalltalk.method({
 selector: "messageText",
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self,"_receiver",[]),"_asString",[]),"__comma",[" does not understand #"]),"__comma",[smalltalk.send(smalltalk.send(self,"_message",[]),"_selector",[])]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(_st(_st(self)._receiver())._asString()).__comma(" does not understand #")).__comma(_st(_st(self)._message())._selector());
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"messageText",{}, smalltalk.MessageNotUnderstood)})}
 }),
 smalltalk.MessageNotUnderstood);
 
@@ -152,8 +163,10 @@ smalltalk.method({
 selector: "receiver",
 fn: function (){
 var self=this;
-return self["@receiver"];
-}
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@receiver"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"receiver",{}, smalltalk.MessageNotUnderstood)})}
 }),
 smalltalk.MessageNotUnderstood);
 
@@ -163,8 +176,8 @@ smalltalk.method({
 selector: "receiver:",
 fn: function (anObject){
 var self=this;
-self["@receiver"]=anObject;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@receiver"]=anObject;
+return self}, function($ctx1) {$ctx1.fill(self,"receiver:",{anObject:anObject}, smalltalk.MessageNotUnderstood)})}
 }),
 smalltalk.MessageNotUnderstood);
 
@@ -177,8 +190,10 @@ smalltalk.method({
 selector: "object",
 fn: function (){
 var self=this;
-return self["@object"];
-}
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@object"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"object",{}, smalltalk.NonBooleanReceiver)})}
 }),
 smalltalk.NonBooleanReceiver);
 
@@ -188,8 +203,8 @@ smalltalk.method({
 selector: "object:",
 fn: function (anObject){
 var self=this;
-self["@object"]=anObject;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@object"]=anObject;
+return self}, function($ctx1) {$ctx1.fill(self,"object:",{anObject:anObject}, smalltalk.NonBooleanReceiver)})}
 }),
 smalltalk.NonBooleanReceiver);
 
@@ -202,15 +217,15 @@ smalltalk.method({
 selector: "handleError:",
 fn: function (anError){
 var self=this;
-var $1;
-$1=smalltalk.send(anError,"_context",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(anError)._context();
 if(($receiver = $1) == nil || $receiver == undefined){
 $1;
 } else {
-smalltalk.send(self,"_logErrorContext_",[smalltalk.send(anError,"_context",[])]);
+_st(self)._logErrorContext_(_st(anError)._context());
 };
-smalltalk.send(self,"_logError_",[anError]);
-return self}
+_st(self)._logError_(anError);
+return self}, function($ctx1) {$ctx1.fill(self,"handleError:",{anError:anError}, smalltalk.ErrorHandler)})}
 }),
 smalltalk.ErrorHandler);
 
@@ -220,8 +235,8 @@ smalltalk.method({
 selector: "log:",
 fn: function (aString){
 var self=this;
-smalltalk.send(console,"_log_",[aString]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(console)._log_(aString);
+return self}, function($ctx1) {$ctx1.fill(self,"log:",{aString:aString}, smalltalk.ErrorHandler)})}
 }),
 smalltalk.ErrorHandler);
 
@@ -231,15 +246,15 @@ smalltalk.method({
 selector: "logContext:",
 fn: function (aContext){
 var self=this;
-var $1;
-$1=smalltalk.send(aContext,"_home",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(aContext)._home();
 if(($receiver = $1) == nil || $receiver == undefined){
 $1;
 } else {
-smalltalk.send(self,"_logContext_",[smalltalk.send(aContext,"_home",[])]);
+_st(self)._logContext_(_st(aContext)._home());
 };
-smalltalk.send(self,"_log_",[smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aContext,"_receiver",[]),"_asString",[]),"__comma",[">>"]),"__comma",[smalltalk.send(aContext,"_selector",[])])]);
-return self}
+_st(self)._log_(_st(_st(_st(_st(aContext)._receiver())._asString()).__comma(">>")).__comma(_st(_st(aContext)._selector())._asString()));
+return self}, function($ctx1) {$ctx1.fill(self,"logContext:",{aContext:aContext}, smalltalk.ErrorHandler)})}
 }),
 smalltalk.ErrorHandler);
 
@@ -249,8 +264,8 @@ smalltalk.method({
 selector: "logError:",
 fn: function (anError){
 var self=this;
-smalltalk.send(self,"_log_",[smalltalk.send(anError,"_messageText",[])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._log_(_st(anError)._messageText());
+return self}, function($ctx1) {$ctx1.fill(self,"logError:",{anError:anError}, smalltalk.ErrorHandler)})}
 }),
 smalltalk.ErrorHandler);
 
@@ -260,18 +275,18 @@ smalltalk.method({
 selector: "logErrorContext:",
 fn: function (aContext){
 var self=this;
-var $1;
-if(($receiver = aContext) == nil || $receiver == undefined){
-aContext;
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
+$1=aContext;
+$2=(function(){
+return smalltalk.withContext(function($ctx2) {
$3=_st(aContext)._home();
+if(($receiver = $3) == nil || $receiver == undefined){
+return $3;
 } else {
-$1=smalltalk.send(aContext,"_home",[]);
-if(($receiver = $1) == nil || $receiver == undefined){
-$1;
-} else {
-smalltalk.send(self,"_logContext_",[smalltalk.send(aContext,"_home",[])]);
+return _st(self)._logContext_(_st(aContext)._home());
 };
-};
-return self}
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+_st($1)._ifNotNil_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"logErrorContext:",{aContext:aContext}, smalltalk.ErrorHandler)})}
 }),
 smalltalk.ErrorHandler);
 
@@ -283,15 +298,16 @@ smalltalk.method({
 selector: "current",
 fn: function (){
 var self=this;
-var $1;
-if(($receiver = self["@current"]) == nil || $receiver == undefined){
-self["@current"]=smalltalk.send(self,"_new",[]);
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@current"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@current"]=_st(self)._new();
 $1=self["@current"];
 } else {
-$1=self["@current"];
+$1=$2;
 };
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"current",{}, smalltalk.ErrorHandler.klass)})}
 }),
 smalltalk.ErrorHandler.klass);
 
@@ -301,8 +317,8 @@ smalltalk.method({
 selector: "initialize",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_register",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._register();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.ErrorHandler.klass)})}
 }),
 smalltalk.ErrorHandler.klass);
 
@@ -312,8 +328,8 @@ smalltalk.method({
 selector: "register",
 fn: function (){
 var self=this;
-smalltalk.send((smalltalk.ErrorHandler || ErrorHandler),"_setCurrent_",[smalltalk.send(self,"_new",[])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st((smalltalk.ErrorHandler || ErrorHandler))._setCurrent_(_st(self)._new());
+return self}, function($ctx1) {$ctx1.fill(self,"register",{}, smalltalk.ErrorHandler.klass)})}
 }),
 smalltalk.ErrorHandler.klass);
 
@@ -323,8 +339,8 @@ smalltalk.method({
 selector: "setCurrent:",
 fn: function (anHandler){
 var self=this;
-self["@current"]=anHandler;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@current"]=anHandler;
+return self}, function($ctx1) {$ctx1.fill(self,"setCurrent:",{anHandler:anHandler}, smalltalk.ErrorHandler.klass)})}
 }),
 smalltalk.ErrorHandler.klass);
 

+ 98 - 77
js/Kernel-Exceptions.js

@@ -7,9 +7,8 @@ selector: "context",
 category: 'accessing',
 fn: function (){
 var self=this;
-return self.context;
-;
-return self},
+return smalltalk.withContext(function($ctx1) { 
return self.context;
+return self}, function($ctx1) {$ctx1.fill(self,"context",{}, smalltalk.Error)})},
 args: [],
 source: "context\x0a\x09<return self.context>",
 messageSends: [],
@@ -17,6 +16,22 @@ referencedClasses: []
 }),
 smalltalk.Error);
 
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+category: 'initialization',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._messageText_(_st("Errorclass: ").__comma(_st(_st(self)._class())._name()));
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.Error)})},
+args: [],
+source: "initialize\x0a\x09self messageText: 'Errorclass: ', (self class name).",
+messageSends: ["messageText:", ",", "name", "class"],
+referencedClasses: []
+}),
+smalltalk.Error);
+
 smalltalk.addMethod(
 "_isSmalltalkError",
 smalltalk.method({
@@ -24,9 +39,8 @@ selector: "isSmalltalkError",
 category: 'testing',
 fn: function (){
 var self=this;
-return self.smalltalkError === true;
-;
-return self},
+return smalltalk.withContext(function($ctx1) { 
return self.smalltalkError === true;
+return self}, function($ctx1) {$ctx1.fill(self,"isSmalltalkError",{}, smalltalk.Error)})},
 args: [],
 source: "isSmalltalkError\x0a\x09<return self.smalltalkError === true>",
 messageSends: [],
@@ -41,9 +55,8 @@ selector: "jsStack",
 category: 'accessing',
 fn: function (){
 var self=this;
-return self.stack;
-;
-return self},
+return smalltalk.withContext(function($ctx1) { 
return self.stack;
+return self}, function($ctx1) {$ctx1.fill(self,"jsStack",{}, smalltalk.Error)})},
 args: [],
 source: "jsStack\x0a\x09<return self.stack>",
 messageSends: [],
@@ -58,8 +71,10 @@ selector: "messageText",
 category: 'accessing',
 fn: function (){
 var self=this;
-return self["@messageText"];
-},
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@messageText"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"messageText",{}, smalltalk.Error)})},
 args: [],
 source: "messageText\x0a\x09^messageText",
 messageSends: [],
@@ -74,8 +89,8 @@ selector: "messageText:",
 category: 'accessing',
 fn: function (aString){
 var self=this;
-self["@messageText"]=aString;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@messageText"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"messageText:",{aString:aString}, smalltalk.Error)})},
 args: ["aString"],
 source: "messageText: aString\x0a\x09messageText := aString",
 messageSends: [],
@@ -90,9 +105,8 @@ selector: "signal",
 category: 'signaling',
 fn: function (){
 var self=this;
-self.context = smalltalk.getThisContext(); self.smalltalkError = true; throw(self);
-;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self.context = smalltalk.getThisContext(); self.smalltalkError = true; throw(self);
+return self}, function($ctx1) {$ctx1.fill(self,"signal",{}, smalltalk.Error)})},
 args: [],
 source: "signal\x0a\x09<self.context = smalltalk.getThisContext(); self.smalltalkError = true; throw(self)>",
 messageSends: [],
@@ -107,9 +121,9 @@ selector: "signal:",
 category: 'signaling',
 fn: function (aString){
 var self=this;
-smalltalk.send(self,"_messageText_",[aString]);
-smalltalk.send(self,"_signal",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._messageText_(aString);
+_st(self)._signal();
+return self}, function($ctx1) {$ctx1.fill(self,"signal:",{aString:aString}, smalltalk.Error)})},
 args: ["aString"],
 source: "signal: aString\x0a\x09self messageText: aString.\x0a\x09self signal",
 messageSends: ["messageText:", "signal"],
@@ -125,10 +139,10 @@ selector: "signal",
 category: 'instance creation',
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(self,"_new",[]),"_signal",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._new())._signal();
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"signal",{}, smalltalk.Error.klass)})},
 args: [],
 source: "signal\x0a\x09^self new signal",
 messageSends: ["signal", "new"],
@@ -143,10 +157,10 @@ selector: "signal:",
 category: 'instance creation',
 fn: function (aString){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(self,"_new",[]),"_signal_",[aString]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._new())._signal_(aString);
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"signal:",{aString:aString}, smalltalk.Error.klass)})},
 args: ["aString"],
 source: "signal: aString\x0a\x09    ^self new\x0a\x09\x09signal: aString",
 messageSends: ["signal:", "new"],
@@ -163,8 +177,10 @@ selector: "message",
 category: 'accessing',
 fn: function (){
 var self=this;
-return self["@message"];
-},
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@message"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"message",{}, smalltalk.MessageNotUnderstood)})},
 args: [],
 source: "message\x0a\x09^message",
 messageSends: [],
@@ -179,8 +195,8 @@ selector: "message:",
 category: 'accessing',
 fn: function (aMessage){
 var self=this;
-self["@message"]=aMessage;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@message"]=aMessage;
+return self}, function($ctx1) {$ctx1.fill(self,"message:",{aMessage:aMessage}, smalltalk.MessageNotUnderstood)})},
 args: ["aMessage"],
 source: "message: aMessage\x0a\x09message := aMessage",
 messageSends: [],
@@ -195,10 +211,10 @@ selector: "messageText",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self,"_receiver",[]),"_asString",[]),"__comma",[" does not understand #"]),"__comma",[smalltalk.send(smalltalk.send(self,"_message",[]),"_selector",[])]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(_st(_st(self)._receiver())._asString()).__comma(" does not understand #")).__comma(_st(_st(self)._message())._selector());
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"messageText",{}, smalltalk.MessageNotUnderstood)})},
 args: [],
 source: "messageText\x0a\x09^self receiver asString, ' does not understand #', self message selector",
 messageSends: [",", "selector", "message", "asString", "receiver"],
@@ -213,8 +229,10 @@ selector: "receiver",
 category: 'accessing',
 fn: function (){
 var self=this;
-return self["@receiver"];
-},
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@receiver"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"receiver",{}, smalltalk.MessageNotUnderstood)})},
 args: [],
 source: "receiver\x0a\x09^receiver",
 messageSends: [],
@@ -229,8 +247,8 @@ selector: "receiver:",
 category: 'accessing',
 fn: function (anObject){
 var self=this;
-self["@receiver"]=anObject;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@receiver"]=anObject;
+return self}, function($ctx1) {$ctx1.fill(self,"receiver:",{anObject:anObject}, smalltalk.MessageNotUnderstood)})},
 args: ["anObject"],
 source: "receiver: anObject\x0a\x09receiver := anObject",
 messageSends: [],
@@ -248,8 +266,10 @@ selector: "object",
 category: 'accessing',
 fn: function (){
 var self=this;
-return self["@object"];
-},
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@object"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"object",{}, smalltalk.NonBooleanReceiver)})},
 args: [],
 source: "object\x0a\x09^ object",
 messageSends: [],
@@ -264,8 +284,8 @@ selector: "object:",
 category: 'accessing',
 fn: function (anObject){
 var self=this;
-self["@object"]=anObject;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@object"]=anObject;
+return self}, function($ctx1) {$ctx1.fill(self,"object:",{anObject:anObject}, smalltalk.NonBooleanReceiver)})},
 args: ["anObject"],
 source: "object: anObject\x0a\x09object := anObject",
 messageSends: [],
@@ -283,15 +303,15 @@ selector: "handleError:",
 category: 'error handling',
 fn: function (anError){
 var self=this;
-var $1;
-$1=smalltalk.send(anError,"_context",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(anError)._context();
 if(($receiver = $1) == nil || $receiver == undefined){
 $1;
 } else {
-smalltalk.send(self,"_logErrorContext_",[smalltalk.send(anError,"_context",[])]);
+_st(self)._logErrorContext_(_st(anError)._context());
 };
-smalltalk.send(self,"_logError_",[anError]);
-return self},
+_st(self)._logError_(anError);
+return self}, function($ctx1) {$ctx1.fill(self,"handleError:",{anError:anError}, smalltalk.ErrorHandler)})},
 args: ["anError"],
 source: "handleError: anError\x0a\x09anError context ifNotNil: [self logErrorContext: anError context].\x0a\x09self logError: anError",
 messageSends: ["ifNotNil:", "logErrorContext:", "context", "logError:"],
@@ -306,8 +326,8 @@ selector: "log:",
 category: 'private',
 fn: function (aString){
 var self=this;
-smalltalk.send(console,"_log_",[aString]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(console)._log_(aString);
+return self}, function($ctx1) {$ctx1.fill(self,"log:",{aString:aString}, smalltalk.ErrorHandler)})},
 args: ["aString"],
 source: "log: aString\x0a\x09console log: aString",
 messageSends: ["log:"],
@@ -322,18 +342,18 @@ selector: "logContext:",
 category: 'private',
 fn: function (aContext){
 var self=this;
-var $1;
-$1=smalltalk.send(aContext,"_home",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(aContext)._home();
 if(($receiver = $1) == nil || $receiver == undefined){
 $1;
 } else {
-smalltalk.send(self,"_logContext_",[smalltalk.send(aContext,"_home",[])]);
+_st(self)._logContext_(_st(aContext)._home());
 };
-smalltalk.send(self,"_log_",[smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aContext,"_receiver",[]),"_asString",[]),"__comma",[">>"]),"__comma",[smalltalk.send(aContext,"_selector",[])])]);
-return self},
+_st(self)._log_(_st(_st(_st(_st(aContext)._receiver())._asString()).__comma(">>")).__comma(_st(_st(aContext)._selector())._asString()));
+return self}, function($ctx1) {$ctx1.fill(self,"logContext:",{aContext:aContext}, smalltalk.ErrorHandler)})},
 args: ["aContext"],
-source: "logContext: aContext\x0a\x09aContext home ifNotNil: [\x0a\x09\x09self logContext: aContext home].\x0a\x09self log: aContext receiver asString, '>>', aContext selector",
-messageSends: ["ifNotNil:", "logContext:", "home", "log:", ",", "selector", "asString", "receiver"],
+source: "logContext: aContext\x0a\x09aContext home ifNotNil: [\x0a\x09\x09self logContext: aContext home].\x0a\x09self log: aContext receiver asString, '>>', aContext selector asString",
+messageSends: ["ifNotNil:", "logContext:", "home", "log:", ",", "asString", "selector", "receiver"],
 referencedClasses: []
 }),
 smalltalk.ErrorHandler);
@@ -345,8 +365,8 @@ selector: "logError:",
 category: 'private',
 fn: function (anError){
 var self=this;
-smalltalk.send(self,"_log_",[smalltalk.send(anError,"_messageText",[])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._log_(_st(anError)._messageText());
+return self}, function($ctx1) {$ctx1.fill(self,"logError:",{anError:anError}, smalltalk.ErrorHandler)})},
 args: ["anError"],
 source: "logError: anError\x0a\x09self log: anError messageText",
 messageSends: ["log:", "messageText"],
@@ -361,18 +381,18 @@ selector: "logErrorContext:",
 category: 'private',
 fn: function (aContext){
 var self=this;
-var $1;
-if(($receiver = aContext) == nil || $receiver == undefined){
-aContext;
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
+$1=aContext;
+$2=(function(){
+return smalltalk.withContext(function($ctx2) {
$3=_st(aContext)._home();
+if(($receiver = $3) == nil || $receiver == undefined){
+return $3;
 } else {
-$1=smalltalk.send(aContext,"_home",[]);
-if(($receiver = $1) == nil || $receiver == undefined){
-$1;
-} else {
-smalltalk.send(self,"_logContext_",[smalltalk.send(aContext,"_home",[])]);
+return _st(self)._logContext_(_st(aContext)._home());
 };
-};
-return self},
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+_st($1)._ifNotNil_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"logErrorContext:",{aContext:aContext}, smalltalk.ErrorHandler)})},
 args: ["aContext"],
 source: "logErrorContext: aContext\x0a\x09aContext ifNotNil: [\x0a\x09\x09aContext home ifNotNil: [\x0a\x09\x09\x09self logContext: aContext home]]",
 messageSends: ["ifNotNil:", "logContext:", "home"],
@@ -389,15 +409,16 @@ selector: "current",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
-if(($receiver = self["@current"]) == nil || $receiver == undefined){
-self["@current"]=smalltalk.send(self,"_new",[]);
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@current"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@current"]=_st(self)._new();
 $1=self["@current"];
 } else {
-$1=self["@current"];
+$1=$2;
 };
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"current",{}, smalltalk.ErrorHandler.klass)})},
 args: [],
 source: "current\x0a\x09^current ifNil: [current := self new]",
 messageSends: ["ifNil:", "new"],
@@ -412,8 +433,8 @@ selector: "initialize",
 category: 'initialization',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_register",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._register();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.ErrorHandler.klass)})},
 args: [],
 source: "initialize\x0a\x09self register",
 messageSends: ["register"],
@@ -428,8 +449,8 @@ selector: "register",
 category: 'initialization',
 fn: function (){
 var self=this;
-smalltalk.send((smalltalk.ErrorHandler || ErrorHandler),"_setCurrent_",[smalltalk.send(self,"_new",[])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st((smalltalk.ErrorHandler || ErrorHandler))._setCurrent_(_st(self)._new());
+return self}, function($ctx1) {$ctx1.fill(self,"register",{}, smalltalk.ErrorHandler.klass)})},
 args: [],
 source: "register\x0a\x09ErrorHandler setCurrent: self new",
 messageSends: ["setCurrent:", "new"],
@@ -444,8 +465,8 @@ selector: "setCurrent:",
 category: 'accessing',
 fn: function (anHandler){
 var self=this;
-self["@current"]=anHandler;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@current"]=anHandler;
+return self}, function($ctx1) {$ctx1.fill(self,"setCurrent:",{anHandler:anHandler}, smalltalk.ErrorHandler.klass)})},
 args: ["anHandler"],
 source: "setCurrent: anHandler\x0a\x09current := anHandler",
 messageSends: [],

Fichier diff supprimé car celui-ci est trop grand
+ 355 - 290
js/Kernel-Methods.deploy.js


Fichier diff supprimé car celui-ci est trop grand
+ 388 - 298
js/Kernel-Methods.js


Fichier diff supprimé car celui-ci est trop grand
+ 333 - 324
js/Kernel-Objects.deploy.js


Fichier diff supprimé car celui-ci est trop grand
+ 332 - 311
js/Kernel-Objects.js


Fichier diff supprimé car celui-ci est trop grand
+ 380 - 315
js/Kernel-Tests.deploy.js


Fichier diff supprimé car celui-ci est trop grand
+ 385 - 315
js/Kernel-Tests.js


+ 23 - 24
js/Kernel-Transcript.deploy.js

@@ -6,7 +6,7 @@ smalltalk.method({
 selector: "clear",
 fn: function (){
 var self=this;
-return self}
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"clear",{}, smalltalk.ConsoleTranscript)})}
 }),
 smalltalk.ConsoleTranscript);
 
@@ -16,7 +16,7 @@ smalltalk.method({
 selector: "cr",
 fn: function (){
 var self=this;
-return self}
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"cr",{}, smalltalk.ConsoleTranscript)})}
 }),
 smalltalk.ConsoleTranscript);
 
@@ -26,7 +26,7 @@ smalltalk.method({
 selector: "open",
 fn: function (){
 var self=this;
-return self}
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"open",{}, smalltalk.ConsoleTranscript)})}
 }),
 smalltalk.ConsoleTranscript);
 
@@ -36,11 +36,8 @@ smalltalk.method({
 selector: "show:",
 fn: function (anObject){
 var self=this;
-var string;
-string=smalltalk.send(anObject,"_asString",[]);
-console.log(String(string));
-;
-return self}
+return smalltalk.withContext(function($ctx1) { 
console.log(String(string._asString()));
+return self}, function($ctx1) {$ctx1.fill(self,"show:",{anObject:anObject}, smalltalk.ConsoleTranscript)})}
 }),
 smalltalk.ConsoleTranscript);
 
@@ -51,8 +48,8 @@ smalltalk.method({
 selector: "initialize",
 fn: function (){
 var self=this;
-smalltalk.send((smalltalk.Transcript || Transcript),"_register_",[smalltalk.send(self,"_new",[])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st((smalltalk.Transcript || Transcript))._register_(_st(self)._new());
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.ConsoleTranscript.klass)})}
 }),
 smalltalk.ConsoleTranscript.klass);
 
@@ -66,8 +63,8 @@ smalltalk.method({
 selector: "clear",
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send(self,"_current",[]),"_clear",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._current())._clear();
+return self}, function($ctx1) {$ctx1.fill(self,"clear",{}, smalltalk.Transcript.klass)})}
 }),
 smalltalk.Transcript.klass);
 
@@ -77,8 +74,8 @@ smalltalk.method({
 selector: "cr",
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send(self,"_current",[]),"_show_",[smalltalk.send((smalltalk.String || String),"_cr",[])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._current())._show_(_st((smalltalk.String || String))._cr());
+return self}, function($ctx1) {$ctx1.fill(self,"cr",{}, smalltalk.Transcript.klass)})}
 }),
 smalltalk.Transcript.klass);
 
@@ -88,8 +85,10 @@ smalltalk.method({
 selector: "current",
 fn: function (){
 var self=this;
-return self["@current"];
-}
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@current"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"current",{}, smalltalk.Transcript.klass)})}
 }),
 smalltalk.Transcript.klass);
 
@@ -99,8 +98,8 @@ smalltalk.method({
 selector: "new",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_shouldNotImplement",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._shouldNotImplement();
+return self}, function($ctx1) {$ctx1.fill(self,"new",{}, smalltalk.Transcript.klass)})}
 }),
 smalltalk.Transcript.klass);
 
@@ -110,8 +109,8 @@ smalltalk.method({
 selector: "open",
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send(self,"_current",[]),"_open",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._current())._open();
+return self}, function($ctx1) {$ctx1.fill(self,"open",{}, smalltalk.Transcript.klass)})}
 }),
 smalltalk.Transcript.klass);
 
@@ -121,8 +120,8 @@ smalltalk.method({
 selector: "register:",
 fn: function (aTranscript){
 var self=this;
-self["@current"]=aTranscript;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@current"]=aTranscript;
+return self}, function($ctx1) {$ctx1.fill(self,"register:",{aTranscript:aTranscript}, smalltalk.Transcript.klass)})}
 }),
 smalltalk.Transcript.klass);
 
@@ -132,8 +131,8 @@ smalltalk.method({
 selector: "show:",
 fn: function (anObject){
 var self=this;
-smalltalk.send(smalltalk.send(self,"_current",[]),"_show_",[anObject]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._current())._show_(anObject);
+return self}, function($ctx1) {$ctx1.fill(self,"show:",{anObject:anObject}, smalltalk.Transcript.klass)})}
 }),
 smalltalk.Transcript.klass);
 

+ 25 - 26
js/Kernel-Transcript.js

@@ -7,7 +7,7 @@ selector: "clear",
 category: 'printing',
 fn: function (){
 var self=this;
-return self},
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"clear",{}, smalltalk.ConsoleTranscript)})},
 args: [],
 source: "clear\x0a\x09\x22no op\x22",
 messageSends: [],
@@ -22,7 +22,7 @@ selector: "cr",
 category: 'printing',
 fn: function (){
 var self=this;
-return self},
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"cr",{}, smalltalk.ConsoleTranscript)})},
 args: [],
 source: "cr\x0a\x09\x22no op\x22",
 messageSends: [],
@@ -37,7 +37,7 @@ selector: "open",
 category: 'actions',
 fn: function (){
 var self=this;
-return self},
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"open",{}, smalltalk.ConsoleTranscript)})},
 args: [],
 source: "open",
 messageSends: [],
@@ -52,14 +52,11 @@ selector: "show:",
 category: 'printing',
 fn: function (anObject){
 var self=this;
-var string;
-string=smalltalk.send(anObject,"_asString",[]);
-console.log(String(string));
-;
-return self},
+return smalltalk.withContext(function($ctx1) { 
console.log(String(string._asString()));
+return self}, function($ctx1) {$ctx1.fill(self,"show:",{anObject:anObject}, smalltalk.ConsoleTranscript)})},
 args: ["anObject"],
-source: "show: anObject\x0a\x09| string |\x0a\x09string := anObject asString.\x0a\x09<console.log(String(string))>",
-messageSends: ["asString"],
+source: "show: anObject\x0a\x09<console.log(String(string._asString()))>",
+messageSends: [],
 referencedClasses: []
 }),
 smalltalk.ConsoleTranscript);
@@ -72,8 +69,8 @@ selector: "initialize",
 category: 'initialization',
 fn: function (){
 var self=this;
-smalltalk.send((smalltalk.Transcript || Transcript),"_register_",[smalltalk.send(self,"_new",[])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st((smalltalk.Transcript || Transcript))._register_(_st(self)._new());
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.ConsoleTranscript.klass)})},
 args: [],
 source: "initialize\x0a\x09Transcript register: self new",
 messageSends: ["register:", "new"],
@@ -92,8 +89,8 @@ selector: "clear",
 category: 'printing',
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send(self,"_current",[]),"_clear",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._current())._clear();
+return self}, function($ctx1) {$ctx1.fill(self,"clear",{}, smalltalk.Transcript.klass)})},
 args: [],
 source: "clear\x0a    self current clear",
 messageSends: ["clear", "current"],
@@ -108,8 +105,8 @@ selector: "cr",
 category: 'printing',
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send(self,"_current",[]),"_show_",[smalltalk.send((smalltalk.String || String),"_cr",[])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._current())._show_(_st((smalltalk.String || String))._cr());
+return self}, function($ctx1) {$ctx1.fill(self,"cr",{}, smalltalk.Transcript.klass)})},
 args: [],
 source: "cr\x0a    self current show: String cr",
 messageSends: ["show:", "cr", "current"],
@@ -124,8 +121,10 @@ selector: "current",
 category: 'instance creation',
 fn: function (){
 var self=this;
-return self["@current"];
-},
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@current"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"current",{}, smalltalk.Transcript.klass)})},
 args: [],
 source: "current\x0a    ^current",
 messageSends: [],
@@ -140,8 +139,8 @@ selector: "new",
 category: 'instance creation',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_shouldNotImplement",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._shouldNotImplement();
+return self}, function($ctx1) {$ctx1.fill(self,"new",{}, smalltalk.Transcript.klass)})},
 args: [],
 source: "new\x0a    self shouldNotImplement",
 messageSends: ["shouldNotImplement"],
@@ -156,8 +155,8 @@ selector: "open",
 category: 'instance creation',
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send(self,"_current",[]),"_open",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._current())._open();
+return self}, function($ctx1) {$ctx1.fill(self,"open",{}, smalltalk.Transcript.klass)})},
 args: [],
 source: "open\x0a    self current open",
 messageSends: ["open", "current"],
@@ -172,8 +171,8 @@ selector: "register:",
 category: 'instance creation',
 fn: function (aTranscript){
 var self=this;
-self["@current"]=aTranscript;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@current"]=aTranscript;
+return self}, function($ctx1) {$ctx1.fill(self,"register:",{aTranscript:aTranscript}, smalltalk.Transcript.klass)})},
 args: ["aTranscript"],
 source: "register: aTranscript\x0a\x09current := aTranscript",
 messageSends: [],
@@ -188,8 +187,8 @@ selector: "show:",
 category: 'printing',
 fn: function (anObject){
 var self=this;
-smalltalk.send(smalltalk.send(self,"_current",[]),"_show_",[anObject]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._current())._show_(anObject);
+return self}, function($ctx1) {$ctx1.fill(self,"show:",{anObject:anObject}, smalltalk.Transcript.klass)})},
 args: ["anObject"],
 source: "show: anObject\x0a    self current show: anObject",
 messageSends: ["show:", "current"],

+ 169 - 175
js/SUnit-Tests.deploy.js

@@ -6,9 +6,9 @@ smalltalk.method({
 selector: "setUp",
 fn: function (){
 var self=this;
-self["@empty"]=smalltalk.send((smalltalk.Set || Set),"_new",[]);
-self["@full"]=smalltalk.send((smalltalk.Set || Set),"_with_with_",[(5),smalltalk.symbolFor("abc")]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@empty"]=_st((smalltalk.Set || Set))._new();
+self["@full"]=_st((smalltalk.Set || Set))._with_with_((5),smalltalk.symbolFor("abc"));
+return self}, function($ctx1) {$ctx1.fill(self,"setUp",{}, smalltalk.ExampleSetTest)})}
 }),
 smalltalk.ExampleSetTest);
 
@@ -18,9 +18,9 @@ smalltalk.method({
 selector: "testAdd",
 fn: function (){
 var self=this;
-smalltalk.send(self["@empty"],"_add_",[(5)]);
-smalltalk.send(self,"_assert_",[smalltalk.send(self["@empty"],"_includes_",[(5)])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self["@empty"])._add_((5));
+_st(self)._assert_(_st(self["@empty"])._includes_((5)));
+return self}, function($ctx1) {$ctx1.fill(self,"testAdd",{}, smalltalk.ExampleSetTest)})}
 }),
 smalltalk.ExampleSetTest);
 
@@ -30,9 +30,9 @@ smalltalk.method({
 selector: "testGrow",
 fn: function (){
 var self=this;
-smalltalk.send(self["@empty"],"_addAll_",[smalltalk.send((1),"_to_",[(100)])]);
-smalltalk.send(self,"_assert_",[smalltalk.send(smalltalk.send(self["@empty"],"_size",[]),"__eq",[(100)])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self["@empty"])._addAll_(_st((1))._to_((100)));
+_st(self)._assert_(_st(_st(self["@empty"])._size()).__eq((100)));
+return self}, function($ctx1) {$ctx1.fill(self,"testGrow",{}, smalltalk.ExampleSetTest)})}
 }),
 smalltalk.ExampleSetTest);
 
@@ -42,13 +42,13 @@ smalltalk.method({
 selector: "testIllegal",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_should_raise_",[(function(){
-return smalltalk.send(self["@empty"],"_at_",[(5)]);
-}),(smalltalk.Error || Error)]);
-smalltalk.send(self,"_should_raise_",[(function(){
-return smalltalk.send(self["@empty"],"_at_put_",[(5),smalltalk.symbolFor("abc")]);
-}),(smalltalk.Error || Error)]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._should_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self["@empty"])._at_((5));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),(smalltalk.Error || Error));
+_st(self)._should_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self["@empty"])._at_put_((5),smalltalk.symbolFor("abc"));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),(smalltalk.Error || Error));
+return self}, function($ctx1) {$ctx1.fill(self,"testIllegal",{}, smalltalk.ExampleSetTest)})}
 }),
 smalltalk.ExampleSetTest);
 
@@ -58,9 +58,9 @@ smalltalk.method({
 selector: "testIncludes",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_assert_",[smalltalk.send(self["@full"],"_includes_",[(5)])]);
-smalltalk.send(self,"_assert_",[smalltalk.send(self["@full"],"_includes_",[smalltalk.symbolFor("abc")])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_(_st(self["@full"])._includes_((5)));
+_st(self)._assert_(_st(self["@full"])._includes_(smalltalk.symbolFor("abc")));
+return self}, function($ctx1) {$ctx1.fill(self,"testIncludes",{}, smalltalk.ExampleSetTest)})}
 }),
 smalltalk.ExampleSetTest);
 
@@ -70,11 +70,11 @@ smalltalk.method({
 selector: "testOccurrences",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_assert_",[smalltalk.send(smalltalk.send(self["@empty"],"_occurrencesOf_",[(0)]),"__eq",[(0)])]);
-smalltalk.send(self,"_assert_",[smalltalk.send(smalltalk.send(self["@full"],"_occurrencesOf_",[(5)]),"__eq",[(1)])]);
-smalltalk.send(self["@full"],"_add_",[(5)]);
-smalltalk.send(self,"_assert_",[smalltalk.send(smalltalk.send(self["@full"],"_occurrencesOf_",[(5)]),"__eq",[(1)])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_(_st(_st(self["@empty"])._occurrencesOf_((0))).__eq((0)));
+_st(self)._assert_(_st(_st(self["@full"])._occurrencesOf_((5))).__eq((1)));
+_st(self["@full"])._add_((5));
+_st(self)._assert_(_st(_st(self["@full"])._occurrencesOf_((5))).__eq((1)));
+return self}, function($ctx1) {$ctx1.fill(self,"testOccurrences",{}, smalltalk.ExampleSetTest)})}
 }),
 smalltalk.ExampleSetTest);
 
@@ -84,10 +84,10 @@ smalltalk.method({
 selector: "testRemove",
 fn: function (){
 var self=this;
-smalltalk.send(self["@full"],"_remove_",[(5)]);
-smalltalk.send(self,"_assert_",[smalltalk.send(self["@full"],"_includes_",[smalltalk.symbolFor("abc")])]);
-smalltalk.send(self,"_deny_",[smalltalk.send(self["@full"],"_includes_",[(5)])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self["@full"])._remove_((5));
+_st(self)._assert_(_st(self["@full"])._includes_(smalltalk.symbolFor("abc")));
+_st(self)._deny_(_st(self["@full"])._includes_((5)));
+return self}, function($ctx1) {$ctx1.fill(self,"testRemove",{}, smalltalk.ExampleSetTest)})}
 }),
 smalltalk.ExampleSetTest);
 
@@ -100,14 +100,14 @@ smalltalk.method({
 selector: "fakeError",
 fn: function (){
 var self=this;
-self["@flag"]="bad";
-smalltalk.send(self,"_timeout_",[(10)]);
-self["@flag"]=smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-self["@flag"]="ok";
+return smalltalk.withContext(function($ctx1) { 
self["@flag"]="bad";
+_st(self)._timeout_((10));
+self["@flag"]=_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
self["@flag"]="ok";
 self["@flag"];
-return smalltalk.send(self,"_error_",["Intentional"]);
-})]),"_valueWithTimeout_",[(5)]);
-return self}
+return _st(self)._error_("Intentional");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((5));
+return self}, function($ctx1) {$ctx1.fill(self,"fakeError",{}, smalltalk.SUnitAsyncTest)})}
 }),
 smalltalk.SUnitAsyncTest);
 
@@ -117,12 +117,12 @@ smalltalk.method({
 selector: "fakeErrorFailingInTearDown",
 fn: function (){
 var self=this;
-self["@flag"]="bad";
-smalltalk.send(self,"_timeout_",[(10)]);
-self["@flag"]=smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-return smalltalk.send(self,"_error_",["Intentional"]);
-})]),"_valueWithTimeout_",[(5)]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@flag"]="bad";
+_st(self)._timeout_((10));
+self["@flag"]=_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._error_("Intentional");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((5));
+return self}, function($ctx1) {$ctx1.fill(self,"fakeErrorFailingInTearDown",{}, smalltalk.SUnitAsyncTest)})}
 }),
 smalltalk.SUnitAsyncTest);
 
@@ -132,14 +132,14 @@ smalltalk.method({
 selector: "fakeFailure",
 fn: function (){
 var self=this;
-self["@flag"]="bad";
-smalltalk.send(self,"_timeout_",[(10)]);
-self["@flag"]=smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-self["@flag"]="ok";
+return smalltalk.withContext(function($ctx1) { 
self["@flag"]="bad";
+_st(self)._timeout_((10));
+self["@flag"]=_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
self["@flag"]="ok";
 self["@flag"];
-return smalltalk.send(self,"_assert_",[false]);
-})]),"_valueWithTimeout_",[(5)]);
-return self}
+return _st(self)._assert_(false);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((5));
+return self}, function($ctx1) {$ctx1.fill(self,"fakeFailure",{}, smalltalk.SUnitAsyncTest)})}
 }),
 smalltalk.SUnitAsyncTest);
 
@@ -149,14 +149,14 @@ smalltalk.method({
 selector: "fakeMultipleTimeoutFailing",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_timeout_",[(100)]);
-smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-smalltalk.send(self,"_timeout_",[(5)]);
-return smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-return smalltalk.send(self,"_finished",[]);
-})]),"_valueWithTimeout_",[(10)]);
-})]),"_valueWithTimeout_",[(5)]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._timeout_((100));
+_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._timeout_((5));
+return _st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx3) {
return _st(self)._finished();
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})})))._valueWithTimeout_((10));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((5));
+return self}, function($ctx1) {$ctx1.fill(self,"fakeMultipleTimeoutFailing",{}, smalltalk.SUnitAsyncTest)})}
 }),
 smalltalk.SUnitAsyncTest);
 
@@ -166,14 +166,14 @@ smalltalk.method({
 selector: "fakeMultipleTimeoutPassing",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_timeout_",[(10)]);
-smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-smalltalk.send(self,"_timeout_",[(20)]);
-return smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-return smalltalk.send(self,"_finished",[]);
-})]),"_valueWithTimeout_",[(10)]);
-})]),"_valueWithTimeout_",[(5)]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._timeout_((10));
+_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._timeout_((20));
+return _st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx3) {
return _st(self)._finished();
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})})))._valueWithTimeout_((10));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((5));
+return self}, function($ctx1) {$ctx1.fill(self,"fakeMultipleTimeoutPassing",{}, smalltalk.SUnitAsyncTest)})}
 }),
 smalltalk.SUnitAsyncTest);
 
@@ -183,11 +183,11 @@ smalltalk.method({
 selector: "fakeTimeout",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_timeout_",[(4)]);
-smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-return smalltalk.send(self,"_finished",[]);
-})]),"_valueWithTimeout_",[(5)]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._timeout_((4));
+_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._finished();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((5));
+return self}, function($ctx1) {$ctx1.fill(self,"fakeTimeout",{}, smalltalk.SUnitAsyncTest)})}
 }),
 smalltalk.SUnitAsyncTest);
 
@@ -197,8 +197,8 @@ smalltalk.method({
 selector: "setUp",
 fn: function (){
 var self=this;
-self["@flag"]="ok";
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@flag"]="ok";
+return self}, function($ctx1) {$ctx1.fill(self,"setUp",{}, smalltalk.SUnitAsyncTest)})}
 }),
 smalltalk.SUnitAsyncTest);
 
@@ -208,12 +208,12 @@ smalltalk.method({
 selector: "sortedSelectors:",
 fn: function (aCollection){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(aCollection,"_collect_",[(function(each){
-return smalltalk.send(each,"_selector",[]);
-})]),"_sorted",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(aCollection)._collect_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(each)._selector();
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})})))._sorted();
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"sortedSelectors:",{aCollection:aCollection}, smalltalk.SUnitAsyncTest)})}
 }),
 smalltalk.SUnitAsyncTest);
 
@@ -223,8 +223,8 @@ smalltalk.method({
 selector: "tearDown",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_assert_equals_",["ok",self["@flag"]]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_equals_("ok",self["@flag"]);
+return self}, function($ctx1) {$ctx1.fill(self,"tearDown",{}, smalltalk.SUnitAsyncTest)})}
 }),
 smalltalk.SUnitAsyncTest);
 
@@ -234,35 +234,32 @@ smalltalk.method({
 selector: "testAsyncErrorsAndFailures",
 fn: function (){
 var self=this;
-var $1,$2,$4,$6,$5,$3;
-var suite;
-var runner;
-var result;
-var assertBlock;
-suite=smalltalk.send(["fakeError", "fakeErrorFailingInTearDown", "fakeFailure", "testPass"],"_collect_",[(function(each){
-return smalltalk.send(smalltalk.send(self,"_class",[]),"_selector_",[each]);
-})]);
-runner=smalltalk.send((smalltalk.TestSuiteRunner || TestSuiteRunner),"_on_",[suite]);
-smalltalk.send(self,"_timeout_",[(200)]);
-result=smalltalk.send(runner,"_result",[]);
-assertBlock=smalltalk.send(self,"_async_",[(function(){
-smalltalk.send(self,"_assert_equals_",[["fakeError"],smalltalk.send(self,"_sortedSelectors_",[smalltalk.send(result,"_errors",[])])]);
-smalltalk.send(self,"_assert_equals_",[["fakeErrorFailingInTearDown", "fakeFailure"],smalltalk.send(self,"_sortedSelectors_",[smalltalk.send(result,"_failures",[])])]);
-return smalltalk.send(self,"_finished",[]);
-})]);
-$1=smalltalk.send(runner,"_announcer",[]);
+var suite,runner,result,assertBlock;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$6,$5,$3;
+suite=_st(["fakeError", "fakeErrorFailingInTearDown", "fakeFailure", "testPass"])._collect_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(self)._class())._selector_(each);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+runner=_st((smalltalk.TestSuiteRunner || TestSuiteRunner))._on_(suite);
+_st(self)._timeout_((200));
+result=_st(runner)._result();
+assertBlock=_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._assert_equals_(["fakeError"],_st(self)._sortedSelectors_(_st(result)._errors()));
+_st(self)._assert_equals_(["fakeErrorFailingInTearDown", "fakeFailure"],_st(self)._sortedSelectors_(_st(result)._failures()));
+return _st(self)._finished();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$1=_st(runner)._announcer();
 $2=(smalltalk.ResultAnnouncement || ResultAnnouncement);
 $3=(function(ann){
-$4=smalltalk.send(smalltalk.send(ann,"_result",[]),"__eq_eq",[result]);
+return smalltalk.withContext(function($ctx2) {
$4=_st(_st(ann)._result()).__eq_eq(result);
 $5=(function(){
-$6=smalltalk.send(smalltalk.send(result,"_runs",[]),"__eq",[smalltalk.send(result,"_total",[])]);
-return smalltalk.send($6,"_ifTrue_",[assertBlock]);
-});
-return smalltalk.send($4,"_ifTrue_",[$5]);
-});
-smalltalk.send($1,"_on_do_",[$2,$3]);
-smalltalk.send(runner,"_run",[]);
-return self}
+return smalltalk.withContext(function($ctx3) {
$6=_st(_st(result)._runs()).__eq(_st(result)._total());
+return _st($6)._ifTrue_(assertBlock);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
+return _st($4)._ifTrue_($5);
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})});
+_st($1)._on_do_($2,$3);
+_st(runner)._run();
+return self}, function($ctx1) {$ctx1.fill(self,"testAsyncErrorsAndFailures",{suite:suite,runner:runner,result:result,assertBlock:assertBlock}, smalltalk.SUnitAsyncTest)})}
 }),
 smalltalk.SUnitAsyncTest);
 
@@ -272,17 +269,17 @@ smalltalk.method({
 selector: "testAsyncNeedsTimeout",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_should_raise_",[(function(){
-return smalltalk.send(self,"_async_",[(function(){
-})]);
-}),(smalltalk.Error || Error)]);
-smalltalk.send(self,"_timeout_",[(0)]);
-smalltalk.send(self,"_shouldnt_raise_",[(function(){
-return smalltalk.send(self,"_async_",[(function(){
-})]);
-}),(smalltalk.Error || Error)]);
-smalltalk.send(self,"_finished",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._should_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._async_((function(){
+return smalltalk.withContext(function($ctx3) {
}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),(smalltalk.Error || Error));
+_st(self)._timeout_((0));
+_st(self)._shouldnt_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._async_((function(){
+return smalltalk.withContext(function($ctx3) {
}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),(smalltalk.Error || Error));
+_st(self)._finished();
+return self}, function($ctx1) {$ctx1.fill(self,"testAsyncNeedsTimeout",{}, smalltalk.SUnitAsyncTest)})}
 }),
 smalltalk.SUnitAsyncTest);
 
@@ -292,14 +289,14 @@ smalltalk.method({
 selector: "testFinishedNeedsTimeout",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_should_raise_",[(function(){
-return smalltalk.send(self,"_finished",[]);
-}),(smalltalk.Error || Error)]);
-smalltalk.send(self,"_timeout_",[(0)]);
-smalltalk.send(self,"_shouldnt_raise_",[(function(){
-return smalltalk.send(self,"_finished",[]);
-}),(smalltalk.Error || Error)]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._should_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._finished();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),(smalltalk.Error || Error));
+_st(self)._timeout_((0));
+_st(self)._shouldnt_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._finished();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),(smalltalk.Error || Error));
+return self}, function($ctx1) {$ctx1.fill(self,"testFinishedNeedsTimeout",{}, smalltalk.SUnitAsyncTest)})}
 }),
 smalltalk.SUnitAsyncTest);
 
@@ -309,12 +306,12 @@ smalltalk.method({
 selector: "testIsAsyncReturnsCorrectValues",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_deny_",[smalltalk.send(self,"_isAsync",[])]);
-smalltalk.send(self,"_timeout_",[(0)]);
-smalltalk.send(self,"_assert_",[smalltalk.send(self,"_isAsync",[])]);
-smalltalk.send(self,"_finished",[]);
-smalltalk.send(self,"_deny_",[smalltalk.send(self,"_isAsync",[])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._deny_(_st(self)._isAsync());
+_st(self)._timeout_((0));
+_st(self)._assert_(_st(self)._isAsync());
+_st(self)._finished();
+_st(self)._deny_(_st(self)._isAsync());
+return self}, function($ctx1) {$ctx1.fill(self,"testIsAsyncReturnsCorrectValues",{}, smalltalk.SUnitAsyncTest)})}
 }),
 smalltalk.SUnitAsyncTest);
 
@@ -324,15 +321,15 @@ smalltalk.method({
 selector: "testPass",
 fn: function (){
 var self=this;
-self["@flag"]="bad";
-smalltalk.send(self,"_timeout_",[(10)]);
-self["@flag"]=smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-smalltalk.send(self,"_assert_",[true]);
-smalltalk.send(self,"_finished",[]);
+return smalltalk.withContext(function($ctx1) { 
self["@flag"]="bad";
+_st(self)._timeout_((10));
+self["@flag"]=_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._assert_(true);
+_st(self)._finished();
 self["@flag"]="ok";
 return self["@flag"];
-})]),"_valueWithTimeout_",[(5)]);
-return self}
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((5));
+return self}, function($ctx1) {$ctx1.fill(self,"testPass",{}, smalltalk.SUnitAsyncTest)})}
 }),
 smalltalk.SUnitAsyncTest);
 
@@ -342,35 +339,32 @@ smalltalk.method({
 selector: "testTimeouts",
 fn: function (){
 var self=this;
-var $1,$2,$4,$6,$5,$3;
-var suite;
-var runner;
-var result;
-var assertBlock;
-suite=smalltalk.send(["fakeTimeout", "fakeMultipleTimeoutFailing", "fakeMultipleTimeoutPassing", "testPass"],"_collect_",[(function(each){
-return smalltalk.send(smalltalk.send(self,"_class",[]),"_selector_",[each]);
-})]);
-runner=smalltalk.send((smalltalk.TestSuiteRunner || TestSuiteRunner),"_on_",[suite]);
-smalltalk.send(self,"_timeout_",[(200)]);
-result=smalltalk.send(runner,"_result",[]);
-assertBlock=smalltalk.send(self,"_async_",[(function(){
-smalltalk.send(self,"_assert_",[smalltalk.send(smalltalk.send(result,"_errors",[]),"_isEmpty",[])]);
-smalltalk.send(self,"_assert_equals_",[["fakeMultipleTimeoutFailing", "fakeTimeout"],smalltalk.send(self,"_sortedSelectors_",[smalltalk.send(result,"_failures",[])])]);
-return smalltalk.send(self,"_finished",[]);
-})]);
-$1=smalltalk.send(runner,"_announcer",[]);
+var suite,runner,result,assertBlock;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$6,$5,$3;
+suite=_st(["fakeTimeout", "fakeMultipleTimeoutFailing", "fakeMultipleTimeoutPassing", "testPass"])._collect_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(self)._class())._selector_(each);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+runner=_st((smalltalk.TestSuiteRunner || TestSuiteRunner))._on_(suite);
+_st(self)._timeout_((200));
+result=_st(runner)._result();
+assertBlock=_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._assert_(_st(_st(result)._errors())._isEmpty());
+_st(self)._assert_equals_(["fakeMultipleTimeoutFailing", "fakeTimeout"],_st(self)._sortedSelectors_(_st(result)._failures()));
+return _st(self)._finished();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$1=_st(runner)._announcer();
 $2=(smalltalk.ResultAnnouncement || ResultAnnouncement);
 $3=(function(ann){
-$4=smalltalk.send(smalltalk.send(ann,"_result",[]),"__eq_eq",[result]);
+return smalltalk.withContext(function($ctx2) {
$4=_st(_st(ann)._result()).__eq_eq(result);
 $5=(function(){
-$6=smalltalk.send(smalltalk.send(result,"_runs",[]),"__eq",[smalltalk.send(result,"_total",[])]);
-return smalltalk.send($6,"_ifTrue_",[assertBlock]);
-});
-return smalltalk.send($4,"_ifTrue_",[$5]);
-});
-smalltalk.send($1,"_on_do_",[$2,$3]);
-smalltalk.send(runner,"_run",[]);
-return self}
+return smalltalk.withContext(function($ctx3) {
$6=_st(_st(result)._runs()).__eq(_st(result)._total());
+return _st($6)._ifTrue_(assertBlock);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
+return _st($4)._ifTrue_($5);
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})});
+_st($1)._on_do_($2,$3);
+_st(runner)._run();
+return self}, function($ctx1) {$ctx1.fill(self,"testTimeouts",{suite:suite,runner:runner,result:result,assertBlock:assertBlock}, smalltalk.SUnitAsyncTest)})}
 }),
 smalltalk.SUnitAsyncTest);
 
@@ -381,26 +375,26 @@ selector: "testTwoAsyncPassesWithFinishedOnlyOneIsRun",
 fn: function (){
 var self=this;
 var x;
-self["@flag"]="bad";
-smalltalk.send(self,"_timeout_",[(10)]);
+return smalltalk.withContext(function($ctx1) { 
self["@flag"]="bad";
+_st(self)._timeout_((10));
 x=(0);
-self["@flag"]=smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-smalltalk.send(self,"_finished",[]);
+self["@flag"]=_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._finished();
 self["@flag"]="ok";
 self["@flag"];
-x=smalltalk.send(x,"__plus",[(1)]);
+x=_st(x).__plus((1));
 x;
-return smalltalk.send(self,"_assert_equals_",[(1),x]);
-})]),"_valueWithTimeout_",[(0)]);
-self["@flag"]=smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-smalltalk.send(self,"_finished",[]);
+return _st(self)._assert_equals_((1),x);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((0));
+self["@flag"]=_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._finished();
 self["@flag"]="ok";
 self["@flag"];
-x=smalltalk.send(x,"__plus",[(1)]);
+x=_st(x).__plus((1));
 x;
-return smalltalk.send(self,"_assert_equals_",[(1),x]);
-})]),"_valueWithTimeout_",[(0)]);
-return self}
+return _st(self)._assert_equals_((1),x);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((0));
+return self}, function($ctx1) {$ctx1.fill(self,"testTwoAsyncPassesWithFinishedOnlyOneIsRun",{x:x}, smalltalk.SUnitAsyncTest)})}
 }),
 smalltalk.SUnitAsyncTest);
 

+ 182 - 188
js/SUnit-Tests.js

@@ -8,9 +8,9 @@ selector: "setUp",
 category: 'running',
 fn: function (){
 var self=this;
-self["@empty"]=smalltalk.send((smalltalk.Set || Set),"_new",[]);
-self["@full"]=smalltalk.send((smalltalk.Set || Set),"_with_with_",[(5),smalltalk.symbolFor("abc")]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@empty"]=_st((smalltalk.Set || Set))._new();
+self["@full"]=_st((smalltalk.Set || Set))._with_with_((5),smalltalk.symbolFor("abc"));
+return self}, function($ctx1) {$ctx1.fill(self,"setUp",{}, smalltalk.ExampleSetTest)})},
 args: [],
 source: "setUp\x0a\x09empty := Set new.\x0a\x09full := Set with: 5 with: #abc",
 messageSends: ["new", "with:with:"],
@@ -25,9 +25,9 @@ selector: "testAdd",
 category: 'tests',
 fn: function (){
 var self=this;
-smalltalk.send(self["@empty"],"_add_",[(5)]);
-smalltalk.send(self,"_assert_",[smalltalk.send(self["@empty"],"_includes_",[(5)])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self["@empty"])._add_((5));
+_st(self)._assert_(_st(self["@empty"])._includes_((5)));
+return self}, function($ctx1) {$ctx1.fill(self,"testAdd",{}, smalltalk.ExampleSetTest)})},
 args: [],
 source: "testAdd\x0a\x09empty add: 5.\x0a\x09self assert: (empty includes: 5)",
 messageSends: ["add:", "assert:", "includes:"],
@@ -42,9 +42,9 @@ selector: "testGrow",
 category: 'tests',
 fn: function (){
 var self=this;
-smalltalk.send(self["@empty"],"_addAll_",[smalltalk.send((1),"_to_",[(100)])]);
-smalltalk.send(self,"_assert_",[smalltalk.send(smalltalk.send(self["@empty"],"_size",[]),"__eq",[(100)])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self["@empty"])._addAll_(_st((1))._to_((100)));
+_st(self)._assert_(_st(_st(self["@empty"])._size()).__eq((100)));
+return self}, function($ctx1) {$ctx1.fill(self,"testGrow",{}, smalltalk.ExampleSetTest)})},
 args: [],
 source: "testGrow\x0a\x09empty addAll: (1 to: 100).\x0a\x09self assert: empty size = 100",
 messageSends: ["addAll:", "to:", "assert:", "=", "size"],
@@ -59,13 +59,13 @@ selector: "testIllegal",
 category: 'tests',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_should_raise_",[(function(){
-return smalltalk.send(self["@empty"],"_at_",[(5)]);
-}),(smalltalk.Error || Error)]);
-smalltalk.send(self,"_should_raise_",[(function(){
-return smalltalk.send(self["@empty"],"_at_put_",[(5),smalltalk.symbolFor("abc")]);
-}),(smalltalk.Error || Error)]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._should_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self["@empty"])._at_((5));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),(smalltalk.Error || Error));
+_st(self)._should_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self["@empty"])._at_put_((5),smalltalk.symbolFor("abc"));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),(smalltalk.Error || Error));
+return self}, function($ctx1) {$ctx1.fill(self,"testIllegal",{}, smalltalk.ExampleSetTest)})},
 args: [],
 source: "testIllegal\x0a\x09self \x0a\x09\x09should: [empty at: 5] \x0a\x09\x09raise: Error.\x0a\x09self \x0a\x09\x09should: [empty at: 5 put: #abc] \x0a\x09\x09raise: Error",
 messageSends: ["should:raise:", "at:", "at:put:"],
@@ -80,9 +80,9 @@ selector: "testIncludes",
 category: 'tests',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_assert_",[smalltalk.send(self["@full"],"_includes_",[(5)])]);
-smalltalk.send(self,"_assert_",[smalltalk.send(self["@full"],"_includes_",[smalltalk.symbolFor("abc")])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_(_st(self["@full"])._includes_((5)));
+_st(self)._assert_(_st(self["@full"])._includes_(smalltalk.symbolFor("abc")));
+return self}, function($ctx1) {$ctx1.fill(self,"testIncludes",{}, smalltalk.ExampleSetTest)})},
 args: [],
 source: "testIncludes\x0a\x09self assert: (full includes: 5).\x0a\x09self assert: (full includes: #abc)",
 messageSends: ["assert:", "includes:"],
@@ -97,11 +97,11 @@ selector: "testOccurrences",
 category: 'tests',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_assert_",[smalltalk.send(smalltalk.send(self["@empty"],"_occurrencesOf_",[(0)]),"__eq",[(0)])]);
-smalltalk.send(self,"_assert_",[smalltalk.send(smalltalk.send(self["@full"],"_occurrencesOf_",[(5)]),"__eq",[(1)])]);
-smalltalk.send(self["@full"],"_add_",[(5)]);
-smalltalk.send(self,"_assert_",[smalltalk.send(smalltalk.send(self["@full"],"_occurrencesOf_",[(5)]),"__eq",[(1)])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_(_st(_st(self["@empty"])._occurrencesOf_((0))).__eq((0)));
+_st(self)._assert_(_st(_st(self["@full"])._occurrencesOf_((5))).__eq((1)));
+_st(self["@full"])._add_((5));
+_st(self)._assert_(_st(_st(self["@full"])._occurrencesOf_((5))).__eq((1)));
+return self}, function($ctx1) {$ctx1.fill(self,"testOccurrences",{}, smalltalk.ExampleSetTest)})},
 args: [],
 source: "testOccurrences\x0a\x09self assert: (empty occurrencesOf: 0) = 0.\x0a\x09self assert: (full occurrencesOf: 5) = 1.\x0a\x09full add: 5.\x0a\x09self assert: (full occurrencesOf: 5) = 1",
 messageSends: ["assert:", "=", "occurrencesOf:", "add:"],
@@ -116,10 +116,10 @@ selector: "testRemove",
 category: 'tests',
 fn: function (){
 var self=this;
-smalltalk.send(self["@full"],"_remove_",[(5)]);
-smalltalk.send(self,"_assert_",[smalltalk.send(self["@full"],"_includes_",[smalltalk.symbolFor("abc")])]);
-smalltalk.send(self,"_deny_",[smalltalk.send(self["@full"],"_includes_",[(5)])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self["@full"])._remove_((5));
+_st(self)._assert_(_st(self["@full"])._includes_(smalltalk.symbolFor("abc")));
+_st(self)._deny_(_st(self["@full"])._includes_((5)));
+return self}, function($ctx1) {$ctx1.fill(self,"testRemove",{}, smalltalk.ExampleSetTest)})},
 args: [],
 source: "testRemove\x0a\x09full remove: 5.\x0a\x09self assert: (full includes: #abc).\x0a\x09self deny: (full includes: 5)",
 messageSends: ["remove:", "assert:", "includes:", "deny:"],
@@ -137,16 +137,16 @@ selector: "fakeError",
 category: 'helpers',
 fn: function (){
 var self=this;
-self["@flag"]="bad";
-smalltalk.send(self,"_timeout_",[(10)]);
-self["@flag"]=smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-self["@flag"]="ok";
+return smalltalk.withContext(function($ctx1) { 
self["@flag"]="bad";
+_st(self)._timeout_((10));
+self["@flag"]=_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
self["@flag"]="ok";
 self["@flag"];
-return smalltalk.send(self,"_error_",["Intentional"]);
-})]),"_valueWithTimeout_",[(5)]);
-return self},
+return _st(self)._error_("Intentional");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((5));
+return self}, function($ctx1) {$ctx1.fill(self,"fakeError",{}, smalltalk.SUnitAsyncTest)})},
 args: [],
-source: "fakeError\x0a\x09flag := 'bad'.\x0a\x09self timeout: 10.\x0a    flag := (self async: [ flag := 'ok'. self error: 'Intentional' ]) valueWithTimeout: 5\x0a",
+source: "fakeError\x0a\x09flag := 'bad'.\x0a\x09self timeout: 10.\x0a    flag := (self async: [ flag := 'ok'. self error: 'Intentional' ]) valueWithTimeout: 5",
 messageSends: ["timeout:", "valueWithTimeout:", "async:", "error:"],
 referencedClasses: []
 }),
@@ -159,14 +159,14 @@ selector: "fakeErrorFailingInTearDown",
 category: 'helpers',
 fn: function (){
 var self=this;
-self["@flag"]="bad";
-smalltalk.send(self,"_timeout_",[(10)]);
-self["@flag"]=smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-return smalltalk.send(self,"_error_",["Intentional"]);
-})]),"_valueWithTimeout_",[(5)]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@flag"]="bad";
+_st(self)._timeout_((10));
+self["@flag"]=_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._error_("Intentional");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((5));
+return self}, function($ctx1) {$ctx1.fill(self,"fakeErrorFailingInTearDown",{}, smalltalk.SUnitAsyncTest)})},
 args: [],
-source: "fakeErrorFailingInTearDown\x0a\x09flag := 'bad'.\x0a\x09self timeout: 10.\x0a    flag := (self async: [ self error: 'Intentional' ]) valueWithTimeout: 5\x0a",
+source: "fakeErrorFailingInTearDown\x0a\x09flag := 'bad'.\x0a\x09self timeout: 10.\x0a    flag := (self async: [ self error: 'Intentional' ]) valueWithTimeout: 5",
 messageSends: ["timeout:", "valueWithTimeout:", "async:", "error:"],
 referencedClasses: []
 }),
@@ -179,16 +179,16 @@ selector: "fakeFailure",
 category: 'helpers',
 fn: function (){
 var self=this;
-self["@flag"]="bad";
-smalltalk.send(self,"_timeout_",[(10)]);
-self["@flag"]=smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-self["@flag"]="ok";
+return smalltalk.withContext(function($ctx1) { 
self["@flag"]="bad";
+_st(self)._timeout_((10));
+self["@flag"]=_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
self["@flag"]="ok";
 self["@flag"];
-return smalltalk.send(self,"_assert_",[false]);
-})]),"_valueWithTimeout_",[(5)]);
-return self},
+return _st(self)._assert_(false);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((5));
+return self}, function($ctx1) {$ctx1.fill(self,"fakeFailure",{}, smalltalk.SUnitAsyncTest)})},
 args: [],
-source: "fakeFailure\x0a\x09flag := 'bad'.\x0a\x09self timeout: 10.\x0a    flag := (self async: [ flag := 'ok'. self assert: false ]) valueWithTimeout: 5\x0a",
+source: "fakeFailure\x0a\x09flag := 'bad'.\x0a\x09self timeout: 10.\x0a    flag := (self async: [ flag := 'ok'. self assert: false ]) valueWithTimeout: 5",
 messageSends: ["timeout:", "valueWithTimeout:", "async:", "assert:"],
 referencedClasses: []
 }),
@@ -201,16 +201,16 @@ selector: "fakeMultipleTimeoutFailing",
 category: 'helpers',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_timeout_",[(100)]);
-smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-smalltalk.send(self,"_timeout_",[(5)]);
-return smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-return smalltalk.send(self,"_finished",[]);
-})]),"_valueWithTimeout_",[(10)]);
-})]),"_valueWithTimeout_",[(5)]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._timeout_((100));
+_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._timeout_((5));
+return _st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx3) {
return _st(self)._finished();
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})})))._valueWithTimeout_((10));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((5));
+return self}, function($ctx1) {$ctx1.fill(self,"fakeMultipleTimeoutFailing",{}, smalltalk.SUnitAsyncTest)})},
 args: [],
-source: "fakeMultipleTimeoutFailing\x0a\x09self timeout: 100.\x0a    (self async: [\x0a\x09\x09self timeout: 5.\x0a        (self async: [ self finished ]) valueWithTimeout: 10\x0a\x09]) valueWithTimeout: 5\x0a",
+source: "fakeMultipleTimeoutFailing\x0a\x09self timeout: 100.\x0a    (self async: [\x0a\x09\x09self timeout: 5.\x0a        (self async: [ self finished ]) valueWithTimeout: 10\x0a\x09]) valueWithTimeout: 5",
 messageSends: ["timeout:", "valueWithTimeout:", "async:", "finished"],
 referencedClasses: []
 }),
@@ -223,16 +223,16 @@ selector: "fakeMultipleTimeoutPassing",
 category: 'helpers',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_timeout_",[(10)]);
-smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-smalltalk.send(self,"_timeout_",[(20)]);
-return smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-return smalltalk.send(self,"_finished",[]);
-})]),"_valueWithTimeout_",[(10)]);
-})]),"_valueWithTimeout_",[(5)]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._timeout_((10));
+_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._timeout_((20));
+return _st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx3) {
return _st(self)._finished();
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})})))._valueWithTimeout_((10));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((5));
+return self}, function($ctx1) {$ctx1.fill(self,"fakeMultipleTimeoutPassing",{}, smalltalk.SUnitAsyncTest)})},
 args: [],
-source: "fakeMultipleTimeoutPassing\x0a\x09self timeout: 10.\x0a    (self async: [\x0a\x09\x09self timeout: 20.\x0a        (self async: [ self finished ]) valueWithTimeout: 10\x0a\x09]) valueWithTimeout: 5\x0a",
+source: "fakeMultipleTimeoutPassing\x0a\x09self timeout: 10.\x0a    (self async: [\x0a\x09\x09self timeout: 20.\x0a        (self async: [ self finished ]) valueWithTimeout: 10\x0a\x09]) valueWithTimeout: 5",
 messageSends: ["timeout:", "valueWithTimeout:", "async:", "finished"],
 referencedClasses: []
 }),
@@ -245,13 +245,13 @@ selector: "fakeTimeout",
 category: 'helpers',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_timeout_",[(4)]);
-smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-return smalltalk.send(self,"_finished",[]);
-})]),"_valueWithTimeout_",[(5)]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._timeout_((4));
+_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._finished();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((5));
+return self}, function($ctx1) {$ctx1.fill(self,"fakeTimeout",{}, smalltalk.SUnitAsyncTest)})},
 args: [],
-source: "fakeTimeout\x0a\x09self timeout: 4.\x0a    (self async: [ self finished ]) valueWithTimeout: 5\x0a",
+source: "fakeTimeout\x0a\x09self timeout: 4.\x0a    (self async: [ self finished ]) valueWithTimeout: 5",
 messageSends: ["timeout:", "valueWithTimeout:", "async:", "finished"],
 referencedClasses: []
 }),
@@ -264,10 +264,10 @@ selector: "setUp",
 category: 'running',
 fn: function (){
 var self=this;
-self["@flag"]="ok";
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@flag"]="ok";
+return self}, function($ctx1) {$ctx1.fill(self,"setUp",{}, smalltalk.SUnitAsyncTest)})},
 args: [],
-source: "setUp\x0a\x09flag := 'ok'\x0a",
+source: "setUp\x0a\x09flag := 'ok'",
 messageSends: [],
 referencedClasses: []
 }),
@@ -280,12 +280,12 @@ selector: "sortedSelectors:",
 category: 'private',
 fn: function (aCollection){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(aCollection,"_collect_",[(function(each){
-return smalltalk.send(each,"_selector",[]);
-})]),"_sorted",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(aCollection)._collect_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(each)._selector();
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})})))._sorted();
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"sortedSelectors:",{aCollection:aCollection}, smalltalk.SUnitAsyncTest)})},
 args: ["aCollection"],
 source: "sortedSelectors: aCollection\x0a\x09^(aCollection collect: [:each | each selector]) sorted",
 messageSends: ["sorted", "collect:", "selector"],
@@ -300,10 +300,10 @@ selector: "tearDown",
 category: 'running',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_assert_equals_",["ok",self["@flag"]]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_equals_("ok",self["@flag"]);
+return self}, function($ctx1) {$ctx1.fill(self,"tearDown",{}, smalltalk.SUnitAsyncTest)})},
 args: [],
-source: "tearDown\x0a\x09self assert: 'ok' equals: flag\x0a",
+source: "tearDown\x0a\x09self assert: 'ok' equals: flag",
 messageSends: ["assert:equals:"],
 referencedClasses: []
 }),
@@ -316,35 +316,32 @@ selector: "testAsyncErrorsAndFailures",
 category: 'tests',
 fn: function (){
 var self=this;
-var $1,$2,$4,$6,$5,$3;
-var suite;
-var runner;
-var result;
-var assertBlock;
-suite=smalltalk.send(["fakeError", "fakeErrorFailingInTearDown", "fakeFailure", "testPass"],"_collect_",[(function(each){
-return smalltalk.send(smalltalk.send(self,"_class",[]),"_selector_",[each]);
-})]);
-runner=smalltalk.send((smalltalk.TestSuiteRunner || TestSuiteRunner),"_on_",[suite]);
-smalltalk.send(self,"_timeout_",[(200)]);
-result=smalltalk.send(runner,"_result",[]);
-assertBlock=smalltalk.send(self,"_async_",[(function(){
-smalltalk.send(self,"_assert_equals_",[["fakeError"],smalltalk.send(self,"_sortedSelectors_",[smalltalk.send(result,"_errors",[])])]);
-smalltalk.send(self,"_assert_equals_",[["fakeErrorFailingInTearDown", "fakeFailure"],smalltalk.send(self,"_sortedSelectors_",[smalltalk.send(result,"_failures",[])])]);
-return smalltalk.send(self,"_finished",[]);
-})]);
-$1=smalltalk.send(runner,"_announcer",[]);
+var suite,runner,result,assertBlock;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$6,$5,$3;
+suite=_st(["fakeError", "fakeErrorFailingInTearDown", "fakeFailure", "testPass"])._collect_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(self)._class())._selector_(each);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+runner=_st((smalltalk.TestSuiteRunner || TestSuiteRunner))._on_(suite);
+_st(self)._timeout_((200));
+result=_st(runner)._result();
+assertBlock=_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._assert_equals_(["fakeError"],_st(self)._sortedSelectors_(_st(result)._errors()));
+_st(self)._assert_equals_(["fakeErrorFailingInTearDown", "fakeFailure"],_st(self)._sortedSelectors_(_st(result)._failures()));
+return _st(self)._finished();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$1=_st(runner)._announcer();
 $2=(smalltalk.ResultAnnouncement || ResultAnnouncement);
 $3=(function(ann){
-$4=smalltalk.send(smalltalk.send(ann,"_result",[]),"__eq_eq",[result]);
+return smalltalk.withContext(function($ctx2) {
$4=_st(_st(ann)._result()).__eq_eq(result);
 $5=(function(){
-$6=smalltalk.send(smalltalk.send(result,"_runs",[]),"__eq",[smalltalk.send(result,"_total",[])]);
-return smalltalk.send($6,"_ifTrue_",[assertBlock]);
-});
-return smalltalk.send($4,"_ifTrue_",[$5]);
-});
-smalltalk.send($1,"_on_do_",[$2,$3]);
-smalltalk.send(runner,"_run",[]);
-return self},
+return smalltalk.withContext(function($ctx3) {
$6=_st(_st(result)._runs()).__eq(_st(result)._total());
+return _st($6)._ifTrue_(assertBlock);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
+return _st($4)._ifTrue_($5);
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})});
+_st($1)._on_do_($2,$3);
+_st(runner)._run();
+return self}, function($ctx1) {$ctx1.fill(self,"testAsyncErrorsAndFailures",{suite:suite,runner:runner,result:result,assertBlock:assertBlock}, smalltalk.SUnitAsyncTest)})},
 args: [],
 source: "testAsyncErrorsAndFailures\x0a\x09| suite runner result assertBlock |\x0a\x09suite := #('fakeError' 'fakeErrorFailingInTearDown' 'fakeFailure' 'testPass') collect: [ :each | self class selector: each ].\x0a    runner := TestSuiteRunner on: suite.\x0a    self timeout: 200.\x0a\x09result := runner result.\x0a    assertBlock := self async: [\x0a\x09\x09self assert: #('fakeError') equals: (self sortedSelectors: result errors).\x0a\x09\x09self assert: #('fakeErrorFailingInTearDown' 'fakeFailure') equals: (self sortedSelectors: result failures).\x0a\x09\x09self finished\x0a  \x09].\x0a    runner announcer on: ResultAnnouncement do: [:ann |\x0a    \x09ann result == result  ifTrue: [ result runs = result total ifTrue: assertBlock ]].\x0a\x09runner run",
 messageSends: ["collect:", "selector:", "class", "on:", "timeout:", "result", "async:", "assert:equals:", "sortedSelectors:", "errors", "failures", "finished", "on:do:", "ifTrue:", "=", "total", "runs", "==", "announcer", "run"],
@@ -359,19 +356,19 @@ selector: "testAsyncNeedsTimeout",
 category: 'tests',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_should_raise_",[(function(){
-return smalltalk.send(self,"_async_",[(function(){
-})]);
-}),(smalltalk.Error || Error)]);
-smalltalk.send(self,"_timeout_",[(0)]);
-smalltalk.send(self,"_shouldnt_raise_",[(function(){
-return smalltalk.send(self,"_async_",[(function(){
-})]);
-}),(smalltalk.Error || Error)]);
-smalltalk.send(self,"_finished",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._should_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._async_((function(){
+return smalltalk.withContext(function($ctx3) {
}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),(smalltalk.Error || Error));
+_st(self)._timeout_((0));
+_st(self)._shouldnt_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._async_((function(){
+return smalltalk.withContext(function($ctx3) {
}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),(smalltalk.Error || Error));
+_st(self)._finished();
+return self}, function($ctx1) {$ctx1.fill(self,"testAsyncNeedsTimeout",{}, smalltalk.SUnitAsyncTest)})},
 args: [],
-source: "testAsyncNeedsTimeout\x0a    self should: [ self async: [ ] ] raise: Error.\x0a    self timeout: 0.\x0a    self shouldnt: [ self async: [ ] ] raise: Error.\x0a    self finished\x0a",
+source: "testAsyncNeedsTimeout\x0a    self should: [ self async: [ ] ] raise: Error.\x0a    self timeout: 0.\x0a    self shouldnt: [ self async: [ ] ] raise: Error.\x0a    self finished",
 messageSends: ["should:raise:", "async:", "timeout:", "shouldnt:raise:", "finished"],
 referencedClasses: ["Error"]
 }),
@@ -384,16 +381,16 @@ selector: "testFinishedNeedsTimeout",
 category: 'tests',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_should_raise_",[(function(){
-return smalltalk.send(self,"_finished",[]);
-}),(smalltalk.Error || Error)]);
-smalltalk.send(self,"_timeout_",[(0)]);
-smalltalk.send(self,"_shouldnt_raise_",[(function(){
-return smalltalk.send(self,"_finished",[]);
-}),(smalltalk.Error || Error)]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._should_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._finished();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),(smalltalk.Error || Error));
+_st(self)._timeout_((0));
+_st(self)._shouldnt_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._finished();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),(smalltalk.Error || Error));
+return self}, function($ctx1) {$ctx1.fill(self,"testFinishedNeedsTimeout",{}, smalltalk.SUnitAsyncTest)})},
 args: [],
-source: "testFinishedNeedsTimeout\x0a    self should: [ self finished ] raise: Error.\x0a    self timeout: 0.\x0a    self shouldnt: [ self finished ] raise: Error.\x0a",
+source: "testFinishedNeedsTimeout\x0a    self should: [ self finished ] raise: Error.\x0a    self timeout: 0.\x0a    self shouldnt: [ self finished ] raise: Error.",
 messageSends: ["should:raise:", "finished", "timeout:", "shouldnt:raise:"],
 referencedClasses: ["Error"]
 }),
@@ -406,14 +403,14 @@ selector: "testIsAsyncReturnsCorrectValues",
 category: 'tests',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_deny_",[smalltalk.send(self,"_isAsync",[])]);
-smalltalk.send(self,"_timeout_",[(0)]);
-smalltalk.send(self,"_assert_",[smalltalk.send(self,"_isAsync",[])]);
-smalltalk.send(self,"_finished",[]);
-smalltalk.send(self,"_deny_",[smalltalk.send(self,"_isAsync",[])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._deny_(_st(self)._isAsync());
+_st(self)._timeout_((0));
+_st(self)._assert_(_st(self)._isAsync());
+_st(self)._finished();
+_st(self)._deny_(_st(self)._isAsync());
+return self}, function($ctx1) {$ctx1.fill(self,"testIsAsyncReturnsCorrectValues",{}, smalltalk.SUnitAsyncTest)})},
 args: [],
-source: "testIsAsyncReturnsCorrectValues\x0a    self deny: self isAsync.\x0a    self timeout: 0.\x0a    self assert: self isAsync.\x0a    self finished.\x0a    self deny: self isAsync\x0a",
+source: "testIsAsyncReturnsCorrectValues\x0a    self deny: self isAsync.\x0a    self timeout: 0.\x0a    self assert: self isAsync.\x0a    self finished.\x0a    self deny: self isAsync",
 messageSends: ["deny:", "isAsync", "timeout:", "assert:", "finished"],
 referencedClasses: []
 }),
@@ -426,17 +423,17 @@ selector: "testPass",
 category: 'tests',
 fn: function (){
 var self=this;
-self["@flag"]="bad";
-smalltalk.send(self,"_timeout_",[(10)]);
-self["@flag"]=smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-smalltalk.send(self,"_assert_",[true]);
-smalltalk.send(self,"_finished",[]);
+return smalltalk.withContext(function($ctx1) { 
self["@flag"]="bad";
+_st(self)._timeout_((10));
+self["@flag"]=_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._assert_(true);
+_st(self)._finished();
 self["@flag"]="ok";
 return self["@flag"];
-})]),"_valueWithTimeout_",[(5)]);
-return self},
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((5));
+return self}, function($ctx1) {$ctx1.fill(self,"testPass",{}, smalltalk.SUnitAsyncTest)})},
 args: [],
-source: "testPass\x0a\x09flag := 'bad'.\x0a\x09self timeout: 10.\x0a    flag := (self async: [ self assert: true. self finished. flag := 'ok' ]) valueWithTimeout: 5\x0a",
+source: "testPass\x0a\x09flag := 'bad'.\x0a\x09self timeout: 10.\x0a    flag := (self async: [ self assert: true. self finished. flag := 'ok' ]) valueWithTimeout: 5",
 messageSends: ["timeout:", "valueWithTimeout:", "async:", "assert:", "finished"],
 referencedClasses: []
 }),
@@ -449,35 +446,32 @@ selector: "testTimeouts",
 category: 'tests',
 fn: function (){
 var self=this;
-var $1,$2,$4,$6,$5,$3;
-var suite;
-var runner;
-var result;
-var assertBlock;
-suite=smalltalk.send(["fakeTimeout", "fakeMultipleTimeoutFailing", "fakeMultipleTimeoutPassing", "testPass"],"_collect_",[(function(each){
-return smalltalk.send(smalltalk.send(self,"_class",[]),"_selector_",[each]);
-})]);
-runner=smalltalk.send((smalltalk.TestSuiteRunner || TestSuiteRunner),"_on_",[suite]);
-smalltalk.send(self,"_timeout_",[(200)]);
-result=smalltalk.send(runner,"_result",[]);
-assertBlock=smalltalk.send(self,"_async_",[(function(){
-smalltalk.send(self,"_assert_",[smalltalk.send(smalltalk.send(result,"_errors",[]),"_isEmpty",[])]);
-smalltalk.send(self,"_assert_equals_",[["fakeMultipleTimeoutFailing", "fakeTimeout"],smalltalk.send(self,"_sortedSelectors_",[smalltalk.send(result,"_failures",[])])]);
-return smalltalk.send(self,"_finished",[]);
-})]);
-$1=smalltalk.send(runner,"_announcer",[]);
+var suite,runner,result,assertBlock;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$6,$5,$3;
+suite=_st(["fakeTimeout", "fakeMultipleTimeoutFailing", "fakeMultipleTimeoutPassing", "testPass"])._collect_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(self)._class())._selector_(each);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+runner=_st((smalltalk.TestSuiteRunner || TestSuiteRunner))._on_(suite);
+_st(self)._timeout_((200));
+result=_st(runner)._result();
+assertBlock=_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._assert_(_st(_st(result)._errors())._isEmpty());
+_st(self)._assert_equals_(["fakeMultipleTimeoutFailing", "fakeTimeout"],_st(self)._sortedSelectors_(_st(result)._failures()));
+return _st(self)._finished();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$1=_st(runner)._announcer();
 $2=(smalltalk.ResultAnnouncement || ResultAnnouncement);
 $3=(function(ann){
-$4=smalltalk.send(smalltalk.send(ann,"_result",[]),"__eq_eq",[result]);
+return smalltalk.withContext(function($ctx2) {
$4=_st(_st(ann)._result()).__eq_eq(result);
 $5=(function(){
-$6=smalltalk.send(smalltalk.send(result,"_runs",[]),"__eq",[smalltalk.send(result,"_total",[])]);
-return smalltalk.send($6,"_ifTrue_",[assertBlock]);
-});
-return smalltalk.send($4,"_ifTrue_",[$5]);
-});
-smalltalk.send($1,"_on_do_",[$2,$3]);
-smalltalk.send(runner,"_run",[]);
-return self},
+return smalltalk.withContext(function($ctx3) {
$6=_st(_st(result)._runs()).__eq(_st(result)._total());
+return _st($6)._ifTrue_(assertBlock);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
+return _st($4)._ifTrue_($5);
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})});
+_st($1)._on_do_($2,$3);
+_st(runner)._run();
+return self}, function($ctx1) {$ctx1.fill(self,"testTimeouts",{suite:suite,runner:runner,result:result,assertBlock:assertBlock}, smalltalk.SUnitAsyncTest)})},
 args: [],
 source: "testTimeouts\x0a\x09| suite runner result assertBlock |\x0a\x09suite := #('fakeTimeout' 'fakeMultipleTimeoutFailing' 'fakeMultipleTimeoutPassing' 'testPass') collect: [ :each | self class selector: each ].\x0a    runner := TestSuiteRunner on: suite.\x0a    self timeout: 200.\x0a\x09result := runner result.\x0a    assertBlock := self async: [\x0a\x09\x09self assert: result errors isEmpty.\x0a\x09\x09self assert: #('fakeMultipleTimeoutFailing' 'fakeTimeout') equals: (self sortedSelectors: result failures).\x0a\x09\x09self finished\x0a  \x09].\x0a    runner announcer on: ResultAnnouncement do: [:ann |\x0a    \x09ann result == result  ifTrue: [ result runs = result total ifTrue: assertBlock ]].\x0a\x09runner run",
 messageSends: ["collect:", "selector:", "class", "on:", "timeout:", "result", "async:", "assert:", "isEmpty", "errors", "assert:equals:", "sortedSelectors:", "failures", "finished", "on:do:", "ifTrue:", "=", "total", "runs", "==", "announcer", "run"],
@@ -493,28 +487,28 @@ category: 'tests',
 fn: function (){
 var self=this;
 var x;
-self["@flag"]="bad";
-smalltalk.send(self,"_timeout_",[(10)]);
+return smalltalk.withContext(function($ctx1) { 
self["@flag"]="bad";
+_st(self)._timeout_((10));
 x=(0);
-self["@flag"]=smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-smalltalk.send(self,"_finished",[]);
+self["@flag"]=_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._finished();
 self["@flag"]="ok";
 self["@flag"];
-x=smalltalk.send(x,"__plus",[(1)]);
+x=_st(x).__plus((1));
 x;
-return smalltalk.send(self,"_assert_equals_",[(1),x]);
-})]),"_valueWithTimeout_",[(0)]);
-self["@flag"]=smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-smalltalk.send(self,"_finished",[]);
+return _st(self)._assert_equals_((1),x);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((0));
+self["@flag"]=_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._finished();
 self["@flag"]="ok";
 self["@flag"];
-x=smalltalk.send(x,"__plus",[(1)]);
+x=_st(x).__plus((1));
 x;
-return smalltalk.send(self,"_assert_equals_",[(1),x]);
-})]),"_valueWithTimeout_",[(0)]);
-return self},
+return _st(self)._assert_equals_((1),x);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_((0));
+return self}, function($ctx1) {$ctx1.fill(self,"testTwoAsyncPassesWithFinishedOnlyOneIsRun",{x:x}, smalltalk.SUnitAsyncTest)})},
 args: [],
-source: "testTwoAsyncPassesWithFinishedOnlyOneIsRun\x0a\x09| x |\x0a\x09flag := 'bad'.\x0a\x09self timeout: 10.\x0a    x := 0.\x0a    flag := (self async: [ self finished. flag := 'ok'. x := x+1. self assert: 1 equals: x ]) valueWithTimeout: 0.\x0a    flag := (self async: [ self finished. flag := 'ok'. x := x+1. self assert: 1 equals: x ]) valueWithTimeout: 0.\x0a",
+source: "testTwoAsyncPassesWithFinishedOnlyOneIsRun\x0a\x09| x |\x0a\x09flag := 'bad'.\x0a\x09self timeout: 10.\x0a    x := 0.\x0a    flag := (self async: [ self finished. flag := 'ok'. x := x+1. self assert: 1 equals: x ]) valueWithTimeout: 0.\x0a    flag := (self async: [ self finished. flag := 'ok'. x := x+1. self assert: 1 equals: x ]) valueWithTimeout: 0.",
 messageSends: ["timeout:", "valueWithTimeout:", "async:", "finished", "+", "assert:equals:"],
 referencedClasses: []
 }),

+ 249 - 213
js/SUnit.deploy.js

@@ -6,10 +6,10 @@ smalltalk.method({
 selector: "result",
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@result"];
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"result",{}, smalltalk.ResultAnnouncement)})}
 }),
 smalltalk.ResultAnnouncement);
 
@@ -19,8 +19,8 @@ smalltalk.method({
 selector: "result:",
 fn: function (aTestResult){
 var self=this;
-self["@result"]=aTestResult;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@result"]=aTestResult;
+return self}, function($ctx1) {$ctx1.fill(self,"result:",{aTestResult:aTestResult}, smalltalk.ResultAnnouncement)})}
 }),
 smalltalk.ResultAnnouncement);
 
@@ -33,8 +33,8 @@ smalltalk.method({
 selector: "assert:",
 fn: function (aBoolean){
 var self=this;
-smalltalk.send(self,"_assert_description_",[aBoolean,"Assertion failed"]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_description_(aBoolean,"Assertion failed");
+return self}, function($ctx1) {$ctx1.fill(self,"assert:",{aBoolean:aBoolean}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -44,12 +44,12 @@ smalltalk.method({
 selector: "assert:description:",
 fn: function (aBoolean,aString){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=aBoolean;
 if(! smalltalk.assert($1)){
-smalltalk.send(self,"_signalFailure_",[aString]);
+_st(self)._signalFailure_(aString);
 };
-return self}
+return self}, function($ctx1) {$ctx1.fill(self,"assert:description:",{aBoolean:aBoolean,aString:aString}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -59,10 +59,10 @@ smalltalk.method({
 selector: "assert:equals:",
 fn: function (expected,actual){
 var self=this;
-var $1;
-$1=smalltalk.send(self,"_assert_description_",[smalltalk.send(expected,"__eq",[actual]),smalltalk.send(smalltalk.send(smalltalk.send("Expected: ","__comma",[smalltalk.send(expected,"_asString",[])]),"__comma",[" but was: "]),"__comma",[smalltalk.send(actual,"_asString",[])])]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(self)._assert_description_(_st(expected).__eq(actual),_st(_st(_st("Expected: ").__comma(_st(expected)._asString())).__comma(" but was: ")).__comma(_st(actual)._asString()));
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"assert:equals:",{expected:expected,actual:actual}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -72,18 +72,18 @@ smalltalk.method({
 selector: "async:",
 fn: function (aBlock){
 var self=this;
-var $2,$1;
 var c;
-smalltalk.send(self,"_errorIfNotAsync_",["#async"]);
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+_st(self)._errorIfNotAsync_("#async");
 c=self["@context"];
 $1=(function(){
-$2=smalltalk.send(self,"_isAsync",[]);
+return smalltalk.withContext(function($ctx2) {
$2=_st(self)._isAsync();
 if(smalltalk.assert($2)){
-return smalltalk.send(c,"_execute_",[aBlock]);
+return _st(c)._execute_(aBlock);
 };
-});
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"async:",{aBlock:aBlock,c:c}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -93,8 +93,8 @@ smalltalk.method({
 selector: "context:",
 fn: function (aRunningTestContext){
 var self=this;
-self["@context"]=aRunningTestContext;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@context"]=aRunningTestContext;
+return self}, function($ctx1) {$ctx1.fill(self,"context:",{aRunningTestContext:aRunningTestContext}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -104,8 +104,8 @@ smalltalk.method({
 selector: "deny:",
 fn: function (aBoolean){
 var self=this;
-smalltalk.send(self,"_assert_",[smalltalk.send(aBoolean,"_not",[])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_(_st(aBoolean)._not());
+return self}, function($ctx1) {$ctx1.fill(self,"deny:",{aBoolean:aBoolean}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -115,12 +115,12 @@ smalltalk.method({
 selector: "errorIfNotAsync:",
 fn: function (aString){
 var self=this;
-var $1;
-$1=smalltalk.send(self,"_isAsync",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(self)._isAsync();
 if(! smalltalk.assert($1)){
-smalltalk.send(self,"_error_",[smalltalk.send(aString,"__comma",[" used without prior #timeout:"])]);
+_st(self)._error_(_st(aString).__comma(" used without prior #timeout:"));
 };
-return self}
+return self}, function($ctx1) {$ctx1.fill(self,"errorIfNotAsync:",{aString:aString}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -130,9 +130,9 @@ smalltalk.method({
 selector: "finished",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_errorIfNotAsync_",["#finished"]);
+return smalltalk.withContext(function($ctx1) { 
_st(self)._errorIfNotAsync_("#finished");
 self["@asyncTimeout"]=nil;
-return self}
+return self}, function($ctx1) {$ctx1.fill(self,"finished",{}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -142,10 +142,10 @@ smalltalk.method({
 selector: "isAsync",
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(self["@asyncTimeout"],"_notNil",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(self["@asyncTimeout"])._notNil();
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"isAsync",{}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -155,9 +155,9 @@ smalltalk.method({
 selector: "performTest",
 fn: function (){
 var self=this;
-self["@asyncTimeout"]=nil;
-smalltalk.send(self,"_perform_",[smalltalk.send(self,"_selector",[])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@asyncTimeout"]=nil;
+_st(self)._perform_(_st(self)._selector());
+return self}, function($ctx1) {$ctx1.fill(self,"performTest",{}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -167,8 +167,8 @@ smalltalk.method({
 selector: "runCase",
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send((smalltalk.TestContext || TestContext),"_testCase_",[self]),"_start",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(_st((smalltalk.TestContext || TestContext))._testCase_(self))._start();
+return self}, function($ctx1) {$ctx1.fill(self,"runCase",{}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -178,10 +178,10 @@ smalltalk.method({
 selector: "selector",
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@testSelector"];
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"selector",{}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -191,8 +191,8 @@ smalltalk.method({
 selector: "setTestSelector:",
 fn: function (aSelector){
 var self=this;
-self["@testSelector"]=aSelector;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@testSelector"]=aSelector;
+return self}, function($ctx1) {$ctx1.fill(self,"setTestSelector:",{aSelector:aSelector}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -202,7 +202,7 @@ smalltalk.method({
 selector: "setUp",
 fn: function (){
 var self=this;
-return self}
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"setUp",{}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -212,8 +212,8 @@ smalltalk.method({
 selector: "should:",
 fn: function (aBlock){
 var self=this;
-smalltalk.send(self,"_assert_",[smalltalk.send(aBlock,"_value",[])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_(_st(aBlock)._value());
+return self}, function($ctx1) {$ctx1.fill(self,"should:",{aBlock:aBlock}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -223,13 +223,13 @@ smalltalk.method({
 selector: "should:raise:",
 fn: function (aBlock,anExceptionClass){
 var self=this;
-smalltalk.send(self,"_assert_",[smalltalk.send((function(){
-smalltalk.send(aBlock,"_value",[]);
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_(_st((function(){
+return smalltalk.withContext(function($ctx2) {
_st(aBlock)._value();
 return false;
-}),"_on_do_",[anExceptionClass,(function(ex){
-return true;
-})])]);
-return self}
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_(anExceptionClass,(function(ex){
+return smalltalk.withContext(function($ctx2) {
return true;
+}, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})})));
+return self}, function($ctx1) {$ctx1.fill(self,"should:raise:",{aBlock:aBlock,anExceptionClass:anExceptionClass}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -239,13 +239,13 @@ smalltalk.method({
 selector: "shouldnt:raise:",
 fn: function (aBlock,anExceptionClass){
 var self=this;
-smalltalk.send(self,"_assert_",[smalltalk.send((function(){
-smalltalk.send(aBlock,"_value",[]);
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_(_st((function(){
+return smalltalk.withContext(function($ctx2) {
_st(aBlock)._value();
 return true;
-}),"_on_do_",[anExceptionClass,(function(ex){
-return false;
-})])]);
-return self}
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_(anExceptionClass,(function(ex){
+return smalltalk.withContext(function($ctx2) {
return false;
+}, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})})));
+return self}, function($ctx1) {$ctx1.fill(self,"shouldnt:raise:",{aBlock:aBlock,anExceptionClass:anExceptionClass}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -255,11 +255,11 @@ smalltalk.method({
 selector: "signalFailure:",
 fn: function (aString){
 var self=this;
-var $1,$2;
-$1=smalltalk.send((smalltalk.TestFailure || TestFailure),"_new",[]);
-smalltalk.send($1,"_messageText_",[aString]);
-$2=smalltalk.send($1,"_signal",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st((smalltalk.TestFailure || TestFailure))._new();
+_st($1)._messageText_(aString);
+$2=_st($1)._signal();
+return self}, function($ctx1) {$ctx1.fill(self,"signalFailure:",{aString:aString}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -269,7 +269,7 @@ smalltalk.method({
 selector: "tearDown",
 fn: function (){
 var self=this;
-return self}
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"tearDown",{}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -279,18 +279,18 @@ smalltalk.method({
 selector: "timeout:",
 fn: function (aNumber){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@asyncTimeout"];
 if(($receiver = $1) == nil || $receiver == undefined){
 $1;
 } else {
-smalltalk.send(self["@asyncTimeout"],"_clearTimeout",[]);
+_st(self["@asyncTimeout"])._clearTimeout();
 };
 self["@asyncTimeout"]=(0);
-self["@asyncTimeout"]=smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-return smalltalk.send(self,"_assert_description_",[false,"SUnit grace time exhausted"]);
-})]),"_valueWithTimeout_",[aNumber]);
-return self}
+self["@asyncTimeout"]=_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._assert_description_(false,"SUnit grace time exhausted");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_(aNumber);
+return self}, function($ctx1) {$ctx1.fill(self,"timeout:",{aNumber:aNumber}, smalltalk.TestCase)})}
 }),
 smalltalk.TestCase);
 
@@ -301,16 +301,16 @@ smalltalk.method({
 selector: "allTestSelectors",
 fn: function (){
 var self=this;
-var $1,$2;
 var selectors;
-selectors=smalltalk.send(self,"_testSelectors",[]);
-$1=smalltalk.send(self,"_shouldInheritSelectors",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+selectors=_st(self)._testSelectors();
+$1=_st(self)._shouldInheritSelectors();
 if(smalltalk.assert($1)){
-smalltalk.send(selectors,"_addAll_",[smalltalk.send(smalltalk.send(self,"_superclass",[]),"_allTestSelectors",[])]);
+_st(selectors)._addAll_(_st(_st(self)._superclass())._allTestSelectors());
 };
 $2=selectors;
 return $2;
-}
+}, function($ctx1) {$ctx1.fill(self,"allTestSelectors",{selectors:selectors}, smalltalk.TestCase.klass)})}
 }),
 smalltalk.TestCase.klass);
 
@@ -320,12 +320,12 @@ smalltalk.method({
 selector: "buildSuite",
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(self,"_allTestSelectors",[]),"_collect_",[(function(each){
-return smalltalk.send(self,"_selector_",[each]);
-})]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._allTestSelectors())._collect_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._selector_(each);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"buildSuite",{}, smalltalk.TestCase.klass)})}
 }),
 smalltalk.TestCase.klass);
 
@@ -335,10 +335,10 @@ smalltalk.method({
 selector: "isAbstract",
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(self,"_name",[]),"__eq",["TestCase"]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._name()).__eq("TestCase");
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"isAbstract",{}, smalltalk.TestCase.klass)})}
 }),
 smalltalk.TestCase.klass);
 
@@ -348,10 +348,10 @@ smalltalk.method({
 selector: "lookupHierarchyRoot",
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=(smalltalk.TestCase || TestCase);
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"lookupHierarchyRoot",{}, smalltalk.TestCase.klass)})}
 }),
 smalltalk.TestCase.klass);
 
@@ -361,13 +361,13 @@ smalltalk.method({
 selector: "selector:",
 fn: function (aSelector){
 var self=this;
-var $2,$3,$1;
-$2=smalltalk.send(self,"_new",[]);
-smalltalk.send($2,"_setTestSelector_",[aSelector]);
-$3=smalltalk.send($2,"_yourself",[]);
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
+$2=_st(self)._new();
+_st($2)._setTestSelector_(aSelector);
+$3=_st($2)._yourself();
 $1=$3;
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"selector:",{aSelector:aSelector}, smalltalk.TestCase.klass)})}
 }),
 smalltalk.TestCase.klass);
 
@@ -377,10 +377,10 @@ smalltalk.method({
 selector: "shouldInheritSelectors",
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(self,"_~_eq",[smalltalk.send(self,"_lookupHierarchyRoot",[])]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(self).__tild_eq(_st(self)._lookupHierarchyRoot());
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"shouldInheritSelectors",{}, smalltalk.TestCase.klass)})}
 }),
 smalltalk.TestCase.klass);
 
@@ -390,12 +390,12 @@ smalltalk.method({
 selector: "testSelectors",
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(smalltalk.send(self,"_methodDictionary",[]),"_keys",[]),"_select_",[(function(each){
-return smalltalk.send(each,"_match_",["^test"]);
-})]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(_st(self)._methodDictionary())._keys())._select_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(each)._match_("^test");
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"testSelectors",{}, smalltalk.TestCase.klass)})}
 }),
 smalltalk.TestCase.klass);
 
@@ -407,31 +407,31 @@ smalltalk.method({
 selector: "execute:",
 fn: function (aBlock){
 var self=this;
-var $1,$3,$4,$2;
 var failed;
-smalltalk.send(self["@testCase"],"_context_",[self]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$4,$2;
+_st(self["@testCase"])._context_(self);
 $1=(function(){
-failed=true;
+return smalltalk.withContext(function($ctx2) {
failed=true;
 failed;
-smalltalk.send(aBlock,"_value",[]);
+_st(aBlock)._value();
 failed=false;
 return failed;
-});
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
 $2=(function(){
-smalltalk.send(self["@testCase"],"_context_",[nil]);
-$3=smalltalk.send(failed,"_and_",[(function(){
-return smalltalk.send(self["@testCase"],"_isAsync",[]);
-})]);
+return smalltalk.withContext(function($ctx2) {
_st(self["@testCase"])._context_(nil);
+$3=_st(failed)._and_((function(){
+return smalltalk.withContext(function($ctx3) {
return _st(self["@testCase"])._isAsync();
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 if(smalltalk.assert($3)){
-smalltalk.send(self["@testCase"],"_finished",[]);
+_st(self["@testCase"])._finished();
 };
-$4=smalltalk.send(self["@testCase"],"_isAsync",[]);
+$4=_st(self["@testCase"])._isAsync();
 if(! smalltalk.assert($4)){
-return smalltalk.send(self["@testCase"],"_tearDown",[]);
+return _st(self["@testCase"])._tearDown();
 };
-});
-smalltalk.send($1,"_ensure_",[$2]);
-return self}
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+_st($1)._ensure_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"execute:",{aBlock:aBlock,failed:failed}, smalltalk.TestContext)})}
 }),
 smalltalk.TestContext);
 
@@ -441,11 +441,11 @@ smalltalk.method({
 selector: "start",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_execute_",[(function(){
-smalltalk.send(self["@testCase"],"_setUp",[]);
-return smalltalk.send(self["@testCase"],"_performTest",[]);
-})]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._execute_((function(){
+return smalltalk.withContext(function($ctx2) {
_st(self["@testCase"])._setUp();
+return _st(self["@testCase"])._performTest();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"start",{}, smalltalk.TestContext)})}
 }),
 smalltalk.TestContext);
 
@@ -455,8 +455,8 @@ smalltalk.method({
 selector: "testCase:",
 fn: function (aTestCase){
 var self=this;
-self["@testCase"]=aTestCase;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@testCase"]=aTestCase;
+return self}, function($ctx1) {$ctx1.fill(self,"testCase:",{aTestCase:aTestCase}, smalltalk.TestContext)})}
 }),
 smalltalk.TestContext);
 
@@ -467,13 +467,13 @@ smalltalk.method({
 selector: "testCase:",
 fn: function (aTestCase){
 var self=this;
-var $2,$3,$1;
-$2=smalltalk.send(self,"_new",[]);
-smalltalk.send($2,"_testCase_",[aTestCase]);
-$3=smalltalk.send($2,"_yourself",[]);
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
+$2=_st(self)._new();
+_st($2)._testCase_(aTestCase);
+$3=_st($2)._yourself();
 $1=$3;
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"testCase:",{aTestCase:aTestCase}, smalltalk.TestContext.klass)})}
 }),
 smalltalk.TestContext.klass);
 
@@ -485,21 +485,21 @@ smalltalk.method({
 selector: "execute:",
 fn: function (aBlock){
 var self=this;
-var $1,$3,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
 $1=(function(){
-return smalltalk.send(self,"_withErrorReporting_",[(function(){
-return smalltalk.send(self,"_execute_",[aBlock],smalltalk.TestContext);
-})]);
-});
+return smalltalk.withContext(function($ctx2) {
return _st(self)._withErrorReporting_((function(){
+return smalltalk.withContext(function($ctx3) {
return smalltalk.TestContext.fn.prototype._execute_.apply(_st(self), [aBlock]);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
 $2=(function(){
-$3=smalltalk.send(self["@testCase"],"_isAsync",[]);
+return smalltalk.withContext(function($ctx2) {
$3=_st(self["@testCase"])._isAsync();
 if(! smalltalk.assert($3)){
-smalltalk.send(self["@result"],"_increaseRuns",[]);
-return smalltalk.send(self["@finished"],"_value",[]);
+_st(self["@result"])._increaseRuns();
+return _st(self["@finished"])._value();
 };
-});
-smalltalk.send($1,"_ensure_",[$2]);
-return self}
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+_st($1)._ensure_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"execute:",{aBlock:aBlock}, smalltalk.ReportingTestContext)})}
 }),
 smalltalk.ReportingTestContext);
 
@@ -509,8 +509,8 @@ smalltalk.method({
 selector: "finished:",
 fn: function (aBlock){
 var self=this;
-self["@finished"]=aBlock;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@finished"]=aBlock;
+return self}, function($ctx1) {$ctx1.fill(self,"finished:",{aBlock:aBlock}, smalltalk.ReportingTestContext)})}
 }),
 smalltalk.ReportingTestContext);
 
@@ -520,8 +520,8 @@ smalltalk.method({
 selector: "result:",
 fn: function (aTestResult){
 var self=this;
-self["@result"]=aTestResult;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@result"]=aTestResult;
+return self}, function($ctx1) {$ctx1.fill(self,"result:",{aTestResult:aTestResult}, smalltalk.ReportingTestContext)})}
 }),
 smalltalk.ReportingTestContext);
 
@@ -531,14 +531,14 @@ smalltalk.method({
 selector: "withErrorReporting:",
 fn: function (aBlock){
 var self=this;
-smalltalk.send((function(){
-return smalltalk.send(aBlock,"_on_do_",[(smalltalk.TestFailure || TestFailure),(function(ex){
-return smalltalk.send(self["@result"],"_addFailure_",[self["@testCase"]]);
-})]);
-}),"_on_do_",[(smalltalk.Error || Error),(function(ex){
-return smalltalk.send(self["@result"],"_addError_",[self["@testCase"]]);
-})]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(aBlock)._on_do_((smalltalk.TestFailure || TestFailure),(function(ex){
+return smalltalk.withContext(function($ctx3) {
return _st(self["@result"])._addFailure_(self["@testCase"]);
+}, function($ctx3) {$ctx3.fillBlock({ex:ex},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_((smalltalk.Error || Error),(function(ex){
+return smalltalk.withContext(function($ctx2) {
return _st(self["@result"])._addError_(self["@testCase"]);
+}, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"withErrorReporting:",{aBlock:aBlock}, smalltalk.ReportingTestContext)})}
 }),
 smalltalk.ReportingTestContext);
 
@@ -549,14 +549,14 @@ smalltalk.method({
 selector: "testCase:result:finished:",
 fn: function (aTestCase,aTestResult,aBlock){
 var self=this;
-var $2,$3,$1;
-$2=smalltalk.send(self,"_testCase_",[aTestCase],smalltalk.TestContext.klass);
-smalltalk.send($2,"_result_",[aTestResult]);
-smalltalk.send($2,"_finished_",[aBlock]);
-$3=smalltalk.send($2,"_yourself",[]);
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
+$2=smalltalk.TestContext.klass.fn.prototype._testCase_.apply(_st(self), [aTestCase]);
+_st($2)._result_(aTestResult);
+_st($2)._finished_(aBlock);
+$3=_st($2)._yourself();
 $1=$3;
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"testCase:result:finished:",{aTestCase:aTestCase,aTestResult:aTestResult,aBlock:aBlock}, smalltalk.ReportingTestContext.klass)})}
 }),
 smalltalk.ReportingTestContext.klass);
 
@@ -571,8 +571,8 @@ smalltalk.method({
 selector: "addError:",
 fn: function (anError){
 var self=this;
-smalltalk.send(smalltalk.send(self,"_errors",[]),"_add_",[anError]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._errors())._add_(anError);
+return self}, function($ctx1) {$ctx1.fill(self,"addError:",{anError:anError}, smalltalk.TestResult)})}
 }),
 smalltalk.TestResult);
 
@@ -582,8 +582,8 @@ smalltalk.method({
 selector: "addFailure:",
 fn: function (aFailure){
 var self=this;
-smalltalk.send(smalltalk.send(self,"_failures",[]),"_add_",[aFailure]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._failures())._add_(aFailure);
+return self}, function($ctx1) {$ctx1.fill(self,"addFailure:",{aFailure:aFailure}, smalltalk.TestResult)})}
 }),
 smalltalk.TestResult);
 
@@ -593,10 +593,10 @@ smalltalk.method({
 selector: "errors",
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@errors"];
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"errors",{}, smalltalk.TestResult)})}
 }),
 smalltalk.TestResult);
 
@@ -606,10 +606,10 @@ smalltalk.method({
 selector: "failures",
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@failures"];
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"failures",{}, smalltalk.TestResult)})}
 }),
 smalltalk.TestResult);
 
@@ -619,8 +619,8 @@ smalltalk.method({
 selector: "increaseRuns",
 fn: function (){
 var self=this;
-self["@runs"]=smalltalk.send(self["@runs"],"__plus",[(1)]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@runs"]=_st(self["@runs"]).__plus((1));
+return self}, function($ctx1) {$ctx1.fill(self,"increaseRuns",{}, smalltalk.TestResult)})}
 }),
 smalltalk.TestResult);
 
@@ -630,13 +630,49 @@ smalltalk.method({
 selector: "initialize",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_initialize",[],smalltalk.Object);
-self["@timestamp"]=smalltalk.send((smalltalk.Date || Date),"_now",[]);
+return smalltalk.withContext(function($ctx1) { 
smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+self["@timestamp"]=_st((smalltalk.Date || Date))._now();
 self["@runs"]=(0);
-self["@errors"]=smalltalk.send((smalltalk.Array || Array),"_new",[]);
-self["@failures"]=smalltalk.send((smalltalk.Array || Array),"_new",[]);
+self["@errors"]=_st((smalltalk.Array || Array))._new();
+self["@failures"]=_st((smalltalk.Array || Array))._new();
 self["@total"]=(0);
-return self}
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.TestResult)})}
+}),
+smalltalk.TestResult);
+
+smalltalk.addMethod(
+"_nextRunDo_",
+smalltalk.method({
+selector: "nextRunDo:",
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=_st(_st(self)._runs()).__eq_eq(_st(self)._total());
+if(! smalltalk.assert($2)){
+$1=_st(aBlock)._value_(_st(_st(self)._runs()).__plus((1)));
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"nextRunDo:",{aBlock:aBlock}, smalltalk.TestResult)})}
+}),
+smalltalk.TestResult);
+
+smalltalk.addMethod(
+"_runCase_",
+smalltalk.method({
+selector: "runCase:",
+fn: function (aTestCase){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st((function(){
+return smalltalk.withContext(function($ctx2) {
return _st((function(){
+return smalltalk.withContext(function($ctx3) {
_st(self)._increaseRuns();
+return _st(aTestCase)._runCase();
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}))._on_do_((smalltalk.TestFailure || TestFailure),(function(ex){
+return smalltalk.withContext(function($ctx3) {
return _st(self)._addFailure_(aTestCase);
+}, function($ctx3) {$ctx3.fillBlock({ex:ex},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_((smalltalk.Error || Error),(function(ex){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._addError_(aTestCase);
+}, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"runCase:",{aTestCase:aTestCase}, smalltalk.TestResult)})}
 }),
 smalltalk.TestResult);
 
@@ -646,10 +682,10 @@ smalltalk.method({
 selector: "runs",
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@runs"];
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"runs",{}, smalltalk.TestResult)})}
 }),
 smalltalk.TestResult);
 
@@ -659,21 +695,21 @@ smalltalk.method({
 selector: "status",
 fn: function (){
 var self=this;
-var $2,$4,$3,$1;
-$2=smalltalk.send(smalltalk.send(self,"_errors",[]),"_isEmpty",[]);
+return smalltalk.withContext(function($ctx1) { 
var $2,$4,$3,$1;
+$2=_st(_st(self)._errors())._isEmpty();
 $3=(function(){
-$4=smalltalk.send(smalltalk.send(self,"_failures",[]),"_isEmpty",[]);
+return smalltalk.withContext(function($ctx2) {
$4=_st(_st(self)._failures())._isEmpty();
 if(smalltalk.assert($4)){
 return "success";
 } else {
 return "failure";
 };
-});
-$1=smalltalk.send($2,"_ifTrue_ifFalse_",[$3,(function(){
-return "error";
-})]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+$1=_st($2)._ifTrue_ifFalse_($3,(function(){
+return smalltalk.withContext(function($ctx2) {
return "error";
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"status",{}, smalltalk.TestResult)})}
 }),
 smalltalk.TestResult);
 
@@ -683,10 +719,10 @@ smalltalk.method({
 selector: "timestamp",
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@timestamp"];
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"timestamp",{}, smalltalk.TestResult)})}
 }),
 smalltalk.TestResult);
 
@@ -696,10 +732,10 @@ smalltalk.method({
 selector: "total",
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@total"];
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"total",{}, smalltalk.TestResult)})}
 }),
 smalltalk.TestResult);
 
@@ -709,8 +745,8 @@ smalltalk.method({
 selector: "total:",
 fn: function (aNumber){
 var self=this;
-self["@total"]=aNumber;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@total"]=aNumber;
+return self}, function($ctx1) {$ctx1.fill(self,"total:",{aNumber:aNumber}, smalltalk.TestResult)})}
 }),
 smalltalk.TestResult);
 
@@ -723,10 +759,10 @@ smalltalk.method({
 selector: "announcer",
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@announcer"];
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"announcer",{}, smalltalk.TestSuiteRunner)})}
 }),
 smalltalk.TestSuiteRunner);
 
@@ -736,12 +772,12 @@ smalltalk.method({
 selector: "contextOf:",
 fn: function (anInteger){
 var self=this;
-var $1;
-$1=smalltalk.send((smalltalk.ReportingTestContext || ReportingTestContext),"_testCase_result_finished_",[smalltalk.send(self["@suite"],"_at_",[anInteger]),self["@result"],(function(){
-return smalltalk.send(self,"_resume",[]);
-})]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st((smalltalk.ReportingTestContext || ReportingTestContext))._testCase_result_finished_(_st(self["@suite"])._at_(anInteger),self["@result"],(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._resume();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"contextOf:",{anInteger:anInteger}, smalltalk.TestSuiteRunner)})}
 }),
 smalltalk.TestSuiteRunner);
 
@@ -751,20 +787,20 @@ smalltalk.method({
 selector: "initialize",
 fn: function (){
 var self=this;
-var $1;
-smalltalk.send(self,"_initialize",[],smalltalk.Object);
-self["@announcer"]=smalltalk.send((smalltalk.Announcer || Announcer),"_new",[]);
-self["@result"]=smalltalk.send((smalltalk.TestResult || TestResult),"_new",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+self["@announcer"]=_st((smalltalk.Announcer || Announcer))._new();
+self["@result"]=_st((smalltalk.TestResult || TestResult))._new();
 self["@runNextTest"]=(function(){
 var runs;
-runs=smalltalk.send(self["@result"],"_runs",[]);
+return smalltalk.withContext(function($ctx2) {
runs=_st(self["@result"])._runs();
 runs;
-$1=smalltalk.send(runs,"__lt",[smalltalk.send(self["@result"],"_total",[])]);
+$1=_st(runs).__lt(_st(self["@result"])._total());
 if(smalltalk.assert($1)){
-return smalltalk.send(smalltalk.send(self,"_contextOf_",[smalltalk.send(runs,"__plus",[(1)])]),"_start",[]);
+return _st(_st(self)._contextOf_(_st(runs).__plus((1))))._start();
 };
-});
-return self}
+}, function($ctx2) {$ctx2.fillBlock({runs:runs},$ctx1)})});
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.TestSuiteRunner)})}
 }),
 smalltalk.TestSuiteRunner);
 
@@ -774,10 +810,10 @@ smalltalk.method({
 selector: "result",
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@result"];
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"result",{}, smalltalk.TestSuiteRunner)})}
 }),
 smalltalk.TestSuiteRunner);
 
@@ -787,9 +823,9 @@ smalltalk.method({
 selector: "resume",
 fn: function (){
 var self=this;
-smalltalk.send(self["@runNextTest"],"_fork",[]);
-smalltalk.send(self["@announcer"],"_announce_",[smalltalk.send(smalltalk.send((smalltalk.ResultAnnouncement || ResultAnnouncement),"_new",[]),"_result_",[self["@result"]])]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self["@runNextTest"])._fork();
+_st(self["@announcer"])._announce_(_st(_st((smalltalk.ResultAnnouncement || ResultAnnouncement))._new())._result_(self["@result"]));
+return self}, function($ctx1) {$ctx1.fill(self,"resume",{}, smalltalk.TestSuiteRunner)})}
 }),
 smalltalk.TestSuiteRunner);
 
@@ -799,9 +835,9 @@ smalltalk.method({
 selector: "run",
 fn: function (){
 var self=this;
-smalltalk.send(self["@result"],"_total_",[smalltalk.send(self["@suite"],"_size",[])]);
-smalltalk.send(self,"_resume",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self["@result"])._total_(_st(self["@suite"])._size());
+_st(self)._resume();
+return self}, function($ctx1) {$ctx1.fill(self,"run",{}, smalltalk.TestSuiteRunner)})}
 }),
 smalltalk.TestSuiteRunner);
 
@@ -811,8 +847,8 @@ smalltalk.method({
 selector: "suite:",
 fn: function (aCollection){
 var self=this;
-self["@suite"]=aCollection;
-return self}
+return smalltalk.withContext(function($ctx1) { 
self["@suite"]=aCollection;
+return self}, function($ctx1) {$ctx1.fill(self,"suite:",{aCollection:aCollection}, smalltalk.TestSuiteRunner)})}
 }),
 smalltalk.TestSuiteRunner);
 
@@ -823,8 +859,8 @@ smalltalk.method({
 selector: "new",
 fn: function (){
 var self=this;
-smalltalk.send(self,"_shouldNotImplement",[]);
-return self}
+return smalltalk.withContext(function($ctx1) { 
_st(self)._shouldNotImplement();
+return self}, function($ctx1) {$ctx1.fill(self,"new",{}, smalltalk.TestSuiteRunner.klass)})}
 }),
 smalltalk.TestSuiteRunner.klass);
 
@@ -834,10 +870,10 @@ smalltalk.method({
 selector: "on:",
 fn: function (aCollection){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(self,"_new",[],smalltalk.Object.klass),"_suite_",[aCollection]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(smalltalk.Object.klass.fn.prototype._new.apply(_st(self), []))._suite_(aCollection);
 return $1;
-}
+}, function($ctx1) {$ctx1.fill(self,"on:",{aCollection:aCollection}, smalltalk.TestSuiteRunner.klass)})}
 }),
 smalltalk.TestSuiteRunner.klass);
 

+ 265 - 219
js/SUnit.js

@@ -7,10 +7,10 @@ selector: "result",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@result"];
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"result",{}, smalltalk.ResultAnnouncement)})},
 args: [],
 source: "result\x0a\x09^result",
 messageSends: [],
@@ -25,8 +25,8 @@ selector: "result:",
 category: 'accessing',
 fn: function (aTestResult){
 var self=this;
-self["@result"]=aTestResult;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@result"]=aTestResult;
+return self}, function($ctx1) {$ctx1.fill(self,"result:",{aTestResult:aTestResult}, smalltalk.ResultAnnouncement)})},
 args: ["aTestResult"],
 source: "result: aTestResult\x0a\x09result := aTestResult",
 messageSends: [],
@@ -37,7 +37,7 @@ smalltalk.ResultAnnouncement);
 
 
 smalltalk.addClass('TestCase', smalltalk.Object, ['testSelector', 'asyncTimeout', 'context'], 'SUnit');
-smalltalk.TestCase.comment="A TestCase is an implementation of the command pattern to run a test.  \x0a\x0a`TestCase` instances are created with the class method `#selector:`, \x0apassing the symbol that names the method to be executed when the test case runs.\x0a\x0aWhen you discover a new fixture, subclass `TestCase` and create a `#test...` method for the first test.  \x0aAs that method develops and more `#test...` methods are added, you will find yourself refactoring temps \x0ainto instance variables for the objects in the fixture and overriding `#setUp` to initialize these variables.  \x0aAs required, override `#tearDown` to nil references, release objects and deallocate.\x0a\x0a"
+smalltalk.TestCase.comment="A TestCase is an implementation of the command pattern to run a test.  \x0a\x0a`TestCase` instances are created with the class method `#selector:`, \x0apassing the symbol that names the method to be executed when the test case runs.\x0a\x0aWhen you discover a new fixture, subclass `TestCase` and create a `#test...` method for the first test.  \x0aAs that method develops and more `#test...` methods are added, you will find yourself refactoring temps \x0ainto instance variables for the objects in the fixture and overriding `#setUp` to initialize these variables.  \x0aAs required, override `#tearDown` to nil references, release objects and deallocate."
 smalltalk.addMethod(
 "_assert_",
 smalltalk.method({
@@ -45,8 +45,8 @@ selector: "assert:",
 category: 'testing',
 fn: function (aBoolean){
 var self=this;
-smalltalk.send(self,"_assert_description_",[aBoolean,"Assertion failed"]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_description_(aBoolean,"Assertion failed");
+return self}, function($ctx1) {$ctx1.fill(self,"assert:",{aBoolean:aBoolean}, smalltalk.TestCase)})},
 args: ["aBoolean"],
 source: "assert: aBoolean\x0a\x09self assert: aBoolean description: 'Assertion failed'",
 messageSends: ["assert:description:"],
@@ -61,12 +61,12 @@ selector: "assert:description:",
 category: 'testing',
 fn: function (aBoolean,aString){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=aBoolean;
 if(! smalltalk.assert($1)){
-smalltalk.send(self,"_signalFailure_",[aString]);
+_st(self)._signalFailure_(aString);
 };
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"assert:description:",{aBoolean:aBoolean,aString:aString}, smalltalk.TestCase)})},
 args: ["aBoolean", "aString"],
 source: "assert: aBoolean description: aString\x0a\x09aBoolean ifFalse: [self signalFailure: aString]",
 messageSends: ["ifFalse:", "signalFailure:"],
@@ -81,10 +81,10 @@ selector: "assert:equals:",
 category: 'testing',
 fn: function (expected,actual){
 var self=this;
-var $1;
-$1=smalltalk.send(self,"_assert_description_",[smalltalk.send(expected,"__eq",[actual]),smalltalk.send(smalltalk.send(smalltalk.send("Expected: ","__comma",[smalltalk.send(expected,"_asString",[])]),"__comma",[" but was: "]),"__comma",[smalltalk.send(actual,"_asString",[])])]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(self)._assert_description_(_st(expected).__eq(actual),_st(_st(_st("Expected: ").__comma(_st(expected)._asString())).__comma(" but was: ")).__comma(_st(actual)._asString()));
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"assert:equals:",{expected:expected,actual:actual}, smalltalk.TestCase)})},
 args: ["expected", "actual"],
 source: "assert: expected equals: actual\x0a\x09^ self assert: (expected = actual) description: 'Expected: ', expected asString, ' but was: ', actual asString",
 messageSends: ["assert:description:", "=", ",", "asString"],
@@ -99,18 +99,18 @@ selector: "async:",
 category: 'async',
 fn: function (aBlock){
 var self=this;
-var $2,$1;
 var c;
-smalltalk.send(self,"_errorIfNotAsync_",["#async"]);
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+_st(self)._errorIfNotAsync_("#async");
 c=self["@context"];
 $1=(function(){
-$2=smalltalk.send(self,"_isAsync",[]);
+return smalltalk.withContext(function($ctx2) {
$2=_st(self)._isAsync();
 if(smalltalk.assert($2)){
-return smalltalk.send(c,"_execute_",[aBlock]);
+return _st(c)._execute_(aBlock);
 };
-});
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"async:",{aBlock:aBlock,c:c}, smalltalk.TestCase)})},
 args: ["aBlock"],
 source: "async: aBlock\x0a\x09| c |\x0a\x09self errorIfNotAsync: '#async'.\x0a    c := context.\x0a    ^ [ self isAsync ifTrue: [ c execute: aBlock ] ]",
 messageSends: ["errorIfNotAsync:", "ifTrue:", "execute:", "isAsync"],
@@ -125,8 +125,8 @@ selector: "context:",
 category: 'accessing',
 fn: function (aRunningTestContext){
 var self=this;
-self["@context"]=aRunningTestContext;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@context"]=aRunningTestContext;
+return self}, function($ctx1) {$ctx1.fill(self,"context:",{aRunningTestContext:aRunningTestContext}, smalltalk.TestCase)})},
 args: ["aRunningTestContext"],
 source: "context: aRunningTestContext\x0a\x09context := aRunningTestContext",
 messageSends: [],
@@ -141,8 +141,8 @@ selector: "deny:",
 category: 'testing',
 fn: function (aBoolean){
 var self=this;
-smalltalk.send(self,"_assert_",[smalltalk.send(aBoolean,"_not",[])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_(_st(aBoolean)._not());
+return self}, function($ctx1) {$ctx1.fill(self,"deny:",{aBoolean:aBoolean}, smalltalk.TestCase)})},
 args: ["aBoolean"],
 source: "deny: aBoolean\x0a\x09self assert: aBoolean not",
 messageSends: ["assert:", "not"],
@@ -157,12 +157,12 @@ selector: "errorIfNotAsync:",
 category: 'error handling',
 fn: function (aString){
 var self=this;
-var $1;
-$1=smalltalk.send(self,"_isAsync",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(self)._isAsync();
 if(! smalltalk.assert($1)){
-smalltalk.send(self,"_error_",[smalltalk.send(aString,"__comma",[" used without prior #timeout:"])]);
+_st(self)._error_(_st(aString).__comma(" used without prior #timeout:"));
 };
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"errorIfNotAsync:",{aString:aString}, smalltalk.TestCase)})},
 args: ["aString"],
 source: "errorIfNotAsync: aString\x0a\x09self isAsync ifFalse: [ \x0a    \x09self error: aString, ' used without prior #timeout:' ]",
 messageSends: ["ifFalse:", "error:", ",", "isAsync"],
@@ -177,9 +177,9 @@ selector: "finished",
 category: 'async',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_errorIfNotAsync_",["#finished"]);
+return smalltalk.withContext(function($ctx1) { 
_st(self)._errorIfNotAsync_("#finished");
 self["@asyncTimeout"]=nil;
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"finished",{}, smalltalk.TestCase)})},
 args: [],
 source: "finished\x0a\x09self errorIfNotAsync: '#finished'.\x0a\x09asyncTimeout := nil",
 messageSends: ["errorIfNotAsync:"],
@@ -194,10 +194,10 @@ selector: "isAsync",
 category: 'testing',
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(self["@asyncTimeout"],"_notNil",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(self["@asyncTimeout"])._notNil();
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"isAsync",{}, smalltalk.TestCase)})},
 args: [],
 source: "isAsync\x0a\x09^asyncTimeout notNil",
 messageSends: ["notNil"],
@@ -212,11 +212,11 @@ selector: "performTest",
 category: 'running',
 fn: function (){
 var self=this;
-self["@asyncTimeout"]=nil;
-smalltalk.send(self,"_perform_",[smalltalk.send(self,"_selector",[])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@asyncTimeout"]=nil;
+_st(self)._perform_(_st(self)._selector());
+return self}, function($ctx1) {$ctx1.fill(self,"performTest",{}, smalltalk.TestCase)})},
 args: [],
-source: "performTest\x0a\x09asyncTimeout := nil.\x0a\x09self perform: self selector\x0a",
+source: "performTest\x0a\x09asyncTimeout := nil.\x0a\x09self perform: self selector",
 messageSends: ["perform:", "selector"],
 referencedClasses: []
 }),
@@ -229,8 +229,8 @@ selector: "runCase",
 category: 'running',
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send((smalltalk.TestContext || TestContext),"_testCase_",[self]),"_start",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(_st((smalltalk.TestContext || TestContext))._testCase_(self))._start();
+return self}, function($ctx1) {$ctx1.fill(self,"runCase",{}, smalltalk.TestCase)})},
 args: [],
 source: "runCase\x0a\x09\x22Runs a test case in isolated context, leaking all errors.\x22\x0a\x0a\x09(TestContext testCase: self) start",
 messageSends: ["start", "testCase:"],
@@ -245,10 +245,10 @@ selector: "selector",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@testSelector"];
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"selector",{}, smalltalk.TestCase)})},
 args: [],
 source: "selector\x0a\x09^testSelector",
 messageSends: [],
@@ -263,8 +263,8 @@ selector: "setTestSelector:",
 category: 'accessing',
 fn: function (aSelector){
 var self=this;
-self["@testSelector"]=aSelector;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@testSelector"]=aSelector;
+return self}, function($ctx1) {$ctx1.fill(self,"setTestSelector:",{aSelector:aSelector}, smalltalk.TestCase)})},
 args: ["aSelector"],
 source: "setTestSelector: aSelector\x0a\x09testSelector := aSelector",
 messageSends: [],
@@ -279,7 +279,7 @@ selector: "setUp",
 category: 'running',
 fn: function (){
 var self=this;
-return self},
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"setUp",{}, smalltalk.TestCase)})},
 args: [],
 source: "setUp",
 messageSends: [],
@@ -294,8 +294,8 @@ selector: "should:",
 category: 'testing',
 fn: function (aBlock){
 var self=this;
-smalltalk.send(self,"_assert_",[smalltalk.send(aBlock,"_value",[])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_(_st(aBlock)._value());
+return self}, function($ctx1) {$ctx1.fill(self,"should:",{aBlock:aBlock}, smalltalk.TestCase)})},
 args: ["aBlock"],
 source: "should: aBlock\x0a\x09self assert: aBlock value",
 messageSends: ["assert:", "value"],
@@ -310,13 +310,13 @@ selector: "should:raise:",
 category: 'testing',
 fn: function (aBlock,anExceptionClass){
 var self=this;
-smalltalk.send(self,"_assert_",[smalltalk.send((function(){
-smalltalk.send(aBlock,"_value",[]);
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_(_st((function(){
+return smalltalk.withContext(function($ctx2) {
_st(aBlock)._value();
 return false;
-}),"_on_do_",[anExceptionClass,(function(ex){
-return true;
-})])]);
-return self},
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_(anExceptionClass,(function(ex){
+return smalltalk.withContext(function($ctx2) {
return true;
+}, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})})));
+return self}, function($ctx1) {$ctx1.fill(self,"should:raise:",{aBlock:aBlock,anExceptionClass:anExceptionClass}, smalltalk.TestCase)})},
 args: ["aBlock", "anExceptionClass"],
 source: "should: aBlock raise: anExceptionClass\x0a\x09self assert: ([aBlock value. false] \x0a\x09\x09on: anExceptionClass \x0a\x09\x09do: [:ex | true])",
 messageSends: ["assert:", "on:do:", "value"],
@@ -331,13 +331,13 @@ selector: "shouldnt:raise:",
 category: 'testing',
 fn: function (aBlock,anExceptionClass){
 var self=this;
-smalltalk.send(self,"_assert_",[smalltalk.send((function(){
-smalltalk.send(aBlock,"_value",[]);
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_(_st((function(){
+return smalltalk.withContext(function($ctx2) {
_st(aBlock)._value();
 return true;
-}),"_on_do_",[anExceptionClass,(function(ex){
-return false;
-})])]);
-return self},
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_(anExceptionClass,(function(ex){
+return smalltalk.withContext(function($ctx2) {
return false;
+}, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})})));
+return self}, function($ctx1) {$ctx1.fill(self,"shouldnt:raise:",{aBlock:aBlock,anExceptionClass:anExceptionClass}, smalltalk.TestCase)})},
 args: ["aBlock", "anExceptionClass"],
 source: "shouldnt: aBlock raise: anExceptionClass\x0a\x09self assert: ([aBlock value. true] \x0a\x09\x09on: anExceptionClass \x0a\x09\x09do: [:ex | false])",
 messageSends: ["assert:", "on:do:", "value"],
@@ -352,11 +352,11 @@ selector: "signalFailure:",
 category: 'private',
 fn: function (aString){
 var self=this;
-var $1,$2;
-$1=smalltalk.send((smalltalk.TestFailure || TestFailure),"_new",[]);
-smalltalk.send($1,"_messageText_",[aString]);
-$2=smalltalk.send($1,"_signal",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st((smalltalk.TestFailure || TestFailure))._new();
+_st($1)._messageText_(aString);
+$2=_st($1)._signal();
+return self}, function($ctx1) {$ctx1.fill(self,"signalFailure:",{aString:aString}, smalltalk.TestCase)})},
 args: ["aString"],
 source: "signalFailure: aString\x0a\x09TestFailure new\x0a\x09\x09messageText: aString;\x0a\x09\x09signal",
 messageSends: ["messageText:", "new", "signal"],
@@ -371,7 +371,7 @@ selector: "tearDown",
 category: 'running',
 fn: function (){
 var self=this;
-return self},
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"tearDown",{}, smalltalk.TestCase)})},
 args: [],
 source: "tearDown",
 messageSends: [],
@@ -386,18 +386,18 @@ selector: "timeout:",
 category: 'async',
 fn: function (aNumber){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@asyncTimeout"];
 if(($receiver = $1) == nil || $receiver == undefined){
 $1;
 } else {
-smalltalk.send(self["@asyncTimeout"],"_clearTimeout",[]);
+_st(self["@asyncTimeout"])._clearTimeout();
 };
 self["@asyncTimeout"]=(0);
-self["@asyncTimeout"]=smalltalk.send(smalltalk.send(self,"_async_",[(function(){
-return smalltalk.send(self,"_assert_description_",[false,"SUnit grace time exhausted"]);
-})]),"_valueWithTimeout_",[aNumber]);
-return self},
+self["@asyncTimeout"]=_st(_st(self)._async_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._assert_description_(false,"SUnit grace time exhausted");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})))._valueWithTimeout_(aNumber);
+return self}, function($ctx1) {$ctx1.fill(self,"timeout:",{aNumber:aNumber}, smalltalk.TestCase)})},
 args: ["aNumber"],
 source: "timeout: aNumber\x0a\x09\x22Set a grace time timeout in milliseconds to run the test asynchronously\x22\x0a    \x0a\x09asyncTimeout ifNotNil: [ asyncTimeout clearTimeout ].\x0a    \x0a     \x22to allow #async: message send without throwing an error\x22\x0a\x09asyncTimeout := 0.\x0a    \x0a\x09asyncTimeout := (self async: [ \x0a    \x09self assert: false description: 'SUnit grace time exhausted' ])\x0a        \x09valueWithTimeout: aNumber",
 messageSends: ["ifNotNil:", "clearTimeout", "valueWithTimeout:", "async:", "assert:description:"],
@@ -413,16 +413,16 @@ selector: "allTestSelectors",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1,$2;
 var selectors;
-selectors=smalltalk.send(self,"_testSelectors",[]);
-$1=smalltalk.send(self,"_shouldInheritSelectors",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+selectors=_st(self)._testSelectors();
+$1=_st(self)._shouldInheritSelectors();
 if(smalltalk.assert($1)){
-smalltalk.send(selectors,"_addAll_",[smalltalk.send(smalltalk.send(self,"_superclass",[]),"_allTestSelectors",[])]);
+_st(selectors)._addAll_(_st(_st(self)._superclass())._allTestSelectors());
 };
 $2=selectors;
 return $2;
-},
+}, function($ctx1) {$ctx1.fill(self,"allTestSelectors",{selectors:selectors}, smalltalk.TestCase.klass)})},
 args: [],
 source: "allTestSelectors\x0a\x09| selectors |\x0a\x09selectors := self testSelectors.\x0a\x09self shouldInheritSelectors ifTrue: [\x0a\x09\x09selectors addAll: self superclass allTestSelectors].\x0a\x09^selectors",
 messageSends: ["testSelectors", "ifTrue:", "addAll:", "allTestSelectors", "superclass", "shouldInheritSelectors"],
@@ -437,12 +437,12 @@ selector: "buildSuite",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(self,"_allTestSelectors",[]),"_collect_",[(function(each){
-return smalltalk.send(self,"_selector_",[each]);
-})]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._allTestSelectors())._collect_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._selector_(each);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"buildSuite",{}, smalltalk.TestCase.klass)})},
 args: [],
 source: "buildSuite\x0a\x09^self allTestSelectors collect: [:each | self selector: each]",
 messageSends: ["collect:", "selector:", "allTestSelectors"],
@@ -457,10 +457,10 @@ selector: "isAbstract",
 category: 'testing',
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(self,"_name",[]),"__eq",["TestCase"]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._name()).__eq("TestCase");
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"isAbstract",{}, smalltalk.TestCase.klass)})},
 args: [],
 source: "isAbstract\x0a\x09^ self name = 'TestCase'",
 messageSends: ["=", "name"],
@@ -475,10 +475,10 @@ selector: "lookupHierarchyRoot",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=(smalltalk.TestCase || TestCase);
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"lookupHierarchyRoot",{}, smalltalk.TestCase.klass)})},
 args: [],
 source: "lookupHierarchyRoot\x0a\x09^TestCase",
 messageSends: [],
@@ -493,13 +493,13 @@ selector: "selector:",
 category: 'accessing',
 fn: function (aSelector){
 var self=this;
-var $2,$3,$1;
-$2=smalltalk.send(self,"_new",[]);
-smalltalk.send($2,"_setTestSelector_",[aSelector]);
-$3=smalltalk.send($2,"_yourself",[]);
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
+$2=_st(self)._new();
+_st($2)._setTestSelector_(aSelector);
+$3=_st($2)._yourself();
 $1=$3;
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"selector:",{aSelector:aSelector}, smalltalk.TestCase.klass)})},
 args: ["aSelector"],
 source: "selector: aSelector\x0a\x09^self new\x0a\x09\x09setTestSelector: aSelector;\x0a\x09\x09yourself",
 messageSends: ["setTestSelector:", "new", "yourself"],
@@ -514,10 +514,10 @@ selector: "shouldInheritSelectors",
 category: 'testing',
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(self,"_~_eq",[smalltalk.send(self,"_lookupHierarchyRoot",[])]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(self).__tild_eq(_st(self)._lookupHierarchyRoot());
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"shouldInheritSelectors",{}, smalltalk.TestCase.klass)})},
 args: [],
 source: "shouldInheritSelectors\x0a\x09^self ~= self lookupHierarchyRoot",
 messageSends: ["~=", "lookupHierarchyRoot"],
@@ -532,12 +532,12 @@ selector: "testSelectors",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(smalltalk.send(self,"_methodDictionary",[]),"_keys",[]),"_select_",[(function(each){
-return smalltalk.send(each,"_match_",["^test"]);
-})]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(_st(self)._methodDictionary())._keys())._select_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(each)._match_("^test");
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"testSelectors",{}, smalltalk.TestCase.klass)})},
 args: [],
 source: "testSelectors\x0a\x09^self methodDictionary keys select: [:each | each match: '^test']",
 messageSends: ["select:", "match:", "keys", "methodDictionary"],
@@ -555,31 +555,31 @@ selector: "execute:",
 category: 'running',
 fn: function (aBlock){
 var self=this;
-var $1,$3,$4,$2;
 var failed;
-smalltalk.send(self["@testCase"],"_context_",[self]);
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$4,$2;
+_st(self["@testCase"])._context_(self);
 $1=(function(){
-failed=true;
+return smalltalk.withContext(function($ctx2) {
failed=true;
 failed;
-smalltalk.send(aBlock,"_value",[]);
+_st(aBlock)._value();
 failed=false;
 return failed;
-});
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
 $2=(function(){
-smalltalk.send(self["@testCase"],"_context_",[nil]);
-$3=smalltalk.send(failed,"_and_",[(function(){
-return smalltalk.send(self["@testCase"],"_isAsync",[]);
-})]);
+return smalltalk.withContext(function($ctx2) {
_st(self["@testCase"])._context_(nil);
+$3=_st(failed)._and_((function(){
+return smalltalk.withContext(function($ctx3) {
return _st(self["@testCase"])._isAsync();
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 if(smalltalk.assert($3)){
-smalltalk.send(self["@testCase"],"_finished",[]);
+_st(self["@testCase"])._finished();
 };
-$4=smalltalk.send(self["@testCase"],"_isAsync",[]);
+$4=_st(self["@testCase"])._isAsync();
 if(! smalltalk.assert($4)){
-return smalltalk.send(self["@testCase"],"_tearDown",[]);
+return _st(self["@testCase"])._tearDown();
 };
-});
-smalltalk.send($1,"_ensure_",[$2]);
-return self},
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+_st($1)._ensure_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"execute:",{aBlock:aBlock,failed:failed}, smalltalk.TestContext)})},
 args: ["aBlock"],
 source: "execute: aBlock\x0a\x09| failed |\x0a    \x0a    testCase context: self.\x0a    [ \x0a    \x09failed := true. \x0a        aBlock value. \x0a        failed := false \x0a\x09] \x0a    \x09ensure: [\x0a        \x09testCase context: nil.\x0a            \x0a        \x09(failed and: [ testCase isAsync ]) ifTrue: [ \x0a            \x09testCase finished ].\x0a        \x09testCase isAsync ifFalse: [ \x0a        \x09\x09testCase tearDown ] ]",
 messageSends: ["context:", "ensure:", "ifTrue:", "finished", "and:", "isAsync", "ifFalse:", "tearDown", "value"],
@@ -594,11 +594,11 @@ selector: "start",
 category: 'running',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_execute_",[(function(){
-smalltalk.send(self["@testCase"],"_setUp",[]);
-return smalltalk.send(self["@testCase"],"_performTest",[]);
-})]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._execute_((function(){
+return smalltalk.withContext(function($ctx2) {
_st(self["@testCase"])._setUp();
+return _st(self["@testCase"])._performTest();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"start",{}, smalltalk.TestContext)})},
 args: [],
 source: "start\x0a\x09self execute: [ \x0a    \x09testCase setUp. \x0a        testCase performTest ]",
 messageSends: ["execute:", "setUp", "performTest"],
@@ -613,8 +613,8 @@ selector: "testCase:",
 category: 'accessing',
 fn: function (aTestCase){
 var self=this;
-self["@testCase"]=aTestCase;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@testCase"]=aTestCase;
+return self}, function($ctx1) {$ctx1.fill(self,"testCase:",{aTestCase:aTestCase}, smalltalk.TestContext)})},
 args: ["aTestCase"],
 source: "testCase: aTestCase\x0a\x09testCase := aTestCase",
 messageSends: [],
@@ -630,13 +630,13 @@ selector: "testCase:",
 category: 'instance creation',
 fn: function (aTestCase){
 var self=this;
-var $2,$3,$1;
-$2=smalltalk.send(self,"_new",[]);
-smalltalk.send($2,"_testCase_",[aTestCase]);
-$3=smalltalk.send($2,"_yourself",[]);
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
+$2=_st(self)._new();
+_st($2)._testCase_(aTestCase);
+$3=_st($2)._yourself();
 $1=$3;
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"testCase:",{aTestCase:aTestCase}, smalltalk.TestContext.klass)})},
 args: ["aTestCase"],
 source: "testCase: aTestCase\x0a\x09^self new\x0a        testCase: aTestCase;\x0a        yourself",
 messageSends: ["testCase:", "new", "yourself"],
@@ -646,7 +646,7 @@ smalltalk.TestContext.klass);
 
 
 smalltalk.addClass('ReportingTestContext', smalltalk.TestContext, ['finished', 'result'], 'SUnit');
-smalltalk.ReportingTestContext.comment="ReportingTestContext adds `TestResult` reporting\x0ato `TestContext`.\x0a\x0aErrors are caught and save into a `TestResult`,\x0aWhen test case is finished (which can be later for async tests),\x0aa callback block is executed; this is used by a `TestSuiteRunner`.\x0a"
+smalltalk.ReportingTestContext.comment="ReportingTestContext adds `TestResult` reporting\x0ato `TestContext`.\x0a\x0aErrors are caught and save into a `TestResult`,\x0aWhen test case is finished (which can be later for async tests),\x0aa callback block is executed; this is used by a `TestSuiteRunner`."
 smalltalk.addMethod(
 "_execute_",
 smalltalk.method({
@@ -654,21 +654,21 @@ selector: "execute:",
 category: 'running',
 fn: function (aBlock){
 var self=this;
-var $1,$3,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
 $1=(function(){
-return smalltalk.send(self,"_withErrorReporting_",[(function(){
-return smalltalk.send(self,"_execute_",[aBlock],smalltalk.TestContext);
-})]);
-});
+return smalltalk.withContext(function($ctx2) {
return _st(self)._withErrorReporting_((function(){
+return smalltalk.withContext(function($ctx3) {
return smalltalk.TestContext.fn.prototype._execute_.apply(_st(self), [aBlock]);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
 $2=(function(){
-$3=smalltalk.send(self["@testCase"],"_isAsync",[]);
+return smalltalk.withContext(function($ctx2) {
$3=_st(self["@testCase"])._isAsync();
 if(! smalltalk.assert($3)){
-smalltalk.send(self["@result"],"_increaseRuns",[]);
-return smalltalk.send(self["@finished"],"_value",[]);
+_st(self["@result"])._increaseRuns();
+return _st(self["@finished"])._value();
 };
-});
-smalltalk.send($1,"_ensure_",[$2]);
-return self},
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+_st($1)._ensure_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"execute:",{aBlock:aBlock}, smalltalk.ReportingTestContext)})},
 args: ["aBlock"],
 source: "execute: aBlock\x0a    [ \x0a    \x09self withErrorReporting: [ super execute: aBlock ] \x0a\x09]\x0a    \x09ensure: [ \x0a        \x09testCase isAsync ifFalse: [ \x0a            \x09result increaseRuns. finished value ] ]",
 messageSends: ["ensure:", "ifFalse:", "increaseRuns", "value", "isAsync", "withErrorReporting:", "execute:"],
@@ -683,8 +683,8 @@ selector: "finished:",
 category: 'accessing',
 fn: function (aBlock){
 var self=this;
-self["@finished"]=aBlock;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@finished"]=aBlock;
+return self}, function($ctx1) {$ctx1.fill(self,"finished:",{aBlock:aBlock}, smalltalk.ReportingTestContext)})},
 args: ["aBlock"],
 source: "finished: aBlock\x0a\x09finished := aBlock",
 messageSends: [],
@@ -699,8 +699,8 @@ selector: "result:",
 category: 'accessing',
 fn: function (aTestResult){
 var self=this;
-self["@result"]=aTestResult;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@result"]=aTestResult;
+return self}, function($ctx1) {$ctx1.fill(self,"result:",{aTestResult:aTestResult}, smalltalk.ReportingTestContext)})},
 args: ["aTestResult"],
 source: "result: aTestResult\x0a\x09result := aTestResult",
 messageSends: [],
@@ -715,14 +715,14 @@ selector: "withErrorReporting:",
 category: 'private',
 fn: function (aBlock){
 var self=this;
-smalltalk.send((function(){
-return smalltalk.send(aBlock,"_on_do_",[(smalltalk.TestFailure || TestFailure),(function(ex){
-return smalltalk.send(self["@result"],"_addFailure_",[self["@testCase"]]);
-})]);
-}),"_on_do_",[(smalltalk.Error || Error),(function(ex){
-return smalltalk.send(self["@result"],"_addError_",[self["@testCase"]]);
-})]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(aBlock)._on_do_((smalltalk.TestFailure || TestFailure),(function(ex){
+return smalltalk.withContext(function($ctx3) {
return _st(self["@result"])._addFailure_(self["@testCase"]);
+}, function($ctx3) {$ctx3.fillBlock({ex:ex},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_((smalltalk.Error || Error),(function(ex){
+return smalltalk.withContext(function($ctx2) {
return _st(self["@result"])._addError_(self["@testCase"]);
+}, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"withErrorReporting:",{aBlock:aBlock}, smalltalk.ReportingTestContext)})},
 args: ["aBlock"],
 source: "withErrorReporting: aBlock\x0a \x09[ aBlock\x0a\x09\x09on: TestFailure \x0a\x09\x09do: [ :ex | result addFailure: testCase ] \x0a\x09]\x0a    \x09on: Error \x0a        do: [ :ex | result addError: testCase ]",
 messageSends: ["on:do:", "addError:", "addFailure:"],
@@ -738,14 +738,14 @@ selector: "testCase:result:finished:",
 category: 'instance creation',
 fn: function (aTestCase,aTestResult,aBlock){
 var self=this;
-var $2,$3,$1;
-$2=smalltalk.send(self,"_testCase_",[aTestCase],smalltalk.TestContext.klass);
-smalltalk.send($2,"_result_",[aTestResult]);
-smalltalk.send($2,"_finished_",[aBlock]);
-$3=smalltalk.send($2,"_yourself",[]);
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
+$2=smalltalk.TestContext.klass.fn.prototype._testCase_.apply(_st(self), [aTestCase]);
+_st($2)._result_(aTestResult);
+_st($2)._finished_(aBlock);
+$3=_st($2)._yourself();
 $1=$3;
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"testCase:result:finished:",{aTestCase:aTestCase,aTestResult:aTestResult,aBlock:aBlock}, smalltalk.ReportingTestContext.klass)})},
 args: ["aTestCase", "aTestResult", "aBlock"],
 source: "testCase: aTestCase result: aTestResult finished: aBlock\x0a\x09^(super testCase: aTestCase)\x0a        result: aTestResult;\x0a        finished: aBlock;\x0a        yourself",
 messageSends: ["result:", "testCase:", "finished:", "yourself"],
@@ -767,8 +767,8 @@ selector: "addError:",
 category: 'accessing',
 fn: function (anError){
 var self=this;
-smalltalk.send(smalltalk.send(self,"_errors",[]),"_add_",[anError]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._errors())._add_(anError);
+return self}, function($ctx1) {$ctx1.fill(self,"addError:",{anError:anError}, smalltalk.TestResult)})},
 args: ["anError"],
 source: "addError: anError\x0a\x09self errors add: anError",
 messageSends: ["add:", "errors"],
@@ -783,8 +783,8 @@ selector: "addFailure:",
 category: 'accessing',
 fn: function (aFailure){
 var self=this;
-smalltalk.send(smalltalk.send(self,"_failures",[]),"_add_",[aFailure]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._failures())._add_(aFailure);
+return self}, function($ctx1) {$ctx1.fill(self,"addFailure:",{aFailure:aFailure}, smalltalk.TestResult)})},
 args: ["aFailure"],
 source: "addFailure: aFailure\x0a\x09self failures add: aFailure",
 messageSends: ["add:", "failures"],
@@ -799,10 +799,10 @@ selector: "errors",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@errors"];
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"errors",{}, smalltalk.TestResult)})},
 args: [],
 source: "errors\x0a\x09^errors",
 messageSends: [],
@@ -817,10 +817,10 @@ selector: "failures",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@failures"];
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"failures",{}, smalltalk.TestResult)})},
 args: [],
 source: "failures\x0a\x09^failures",
 messageSends: [],
@@ -835,8 +835,8 @@ selector: "increaseRuns",
 category: 'accessing',
 fn: function (){
 var self=this;
-self["@runs"]=smalltalk.send(self["@runs"],"__plus",[(1)]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@runs"]=_st(self["@runs"]).__plus((1));
+return self}, function($ctx1) {$ctx1.fill(self,"increaseRuns",{}, smalltalk.TestResult)})},
 args: [],
 source: "increaseRuns\x0a\x09runs := runs + 1",
 messageSends: ["+"],
@@ -851,13 +851,13 @@ selector: "initialize",
 category: 'initialization',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_initialize",[],smalltalk.Object);
-self["@timestamp"]=smalltalk.send((smalltalk.Date || Date),"_now",[]);
+return smalltalk.withContext(function($ctx1) { 
smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+self["@timestamp"]=_st((smalltalk.Date || Date))._now();
 self["@runs"]=(0);
-self["@errors"]=smalltalk.send((smalltalk.Array || Array),"_new",[]);
-self["@failures"]=smalltalk.send((smalltalk.Array || Array),"_new",[]);
+self["@errors"]=_st((smalltalk.Array || Array))._new();
+self["@failures"]=_st((smalltalk.Array || Array))._new();
 self["@total"]=(0);
-return self},
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.TestResult)})},
 args: [],
 source: "initialize\x0a\x09super initialize.\x0a\x09timestamp := Date now.\x0a\x09runs := 0.\x0a\x09errors := Array new.\x0a\x09failures := Array new.\x0a\x09total := 0",
 messageSends: ["initialize", "now", "new"],
@@ -865,6 +865,52 @@ referencedClasses: ["Date", "Array"]
 }),
 smalltalk.TestResult);
 
+smalltalk.addMethod(
+"_nextRunDo_",
+smalltalk.method({
+selector: "nextRunDo:",
+category: 'running',
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=_st(_st(self)._runs()).__eq_eq(_st(self)._total());
+if(! smalltalk.assert($2)){
+$1=_st(aBlock)._value_(_st(_st(self)._runs()).__plus((1)));
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"nextRunDo:",{aBlock:aBlock}, smalltalk.TestResult)})},
+args: ["aBlock"],
+source: "nextRunDo: aBlock\x0a\x22Runs aBlock with index of next run\x0aor does nothing if no more runs\x22\x0a^self runs == self total\x0a\x09ifFalse: [ aBlock value: self runs + 1 ]",
+messageSends: ["ifFalse:", "value:", "+", "runs", "==", "total"],
+referencedClasses: []
+}),
+smalltalk.TestResult);
+
+smalltalk.addMethod(
+"_runCase_",
+smalltalk.method({
+selector: "runCase:",
+category: 'running',
+fn: function (aTestCase){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st((function(){
+return smalltalk.withContext(function($ctx2) {
return _st((function(){
+return smalltalk.withContext(function($ctx3) {
_st(self)._increaseRuns();
+return _st(aTestCase)._runCase();
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}))._on_do_((smalltalk.TestFailure || TestFailure),(function(ex){
+return smalltalk.withContext(function($ctx3) {
return _st(self)._addFailure_(aTestCase);
+}, function($ctx3) {$ctx3.fillBlock({ex:ex},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_((smalltalk.Error || Error),(function(ex){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._addError_(aTestCase);
+}, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"runCase:",{aTestCase:aTestCase}, smalltalk.TestResult)})},
+args: ["aTestCase"],
+source: "runCase: aTestCase\x0a\x09[[\x09self increaseRuns.\x0a    \x09aTestCase runCase]\x0a\x09on: TestFailure do: [:ex | self addFailure: aTestCase]]\x0a\x09on: Error do: [:ex | self addError: aTestCase]\x0a",
+messageSends: ["on:do:", "addError:", "addFailure:", "increaseRuns", "runCase"],
+referencedClasses: ["Error", "TestFailure"]
+}),
+smalltalk.TestResult);
+
 smalltalk.addMethod(
 "_runs",
 smalltalk.method({
@@ -872,10 +918,10 @@ selector: "runs",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@runs"];
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"runs",{}, smalltalk.TestResult)})},
 args: [],
 source: "runs\x0a\x09^runs",
 messageSends: [],
@@ -890,21 +936,21 @@ selector: "status",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $2,$4,$3,$1;
-$2=smalltalk.send(smalltalk.send(self,"_errors",[]),"_isEmpty",[]);
+return smalltalk.withContext(function($ctx1) { 
var $2,$4,$3,$1;
+$2=_st(_st(self)._errors())._isEmpty();
 $3=(function(){
-$4=smalltalk.send(smalltalk.send(self,"_failures",[]),"_isEmpty",[]);
+return smalltalk.withContext(function($ctx2) {
$4=_st(_st(self)._failures())._isEmpty();
 if(smalltalk.assert($4)){
 return "success";
 } else {
 return "failure";
 };
-});
-$1=smalltalk.send($2,"_ifTrue_ifFalse_",[$3,(function(){
-return "error";
-})]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+$1=_st($2)._ifTrue_ifFalse_($3,(function(){
+return smalltalk.withContext(function($ctx2) {
return "error";
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"status",{}, smalltalk.TestResult)})},
 args: [],
 source: "status\x0a\x09^self errors isEmpty \x0a\x09\x09ifTrue: [\x0a\x09\x09\x09self failures isEmpty \x0a\x09\x09\x09\x09ifTrue: ['success']\x0a\x09\x09\x09\x09ifFalse: ['failure']]\x0a\x09\x09ifFalse: ['error']",
 messageSends: ["ifTrue:ifFalse:", "isEmpty", "failures", "errors"],
@@ -919,10 +965,10 @@ selector: "timestamp",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@timestamp"];
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"timestamp",{}, smalltalk.TestResult)})},
 args: [],
 source: "timestamp\x0a\x09^timestamp",
 messageSends: [],
@@ -937,10 +983,10 @@ selector: "total",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@total"];
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"total",{}, smalltalk.TestResult)})},
 args: [],
 source: "total\x0a\x09^total",
 messageSends: [],
@@ -955,8 +1001,8 @@ selector: "total:",
 category: 'accessing',
 fn: function (aNumber){
 var self=this;
-self["@total"]=aNumber;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@total"]=aNumber;
+return self}, function($ctx1) {$ctx1.fill(self,"total:",{aNumber:aNumber}, smalltalk.TestResult)})},
 args: ["aNumber"],
 source: "total: aNumber\x0a\x09total := aNumber",
 messageSends: [],
@@ -974,10 +1020,10 @@ selector: "announcer",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@announcer"];
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"announcer",{}, smalltalk.TestSuiteRunner)})},
 args: [],
 source: "announcer\x0a\x09^announcer",
 messageSends: [],
@@ -992,14 +1038,14 @@ selector: "contextOf:",
 category: 'private',
 fn: function (anInteger){
 var self=this;
-var $1;
-$1=smalltalk.send((smalltalk.ReportingTestContext || ReportingTestContext),"_testCase_result_finished_",[smalltalk.send(self["@suite"],"_at_",[anInteger]),self["@result"],(function(){
-return smalltalk.send(self,"_resume",[]);
-})]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st((smalltalk.ReportingTestContext || ReportingTestContext))._testCase_result_finished_(_st(self["@suite"])._at_(anInteger),self["@result"],(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._resume();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"contextOf:",{anInteger:anInteger}, smalltalk.TestSuiteRunner)})},
 args: ["anInteger"],
-source: "contextOf: anInteger\x0a   \x09^ReportingTestContext testCase: (suite at: anInteger) result: result finished: [ self resume ]\x0a",
+source: "contextOf: anInteger\x0a   \x09^ReportingTestContext testCase: (suite at: anInteger) result: result finished: [ self resume ]",
 messageSends: ["testCase:result:finished:", "at:", "resume"],
 referencedClasses: ["ReportingTestContext"]
 }),
@@ -1012,22 +1058,22 @@ selector: "initialize",
 category: 'initialization',
 fn: function (){
 var self=this;
-var $1;
-smalltalk.send(self,"_initialize",[],smalltalk.Object);
-self["@announcer"]=smalltalk.send((smalltalk.Announcer || Announcer),"_new",[]);
-self["@result"]=smalltalk.send((smalltalk.TestResult || TestResult),"_new",[]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+self["@announcer"]=_st((smalltalk.Announcer || Announcer))._new();
+self["@result"]=_st((smalltalk.TestResult || TestResult))._new();
 self["@runNextTest"]=(function(){
 var runs;
-runs=smalltalk.send(self["@result"],"_runs",[]);
+return smalltalk.withContext(function($ctx2) {
runs=_st(self["@result"])._runs();
 runs;
-$1=smalltalk.send(runs,"__lt",[smalltalk.send(self["@result"],"_total",[])]);
+$1=_st(runs).__lt(_st(self["@result"])._total());
 if(smalltalk.assert($1)){
-return smalltalk.send(smalltalk.send(self,"_contextOf_",[smalltalk.send(runs,"__plus",[(1)])]),"_start",[]);
+return _st(_st(self)._contextOf_(_st(runs).__plus((1))))._start();
 };
-});
-return self},
+}, function($ctx2) {$ctx2.fillBlock({runs:runs},$ctx1)})});
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.TestSuiteRunner)})},
 args: [],
-source: "initialize\x0a\x09super initialize.\x0a\x09announcer := Announcer new.\x0a    result := TestResult new.\x0a    runNextTest := [ | runs | runs := result runs. runs < result total ifTrue: [ (self contextOf: runs + 1) start ]].\x0a",
+source: "initialize\x0a\x09super initialize.\x0a\x09announcer := Announcer new.\x0a    result := TestResult new.\x0a    runNextTest := [ | runs | runs := result runs. runs < result total ifTrue: [ (self contextOf: runs + 1) start ]].",
 messageSends: ["initialize", "new", "runs", "ifTrue:", "start", "contextOf:", "+", "<", "total"],
 referencedClasses: ["Announcer", "TestResult"]
 }),
@@ -1040,10 +1086,10 @@ selector: "result",
 category: 'accessing',
 fn: function (){
 var self=this;
-var $1;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@result"];
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"result",{}, smalltalk.TestSuiteRunner)})},
 args: [],
 source: "result\x0a\x09^result",
 messageSends: [],
@@ -1058,11 +1104,11 @@ selector: "resume",
 category: 'actions',
 fn: function (){
 var self=this;
-smalltalk.send(self["@runNextTest"],"_fork",[]);
-smalltalk.send(self["@announcer"],"_announce_",[smalltalk.send(smalltalk.send((smalltalk.ResultAnnouncement || ResultAnnouncement),"_new",[]),"_result_",[self["@result"]])]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self["@runNextTest"])._fork();
+_st(self["@announcer"])._announce_(_st(_st((smalltalk.ResultAnnouncement || ResultAnnouncement))._new())._result_(self["@result"]));
+return self}, function($ctx1) {$ctx1.fill(self,"resume",{}, smalltalk.TestSuiteRunner)})},
 args: [],
-source: "resume\x0a\x09runNextTest fork.\x0a    announcer announce: (ResultAnnouncement new result: result)\x0a",
+source: "resume\x0a\x09runNextTest fork.\x0a    announcer announce: (ResultAnnouncement new result: result)",
 messageSends: ["fork", "announce:", "result:", "new"],
 referencedClasses: ["ResultAnnouncement"]
 }),
@@ -1075,9 +1121,9 @@ selector: "run",
 category: 'actions',
 fn: function (){
 var self=this;
-smalltalk.send(self["@result"],"_total_",[smalltalk.send(self["@suite"],"_size",[])]);
-smalltalk.send(self,"_resume",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self["@result"])._total_(_st(self["@suite"])._size());
+_st(self)._resume();
+return self}, function($ctx1) {$ctx1.fill(self,"run",{}, smalltalk.TestSuiteRunner)})},
 args: [],
 source: "run\x0a\x09result total: suite size.\x0a\x09self resume",
 messageSends: ["total:", "size", "resume"],
@@ -1092,8 +1138,8 @@ selector: "suite:",
 category: 'accessing',
 fn: function (aCollection){
 var self=this;
-self["@suite"]=aCollection;
-return self},
+return smalltalk.withContext(function($ctx1) { 
self["@suite"]=aCollection;
+return self}, function($ctx1) {$ctx1.fill(self,"suite:",{aCollection:aCollection}, smalltalk.TestSuiteRunner)})},
 args: ["aCollection"],
 source: "suite: aCollection\x0a\x09suite := aCollection",
 messageSends: [],
@@ -1109,8 +1155,8 @@ selector: "new",
 category: 'instance creation',
 fn: function (){
 var self=this;
-smalltalk.send(self,"_shouldNotImplement",[]);
-return self},
+return smalltalk.withContext(function($ctx1) { 
_st(self)._shouldNotImplement();
+return self}, function($ctx1) {$ctx1.fill(self,"new",{}, smalltalk.TestSuiteRunner.klass)})},
 args: [],
 source: "new\x0a\x09self shouldNotImplement",
 messageSends: ["shouldNotImplement"],
@@ -1125,10 +1171,10 @@ selector: "on:",
 category: 'instance creation',
 fn: function (aCollection){
 var self=this;
-var $1;
-$1=smalltalk.send(smalltalk.send(self,"_new",[],smalltalk.Object.klass),"_suite_",[aCollection]);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(smalltalk.Object.klass.fn.prototype._new.apply(_st(self), []))._suite_(aCollection);
 return $1;
-},
+}, function($ctx1) {$ctx1.fill(self,"on:",{aCollection:aCollection}, smalltalk.TestSuiteRunner.klass)})},
 args: ["aCollection"],
 source: "on: aCollection\x0a\x09^super new suite: aCollection",
 messageSends: ["suite:", "new"],

+ 1 - 0
js/amber.js

@@ -92,6 +92,7 @@ amber = (function() {
 				'Compiler-Semantic',
 				'Compiler-IR',
 				'Compiler-Inlining',
+				'Compiler-Interpreter',
 				'Compiler-Tests',
 				'parser',
 				'IDE',

+ 413 - 240
js/boot.js

@@ -13,29 +13,29 @@
    | Amber is released under the MIT license
    |
    | Permission is hereby granted, free of charge, to any person obtaining
-   | a copy of this software and associated documentation files (the 
-   | 'Software'), to deal in the Software without restriction, including 
-   | without limitation the rights to use, copy, modify, merge, publish, 
-   | distribute, sublicense, and/or sell copies of the Software, and to 
-   | permit persons to whom the Software is furnished to do so, subject to 
+   | a copy of this software and associated documentation files (the
+   | 'Software'), to deal in the Software without restriction, including
+   | without limitation the rights to use, copy, modify, merge, publish,
+   | distribute, sublicense, and/or sell copies of the Software, and to
+   | permit persons to whom the Software is furnished to do so, subject to
    | the following conditions:
    |
-   | The above copyright notice and this permission notice shall be 
+   | The above copyright notice and this permission notice shall be
    | included in all copies or substantial portions of the Software.
    |
-   | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 
-   | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
-   | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
-   | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
-   | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
-   | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
-   | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
+   | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+   | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+   | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+   | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+   | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    |
    ==================================================================== */
 
 /* Make sure that console is defined */
 
-if (typeof console === "undefined") {
+if(typeof console === "undefined") {
 	this.console = {
 		log: function() {},
 		warn: function() {},
@@ -45,51 +45,61 @@ if (typeof console === "undefined") {
 	};
 }
 
-/* Smalltalk constructors definition */
+/* Array extensions */
 
-function SmalltalkObject(){};
-function SmalltalkBehavior(){};
-function SmalltalkClass(){};
-function SmalltalkPackage(){};
-function SmalltalkMetaclass(){
-	this.meta = true;
+Array.prototype.addElement = function(el) {
+	if(typeof el === 'undefined') { return; }
+	if(this.indexOf(el) == -1) {
+        this.push(el);
+    }
 };
-function SmalltalkMethod(){};
-function SmalltalkNil(){};
 
-function SmalltalkSymbol(string){
-	this.value = string;
+Array.prototype.removeElement = function(el) {
+    var i = this.indexOf(el);
+    if (i !== -1) { this.splice(i, 1); }
 };
 
+
+/* Smalltalk constructors definition */
+
+function SmalltalkObject() {}
+function SmalltalkBehavior() {}
+function SmalltalkClass() {}
+function SmalltalkMetaclass() {
+	this.meta = true;
+}
+function SmalltalkPackage() {}
+function SmalltalkMethod() {}
+function SmalltalkNil() {}
+function SmalltalkSymbol(string) {
+	this.value = string;
+}
 function SmalltalkOrganizer() {
     this.elements = [];
-};
+}
 
-SmalltalkOrganizer.prototype.addElement = function(el) {
-    if(typeof el === 'undefined' || el === nil) {
-        return false;
-    }
-    if(this.elements.indexOf(el) == -1) {
-        this.elements.push(el);
-    }
-};
+function inherits(child, parent) {
+	child.prototype = Object.create(parent.prototype, {
+		constructor: { value: child,
+			enumerable: false, configurable: true, writable: true }
+	});
+}
 
-SmalltalkOrganizer.prototype.removeElement = function(el) {
-    for(var i=0; i<this.elements.length; i++) {
-        if(this.elements[i] == el) {
-            this.elements.splice(i, 1);
-            break;
-        }
-    }
-};
+inherits(SmalltalkBehavior, SmalltalkObject);
+inherits(SmalltalkClass, SmalltalkBehavior);
+inherits(SmalltalkMetaclass, SmalltalkBehavior);
+inherits(SmalltalkNil, SmalltalkObject);
+inherits(SmalltalkMethod, SmalltalkObject);
+inherits(SmalltalkPackage, SmalltalkObject);
+inherits(SmalltalkOrganizer, SmalltalkObject);
 
 
-function Smalltalk(){
+function Smalltalk() {
 
 	var st = this;
 
 	/* This is the current call context object. While it is publicly available,
-	   Use smalltalk.getThisContext() instead which will answer a safe copy of 
+	   Use smalltalk.getThisContext() instead which will answer a safe copy of
 	   the current context */
 
 	st.thisContext = undefined;
@@ -111,20 +121,55 @@ function Smalltalk(){
 		'implements', 'interface', 'let', 'package', 'private', 'protected',
 		'public', 'static', 'yield'];
 
+    var initialized = false;
+
+    /* Smalltalk classes */
+
+    var classes = [];
+    var wrappedClasses = [];
+
+    /* Method not implemented handlers */
+
+	var dnu = {
+		methods: [],
+		selectors: [],
+
+		get: function (string) {
+			var index = this.selectors.indexOf(string);
+			if(index !== -1) {
+				return this.methods[index];
+			}
+			this.selectors.push(string);
+			var selector = st.selector(string);
+			var method = {jsSelector: selector, fn: this.createHandler(selector)};
+			this.methods.push(method);
+			return method;
+		},
+
+		/* Dnu handler method */
+
+		createHandler: function (selector) {
+			return function () {
+				var args = Array.prototype.slice.call(arguments);
+				return messageNotUnderstood(this, selector, args);
+			};
+		}
+	};
+
 	/* The symbol table ensures symbol unicity */
 
-	symbolTable = {};
+	var symbolTable = {};
 	st.symbolFor = function(string) {
 		if(symbolTable[string] === undefined) {
 			symbolTable[string] = new SmalltalkSymbol(string);
-		};
+		}
 
 		return symbolTable[string];
 	};
 
 	/* Unique ID number generator */
 
-	oid = 0;
+	var oid = 0;
 	st.nextId = function() {
 		oid += 1;
 		return oid;
@@ -142,18 +187,22 @@ function Smalltalk(){
         that.organization = new SmalltalkOrganizer();
 		that.properties = spec.properties || {};
 		return that;
-	};
+	}
 
-	/* Smalltalk class creation. A class is an instance of an automatically 
+	/* Smalltalk class creation. A class is an instance of an automatically
 	   created metaclass object. Newly created classes (not their metaclass) 
 	   should be added to the smalltalk object, see smalltalk.addClass().
 	   Superclass linking is *not* handled here, see smalltalk.init()  */
 
 	function klass(spec) {
-		var spec = spec || {};
-		var meta = metaclass();
-		var that = setupClass(meta.instanceClass, spec);
-		that.className = spec.className;
+		spec = spec || {};
+		var meta = metaclass(spec);
+		var that = meta.instanceClass;
+		that.fn = spec.fn || function() {};
+		setupClass(that, spec);
+
+        that.className = spec.className;
+        that.wrapped   = spec.wrapped || false;
 		meta.className = spec.className + ' class';
 		if(spec.superclass) {
 			that.superclass = spec.superclass;
@@ -161,29 +210,36 @@ function Smalltalk(){
 		}
 		return that;
 	}
-	
-	function metaclass() {
-		var meta = setupClass(new SmalltalkMetaclass(), {})
-		meta.instanceClass = new meta.fn;
-		return meta;
+
+	function metaclass(spec) {
+		spec = spec || {};
+		var that = new SmalltalkMetaclass();
+		inherits(
+			that.fn = function() {},
+			spec.superclass ? spec.superclass.klass.fn : SmalltalkClass
+		);
+		that.instanceClass = new that.fn();
+        setupClass(that);
+		return that;
 	}
-	
-	function setupClass(that, spec) {
-		that.fn = spec.fn || function(){};
-		that.iVarNames = spec.iVarNames || [];
-		Object.defineProperty(that, "toString", {
-			value: function() { return 'Smalltalk ' + this.className; }, 
-            configurable: true // no writable - in par with ES6 methods
+
+	function setupClass(klass, spec) {
+        spec = spec || {};
+		klass.iVarNames = spec.iVarNames || [];
+		klass.pkg = spec.pkg;
+
+        Object.defineProperty(klass, "toString", {
+			value: function() { return 'Smalltalk ' + this.className; },
+            enumerable:false, configurable: true, writable: false
 		});
-        that.organization = new SmalltalkOrganizer();
-		that.pkg = spec.pkg;
-		Object.defineProperties(that.fn.prototype, {
-			methods: { value: {}, enumerable: false, configurable: true, writable: true },
-			inheritedMethods: { value: {}, enumerable: false, configurable: true, writable: true },
-			klass: { value: that, enumerable: false, configurable: true, writable: true }
+
+		klass.organization = new SmalltalkOrganizer();
+		Object.defineProperty(klass, "methods", {
+			value: {},
+			enumerable: false, configurable: true, writable: true
 		});
-		return that;
-	};
+		wireKlass(klass);
+	}
 
 	/* Smalltalk method object. To add a method to a class,
 	   use smalltalk.addMethod() */
@@ -201,9 +257,9 @@ function Smalltalk(){
 		return that;
 	};
 
-	/* Initialize a class in its class hierarchy. Handle both class and
+	/* Initialize a class in its class hierarchy. Handle both classes and
 	   metaclasses. */
-	   
+
 	st.init = function(klass) {
 		st.initClass(klass);
 		if(klass.klass && !klass.meta) {
@@ -211,71 +267,102 @@ function Smalltalk(){
 		}
 	};
 
-	st.initClass = function(klass) {
-		var subclasses = st.subclasses(klass);
-		var methods, prototype = klass.fn.prototype;
+    st.initClass = function(klass) {
+        if(klass.wrapped) {
+            copySuperclass(klass);
+        }
+        else {
+            installSuperclass(klass);
+        }
+
+        if(klass === st.Object || klass.wrapped) {
+            installDnuHandlers(klass);
+        }
+    };
+
+	function wireKlass(klass) {
+		Object.defineProperty(klass.fn.prototype, "klass", {
+			value: klass,
+			enumerable: false, configurable: true, writable: true
+		});
+	}
+
+	function installSuperclass(klass) {
+        // only if the klass has not been initialized yet.
+		if(klass.fn.prototype._yourself) { return; }
 
 		if(klass.superclass && klass.superclass !== nil) {
-			methods = st.methods(klass.superclass);
-
-			//Methods linking
-			for(var keys = Object.keys(methods), i=0; i<keys.length; i++) {
-				var key = keys[i];
-				if(!prototype.methods[key]) {
-					prototype.inheritedMethods[key] = methods[key];
-					Object.defineProperty(prototype, methods[key].jsSelector, {
-						value: methods[key].fn, configurable: true, writable: true
-					});
-				}
+            inherits(klass.fn, klass.superclass.fn);
+			wireKlass(klass);
+			reinstallMethods(klass);
+        }
+	}
+
+	function copySuperclass(klass, superclass) {
+		for (superclass = superclass || klass.superclass;
+			 superclass && superclass !== nil;
+			 superclass = superclass.superclass) {
+			for (var keys = Object.keys(superclass.methods), i = 0; i < keys.length; i++) {
+				installMethodIfAbsent(superclass.methods[keys[i]], klass);
 			}
 		}
+	}
+
+	function installMethod(method, klass) {
+        Object.defineProperty(klass.fn.prototype, method.jsSelector, {
+			value: method.fn,
+			enumerable: false, configurable: true, writable: true
+		});
+	}
 
-		for(var i=0; i<subclasses.length; i++) {
-			st.initClass(subclasses[i]);
+	function installMethodIfAbsent(method, klass) {
+		if(!klass.fn.prototype[method.jsSelector]) {
+			installMethod(method, klass);
 		}
-	};
+	}
 
+	function reinstallMethods(klass) {
+        for(var keys = Object.keys(klass.methods), i=0; i<keys.length; i++) {
+            installMethod(klass.methods[keys[i]], klass);
+		}
+	}
+
+	function installDnuHandlers(klass) {
+		var m = dnu.methods;
+        for(var i=0; i<m.length; i++) {
+			installMethodIfAbsent(m[i], klass);
+        }
+	}
+
+	function installNewDnuHandler(newHandler) {
+		installMethodIfAbsent(newHandler, st.Object);
+		for(var i = 0; i < wrappedClasses.length; i++) {
+			installMethodIfAbsent(newHandler, wrappedClasses[i]);
+		}
+	}
 
 	/* Answer all registered Packages as Array */
+    // TODO: Remove this hack
 
 	st.packages.all = function() {
 		var packages = [];
 		for(var i in st.packages) {
-			if (!st.packages.hasOwnProperty(i) || typeof(st.packages[i]) === "function") continue;
+			if(!st.packages.hasOwnProperty(i) || typeof(st.packages[i]) === "function") continue;
 			packages.push(st.packages[i]);
 		}
 		return packages
 	};
 
 	/* Answer all registered Smalltalk classes */
+    //TODO: remove the function and make smalltalk.classes an array
 
 	st.classes = function() {
-		var classes = [], names = Object.keys(st), l = names.length;
-		for (var i=0; i<l; i++) {
-			var name = names[i];
-			if (name.search(/^[A-Z]/) !== -1) {
-				classes.push(st[name]);
-			}
-		}
 		return classes;
 	};
 
-
-	/* Answer all methods (included inherited ones) of klass. */
-
-	st.methods = function(klass) {
-		var methods = {};
-		inheritedMethods = klass.fn.prototype.inheritedMethods;
-		for(var i=0, keys=Object.keys(inheritedMethods); i<keys.length; i++) {
-			methods[keys[i]] = inheritedMethods[keys[i]];
-		}
-		var inheritedMethods = klass.fn.prototype.methods;
-		for(var i=0, keys=Object.keys(inheritedMethods); i<keys.length; i++) {
-			methods[keys[i]] = inheritedMethods[keys[i]];
-		}
-		return methods;
-	};
-
+    st.wrappedClasses = function() {
+        return wrappedClasses;
+    };
 
 	/* Answer the direct subclasses of klass. */
 
@@ -299,23 +386,32 @@ function Smalltalk(){
 		return subclasses;
 	};
 
-	/* Create a new class wrapping a JavaScript constructor, and add it to the 
+	/* Create a new class wrapping a JavaScript constructor, and add it to the
 	   global smalltalk object. Package is lazily created if it does not exist with given name. */
 
-	st.wrapClassName = function(className, pkgName, fn, superclass) {
+	st.wrapClassName = function(className, pkgName, fn, superclass, wrapped) {
+        if(wrapped !== false) {
+            wrapped = true;
+        }
 		var pkg = st.addPackage(pkgName);
 		st[className] = klass({
-			className:  className, 
+			className:  className,
 			superclass: superclass,
-			pkg:        pkg, 
-			fn:         fn
+			pkg:        pkg,
+			fn:         fn,
+            wrapped:    wrapped
 		});
+
+        classes.addElement(st[className]);
+		if(wrapped) {wrappedClasses.addElement(st[className])}
+		pkg.organization.elements.addElement(st[className]);
 	};
 
 	/* Create an alias for an existing class */
+
 	st.alias = function(klass, alias) {
 		st[alias] = klass;
-	}
+	};
 
 	/* Add a package to the smalltalk.packages object, creating a new one if needed.
 	   If pkgName is null or empty we return nil, which is an allowed package for a class.
@@ -331,7 +427,7 @@ function Smalltalk(){
 		} else {
 			if(properties) {
 				st.packages[pkgName].properties = properties;
-			}	
+			}
 		}
 		return st.packages[pkgName];
 	};
@@ -341,73 +437,100 @@ function Smalltalk(){
 
 	st.addClass = function(className, superclass, iVarNames, pkgName) {
 		var pkg = st.addPackage(pkgName);
-		if(st[className]) {
+        if (superclass == nil) { superclass = null; }
+		if(st[className] && st[className].superclass == superclass) {
 			st[className].superclass = superclass;
 			st[className].iVarNames = iVarNames;
 			st[className].pkg = pkg || st[className].pkg;
 		} else {
+            if(st[className]) {
+                st.removeClass(st[className]);
+			}
 			st[className] = klass({
-				className: className, 
+				className: className,
 				superclass: superclass,
 				pkg: pkg,
 				iVarNames: iVarNames
 			});
 		}
 
-        pkg.organization.addElement(st[className]);
+        classes.addElement(st[className]);
+        pkg.organization.elements.addElement(st[className]);
 	};
 
     st.removeClass = function(klass) {
-        klass.pkg.organization.removeElement(klass);
+        klass.pkg.organization.elements.removeElement(klass);
+        classes.removeElement(klass);
         delete st[klass.className];
     };
 
 	/* Add/remove a method to/from a class */
 
 	st.addMethod = function(jsSelector, method, klass) {
-		Object.defineProperty(klass.fn.prototype, jsSelector, {
-			value: method.fn, configurable: true, writable: true
-		});
-		klass.fn.prototype.methods[method.selector] = method;
-		method.methodClass = klass;
 		method.jsSelector = jsSelector;
+		installMethod(method, klass);
+		klass.methods[method.selector] = method;
+		method.methodClass = klass;
+
+        klass.organization.elements.addElement(method.category);
 
-        klass.organization.addElement(method.category);
+        for(var i=0; i<method.messageSends.length; i++) {
+            var dnuHandler = dnu.get(method.messageSends[i]);
+            if(initialized) {
+                installNewDnuHandler(dnuHandler);
+			}
+		}
 	};
 
     st.removeMethod = function(method) {
         var protocol = method.category;
         var klass = method.methodClass;
-		var methods = klass.fn.prototype.methods;
 
-		delete klass.fn.prototype[method.selector._asSelector()];
-		delete methods[method.selector];
+        delete klass.fn.prototype[st.selector(method.selector)];
+	    delete klass.methods[method.selector];
 
-		var selectors = Object.keys(methods);
+		var selectors = Object.keys(klass.methods);
 		var shouldDeleteProtocol = true;
-		for(var i= 0, l = selectors.length; i<l; i++) {
-            if(methods[selectors[i]].category === protocol) {
+
+		for(var i = 0, l = selectors.length; i<l; i++) {
+            if(klass.methods[selectors[i]].category === protocol) {
                 shouldDeleteProtocol = false;
 				break;
             };
         };
         if(shouldDeleteProtocol) {
-            klass.organization.removeElement(protocol)
+            klass.organization.elements.removeElement(protocol)
         };
     };
 
 	/* Handles unhandled errors during message sends */
+    // simply send the message and handle #dnu:
 
 	st.send = function(receiver, selector, args, klass) {
+		var method;
+		if(receiver == null) {
+			receiver = nil;
+		}
+		method = klass ? klass.fn.prototype[selector] : receiver.klass && receiver[selector];
+		if(method) {
+            return method.apply(receiver, args);
+		} else {
+			return messageNotUnderstood(receiver, selector, args);
+		}
+	}
+
+	st.withContext = function(worker, setup) {
 		if(st.thisContext) {
-			return withContextSend(receiver, selector, args, klass);
+            st.thisContext.pc++;
+			return inContext(worker, setup);
 		} else {
-			try {return withContextSend(receiver, selector, args, klass)}
+			try {return inContext(worker, setup)}
 			catch(error) {
 				// Reset the context stack in any case
 				st.thisContext = undefined;
 				if(error.smalltalkError) {
 					handleError(error);
+					return nil;
 				} else {
 					throw(error);
 				}
@@ -415,30 +538,19 @@ function Smalltalk(){
 		}
 	};
 
-	function withContextSend(receiver, selector, args, klass) {
-		var call, method;
-		if(receiver == null) {
-			receiver = nil;
-		}
-		method = klass ? klass.fn.prototype[selector] : receiver.klass && receiver[selector];
-		if(method) {
-			var context = pushContext(receiver, selector, method, args);
-			call = method.apply(receiver, args);
-			popContext(context);
-			return call;
-		} else {
-			return messageNotUnderstood(receiver, selector, args);
-		}
-	};
+	function inContext(worker, setup) {
+		var context = pushContext(setup);
+		var result = worker(context);
+		popContext(context);
+		return result;
+	}
 
-	/* Handles Smalltalk errors. Triggers the registered ErrorHandler 
+	/* Handles Smalltalk errors. Triggers the registered ErrorHandler
 	   (See the Smalltalk class ErrorHandler and its subclasses */
 
 	function handleError(error) {
-        if(!error.cc) {
-		    smalltalk.ErrorHandler._current()._handleError_(error);
-        }
-	};
+        st.ErrorHandler._current()._handleError_(error);
+	}
 
 	/* Handles #dnu: *and* JavaScript method calls.
 	   if the receiver has no klass, we consider it a JS object (outside of the
@@ -450,21 +562,21 @@ function Smalltalk(){
 			return callJavaScriptMethod(receiver, selector, args);
 		}
 
-		/* Handles not understood messages. Also see the Amber counter-part 
+		/* Handles not understood messages. Also see the Amber counter-part
 		   Object>>doesNotUnderstand: */
 
 		return receiver._doesNotUnderstand_(
-				st.Message._new()
+			st.Message._new()
 				._selector_(st.convertSelector(selector))
 				._arguments_(args)
-				);
-	};
+		);
+	}
 
 	/* Call a method of a JS object, or answer a property if it exists.
 	   Else try wrapping a JSObjectProxy around the receiver.
 
        If the object property is a function, then call it, except if it starts with
-       an uppercase character (we probably want to answer the function itself in this 
+       an uppercase character (we probably want to answer the function itself in this
        case and send it #new from Amber).
 
 	   Converts keyword-based selectors by using the first
@@ -488,42 +600,47 @@ function Smalltalk(){
 		}
 
 		return st.send(st.JSObjectProxy._on_(receiver), selector, args);
-	};
-
-
-	/* Reuse one old context stored in oldContext */
-
-	st.oldContext = null;
-
+	}
 
 	/* Handle thisContext pseudo variable */
 
 	st.getThisContext = function() {
-		if(st.thisContext) {
-			return st.thisContext.copy();
-		}
+        if(st.thisContext) {
+		    st.thisContext.init();
+            return st.thisContext;
+        } else {
+            return nil;
+        }
 	};
 
-	function pushContext(receiver, selector, method, temps) {
-		var c = st.oldContext, tc = st.thisContext;
-		if (!c) {
-			return st.thisContext = new SmalltalkMethodContext(receiver, selector, method, temps, tc);
-		}
-		st.oldContext = null;
-		c.homeContext = tc;
-        c.pc          = 1;
-		c.receiver    = receiver;
-        c.selector    = selector;
-		c.method      = method;
-		c.temps       = temps || {};
-		return st.thisContext = c;
-	};
+	function pushContext(setup) {
+		return st.thisContext = new SmalltalkMethodContext(smalltalk.thisContext, setup);
+	}
 
 	function popContext(context) {
 		st.thisContext = context.homeContext;
-		context.homeContext = undefined;
-		st.oldContext = context;
-	};
+	}
+
+	/* Convert a Smalltalk selector into a JS selector */
+
+    st.selector = function(string) {
+        var selector = '_' + string;
+	    selector = selector.replace(/:/g, '_');
+	    selector = selector.replace(/[\&]/g, '_and');
+	    selector = selector.replace(/[\|]/g, '_or');
+	    selector = selector.replace(/[+]/g, '_plus');
+	    selector = selector.replace(/-/g, '_minus');
+	    selector = selector.replace(/[*]/g ,'_star');
+	    selector = selector.replace(/[\/]/g ,'_slash');
+	    selector = selector.replace(/[\\]/g ,'_backslash');
+	    selector = selector.replace(/[\~]/g ,'_tild');
+	    selector = selector.replace(/>/g ,'_gt');
+	    selector = selector.replace(/</g ,'_lt');
+	    selector = selector.replace(/=/g ,'_eq');
+	    selector = selector.replace(/,/g ,'_comma');
+	    selector = selector.replace(/[@]/g ,'_at');
+        return selector
+    };
 
 	/* Convert a string to a valid smalltalk selector.
 	   if you modify the following functions, also change String>>asSelector
@@ -539,21 +656,25 @@ function Smalltalk(){
 
 	function convertKeywordSelector(selector) {
 		return selector.replace(/^_/, '').replace(/_/g, ':');
-	};
+	}
 
 	function convertBinarySelector(selector) {
 		return selector
 			.replace(/^_/, '')
-			.replace(/_plus/, '+')
-			.replace(/_minus/, '-')
-			.replace(/_star/, '*')
-			.replace(/_slash/, '/')
-			.replace(/_gt/, '>')
-			.replace(/_lt/, '<')
-			.replace(/_eq/, '=')
-			.replace(/_comma/, ',')
-			.replace(/_at/, '@')
-	};
+			.replace(/_and/g, '&')
+			.replace(/_or/g, '|')
+			.replace(/_plus/g, '+')
+			.replace(/_minus/g, '-')
+			.replace(/_star/g, '*')
+			.replace(/_slash/g, '/')
+			.replace(/_backslash/g, '\\')
+			.replace(/_tild/g, '~')
+			.replace(/_gt/g, '>')
+			.replace(/_lt/g, '<')
+			.replace(/_eq/g, '=')
+			.replace(/_comma/g, ',')
+			.replace(/_at/g, '@')
+	}
 
 	/* Converts a JavaScript object to valid Smalltalk Object */
 	st.readJSObject = function(js) {
@@ -562,12 +683,12 @@ function Smalltalk(){
 		var readArray = (js.constructor === Array);
 
 		if(readObject) {
-			object = smalltalk.Dictionary._new();
+			object = st.Dictionary._new();
 		}
 		for(var i in js) {
 			if(readObject) {
 				object._at_put_(i, st.readJSObject(js[i]));
-			} 
+			}
 			if(readArray) {
 				object[i] = st.readJSObject(js[i]);
 			}
@@ -582,29 +703,70 @@ function Smalltalk(){
         } else {
             smalltalk.NonBooleanReceiver._new()._object_(shouldBeBoolean)._signal();
         }
-    }
-};
+    };
 
-function SmalltalkMethodContext(receiver, selector, method, temps, home) {
-	this.receiver    = receiver;
-    this.selector    = selector;
-	this.method      = method;
-	this.temps       = temps || {};
+    /* Smalltalk initialization. Called on page load */
+
+    st.initialize = function() {
+		if(initialized) { return; }
+
+		classes.forEach(function(klass) {
+            st.init(klass);
+        });
+        classes.forEach(function(klass) {
+            klass._initialize();
+        });
+
+        initialized = true;
+    };
+}
+
+inherits(Smalltalk, SmalltalkObject);
+
+function SmalltalkMethodContext(home, setup) {
 	this.homeContext = home;
+    this.setup       = setup || function() {};
+    this.pc          = 0;
+}
+
+// Fallbacks
+SmalltalkMethodContext.prototype.locals = {};
+SmalltalkMethodContext.prototype.receiver = null;
+SmalltalkMethodContext.prototype.selector = null;
+SmalltalkMethodContext.prototype.lookupClass = null;
+
+inherits(SmalltalkMethodContext, SmalltalkObject);
+
+SmalltalkMethodContext.prototype.fill = function(receiver, selector, locals, lookupClass) {
+    this.receiver    = receiver;
+    this.selector    = selector;
+    this.locals      = locals || {};
+    this.lookupClass = lookupClass;
 };
 
-SmalltalkMethodContext.prototype.copy = function() {
+SmalltalkMethodContext.prototype.fillBlock = function(locals, ctx) {
+    this.locals        = locals || {};
+    this.methodContext = ctx;
+};
+
+SmalltalkMethodContext.prototype.init = function() {
 	var home = this.homeContext;
-	if(home) {home = home.copy()}
-	return new SmalltalkMethodContext(
-		this.receiver, 
-        this.selector,
-		this.method, 
-		this.temps, 
-		home
-	);
+	if(home) {home = home.init()}
+
+    this.setup(this);
+};
+
+SmalltalkMethodContext.prototype.method = function() {
+    var method;
+    var lookup = this.lookupClass || this.receiver.klass;
+    while(!method && lookup) {
+        method = lookup.methods[smalltalk.convertSelector(this.selector)];
+        lookup = lookup.superclass
+    }
+    return method;
 };
 
+// TODO: this is just wrong :)
 SmalltalkMethodContext.prototype.resume = function() {
     //Brutally set the receiver as thisContext, then re-enter the function
     smalltalk.thisContext = this;
@@ -620,39 +782,50 @@ if(this.jQuery) {
 	this.jQuery.allowJavaScriptCalls = true;
 }
 
-/****************************************************************************************/
+/*
+ * Answer the smalltalk representation of o.
+ * Used in message sends
+ */
+
+var _st = function(o) {
+	if(o == null) {return nil}
+	if(o.klass) {return o}
+	return smalltalk.JSObjectProxy._on_(o);
+}; 
 
 
-/* Base classes wrapping. If you edit this part, do not forget to set the superclass of the
-   object metaclass to Class after the definition of Object */
+/***************************************** BOOTSTRAP ******************************************/
 
-smalltalk.wrapClassName("Object", "Kernel", SmalltalkObject);
-smalltalk.wrapClassName("Smalltalk", "Kernel", Smalltalk, smalltalk.Object);
-smalltalk.wrapClassName("Package", "Kernel", SmalltalkPackage, smalltalk.Object);
-smalltalk.wrapClassName("Behavior", "Kernel", SmalltalkBehavior, smalltalk.Object);
-smalltalk.wrapClassName("Class", "Kernel", SmalltalkClass, smalltalk.Behavior);
-smalltalk.wrapClassName("Metaclass", "Kernel", SmalltalkMetaclass, smalltalk.Behavior);
-smalltalk.wrapClassName("CompiledMethod", "Kernel", SmalltalkMethod, smalltalk.Object);
-smalltalk.wrapClassName("Organizer", "Kernel-Objects", SmalltalkOrganizer, smalltalk.Object);
+smalltalk.wrapClassName("Object", "Kernel-Objects", SmalltalkObject, undefined, false);
+smalltalk.wrapClassName("Behavior", "Kernel-Classes", SmalltalkBehavior, smalltalk.Object, false);
+smalltalk.wrapClassName("Metaclass", "Kernel-Classes", SmalltalkMetaclass, smalltalk.Behavior, false);
+smalltalk.wrapClassName("Class", "Kernel-Classes", SmalltalkClass, smalltalk.Behavior, false);
 
 smalltalk.Object.klass.superclass = smalltalk.Class;
 
+
+smalltalk.wrapClassName("Smalltalk", "Kernel-Objects", Smalltalk, smalltalk.Object, false);
+smalltalk.wrapClassName("Package", "Kernel-Objects", SmalltalkPackage, smalltalk.Object, false);
+smalltalk.wrapClassName("CompiledMethod", "Kernel-Methods", SmalltalkMethod, smalltalk.Object, false);
+smalltalk.wrapClassName("Organizer", "Kernel-Objects", SmalltalkOrganizer, smalltalk.Object, false);
+
+
 smalltalk.wrapClassName("Number", "Kernel", Number, smalltalk.Object);
 smalltalk.wrapClassName("BlockClosure", "Kernel", Function, smalltalk.Object);
 smalltalk.wrapClassName("Boolean", "Kernel", Boolean, smalltalk.Object);
 smalltalk.wrapClassName("Date", "Kernel", Date, smalltalk.Object);
-smalltalk.wrapClassName("UndefinedObject", "Kernel", SmalltalkNil, smalltalk.Object);
+smalltalk.wrapClassName("UndefinedObject", "Kernel", SmalltalkNil, smalltalk.Object, false);
 
-smalltalk.wrapClassName("Collection", "Kernel", null, smalltalk.Object);
-smalltalk.wrapClassName("SequenceableCollection", "Kernel", null, smalltalk.Collection);
-smalltalk.wrapClassName("CharacterArray", "Kernel", null, smalltalk.SequenceableCollection);
+smalltalk.wrapClassName("Collection", "Kernel", null, smalltalk.Object, false);
+smalltalk.wrapClassName("SequenceableCollection", "Kernel", null, smalltalk.Collection, false);
+smalltalk.wrapClassName("CharacterArray", "Kernel", null, smalltalk.SequenceableCollection, false);
 smalltalk.wrapClassName("String", "Kernel", String, smalltalk.CharacterArray);
-smalltalk.wrapClassName("Symbol", "Kernel", SmalltalkSymbol, smalltalk.CharacterArray);
+smalltalk.wrapClassName("Symbol", "Kernel", SmalltalkSymbol, smalltalk.CharacterArray, false);
 smalltalk.wrapClassName("Array", "Kernel", Array, smalltalk.SequenceableCollection);
 smalltalk.wrapClassName("RegularExpression", "Kernel", RegExp, smalltalk.String);
 
 smalltalk.wrapClassName("Error", "Kernel", Error, smalltalk.Object);
-smalltalk.wrapClassName("MethodContext", "Kernel", SmalltalkMethodContext, smalltalk.Object);
+smalltalk.wrapClassName("MethodContext", "Kernel", SmalltalkMethodContext, smalltalk.Object, false);
 
 /* Alias definitions */
 

+ 1 - 4
js/init.js

@@ -1,7 +1,4 @@
-smalltalk.init(smalltalk.Object); //metaclasses are in through Class
-smalltalk.classes()._do_(function(each) {
-	each._initialize();
-});
+smalltalk.initialize();
 
 /* Similar to jQuery(document).ready() */
 

+ 24 - 4
js/parser.js

@@ -73,6 +73,7 @@ smalltalk.parser = (function(){
         "subexpression": parse_subexpression,
         "statements": parse_statements,
         "sequence": parse_sequence,
+        "stSequence": parse_stSequence,
         "block": parse_block,
         "operand": parse_operand,
         "unaryMessage": parse_unaryMessage,
@@ -1809,7 +1810,7 @@ smalltalk.parser = (function(){
           result0 = null;
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, bin) {return bin.join("").replace(/\\/g, '\\\\')})(pos0.offset, pos0.line, pos0.column, result0);
+          result0 = (function(offset, line, column, bin) {return bin.join("")})(pos0.offset, pos0.line, pos0.column, result0);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -2041,9 +2042,6 @@ smalltalk.parser = (function(){
             result0 = parse_keywordSend();
             if (result0 === null) {
               result0 = parse_binarySend();
-              if (result0 === null) {
-                result0 = parse_jsStatement();
-              }
             }
           }
         }
@@ -2863,6 +2861,28 @@ smalltalk.parser = (function(){
           return cachedResult.result;
         }
         
+        var result0;
+        
+        result0 = parse_jsStatement();
+        if (result0 === null) {
+          result0 = parse_stSequence();
+        }
+        
+        cache[cacheKey] = {
+          nextPos: clone(pos),
+          result:  result0
+        };
+        return result0;
+      }
+      
+      function parse_stSequence() {
+        var cacheKey = "stSequence@" + pos.offset;
+        var cachedResult = cache[cacheKey];
+        if (cachedResult) {
+          pos = clone(cachedResult.nextPos);
+          return cachedResult.result;
+        }
+        
         var result0, result1, result2, result3;
         var pos0, pos1;
         

+ 7 - 3
js/parser.pegjs

@@ -61,7 +61,7 @@ reference      = variable / classReference
 
 keywordPair    = key:keyword ws arg:binarySend ws {return {key:key, arg: arg}}
 
-binarySelector = bin:[\\+*/=><,@%~|&-]+ {return bin.join("").replace(/\\/g, '\\\\')}
+binarySelector = bin:[\\+*/=><,@%~|&-]+ {return bin.join("")}
 unarySelector  = identifier
 
 keywordPattern = pairs:(ws key:keyword ws arg:identifier {return {key:key, arg: arg}})+ {
@@ -78,7 +78,7 @@ keywordPattern = pairs:(ws key:keyword ws arg:identifier {return {key:key, arg:
 binaryPattern  = ws selector:binarySelector ws arg:identifier {return [selector, [arg]]}
 unaryPattern   = ws selector:unarySelector {return [selector, []]}
 
-expression     = assignment / cascade / keywordSend / binarySend / jsStatement
+expression     = assignment / cascade / keywordSend / binarySend
 
 expressionList = ws "." ws expression:expression {return expression}
 expressions    = first:expression others:expressionList* {
@@ -116,12 +116,16 @@ statements     = ret:ret [.]* {return [ret]}
                        return expressions || []
                    }
 
-sequence       = temps:temps? ws statements:statements? ws {
+sequence       = jsSequence / stSequence
+
+stSequence     = temps:temps? ws statements:statements? ws {
                      return smalltalk.SequenceNode._new()
                             ._temps_(temps || [])
                             ._nodes_(statements || [])
                  }
 
+jsSequence     = jsStatement
+
 block          = '[' ws params:blockParamList? ws sequence:sequence? ws ']' {
                      return smalltalk.BlockNode._new()
                             ._parameters_(params || [])

+ 1 - 1
repl/REPL.st

@@ -1,6 +1,6 @@
 Object subclass: #Repl
 	instanceVariableNames: 'readline interface util'
-	category: 'REPL'!
+	package: 'REPL'!
 
 !Repl methodsFor: 'accessing'!
 

Fichier diff supprimé car celui-ci est trop grand
+ 511 - 165
repl/amber.js


+ 36 - 9
st/Compiler-AST.st

@@ -1,9 +1,11 @@
 Smalltalk current createPackage: 'Compiler-AST' properties: #{}!
 Object subclass: #Node
-	instanceVariableNames: 'nodes shouldBeInlined shouldBeAliased'
+	instanceVariableNames: 'position nodes shouldBeInlined shouldBeAliased'
 	package: 'Compiler-AST'!
 !Node commentStamp!
-I am the abstract root class of the abstract syntax tree.!
+I am the abstract root class of the abstract syntax tree.
+
+position: holds a point containing lline- and column number of the symbol location in the original source file!
 
 !Node methodsFor: 'accessing'!
 
@@ -15,6 +17,10 @@ nodes
 	^nodes ifNil: [nodes := Array new]
 !
 
+position
+	^position ifNil: [position := 0@0]
+!
+
 shouldBeAliased
 	^ shouldBeAliased ifNil: [ false ]
 !
@@ -29,18 +35,16 @@ shouldBeInlined
 
 shouldBeInlined: aBoolean
 	shouldBeInlined := aBoolean
-!
-
-subtreeNeedsAliasing
-    ^(self shouldBeAliased or: [ self shouldBeInlined ]) or: [
-        (self nodes detect: [ :node | node subtreeNeedsAliasing ] ifNone: [ false ]) ~= false
-    ]
 ! !
 
 !Node methodsFor: 'building'!
 
 nodes: aCollection
 	nodes := aCollection
+!
+
+position: aPosition
+	position := aPosition
 ! !
 
 !Node methodsFor: 'testing'!
@@ -61,6 +65,10 @@ isImmutable
 	^false
 !
 
+isNode
+	^ true
+!
+
 isReturnNode
 	^false
 !
@@ -71,6 +79,11 @@ isSendNode
 
 isValueNode
 	^false
+!
+
+subtreeNeedsAliasing
+    ^(self shouldBeAliased or: [ self shouldBeInlined ]) or: [
+        (self nodes detect: [ :each | each subtreeNeedsAliasing ] ifNone: [ false ]) ~= false ]
 ! !
 
 !Node methodsFor: 'visiting'!
@@ -212,7 +225,7 @@ accept: aVisitor
 ! !
 
 Node subclass: #MethodNode
-	instanceVariableNames: 'selector arguments source scope classReferences messageSends'
+	instanceVariableNames: 'selector arguments source scope classReferences messageSends superSends'
 	package: 'Compiler-AST'!
 
 !MethodNode methodsFor: 'accessing'!
@@ -263,6 +276,14 @@ source
 
 source: aString
 	source := aString
+!
+
+superSends
+	^ superSends
+!
+
+superSends: aCollection
+	superSends := aCollection
 ! !
 
 !MethodNode methodsFor: 'visiting'!
@@ -523,3 +544,9 @@ accept: aVisitor
 	^ aVisitor visitClassReferenceNode: self
 ! !
 
+!Object methodsFor: '*Compiler-AST'!
+
+isNode
+	^ false
+! !
+

+ 1 - 540
st/Compiler-Core.st

@@ -149,7 +149,7 @@ visit: aNode
 !
 
 visitAll: aCollection
-	^ aCollection do: [ :each | self visit: each ]
+	^ aCollection collect: [ :each | self visit: each ]
 !
 
 visitAssignmentNode: aNode
@@ -294,542 +294,3 @@ translator
 		yourself
 ! !
 
-AbstractCodeGenerator subclass: #FunCodeGenerator
-	instanceVariableNames: 'stream nestedBlocks earlyReturn currentSelector unknownVariables tempVariables messageSends referencedClasses classReferenced argVariables'
-	package: 'Compiler-Core'!
-
-!FunCodeGenerator methodsFor: 'accessing'!
-
-argVariables
-	^argVariables copy
-!
-
-knownVariables
-	^self pseudoVariables 
-		addAll: self tempVariables;
-		addAll: self argVariables;
-		yourself
-!
-
-tempVariables
-	^tempVariables copy
-!
-
-unknownVariables
-	^unknownVariables copy
-! !
-
-!FunCodeGenerator methodsFor: 'compiling'!
-
-compileNode: aNode
-	stream := '' writeStream.
-	self visit: aNode.
-	^stream contents
-! !
-
-!FunCodeGenerator methodsFor: 'initialization'!
-
-initialize
-	super initialize.
-	stream := '' writeStream. 
-	unknownVariables := #().
-	tempVariables := #().
-	argVariables := #().
-	messageSends := #().
-	classReferenced := #()
-! !
-
-!FunCodeGenerator methodsFor: 'optimizations'!
-
-checkClass: aClassName for: receiver
-        stream nextPutAll: '((($receiver = ', receiver, ').klass === smalltalk.', aClassName, ') ? '
-!
-
-inline: aSelector receiver: receiver argumentNodes: aCollection
-        | inlined |
-        inlined := false.
-
-	"-- Booleans --"
-
-	(aSelector = 'ifFalse:') ifTrue: [
-		aCollection first isBlockNode ifTrue: [
-                	self checkClass: 'Boolean' for: receiver.
-                	stream nextPutAll: '(!! $receiver ? '.
-                	self visit: aCollection first.
-          		stream nextPutAll: '() : nil)'.
-                	inlined := true]].
-
-	(aSelector = 'ifTrue:') ifTrue: [
-		aCollection first isBlockNode ifTrue: [
-                	self checkClass: 'Boolean' for: receiver.
-                	stream nextPutAll: '($receiver ? '.
-                	self visit: aCollection first.
-          		stream nextPutAll: '() : nil)'.
-                	inlined := true]].
-
-	(aSelector = 'ifTrue:ifFalse:') ifTrue: [
-		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
-                	self checkClass: 'Boolean' for: receiver.
-                	stream nextPutAll: '($receiver ? '.
-                	self visit: aCollection first.
-          		stream nextPutAll: '() : '.
-          		self visit: aCollection second.
-          		stream nextPutAll: '())'.
-                	inlined := true]].
-
-	(aSelector = 'ifFalse:ifTrue:') ifTrue: [
-		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
-                	self checkClass: 'Boolean' for: receiver.
-                	stream nextPutAll: '(!! $receiver ? '.
-                	self visit: aCollection first.
-          		stream nextPutAll: '() : '.
-          		self visit: aCollection second.
-          		stream nextPutAll: '())'.
-                	inlined := true]].
-
-	"-- Numbers --"
-
-	(aSelector = '<') ifTrue: [
-                self checkClass: 'Number' for: receiver.
-                stream nextPutAll: '$receiver <'.
-                self visit: aCollection first.
-                inlined := true].
-
-	(aSelector = '<=') ifTrue: [
-                self checkClass: 'Number' for: receiver.
-                stream nextPutAll: '$receiver <='.
-                self visit: aCollection first.
-                inlined := true].
-
-	(aSelector = '>') ifTrue: [ 
-                self checkClass: 'Number' for: receiver.
-                stream nextPutAll: '$receiver >'.
-                self visit: aCollection first.
-                inlined := true].
-
-	(aSelector = '>=') ifTrue: [
-                self checkClass: 'Number' for: receiver.
-                stream nextPutAll: '$receiver >='.
-                self visit: aCollection first.
-                inlined := true].
-
-        (aSelector = '+') ifTrue: [
-                self checkClass: 'Number' for: receiver.
-                stream nextPutAll: '$receiver +'.
-                self visit: aCollection first.
-                inlined := true].
-
-        (aSelector = '-') ifTrue: [
-                self checkClass: 'Number' for: receiver.
-                stream nextPutAll: '$receiver -'.
-                self visit: aCollection first.
-                inlined := true].
-
-        (aSelector = '*') ifTrue: [
-                self checkClass: 'Number' for: receiver.
-                stream nextPutAll: '$receiver *'.
-                self visit: aCollection first.
-                inlined := true].
-
-        (aSelector = '/') ifTrue: [
-                self checkClass: 'Number' for: receiver.
-                stream nextPutAll: '$receiver /'.
-                self visit: aCollection first.
-                inlined := true].
-
-        ^inlined
-!
-
-inlineLiteral: aSelector receiverNode: anObject argumentNodes: aCollection
-        | inlined |
-        inlined := false.
- 
-	"-- BlockClosures --"
-
-	(aSelector = 'whileTrue:') ifTrue: [
-          	(anObject isBlockNode and: [aCollection first isBlockNode]) ifTrue: [
-                	stream nextPutAll: '(function(){while('.
-                  	self visit: anObject.
-                  	stream nextPutAll: '()) {'.
-                	self visit: aCollection first.
-          		stream nextPutAll: '()}})()'.
-                	inlined := true]].
-
-	(aSelector = 'whileFalse:') ifTrue: [
-          	(anObject isBlockNode and: [aCollection first isBlockNode]) ifTrue: [
-                	stream nextPutAll: '(function(){while(!!'.
-                  	self visit: anObject.
-                  	stream nextPutAll: '()) {'.
-                	self visit: aCollection first.
-          		stream nextPutAll: '()}})()'.
-                	inlined := true]].
-
-	(aSelector = 'whileTrue') ifTrue: [
-          	anObject isBlockNode ifTrue: [
-                	stream nextPutAll: '(function(){while('.
-                  	self visit: anObject.
-                  	stream nextPutAll: '()) {}})()'.
-                	inlined := true]].
-
-	(aSelector = 'whileFalse') ifTrue: [
-          	anObject isBlockNode ifTrue: [
-                	stream nextPutAll: '(function(){while(!!'.
-                  	self visit: anObject.
-                  	stream nextPutAll: '()) {}})()'.
-                	inlined := true]].
-
-	"-- Numbers --"
-
-	(aSelector = '+') ifTrue: [
-          	(self isNode: anObject ofClass: Number) ifTrue: [
-                  	self visit: anObject.
-                  	stream nextPutAll: ' + '.
-                	self visit: aCollection first.
-                	inlined := true]].
-
-	(aSelector = '-') ifTrue: [
-          	(self isNode: anObject ofClass: Number) ifTrue: [
-                  	self visit: anObject.
-                  	stream nextPutAll: ' - '.
-                	self visit: aCollection first.
-                	inlined := true]].
-
-	(aSelector = '*') ifTrue: [
-          	(self isNode: anObject ofClass: Number) ifTrue: [
-                  	self visit: anObject.
-                  	stream nextPutAll: ' * '.
-                	self visit: aCollection first.
-                	inlined := true]].
-
-	(aSelector = '/') ifTrue: [
-          	(self isNode: anObject ofClass: Number) ifTrue: [
-                  	self visit: anObject.
-                  	stream nextPutAll: ' / '.
-                	self visit: aCollection first.
-                	inlined := true]].
-
-	(aSelector = '<') ifTrue: [
-          	(self isNode: anObject ofClass: Number) ifTrue: [
-                  	self visit: anObject.
-                  	stream nextPutAll: ' < '.
-                	self visit: aCollection first.
-                	inlined := true]].
-
-	(aSelector = '<=') ifTrue: [
-          	(self isNode: anObject ofClass: Number) ifTrue: [
-                  	self visit: anObject.
-                  	stream nextPutAll: ' <= '.
-                	self visit: aCollection first.
-                	inlined := true]].
-
-	(aSelector = '>') ifTrue: [
-          	(self isNode: anObject ofClass: Number) ifTrue: [
-                  	self visit: anObject.
-                  	stream nextPutAll: ' > '.
-                	self visit: aCollection first.
-                	inlined := true]].
-
-	(aSelector = '>=') ifTrue: [
-          	(self isNode: anObject ofClass: Number) ifTrue: [
-                  	self visit: anObject.
-                  	stream nextPutAll: ' >= '.
-                	self visit: aCollection first.
-                	inlined := true]].
-                	   
-	"-- UndefinedObject --"
-
-	(aSelector = 'ifNil:') ifTrue: [
-		aCollection first isBlockNode ifTrue: [
-          		stream nextPutAll: '(($receiver = '.
-          		self visit: anObject.
-          		stream nextPutAll: ') == nil || $receiver == undefined) ? '.
-                  	self visit: aCollection first.
-                  	stream nextPutAll: '() : $receiver'.
-                  	inlined := true]].
-
-	(aSelector = 'ifNotNil:') ifTrue: [
-		aCollection first isBlockNode ifTrue: [
-          		stream nextPutAll: '(($receiver = '.
-          		self visit: anObject.
-          		stream nextPutAll: ') !!= nil && $receiver !!= undefined) ? '.
-                  	self visit: aCollection first.
-                  	stream nextPutAll: '() : nil'.
-                  	inlined := true]].
-
-	(aSelector = 'ifNil:ifNotNil:') ifTrue: [
-		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
-          		stream nextPutAll: '(($receiver = '.
-          		self visit: anObject.
-          		stream nextPutAll: ') == nil || $receiver == undefined) ? '.
-                  	self visit: aCollection first.
-                  	stream nextPutAll: '() : '.
-                  	self visit: aCollection second.
-                  	stream nextPutAll: '()'.
-                  	inlined := true]].
-
-	(aSelector = 'ifNotNil:ifNil:') ifTrue: [
-		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
-          		stream nextPutAll: '(($receiver = '.
-          		self visit: anObject.
-          		stream nextPutAll: ') == nil || $receiver == undefined) ? '.
-                  	self visit: aCollection second.
-                  	stream nextPutAll: '() : '.
-                  	self visit: aCollection first.
-                  	stream nextPutAll: '()'.
-                  	inlined := true]].
-                 
-        ^inlined
-!
-
-isNode: aNode ofClass: aClass
-	^aNode isValueNode and: [
-          	aNode value class = aClass or: [
-          		aNode value = 'self' and: [self currentClass = aClass]]]
-! !
-
-!FunCodeGenerator methodsFor: 'testing'!
-
-performOptimizations
-	^self class performOptimizations
-! !
-
-!FunCodeGenerator methodsFor: 'visiting'!
-
-send: aSelector to: aReceiver arguments: aCollection superSend: aBoolean
-	^String streamContents: [:str || tmp |
-        	tmp := stream.
-		str nextPutAll: 'smalltalk.send('.
-		str nextPutAll: aReceiver.
-		str nextPutAll: ', "', aSelector asSelector, '", ['.
-                stream := str.
-		aCollection
-	    		do: [:each | self visit: each]
-	    		separatedBy: [stream nextPutAll: ', '].
-                stream := tmp.
-                str nextPutAll: ']'.
-		aBoolean ifTrue: [
-			str nextPutAll: ', smalltalk.', (self classNameFor: self currentClass), '.superclass || nil'].
-		str nextPutAll: ')']
-!
-
-visit: aNode
-	aNode accept: self
-!
-
-visitAssignmentNode: aNode
-	stream nextPutAll: '('.
-	self visit: aNode left.
-	stream nextPutAll: '='.
-	self visit: aNode right.
-	stream nextPutAll: ')'
-!
-
-visitBlockNode: aNode
-	stream nextPutAll: '(function('.
-	aNode parameters 
-	    do: [:each |
-		tempVariables add: each.
-		stream nextPutAll: each]
-	    separatedBy: [stream nextPutAll: ', '].
-	stream nextPutAll: '){'.
-	aNode nodes do: [:each | self visit: each].
-	stream nextPutAll: '})'
-!
-
-visitBlockSequenceNode: aNode
-	| index |
-	nestedBlocks := nestedBlocks + 1.
-	aNode nodes isEmpty
-	    ifTrue: [
-		stream nextPutAll: 'return nil;']
-	    ifFalse: [
-		aNode temps do: [:each | | temp |
-                    temp := self safeVariableNameFor: each.
-		    tempVariables add: temp.
-		    stream nextPutAll: 'var ', temp, '=nil;'; lf].
-		index := 0.
-		aNode nodes do: [:each |
-		    index := index + 1.
-		    index = aNode nodes size ifTrue: [
-			stream nextPutAll: 'return '].
-		    self visit: each.
-		    stream nextPutAll: ';']].
-	nestedBlocks := nestedBlocks - 1
-!
-
-visitCascadeNode: aNode
-	| index |
-	index := 0.
-	(tempVariables includes: '$rec') ifFalse: [
-		tempVariables add: '$rec'].
-	stream nextPutAll: '(function($rec){'.
-	aNode nodes do: [:each |
-	    index := index + 1.
-	    index = aNode nodes size ifTrue: [
-		stream nextPutAll: 'return '].
-	    each receiver: (VariableNode new value: '$rec').
-	    self visit: each.
-	    stream nextPutAll: ';'].
-	stream nextPutAll: '})('.
-	self visit: aNode receiver.
-	stream nextPutAll: ')'
-!
-
-visitClassReferenceNode: aNode
-	(referencedClasses includes: aNode value) ifFalse: [
-		referencedClasses add: aNode value].
-	stream nextPutAll: '(smalltalk.', aNode value, ' || ', aNode value, ')'
-!
-
-visitDynamicArrayNode: aNode
-	stream nextPutAll: '['.
-	aNode nodes 
-		do: [:each | self visit: each]
-		separatedBy: [stream nextPutAll: ','].
-	stream nextPutAll: ']'
-!
-
-visitDynamicDictionaryNode: aNode
-	stream nextPutAll: 'smalltalk.HashedCollection._fromPairs_(['.
-		aNode nodes 
-			do: [:each | self visit: each]
-			separatedBy: [stream nextPutAll: ','].
-		stream nextPutAll: '])'
-!
-
-visitFailure: aFailure
-	self error: aFailure asString
-!
-
-visitJSStatementNode: aNode
-	stream nextPutAll: aNode source
-!
-
-visitMethodNode: aNode
-	| str currentSelector | 
-	currentSelector := aNode selector asSelector.
-	nestedBlocks := 0.
-	earlyReturn := false.
-	messageSends := #().
-	referencedClasses := #().
-	unknownVariables := #().
-	tempVariables := #().
-	argVariables := #().
-	stream 
-	    nextPutAll: 'smalltalk.method({'; lf;
-	    nextPutAll: 'selector: "', aNode selector, '",'; lf.
-	stream nextPutAll: 'source: ', self source asJavascript, ',';lf.
-	stream nextPutAll: 'fn: function('.
-	aNode arguments 
-	    do: [:each | 
-		argVariables add: each.
-		stream nextPutAll: each]
-	    separatedBy: [stream nextPutAll: ', '].
-	stream 
-	    nextPutAll: '){'; lf;
-	    nextPutAll: 'var self=this;'; lf.
-	str := stream.
-	stream := '' writeStream.
-	aNode nodes do: [:each |
-	    self visit: each].
-	earlyReturn ifTrue: [
-	    str nextPutAll: 'var $early={};'; lf; nextPutAll: 'try{'].
-	str nextPutAll: stream contents.
-	stream := str.
-	stream 
-	    lf; 
-	    nextPutAll: 'return self;'.
-	earlyReturn ifTrue: [
-	    stream lf; nextPutAll: '} catch(e) {if(e===$early)return e[0]; throw e}'].
-	stream nextPutAll: '}'.
-	stream 
-		nextPutAll: ',', String lf, 'messageSends: ';
-		nextPutAll: messageSends asJavascript, ','; lf;
-          	nextPutAll: 'args: ', argVariables asJavascript, ','; lf;
-		nextPutAll: 'referencedClasses: ['.
-	referencedClasses 
-		do: [:each | stream nextPutAll: each printString]
-		separatedBy: [stream nextPutAll: ','].
-	stream nextPutAll: ']'.
-	stream nextPutAll: '})'
-!
-
-visitReturnNode: aNode
-	nestedBlocks > 0 ifTrue: [
-	    earlyReturn := true].
-	nestedBlocks > 0
-	    ifTrue: [
-		stream
-		    nextPutAll: '(function(){throw $early=[']
-	    ifFalse: [stream nextPutAll: 'return '].
-	aNode nodes do: [:each |
-	    self visit: each].
-	nestedBlocks > 0 ifTrue: [
-	    stream nextPutAll: ']})()']
-!
-
-visitSendNode: aNode
-        | str receiver superSend inlined |
-        str := stream.
-        (messageSends includes: aNode selector) ifFalse: [
-                messageSends add: aNode selector].
-        stream := '' writeStream.
-        self visit: aNode receiver.
-        superSend := stream contents = 'super'.
-        receiver := superSend ifTrue: ['self'] ifFalse: [stream contents].
-        stream := str.
-	
-	self performOptimizations 
-		ifTrue: [
-			(self inlineLiteral: aNode selector receiverNode: aNode receiver argumentNodes: aNode arguments) ifFalse: [
-				(self inline: aNode selector receiver: receiver argumentNodes: aNode arguments)
-                			ifTrue: [stream nextPutAll: ' : ', (self send: aNode selector to: '$receiver' arguments: aNode arguments superSend: superSend), ')']
-                			ifFalse: [stream nextPutAll: (self send: aNode selector to: receiver arguments: aNode arguments superSend: superSend)]]]
-		ifFalse: [stream nextPutAll: (self send: aNode selector to: receiver arguments: aNode arguments superSend: superSend)]
-!
-
-visitSequenceNode: aNode
-	aNode temps do: [:each || temp |
-            temp := self safeVariableNameFor: each.
-	    tempVariables add: temp.
-	    stream nextPutAll: 'var ', temp, '=nil;'; lf].
-	aNode nodes do: [:each |
-	    self visit: each.
-	    stream nextPutAll: ';']
-	    separatedBy: [stream lf]
-!
-
-visitValueNode: aNode
-	stream nextPutAll: aNode value asJavascript
-!
-
-visitVariableNode: aNode
-	| varName |
-	(self currentClass allInstanceVariableNames includes: aNode value) 
-		ifTrue: [stream nextPutAll: 'self[''@', aNode value, ''']']
-		ifFalse: [
-                  	varName := self safeVariableNameFor: aNode value.
-			(self knownVariables includes: varName) 
-                  		ifFalse: [
-                                  	unknownVariables add: aNode value.
-                                  	aNode assigned 
-                                  		ifTrue: [stream nextPutAll: varName]
-                                  		ifFalse: [stream nextPutAll: '(typeof ', varName, ' == ''undefined'' ? nil : ', varName, ')']]
-                  		ifTrue: [
-                                  	aNode value = 'thisContext'
-                                  		ifTrue: [stream nextPutAll: '(smalltalk.getThisContext())']
-                				ifFalse: [stream nextPutAll: varName]]]
-! !
-
-FunCodeGenerator class instanceVariableNames: 'performOptimizations'!
-
-!FunCodeGenerator class methodsFor: 'accessing'!
-
-performOptimizations
-	^performOptimizations ifNil: [true]
-!
-
-performOptimizations: aBoolean
-	performOptimizations := aBoolean
-! !
-

+ 4 - 0
st/Compiler-Exceptions.st

@@ -77,6 +77,10 @@ The default behavior is to allow it, as this is how Amber currently is able to s
 
 !UnknownVariableError methodsFor: 'accessing'!
 
+messageText
+	^ 'Unknown Variable error: ', self variableName, ' is not defined'
+!
+
 variableName
 	^ variableName
 !

+ 185 - 79
st/Compiler-IR.st

@@ -76,16 +76,22 @@ alias: aNode
 	^ variable
 !
 
-temporallyDependentList: nodes
+aliasTemporally: aCollection
+	"https://github.com/NicolasPetton/amber/issues/296
+    
+    If a node is aliased, all preceding ones are aliased as well.
+    The tree is iterated twice. First we get the aliasing dependency, 
+    then the aliasing itself is done"
+
 	| threshold result |
     threshold := 0.
     
-    nodes withIndexDo: [ :each :i |
+    aCollection withIndexDo: [ :each :i |
         each subtreeNeedsAliasing
 		    ifTrue: [ threshold := i ]].
 
 	result := OrderedCollection new.
-	nodes withIndexDo: [ :each :i | 
+	aCollection withIndexDo: [ :each :i | 
 		result add: (i <= threshold
 			ifTrue: [ self alias: each ]
 			ifFalse: [ self visit: each ])].
@@ -113,6 +119,7 @@ visitBlockNode: aNode
 	aNode scope temps do: [ :each |
 		closure add: (IRTempDeclaration new 
 			name: each name;
+            scope: aNode scope;
 			yourself) ].
 	aNode nodes do: [ :each | closure add: (self visit: each) ].
 	^ closure
@@ -147,14 +154,14 @@ visitCascadeNode: aNode
 visitDynamicArrayNode: aNode
 	| array |
 	array := IRDynamicArray new.
-	(self temporallyDependentList: aNode nodes) do: [:each | array add: each].
+	(self aliasTemporally: aNode nodes) do: [:each | array add: each].
 	^ array
 !
 
 visitDynamicDictionaryNode: aNode
 	| dictionary |
 	dictionary := IRDynamicDictionary new.
-    (self temporallyDependentList: aNode nodes) do: [:each | dictionary add: each].
+    (self aliasTemporally: aNode nodes) do: [:each | dictionary add: each].
 	^ dictionary
 !
 
@@ -168,9 +175,11 @@ visitMethodNode: aNode
 
 	self method: (IRMethod new
 		source: self source;
+        theClass: self theClass;
 		arguments: aNode arguments;
 		selector: aNode selector;
 		messageSends: aNode messageSends;
+        superSends: aNode superSends;
 		classReferences: aNode classReferences;
 		scope: aNode scope;
 		yourself).
@@ -178,6 +187,7 @@ visitMethodNode: aNode
 	aNode scope temps do: [ :each |
 		self method add: (IRTempDeclaration new
 			name: each name;
+            scope: aNode scope;
 			yourself) ].
 
 	aNode nodes do: [ :each | self method add: (self visit: each) ].
@@ -209,7 +219,7 @@ visitSendNode: aNode
 		index: aNode index.
 	aNode superSend ifTrue: [ send classSend: self theClass superclass ].
     
-    all := self temporallyDependentList: { aNode receiver }, aNode arguments.
+    all := self aliasTemporally: { aNode receiver }, aNode arguments.
 	receiver := all first.
 	arguments := all allButFirst.
 
@@ -254,6 +264,10 @@ instructions
 	^ instructions ifNil: [ instructions := OrderedCollection new ]
 !
 
+method
+	^ self parent method
+!
+
 parent
 	^ parent
 !
@@ -306,6 +320,10 @@ isLocalReturn
 	^ false
 !
 
+isMethod
+	^ false
+!
+
 isReturn
 	^ false
 !
@@ -384,11 +402,11 @@ scope: aScope
 	scope := aScope
 ! !
 
-IRScopedInstruction subclass: #IRClosure
+IRScopedInstruction subclass: #IRClosureInstruction
 	instanceVariableNames: 'arguments'
 	package: 'Compiler-IR'!
 
-!IRClosure methodsFor: 'accessing'!
+!IRClosureInstruction methodsFor: 'accessing'!
 
 arguments
 	^ arguments ifNil: [ #() ]
@@ -398,11 +416,28 @@ arguments: aCollection
 	arguments := aCollection
 !
 
+locals
+	^ self arguments copy
+    	addAll: (self tempDeclarations collect: [ :each | each name ]); 
+        yourself
+!
+
 scope: aScope
 	super scope: aScope.
 	aScope instruction: self
 !
 
+tempDeclarations
+	^ self instructions select: [ :each | 
+    	each isTempDeclaration ]
+! !
+
+IRClosureInstruction subclass: #IRClosure
+	instanceVariableNames: ''
+	package: 'Compiler-IR'!
+
+!IRClosure methodsFor: 'accessing'!
+
 sequence
 	^ self instructions last
 ! !
@@ -419,22 +454,14 @@ accept: aVisitor
 	^ aVisitor visitIRClosure: self
 ! !
 
-IRScopedInstruction subclass: #IRMethod
-	instanceVariableNames: 'source selector classReferences messageSends arguments internalVariables'
+IRClosureInstruction subclass: #IRMethod
+	instanceVariableNames: 'theClass source selector classReferences messageSends superSends internalVariables'
 	package: 'Compiler-IR'!
 !IRMethod commentStamp!
 I am a method instruction!
 
 !IRMethod methodsFor: 'accessing'!
 
-arguments
-	^ arguments
-!
-
-arguments: aCollection
-	arguments := aCollection
-!
-
 classReferences
 	^ classReferences
 !
@@ -447,6 +474,10 @@ internalVariables
 	^ internalVariables ifNil: [ internalVariables := Set new ]
 !
 
+isMethod
+	^ true
+!
+
 messageSends
 	^ messageSends
 !
@@ -455,9 +486,8 @@ messageSends: aCollection
 	messageSends := aCollection
 !
 
-scope: aScope
-	super scope: aScope.
-	aScope instruction: self
+method
+	^ self
 !
 
 selector
@@ -474,6 +504,22 @@ source
 
 source: aString
 	source := aString
+!
+
+superSends
+	^ superSends
+!
+
+superSends: aCollection
+	superSends := aCollection
+!
+
+theClass
+	^ theClass
+!
+
+theClass: aClass
+	theClass := aClass
 ! !
 
 !IRMethod methodsFor: 'visiting'!
@@ -555,6 +601,32 @@ accept: aVisitor
 	^ aVisitor visitIRNonLocalReturn: self
 ! !
 
+IRScopedInstruction subclass: #IRTempDeclaration
+	instanceVariableNames: 'name'
+	package: 'Compiler-IR'!
+
+!IRTempDeclaration methodsFor: 'accessing'!
+
+name
+	^ name
+!
+
+name: aString
+	name := aString
+! !
+
+!IRTempDeclaration methodsFor: 'testing'!
+
+isTempDeclaration
+	^ true
+! !
+
+!IRTempDeclaration methodsFor: 'visiting'!
+
+accept: aVisitor
+	^ aVisitor visitIRTempDeclaration: self
+! !
+
 IRInstruction subclass: #IRSend
 	instanceVariableNames: 'selector classSend index'
 	package: 'Compiler-IR'!
@@ -579,6 +651,12 @@ index: anInteger
 	index := anInteger
 !
 
+javascriptSelector
+	^ self classSend 
+    	ifNil: [ self selector asSelector ]
+      	ifNotNil: [ self selector asSuperSelector ]
+!
+
 selector
 	^ selector
 !
@@ -625,32 +703,6 @@ accept: aVisitor
 	^ aVisitor visitIRBlockSequence: self
 ! !
 
-IRInstruction subclass: #IRTempDeclaration
-	instanceVariableNames: 'name'
-	package: 'Compiler-IR'!
-!IRTempDeclaration commentStamp!
-I am a temporary variable declaration instruction!
-
-!IRTempDeclaration methodsFor: 'accessing'!
-
-name
-	^ name
-!
-
-name: aString
-	name := aString
-! !
-
-!IRTempDeclaration methodsFor: 'visiting'!
-
-accept: aVisitor
-	^ aVisitor visitIRTempDeclaration: self
-!
-
-isTempDeclaration
-	^ true
-! !
-
 IRInstruction subclass: #IRValue
 	instanceVariableNames: 'value'
 	package: 'Compiler-IR'!
@@ -843,7 +895,12 @@ visitIRAssignment: anIRAssignment
 
 visitIRClosure: anIRClosure
 	self stream 
-		nextPutClosureWith: [ super visitIRClosure: anIRClosure ] 
+		nextPutClosureWith: [ 
+        	self stream nextPutVars: (anIRClosure tempDeclarations collect: [ :each |
+    				each name asVariableName ]).
+        	self stream 
+            	nextPutBlockContextFor: anIRClosure
+                during: [ super visitIRClosure: anIRClosure ] ]
 		arguments: anIRClosure arguments
 !
 
@@ -864,10 +921,14 @@ visitIRDynamicDictionary: anIRDynamicDictionary
 !
 
 visitIRMethod: anIRMethod
+
 	self stream
 		nextPutMethodDeclaration: anIRMethod 
 		with: [ self stream 
 			nextPutFunctionWith: [ 
+            	self stream nextPutVars: (anIRMethod tempDeclarations collect: [ :each |
+    				each name asVariableName ]).
+            	self stream nextPutContextFor: anIRMethod during: [
 				anIRMethod internalVariables notEmpty ifTrue: [
 					self stream nextPutVars: (anIRMethod internalVariables asArray collect: [ :each |
 						each variable alias ]) ].
@@ -875,7 +936,7 @@ visitIRMethod: anIRMethod
 					ifTrue: [
 						self stream nextPutNonLocalReturnHandlingWith: [
 							super visitIRMethod: anIRMethod ]]
-					ifFalse: [ super visitIRMethod: anIRMethod ]]
+					ifFalse: [ super visitIRMethod: anIRMethod ]]]
 			arguments: anIRMethod arguments ]
 !
 
@@ -890,23 +951,26 @@ visitIRReturn: anIRReturn
 !
 
 visitIRSend: anIRSend
-	self stream nextPutAll: 'smalltalk.send('.
-	self visit: anIRSend instructions first.
-	self stream nextPutAll:  ',"', anIRSend selector asSelector, '",['.
-	anIRSend instructions allButFirst
-		do: [ :each | self visit: each ]
-		separatedBy: [ self stream nextPutAll: ',' ].
-	self stream nextPutAll: ']'.
-	"anIRSend index > 1 
-		ifTrue: [
-			anIRSend classSend 
-				ifNil: [ self stream nextPutAll: ',undefined' ]
-				ifNotNil: [ self stream nextPutAll: ',', anIRSend classSend asJavascript ].
-			self stream nextPutAll: ',', anIRSend index asString ]
-		ifFalse: ["
-			anIRSend classSend ifNotNil: [  
-				self stream nextPutAll: ',', anIRSend classSend asJavascript ]"]".
-	self stream nextPutAll: ')'
+	anIRSend classSend 
+    	ifNil: [
+			self stream nextPutAll: '_st('.
+			self visit: anIRSend instructions first.
+   		 	self stream nextPutAll: ').', anIRSend selector asSelector, '('.
+			anIRSend instructions allButFirst
+				do: [ :each | self visit: each ]
+				separatedBy: [ self stream nextPutAll: ',' ].
+			self stream nextPutAll: ')' ]
+		ifNotNil: [ 
+			self stream 
+            	nextPutAll: anIRSend classSend asJavascript, '.fn.prototype.';
+				nextPutAll: anIRSend selector asSelector, '.apply(';
+				nextPutAll: '_st('.
+			self visit: anIRSend instructions first.
+			self stream nextPutAll: '), ['.
+			anIRSend instructions allButFirst
+				do: [ :each | self visit: each ]
+				separatedBy: [ self stream nextPutAll: ',' ].
+			self stream nextPutAll: '])' ]
 !
 
 visitIRSequence: anIRSequence
@@ -916,7 +980,9 @@ visitIRSequence: anIRSequence
 !
 
 visitIRTempDeclaration: anIRTempDeclaration
-	self stream nextPutVar: anIRTempDeclaration name asVariableName
+	"self stream 
+    	nextPutAll: 'var ', anIRTempDeclaration name asVariableName, ';'; 
+        lf"
 !
 
 visitIRValue: anIRValue
@@ -969,6 +1035,30 @@ nextPutAssignment
 	stream nextPutAll: '='
 !
 
+nextPutBlockContextFor: anIRClosure during: aBlock
+	self 
+    	nextPutAll: 'return smalltalk.withContext(function(', anIRClosure scope alias, ') {'; 
+        nextPutAll: String cr.
+    
+    aBlock value.
+    
+    self 
+    	nextPutAll: '}, function(', anIRClosure scope alias, ') {';
+        nextPutAll: anIRClosure scope alias, '.fillBlock({'.
+    
+    anIRClosure locals 
+    	do: [ :each |
+    		self 
+        		nextPutAll: each asVariableName;
+           	 	nextPutAll: ':';
+        		nextPutAll: each asVariableName]
+		separatedBy: [ self nextPutAll: ',' ].
+    
+    self
+    	nextPutAll: '},';
+        nextPutAll:  anIRClosure method scope alias, ')})'
+!
+
 nextPutClosureWith: aBlock arguments: anArray
 	stream nextPutAll: '(function('.
 	anArray 
@@ -979,6 +1069,30 @@ nextPutClosureWith: aBlock arguments: anArray
 	stream nextPutAll: '})'
 !
 
+nextPutContextFor: aMethod during: aBlock
+	self 
+    	nextPutAll: 'return smalltalk.withContext(function(', aMethod scope alias, ') { '; 
+        nextPutAll: String cr.
+    aBlock value.
+    
+    self 
+    	nextPutAll: '}, function(', aMethod scope alias, ') {', aMethod scope alias; 
+        nextPutAll: '.fill(self,', aMethod selector asJavascript, ',{'.
+
+    aMethod locals 
+    	do: [ :each |
+    		self 
+        		nextPutAll: each asVariableName;
+           	 	nextPutAll: ':';
+        		nextPutAll: each asVariableName]
+		separatedBy: [ self nextPutAll: ',' ].
+    
+    self
+    	nextPutAll: '}, ';
+        nextPutAll: aMethod theClass asJavascript;
+        nextPutAll: ')})'
+!
+
 nextPutFunctionWith: aBlock arguments: anArray
 	stream nextPutAll: 'fn: function('.
 	anArray 
@@ -1012,12 +1126,12 @@ nextPutMethodDeclaration: aMethod with: aBlock
 	stream 
 		nextPutAll: 'smalltalk.method({'; lf;
 		nextPutAll: 'selector: "', aMethod selector, '",'; lf;
-		nextPutAll: 'source: ', aMethod source asJavascript, ',';lf.
+		nextPutAll: 'source: ', aMethod source asJavascript, ',';lf. 
 	aBlock value.
 	stream 
 		nextPutAll: ',', String lf, 'messageSends: ';
 		nextPutAll: aMethod messageSends asArray asJavascript, ','; lf;
-          	nextPutAll: 'args: ', (aMethod arguments collect: [ :each | each value ]) asArray asJavascript, ','; lf;
+        nextPutAll: 'args: ', (aMethod arguments collect: [ :each | each value ]) asArray asJavascript, ','; lf;
 		nextPutAll: 'referencedClasses: ['.
 	aMethod classReferences 
 		do: [:each | stream nextPutAll: each asJavascript]
@@ -1052,16 +1166,6 @@ nextPutReturnWith: aBlock
 	aBlock value
 !
 
-nextPutSendTo: receiver selector: selector arguments: arguments
-	stream nextPutAll: 'smalltalk.send('.
-	receiver emitOn: self. 
-	stream nextPutAll: ',"', selector asSelector, '",['.
-	arguments 
-		do: [ :each | each emitOn: self ]
-		separatedBy: [ stream nextPutAll: ',' ].
-	stream nextPutAll: '])'
-!
-
 nextPutSequenceWith: aBlock
 	"stream 
 		nextPutAll: 'switch(smalltalk.thisContext.pc){'; lf."
@@ -1086,6 +1190,8 @@ nextPutVar: aString
 !
 
 nextPutVars: aCollection
+	aCollection ifEmpty: [ ^self ].
+    
 	stream nextPutAll: 'var '.
 	aCollection 
 		do: [ :each | stream nextPutAll: each ]

+ 266 - 0
st/Compiler-Interpreter.st

@@ -0,0 +1,266 @@
+Smalltalk current createPackage: 'Compiler-Interpreter' properties: #{}!
+NodeVisitor subclass: #AIContext
+	instanceVariableNames: 'outerContext pc locals receiver selector'
+	package: 'Compiler-Interpreter'!
+
+!AIContext methodsFor: 'accessing'!
+
+initializeFromMethodContext: aMethodContext
+	self pc: aMethodContext pc.
+    self receiver: aMethodContext receiver.
+    self selector: aMethodContext selector.
+    aMethodContext outerContext ifNotNil: [
+		self outerContext: (self class fromMethodContext: aMethodContext outerContext) ].
+    aMethodContext locals keysAndValuesDo: [ :key :value |
+    	self locals at: key put: value ]
+!
+
+localAt: aString
+	^ self locals at: aString ifAbsent: [ nil ]
+!
+
+localAt: aString put: anObject
+	self locals at: aString put: anObject
+!
+
+locals
+	^ locals ifNil: [ locals := Dictionary new ]
+!
+
+outerContext
+	^ outerContext
+!
+
+outerContext: anAIContext
+	outerContext := anAIContext
+!
+
+pc
+	^ pc ifNil: [ pc := 0 ]
+!
+
+pc: anInteger
+	pc := anInteger
+!
+
+receiver
+	^ receiver
+!
+
+receiver: anObject
+	receiver := anObject
+!
+
+selector
+	^ selector
+!
+
+selector: aString
+	selector := aString
+! !
+
+!AIContext class methodsFor: 'instance creation'!
+
+fromMethodContext: aMethodContext
+	^ self new 
+    	initializeFromMethodContext: aMethodContext;
+        yourself
+! !
+
+NodeVisitor subclass: #ASTInterpreter
+	instanceVariableNames: 'currentNode context shouldReturn currentValue'
+	package: 'Compiler-Interpreter'!
+
+!ASTInterpreter methodsFor: 'accessing'!
+
+context
+	^ context ifNil: [ context := AIContext new ]
+!
+
+context: anAIContext
+	context := anAIContext
+!
+
+currentValue
+	^ currentValue
+! !
+
+!ASTInterpreter methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+    shouldReturn := false
+! !
+
+!ASTInterpreter methodsFor: 'interpreting'!
+
+assign: aNode to: anObject
+	^ aNode binding isInstanceVar 
+    	ifTrue: [ self context receiver instVarAt: aNode value put: anObject ]
+      	ifFalse: [ self context localAt: aNode value put: anObject ]
+!
+
+continue: anObject
+	currentValue := anObject
+!
+
+eval: aString
+	"Evaluate aString as JS source inside an JS function. 
+    aString is not sandboxed."
+    
+    | source function |
+    
+    source := String streamContents: [ :str |
+    	str nextPutAll: '(function('.
+        self context locals keys 
+        	do: [ :each | str nextPutAll: each ]
+          	separatedBy: [ str nextPutAll: ',' ].
+        str 
+        	nextPutAll: '){ return (function() {';
+        	nextPutAll: aString;
+            nextPutAll: '})() })' ].
+            
+	function := Compiler new eval: source.
+    
+	^ function valueWithPossibleArguments: self context locals values
+!
+
+interpret: aNode
+	shouldReturn := false.
+    self interpret: aNode continue: [ :value |
+    	currentValue := value ]
+!
+
+interpret: aNode continue: aBlock
+
+	shouldReturn ifTrue: [ ^ self ].
+
+	aNode isNode 
+    	ifTrue: [ self visit: aNode ]
+        ifFalse: [ currentValue := aNode ].
+	aBlock value: self currentValue
+!
+
+interpretAll: aCollection continue: aBlock
+	self 
+    	interpretAll: aCollection 
+        continue: aBlock 
+        result: OrderedCollection new
+!
+
+interpretAll: nodes continue: aBlock result: aCollection
+	nodes isEmpty 
+    	ifTrue: [ aBlock value: aCollection ]
+    	ifFalse: [
+    		self interpret: nodes first continue: [:value |
+    			self 
+                	interpretAll: nodes allButFirst 
+                    continue: aBlock
+  					result: aCollection, { value } ] ]
+!
+
+messageFromSendNode: aSendNode do: aBlock
+	self interpretAll: aSendNode arguments continue: [ :args |
+    	aBlock value: (Message new
+    		selector: aSendNode selector;
+        	arguments: args;
+        	yourself) ]
+! !
+
+!ASTInterpreter methodsFor: 'visiting'!
+
+visitAssignmentNode: aNode
+	self interpret: aNode right continue: [ :value |
+    	self continue: (self assign: aNode left to: value) ]
+!
+
+visitBlockNode: aNode
+	"TODO: Context should be set"
+    self continue: [ self interpret: aNode nodes first; currentValue ]
+!
+
+visitCascadeNode: aNode
+	"TODO: Handle super sends"
+	
+    self interpret: aNode receiver continue: [ :receiver |
+		"Only interpret the receiver once"
+        aNode nodes do: [ :each | each receiver: receiver ].
+  
+    	self 
+        	interpretAll: aNode nodes allButLast
+    		continue: [
+              	self 
+                	interpret: aNode nodes last
+                	continue: [ :val | self continue: val ] ] ]
+!
+
+visitClassReferenceNode: aNode
+	self continue: (Smalltalk current at: aNode value)
+!
+
+visitDynamicArrayNode: aNode
+
+	self interpretAll: aNode nodes continue: [ :array |
+    	self continue: array ]
+!
+
+visitDynamicDictionaryNode: aNode
+	
+    self interpretAll: aNode nodes continue: [ :array | | hashedCollection |
+    	hashedCollection := HashedCollection new.
+        array do: [ :each | hashedCollection add: each ].
+        self continue: hashedCollection ]
+!
+
+visitJSStatementNode: aNode
+	shouldReturn := true.
+	self continue: (self eval: aNode source)
+!
+
+visitReturnNode: aNode
+    self interpret: aNode nodes first continue: [ :value |
+    	shouldReturn := true.
+		self continue: value ]
+!
+
+visitSendNode: aNode
+	"TODO: Handle super sends"
+    
+    self interpret: aNode receiver continue: [ :receiver |
+    	self messageFromSendNode: aNode do: [ :message |
+        	self context pc: self context pc + 1.
+        	self continue: (message sendTo: receiver) ] ]
+!
+
+visitSequenceNode: aNode
+	self interpretAll: aNode nodes continue: [ :array |
+    	self continue: array last ]
+!
+
+visitValueNode: aNode
+	self continue: aNode value
+! !
+
+ASTInterpreter subclass: #ASTDebugger
+	instanceVariableNames: 'continuation'
+	package: 'Compiler-Interpreter'!
+
+!ASTDebugger methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+    continuation := [  ]
+! !
+
+!ASTDebugger methodsFor: 'interpreting'!
+
+interpret: aNode continue: aBlock
+	continuation := [ super interpret: aNode continue: aBlock ]
+! !
+
+!ASTDebugger methodsFor: 'stepping'!
+
+stepOver
+	continuation value
+! !
+

+ 45 - 20
st/Compiler-Semantic.st

@@ -11,6 +11,10 @@ Each context (method/closure) get a fresh scope that inherits from its outer sco
 
 !LexicalScope methodsFor: 'accessing'!
 
+alias
+	^ '$ctx', self scopeLevel asString
+!
+
 allVariableNames
 	^ self args keys, self temps keys
 !
@@ -70,9 +74,10 @@ pseudoVars
 !
 
 scopeLevel
-	^ (self outerScope 
-		ifNil: [ 0 ]
-		ifNotNil: [ self outerScope scopeLevel ]) + 1
+	self outerScope ifNil: [ ^ 1 ].
+	self isInlined ifTrue: [ ^ self outerScope scopeLevel ].
+    
+	^ self outerScope scopeLevel + 1
 !
 
 temps
@@ -102,7 +107,8 @@ isBlockScope
 !
 
 isInlined
-	^ self instruction isInlined
+	^ self instruction notNil and: [
+      	self instruction isInlined ]
 !
 
 isMethodScope
@@ -370,7 +376,7 @@ isUnknownVar
 ! !
 
 NodeVisitor subclass: #SemanticAnalyzer
-	instanceVariableNames: 'currentScope theClass classReferences messageSends'
+	instanceVariableNames: 'currentScope theClass classReferences messageSends superSends'
 	package: 'Compiler-Semantic'!
 !SemanticAnalyzer commentStamp!
 I semantically analyze the abstract syntax tree and annotate it with informations such as non local returns and variable scopes.!
@@ -385,6 +391,10 @@ messageSends
 	^ messageSends ifNil: [ messageSends := Dictionary new ]
 !
 
+superSends
+	^ superSends ifNil: [ superSends := Dictionary new ]
+!
+
 theClass
 	^ theClass
 !
@@ -402,19 +412,24 @@ errorShadowingVariable: aString
 !
 
 errorUnknownVariable: aNode
-	"Throw an error if the variable is undeclared in the global JS scope (i.e. window)"
-
-	| notDefined |
-
-	notDefined := <eval('typeof ' + aNode._value() + ' == "undefined"')>.
-
-	notDefined
-		ifTrue: [ 
-			UnknownVariableError new
-				variableName: aNode value;
-				signal ]
-		ifFalse: [
-			currentScope methodScope unknownVariables add: aNode value. ]
+	"Throw an error if the variable is undeclared in the global JS scope (i.e. window).
+    We allow four variable names in addition: `jQuery`, `window`, `process` and `global` 
+    for nodejs and browser environments. 
+    
+    This is only to make sure compilation works on both browser-based and nodejs environments.
+    The ideal solution would be to use a pragma instead"
+
+	| identifier |
+    identifier := aNode value.
+    
+	((#('jQuery' 'window' 'process' 'global') includes: identifier) not 
+        and: [ self isVariableGloballyUndefined: identifier ]) 
+        	ifTrue: [
+				UnknownVariableError new
+					variableName: aNode value;
+					signal ]
+			ifFalse: [
+				currentScope methodScope unknownVariables add: aNode value ]
 ! !
 
 !SemanticAnalyzer methodsFor: 'factory'!
@@ -452,6 +467,12 @@ validateVariableScope: aString
 		self errorShadowingVariable: aString ]
 ! !
 
+!SemanticAnalyzer methodsFor: 'testing'!
+
+isVariableGloballyUndefined: aString
+	<return eval('typeof ' + aString + ' == "undefined"')>
+! !
+
 !SemanticAnalyzer methodsFor: 'visiting'!
 
 visitAssignmentNode: aNode
@@ -501,7 +522,8 @@ visitMethodNode: aNode
 
 	aNode 
 		classReferences: self classReferences;
-		messageSends: self messageSends keys.
+		messageSends: self messageSends keys;
+        superSends: self superSends keys.
 	self popScope
 !
 
@@ -518,7 +540,10 @@ visitSendNode: aNode
 	aNode receiver value = 'super' 
 		ifTrue: [
 			aNode superSend: true.
-			aNode receiver value: 'self' ]
+			aNode receiver value: 'self'.
+			self superSends at: aNode selector ifAbsentPut: [ Set new ].
+			(self superSends at: aNode selector) add: aNode ]
+          
 		ifFalse: [ (IRSendInliner inlinedSelectors includes: aNode selector) ifTrue: [
 			aNode shouldBeInlined: true.
 			aNode receiver shouldBeAliased: true ] ].

+ 104 - 7
st/Compiler-Tests.st

@@ -1,4 +1,108 @@
 Smalltalk current createPackage: 'Compiler-Tests' properties: #{}!
+TestCase subclass: #ASTInterpreterTest
+	instanceVariableNames: ''
+	package: 'Compiler-Tests'!
+
+!ASTInterpreterTest methodsFor: 'accessing'!
+
+analyze: aNode forClass: aClass
+	(SemanticAnalyzer on: aClass) visit: aNode.
+    ^ aNode
+!
+
+interpret: aString
+	^ self 
+    	interpret: aString 
+        withArguments: Dictionary new
+!
+
+interpret: aString receiver: anObject withArguments: aDictionary
+	"The food is a methodNode. Interpret the sequenceNode only"
+    
+    | ctx |
+    
+    ctx := AIContext new.
+    ctx receiver: anObject.
+    aDictionary keysAndValuesDo: [ :key :value |
+    	ctx localAt: key put: value ].
+    
+    ^ self interpreter
+    	context: ctx;
+    	interpret: (self parse: aString forClass: anObject class) 
+        	nodes first;
+        currentValue
+!
+
+interpret: aString withArguments: aDictionary
+	^ self 
+    	interpret: aString 
+        receiver: Object new
+        withArguments: aDictionary
+!
+
+interpreter
+	^ ASTInterpreter new
+!
+
+parse: aString
+	^ Smalltalk current parse: aString
+!
+
+parse: aString forClass: aClass
+	^ self analyze: (self parse: aString) forClass: aClass
+! !
+
+!ASTInterpreterTest methodsFor: 'tests'!
+
+testBinarySend
+	self assert: (self interpret: 'foo 2+3+4') equals: 9
+!
+
+testBlockLiteral
+	self assert: (self interpret: 'foo ^ true ifTrue: [ 1 ] ifFalse: [ 2 ]') equals: 1.
+    self assert: (self interpret: 'foo true ifTrue: [ ^ 1 ] ifFalse: [ 2 ]') equals: 1.
+    self assert: (self interpret: 'foo ^ false ifTrue: [ 1 ] ifFalse: [ 2 ]') equals: 2
+!
+
+testCascade
+	self assert: (self interpret: 'foo ^ OrderedCollection new add: 2; add: 3; yourself') equals: (OrderedCollection with: 2 with: 3)
+!
+
+testDynamicArray
+	self assert: (self interpret: 'foo ^ {1+1. 2+2}') equals: #(2 4)
+!
+
+testDynamicDictionary
+	self assert: (self interpret: 'foo ^ #{1->1. 2->3}') equals: #{1->1. 2->3}
+!
+
+testInlinedJSStatement
+	self assert: (self interpret: 'foo <return 2+3>') equals: 5.
+    
+    self 
+    	assert: (self 
+    		interpret: 'foo: anInteger <return 2 + anInteger>' 
+        	withArguments: #{ 'anInteger' -> 3}) 
+		equals: 5
+!
+
+testInstVarAssignment
+	self 
+    	assert: (self 
+    		interpret: 'foo: anInteger x := anInteger. ^ x'
+        	receiver: Point new
+        	withArguments: #{'anInteger' -> 2})
+        equals: 2
+!
+
+testNonlocalReturn
+	self assert: (self interpret: 'foo true ifTrue: [ ^ 1 ]. ^2') equals: 1
+!
+
+testTempAssignment
+	self assert: (self interpret: 'foo | a | a := 2. ^ a') equals: 2
+! !
+
 TestCase subclass: #CodeGeneratorTest
 	instanceVariableNames: 'receiver'
 	package: 'Compiler-Tests'!
@@ -359,13 +463,6 @@ testUnknownVariables
 	self should: [ analyzer visit: ast ] raise: UnknownVariableError
 !
 
-testUnknownVariablesDefinedInJS
-
-	< var someVariable = 1 >.
-
-	self shouldnt: [ smalltalk parse: 'foo someVariable' ] raise: UnknownVariableError
-!
-
 testUnknownVariablesWithScope
 	| src ast |
 

+ 3172 - 1541
st/Compiler.st

@@ -1,15 +1,15 @@
 Smalltalk current createPackage: 'Compiler' properties: #{}!
 Object subclass: #ChunkParser
 	instanceVariableNames: 'stream'
-	package: 'Compiler'!
+	package:'Compiler'!
 
-!ChunkParser methodsFor: 'accessing'!
+!ChunkParser methodsFor: '*Compiler'!
 
 stream: aStream
 	stream := aStream
 ! !
 
-!ChunkParser methodsFor: 'reading'!
+!ChunkParser methodsFor: '*Compiler'!
 
 nextChunk
 	"The chunk format (Smalltalk Interchange Format or Fileout format)
@@ -34,145 +34,17 @@ nextChunk
 	^nil "a chunk needs to end with !!"
 ! !
 
-!ChunkParser class methodsFor: 'not yet classified'!
+!ChunkParser class methodsFor: '*Compiler'!
 
 on: aStream
 	^self new stream: aStream
 ! !
 
-Object subclass: #Compiler
-	instanceVariableNames: 'currentClass source unknownVariables codeGeneratorClass'
-	package: 'Compiler'!
-
-!Compiler methodsFor: 'accessing'!
-
-codeGeneratorClass
-	^codeGeneratorClass ifNil: [FunCodeGenerator]
-!
-
-codeGeneratorClass: aClass
-	codeGeneratorClass := aClass
-!
-
-currentClass
-	^currentClass
-!
-
-currentClass: aClass
-	currentClass := aClass
-!
-
-source
-	^source ifNil: ['']
-!
-
-source: aString
-	source := aString
-!
-
-unknownVariables
-	^unknownVariables
-!
-
-unknownVariables: aCollection
-	unknownVariables := aCollection
-! !
-
-!Compiler methodsFor: 'compiling'!
-
-compile: aString
-	^self compileNode: (self parse: aString)
-!
-
-compile: aString forClass: aClass
-	self currentClass: aClass.
-	self source: aString.
-	^self compile: aString
-!
-
-compileExpression: aString
-	self currentClass: DoIt.
-	self source: 'doIt ^[', aString, '] value'.
-	^self compileNode: (self parse: self source)
-!
-
-compileNode: aNode
-	| generator result |
-	generator := self codeGeneratorClass new.
-	generator
-		source: self source;
-		currentClass: self currentClass.
-	result := generator compileNode: aNode.
-	self unknownVariables: generator unknownVariables.
-	^result
-!
-
-eval: aString
-	<return eval(aString)>
-!
-
-evaluateExpression: aString
-	"Unlike #eval: evaluate a Smalltalk expression and answer the returned object"
-	| result |
-	DoIt addCompiledMethod: (self eval: (self compileExpression: aString)).
-	result := DoIt new doIt.
-	DoIt removeCompiledMethod: (DoIt methodDictionary at: 'doIt').
-	^result
-!
-
-install: aString forClass: aBehavior category: anotherString
-	| compiled |
-	compiled := self eval: (self compile: aString forClass: aBehavior).
-	compiled category: anotherString.
-	aBehavior addCompiledMethod: compiled.
-	^compiled
-!
-
-parse: aString
-    ^Smalltalk current parse: aString
-!
-
-parseExpression: aString
-    ^self parse: 'doIt ^[', aString, '] value'
-!
-
-recompile: aClass
-	aClass methodDictionary do: [:each |
-		self install: each source forClass: aClass category: each category].
-	self setupClass: aClass.
-	aClass isMetaclass ifFalse: [self recompile: aClass class]
-!
-
-recompileAll
-	Smalltalk current classes do: [:each |
-		Transcript show: each; cr.
-		[self recompile: each] valueWithTimeout: 100]
-!
-
-setupClass: aClass
-	<smalltalk.init(aClass)>
-! !
-
-!Compiler class methodsFor: 'compiling'!
-
-recompile: aClass
-	self new recompile: aClass
-!
-
-recompileAll
-	Smalltalk current classes do: [:each |
-		self recompile: each]
-! !
-
-Object subclass: #DoIt
-	instanceVariableNames: ''
-	package: 'Compiler'!
-
 Object subclass: #Exporter
 	instanceVariableNames: ''
-	package: 'Compiler'!
+	package:'Compiler'!
 
-!Exporter methodsFor: 'fileOut'!
+!Exporter methodsFor: '*Compiler'!
 
 exportAll
     "Export all packages in the system."
@@ -207,7 +79,7 @@ exportPackage: packageName
 		self exportPackageExtensionsOf: package on: stream]
 ! !
 
-!Exporter methodsFor: 'private'!
+!Exporter methodsFor: '*Compiler'!
 
 classNameFor: aClass
 	^aClass isMetaclass
@@ -301,9 +173,9 @@ exportPackageExtensionsOf: package on: aStream
 
 Exporter subclass: #ChunkExporter
 	instanceVariableNames: ''
-	package: 'Compiler'!
+	package:'Compiler'!
 
-!ChunkExporter methodsFor: 'not yet classified'!
+!ChunkExporter methodsFor: '*Compiler'!
 
 chunkEscape: aString
 	"Replace all occurrences of !! with !!!! and trim at both ends."
@@ -415,9 +287,9 @@ exportPackageExtensionsOf: package on: aStream
 
 Exporter subclass: #StrippedExporter
 	instanceVariableNames: ''
-	package: 'Compiler'!
+	package:'Compiler'!
 
-!StrippedExporter methodsFor: 'private'!
+!StrippedExporter methodsFor: '*Compiler'!
 
 exportDefinitionOf: aClass on: aStream
 	aStream 
@@ -449,9 +321,9 @@ exportMethod: aMethod of: aClass on: aStream
 
 Object subclass: #Importer
 	instanceVariableNames: ''
-	package: 'Compiler'!
+	package:'Compiler'!
 
-!Importer methodsFor: 'fileIn'!
+!Importer methodsFor: '*Compiler'!
 
 import: aStream
     | chunk result parser lastEmpty |
@@ -469,154 +341,158 @@ import: aStream
                                   	result scanFrom: parser]]]
 ! !
 
-Object subclass: #Node
-	instanceVariableNames: 'nodes'
-	package: 'Compiler'!
-
-!Node methodsFor: 'accessing'!
-
-addNode: aNode
-	self nodes add: aNode
-!
-
-nodes
-	^nodes ifNil: [nodes := Array new]
-! !
-
-!Node methodsFor: 'building'!
+Object subclass: #PackageLoader
+	instanceVariableNames: ''
+	package:'Compiler'!
 
-nodes: aCollection
-	nodes := aCollection
-! !
+!PackageLoader methodsFor: '*Compiler'!
 
-!Node methodsFor: 'testing'!
+initializePackageNamed: packageName prefix: aString
 
-isBlockNode
-	^false
+	(Package named: packageName) 
+    	setupClasses;
+        commitPathJs: '/', aString, '/js';
+        commitPathSt: '/', aString, '/st'
 !
 
-isBlockSequenceNode
-	^false
+loadPackage: packageName prefix: aString	
+	| url |
+    url := '/', aString, '/js/', packageName, '.js'.
+	jQuery 
+		ajax: url
+        options: #{
+			'type' -> 'GET'.
+			'dataType' -> 'script'.
+    		'complete' -> [ :jqXHR :textStatus | 
+				jqXHR readyState = 4 
+                	ifTrue: [ self initializePackageNamed: packageName prefix: aString ] ].
+			'error' -> [ window alert: 'Could not load package at:  ', url ]
+		}
 !
 
-isValueNode
-	^false
+loadPackages: aCollection prefix: aString
+	aCollection do: [ :each |
+    	self loadPackage: each prefix: aString ]
 ! !
 
-!Node methodsFor: 'visiting'!
+!PackageLoader class methodsFor: '*Compiler'!
 
-accept: aVisitor
-	aVisitor visitNode: self
+loadPackages: aCollection prefix: aString
+	^ self new loadPackages: aCollection prefix: aString
 ! !
 
-Node subclass: #AssignmentNode
-	instanceVariableNames: 'left right'
-	package: 'Compiler'!
-
-!AssignmentNode methodsFor: 'accessing'!
-
-left
-	^left
-!
-
-left: aNode
-	left := aNode.
-	left assigned: true
-!
-
-right
-	^right
-!
+Error subclass: #CompilerError
+	instanceVariableNames: ''
+	package:'Compiler'!
+!CompilerError commentStamp!
+I am the common superclass of all compiling errors.!
 
-right: aNode
-	right := aNode
-! !
+CompilerError subclass: #ParseError
+	instanceVariableNames: ''
+	package:'Compiler'!
+!ParseError commentStamp!
+Instance of ParseError are signaled on any parsing error. 
+See `Smalltalk >> #parse:`!
 
-!AssignmentNode methodsFor: 'visiting'!
+CompilerError subclass: #SemanticError
+	instanceVariableNames: ''
+	package:'Compiler'!
+!SemanticError commentStamp!
+I represent an abstract semantic error thrown by the SemanticAnalyzer.
+Semantic errors can be unknown variable errors, etc.
+See my subclasses for concrete errors.
 
-accept: aVisitor
-	aVisitor visitAssignmentNode: self
-! !
+The IDE should catch instances of Semantic error to deal with them when compiling!
 
-Node subclass: #BlockNode
-	instanceVariableNames: 'parameters inlined'
-	package: 'Compiler'!
+SemanticError subclass: #InliningError
+	instanceVariableNames: ''
+	package:'Compiler'!
+!InliningError commentStamp!
+Instances of InliningError are signaled when using an `InliningCodeGenerator`in a `Compiler`.!
 
-!BlockNode methodsFor: 'accessing'!
+SemanticError subclass: #InvalidAssignmentError
+	instanceVariableNames: 'variableName'
+	package:'Compiler'!
+!InvalidAssignmentError commentStamp!
+I get signaled when a pseudo variable gets assigned.!
 
-inlined
-	^inlined ifNil: [false]
-!
+!InvalidAssignmentError methodsFor: '*Compiler'!
 
-inlined: aBoolean
-	inlined := aBoolean
+messageText
+	^ ' Invalid assignment to variable: ', self variableName
 !
 
-parameters
-	^parameters ifNil: [parameters := Array new]
+variableName
+	^ variableName
 !
 
-parameters: aCollection
-	parameters := aCollection
+variableName: aString
+	variableName := aString
 ! !
 
-!BlockNode methodsFor: 'testing'!
+SemanticError subclass: #ShadowingVariableError
+	instanceVariableNames: 'variableName'
+	package:'Compiler'!
+!ShadowingVariableError commentStamp!
+I get signaled when a variable in a block or method scope shadows a variable of the same name in an outer scope.!
 
-isBlockNode
-	^true
-! !
+!ShadowingVariableError methodsFor: '*Compiler'!
+
+messageText
+	^ 'Variable shadowing error: ', self variableName, ' is already defined'
+!
 
-!BlockNode methodsFor: 'visiting'!
+variableName
+	^ variableName
+!
 
-accept: aVisitor
-	aVisitor visitBlockNode: self
+variableName: aString
+	variableName := aString
 ! !
 
-Node subclass: #CascadeNode
-	instanceVariableNames: 'receiver'
-	package: 'Compiler'!
+SemanticError subclass: #UnknownVariableError
+	instanceVariableNames: 'variableName'
+	package:'Compiler'!
+!UnknownVariableError commentStamp!
+I get signaled when a variable is not defined.
+The default behavior is to allow it, as this is how Amber currently is able to seamlessly send messages to JavaScript objects.!
 
-!CascadeNode methodsFor: 'accessing'!
+!UnknownVariableError methodsFor: '*Compiler'!
 
-receiver
-	^receiver
+variableName
+	^ variableName
 !
 
-receiver: aNode
-	receiver := aNode
-! !
-
-!CascadeNode methodsFor: 'visiting'!
-
-accept: aVisitor
-	aVisitor visitCascadeNode: self
+variableName: aString
+	variableName := aString
 ! !
 
-Node subclass: #DynamicArrayNode
-	instanceVariableNames: ''
-	package: 'Compiler'!
-
-!DynamicArrayNode methodsFor: 'visiting'!
+Object subclass: #Compiler
+	instanceVariableNames: 'currentClass source unknownVariables codeGeneratorClass'
+	package:'Compiler'!
+!Compiler commentStamp!
+I provide the public interface for compiling Amber source code into JavaScript.
 
-accept: aVisitor
-	aVisitor visitDynamicArrayNode: self
-! !
+The code generator used to produce JavaScript can be plugged with `#codeGeneratorClass`. 
+The default code generator is an instance of `InlinedCodeGenerator`!
 
-Node subclass: #DynamicDictionaryNode
-	instanceVariableNames: ''
-	package: 'Compiler'!
+!Compiler methodsFor: '*Compiler'!
 
-!DynamicDictionaryNode methodsFor: 'visiting'!
+codeGeneratorClass
+	^codeGeneratorClass ifNil: [InliningCodeGenerator]
+!
 
-accept: aVisitor
-	aVisitor visitDynamicDictionaryNode: self
-! !
+codeGeneratorClass: aClass
+	codeGeneratorClass := aClass
+!
 
-Node subclass: #JSStatementNode
-	instanceVariableNames: 'source'
-	package: 'Compiler'!
+currentClass
+	^currentClass
+!
 
-!JSStatementNode methodsFor: 'accessing'!
+currentClass: aClass
+	currentClass := aClass
+!
 
 source
 	^source ifNil: ['']
@@ -624,1590 +500,3345 @@ source
 
 source: aString
 	source := aString
-! !
+!
 
-!JSStatementNode methodsFor: 'visiting'!
+unknownVariables
+	^unknownVariables
+!
 
-accept: aVisitor
-	aVisitor visitJSStatementNode: self
+unknownVariables: aCollection
+	unknownVariables := aCollection
 ! !
 
-Node subclass: #MethodNode
-	instanceVariableNames: 'selector arguments source'
-	package: 'Compiler'!
-
-!MethodNode methodsFor: 'accessing'!
+!Compiler methodsFor: '*Compiler'!
 
-arguments
-	^arguments ifNil: [#()]
+compile: aString
+	^self compileNode: (self parse: aString)
 !
 
-arguments: aCollection
-	arguments := aCollection
+compile: aString forClass: aClass
+	self currentClass: aClass.
+	self source: aString.
+	^self compile: aString
 !
 
-selector
-	^selector
+compileExpression: aString
+	self currentClass: DoIt.
+	self source: 'doIt ^[', aString, '] value'.
+	^self compileNode: (self parse: self source)
 !
 
-selector: aString
-	selector := aString
+compileNode: aNode
+	| generator result |
+	generator := self codeGeneratorClass new.
+	generator
+		source: self source;
+		currentClass: self currentClass.
+	result := generator compileNode: aNode.
+	self unknownVariables: #().
+	^result
 !
 
-source
-	^source
+eval: aString
+	<return eval(aString)>
 !
 
-source: aString
-	source := aString
-! !
+evaluateExpression: aString
+	"Unlike #eval: evaluate a Smalltalk expression and answer the returned object"
+	| result |
+	DoIt addCompiledMethod: (self eval: (self compileExpression: aString)).
+	result := DoIt new doIt.
+	DoIt removeCompiledMethod: (DoIt methodDictionary at: 'doIt').
+	^result
+!
+
+install: aString forClass: aBehavior category: anotherString
+	| compiled |
+	compiled := self eval: (self compile: aString forClass: aBehavior).
+	compiled category: anotherString.
+	aBehavior addCompiledMethod: compiled.
+    self setupClass: aBehavior.
+	^compiled
+!
+
+parse: aString
+    ^Smalltalk current parse: aString
+!
+
+parseExpression: aString
+    ^self parse: 'doIt ^[', aString, '] value'
+!
+
+recompile: aClass
+	aClass methodDictionary do: [:each |
+		console log: aClass name, ' >> ', each selector.
+		self install: each source forClass: aClass category: each category].
+	self setupClass: aClass.
+	aClass isMetaclass ifFalse: [self recompile: aClass class]
+!
+
+recompileAll
+	Smalltalk current classes do: [:each |
+		Transcript show: each; cr.
+		[self recompile: each] valueWithTimeout: 100]
+!
+
+setupClass: aClass
+	<smalltalk.init(aClass)>
+! !
+
+!Compiler class methodsFor: '*Compiler'!
+
+recompile: aClass
+	self new recompile: aClass
+!
+
+recompileAll
+	Smalltalk current classes do: [:each |
+		self recompile: each]
+! !
+
+Object subclass: #DoIt
+	instanceVariableNames: ''
+	package:'Compiler'!
+!DoIt commentStamp!
+`DoIt` is the class used to compile and evaluate expressions. See `Compiler >> evaluateExpression:`.!
+
+Object subclass: #NodeVisitor
+	instanceVariableNames: ''
+	package:'Compiler'!
+!NodeVisitor commentStamp!
+I am the abstract super class of all AST node visitors.!
+
+!NodeVisitor methodsFor: '*Compiler'!
+
+visit: aNode
+	^ aNode accept: self
+!
+
+visitAll: aCollection
+	^ aCollection do: [ :each | self visit: each ]
+!
+
+visitAssignmentNode: aNode
+	^ self visitNode: aNode
+!
+
+visitBlockNode: aNode
+	^ self visitNode: aNode
+!
+
+visitBlockSequenceNode: aNode
+	^ self visitSequenceNode: aNode
+!
+
+visitCascadeNode: aNode
+	^ self visitNode: aNode
+!
+
+visitClassReferenceNode: aNode
+	^ self visitVariableNode: aNode
+!
+
+visitDynamicArrayNode: aNode
+	^ self visitNode: aNode
+!
+
+visitDynamicDictionaryNode: aNode
+	^ self visitNode: aNode
+!
+
+visitJSStatementNode: aNode
+	^ self visitNode: aNode
+!
+
+visitMethodNode: aNode
+	^ self visitNode: aNode
+!
+
+visitNode: aNode
+	^ self visitAll: aNode nodes
+!
+
+visitReturnNode: aNode
+	^ self visitNode: aNode
+!
+
+visitSendNode: aNode
+	^ self visitNode: aNode
+!
+
+visitSequenceNode: aNode
+	^ self visitNode: aNode
+!
+
+visitValueNode: aNode
+	^ self visitNode: aNode
+!
+
+visitVariableNode: aNode
+	^ self visitNode: aNode
+! !
+
+NodeVisitor subclass: #AbstractCodeGenerator
+	instanceVariableNames: 'currentClass source'
+	package:'Compiler'!
+!AbstractCodeGenerator commentStamp!
+I am the abstract super class of all code generators and provide their common API.!
+
+!AbstractCodeGenerator methodsFor: '*Compiler'!
+
+classNameFor: aClass
+	^aClass isMetaclass
+	    ifTrue: [aClass instanceClass name, '.klass']
+	    ifFalse: [
+		aClass isNil
+		    ifTrue: ['nil']
+		    ifFalse: [aClass name]]
+!
+
+currentClass
+	^currentClass
+!
+
+currentClass: aClass
+	currentClass := aClass
+!
+
+pseudoVariables
+	^#('self' 'super' 'true' 'false' 'nil' 'thisContext')
+!
+
+safeVariableNameFor: aString
+	^(Smalltalk current reservedWords includes: aString)
+		ifTrue: [aString, '_']
+		ifFalse: [aString]
+!
+
+source
+	^source ifNil: ['']
+!
+
+source: aString
+	source := aString
+! !
+
+!AbstractCodeGenerator methodsFor: '*Compiler'!
+
+compileNode: aNode
+	self subclassResponsibility
+! !
+
+AbstractCodeGenerator subclass: #CodeGenerator
+	instanceVariableNames: ''
+	package:'Compiler'!
+!CodeGenerator commentStamp!
+I am a basic code generator. I generate a valid JavaScript output, but no not perform any inlining.
+See `InliningCodeGenerator` for an optimized JavaScript code generation.!
+
+!CodeGenerator methodsFor: '*Compiler'!
+
+compileNode: aNode
+	| ir stream |
+	self semanticAnalyzer visit: aNode.
+	ir := self translator visit: aNode.
+	^ self irTranslator
+		visit: ir;
+		contents
+!
+
+irTranslator
+	^ IRJSTranslator new
+!
+
+semanticAnalyzer
+	^ SemanticAnalyzer on: self currentClass
+!
+
+translator
+	^ IRASTTranslator new
+		source: self source;
+		theClass: self currentClass;
+		yourself
+! !
+
+Object subclass: #Node
+	instanceVariableNames: 'position nodes shouldBeInlined shouldBeAliased'
+	package:'Compiler'!
+!Node commentStamp!
+I am the abstract root class of the abstract syntax tree.
+
+position: holds a point containing lline- and column number of the symbol location in the original source file!
+
+!Node methodsFor: '*Compiler'!
+
+addNode: aNode
+	self nodes add: aNode
+!
+
+nodes
+	^nodes ifNil: [nodes := Array new]
+!
+
+position
+	^position ifNil: [position := 0@0]
+!
+
+shouldBeAliased
+	^ shouldBeAliased ifNil: [ false ]
+!
+
+shouldBeAliased: aBoolean
+	shouldBeAliased := aBoolean
+!
+
+shouldBeInlined
+	^ shouldBeInlined ifNil: [ false ]
+!
+
+shouldBeInlined: aBoolean
+	shouldBeInlined := aBoolean
+! !
+
+!Node methodsFor: '*Compiler'!
+
+nodes: aCollection
+	nodes := aCollection
+!
+
+position: aPosition
+	position := aPosition
+! !
+
+!Node methodsFor: '*Compiler'!
+
+isAssignmentNode
+	^ false
+!
+
+isBlockNode
+	^false
+!
+
+isBlockSequenceNode
+	^false
+!
+
+isImmutable
+	^false
+!
+
+isReturnNode
+	^false
+!
+
+isSendNode
+	^false
+!
+
+isValueNode
+	^false
+!
+
+subtreeNeedsAliasing
+    ^(self shouldBeAliased or: [ self shouldBeInlined ]) or: [
+        (self nodes detect: [ :each | each subtreeNeedsAliasing ] ifNone: [ false ]) ~= false ]
+! !
+
+!Node methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitNode: self
+! !
+
+Node subclass: #AssignmentNode
+	instanceVariableNames: 'left right'
+	package:'Compiler'!
+
+!AssignmentNode methodsFor: '*Compiler'!
+
+left
+	^left
+!
+
+left: aNode
+	left := aNode
+!
+
+nodes
+	^ Array with: self left with: self right
+!
+
+right
+	^right
+!
+
+right: aNode
+	right := aNode
+! !
+
+!AssignmentNode methodsFor: '*Compiler'!
+
+isAssignmentNode
+	^ true
+! !
+
+!AssignmentNode methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitAssignmentNode: self
+! !
+
+Node subclass: #BlockNode
+	instanceVariableNames: 'parameters scope'
+	package:'Compiler'!
+
+!BlockNode methodsFor: '*Compiler'!
+
+parameters
+	^parameters ifNil: [parameters := Array new]
+!
+
+parameters: aCollection
+	parameters := aCollection
+!
+
+scope
+	^ scope
+!
+
+scope: aLexicalScope
+	scope := aLexicalScope
+! !
+
+!BlockNode methodsFor: '*Compiler'!
+
+isBlockNode
+	^true
+! !
+
+!BlockNode methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitBlockNode: self
+! !
+
+Node subclass: #CascadeNode
+	instanceVariableNames: 'receiver'
+	package:'Compiler'!
+
+!CascadeNode methodsFor: '*Compiler'!
+
+receiver
+	^receiver
+!
+
+receiver: aNode
+	receiver := aNode
+! !
+
+!CascadeNode methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitCascadeNode: self
+! !
+
+Node subclass: #DynamicArrayNode
+	instanceVariableNames: ''
+	package:'Compiler'!
+
+!DynamicArrayNode methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitDynamicArrayNode: self
+! !
+
+Node subclass: #DynamicDictionaryNode
+	instanceVariableNames: ''
+	package:'Compiler'!
+
+!DynamicDictionaryNode methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitDynamicDictionaryNode: self
+! !
+
+Node subclass: #JSStatementNode
+	instanceVariableNames: 'source'
+	package:'Compiler'!
+
+!JSStatementNode methodsFor: '*Compiler'!
+
+source
+	^source ifNil: ['']
+!
+
+source: aString
+	source := aString
+! !
+
+!JSStatementNode methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitJSStatementNode: self
+! !
+
+Node subclass: #MethodNode
+	instanceVariableNames: 'selector arguments source scope classReferences messageSends superSends'
+	package:'Compiler'!
+
+!MethodNode methodsFor: '*Compiler'!
+
+arguments
+	^arguments ifNil: [#()]
+!
+
+arguments: aCollection
+	arguments := aCollection
+!
+
+classReferences
+	^ classReferences
+!
+
+classReferences: aCollection
+	classReferences := aCollection
+!
+
+messageSends
+	^ messageSends
+!
+
+messageSends: aCollection
+	messageSends := aCollection
+!
+
+scope
+	^ scope
+!
+
+scope: aMethodScope
+	scope := aMethodScope
+!
+
+selector
+	^selector
+!
+
+selector: aString
+	selector := aString
+!
+
+source
+	^source
+!
+
+source: aString
+	source := aString
+!
+
+superSends
+	^ superSends
+!
+
+superSends: aCollection
+	superSends := aCollection
+! !
+
+!MethodNode methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitMethodNode: self
+! !
+
+Node subclass: #ReturnNode
+	instanceVariableNames: 'scope'
+	package:'Compiler'!
+
+!ReturnNode methodsFor: '*Compiler'!
+
+scope
+	^ scope
+!
+
+scope: aLexicalScope
+	scope := aLexicalScope
+! !
+
+!ReturnNode methodsFor: '*Compiler'!
+
+isReturnNode
+	^ true
+!
+
+nonLocalReturn
+	^ self scope isMethodScope not
+! !
+
+!ReturnNode methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitReturnNode: self
+! !
+
+Node subclass: #SendNode
+	instanceVariableNames: 'selector arguments receiver superSend index'
+	package:'Compiler'!
+
+!SendNode methodsFor: '*Compiler'!
+
+arguments
+	^arguments ifNil: [arguments := #()]
+!
+
+arguments: aCollection
+	arguments := aCollection
+!
+
+cascadeNodeWithMessages: aCollection
+	| first |
+	first := SendNode new
+	    selector: self selector;
+	    arguments: self arguments;
+	    yourself.
+	^CascadeNode new
+	    receiver: self receiver;
+	    nodes: (Array with: first), aCollection;
+	    yourself
+!
+
+index
+	^ index
+!
+
+index: anInteger
+	index := anInteger
+!
+
+nodes
+	^ (Array withAll: self arguments)
+		add: self receiver;
+		yourself
+!
+
+receiver
+	^receiver
+!
+
+receiver: aNode
+	receiver := aNode
+!
+
+selector
+	^selector
+!
+
+selector: aString
+	selector := aString
+!
+
+superSend
+	^ superSend ifNil: [ false ]
+!
+
+superSend: aBoolean
+	superSend := aBoolean
+!
+
+valueForReceiver: anObject
+	^SendNode new
+	    receiver: (self receiver 
+		ifNil: [anObject]
+		ifNotNil: [self receiver valueForReceiver: anObject]);
+	    selector: self selector;
+	    arguments: self arguments;
+	    yourself
+! !
+
+!SendNode methodsFor: '*Compiler'!
+
+isSendNode
+	^ true
+! !
+
+!SendNode methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitSendNode: self
+! !
+
+Node subclass: #SequenceNode
+	instanceVariableNames: 'temps scope'
+	package:'Compiler'!
+
+!SequenceNode methodsFor: '*Compiler'!
+
+scope
+	^ scope
+!
+
+scope: aLexicalScope
+	scope := aLexicalScope
+!
+
+temps
+	^temps ifNil: [#()]
+!
+
+temps: aCollection
+	temps := aCollection
+! !
+
+!SequenceNode methodsFor: '*Compiler'!
+
+asBlockSequenceNode
+	^BlockSequenceNode new
+	    nodes: self nodes;
+	    temps: self temps;
+	    yourself
+! !
+
+!SequenceNode methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitSequenceNode: self
+! !
+
+SequenceNode subclass: #BlockSequenceNode
+	instanceVariableNames: ''
+	package:'Compiler'!
+
+!BlockSequenceNode methodsFor: '*Compiler'!
+
+isBlockSequenceNode
+	^true
+! !
+
+!BlockSequenceNode methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitBlockSequenceNode: self
+! !
+
+Node subclass: #ValueNode
+	instanceVariableNames: 'value'
+	package:'Compiler'!
+
+!ValueNode methodsFor: '*Compiler'!
+
+value
+	^value
+!
+
+value: anObject
+	value := anObject
+! !
+
+!ValueNode methodsFor: '*Compiler'!
+
+isImmutable
+	^true
+!
+
+isValueNode
+	^true
+! !
+
+!ValueNode methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitValueNode: self
+! !
+
+ValueNode subclass: #VariableNode
+	instanceVariableNames: 'assigned binding'
+	package:'Compiler'!
+
+!VariableNode methodsFor: '*Compiler'!
+
+alias
+	^ self binding alias
+!
+
+assigned
+	^assigned ifNil: [false]
+!
+
+assigned: aBoolean
+	assigned := aBoolean
+!
+
+beAssigned
+	self binding validateAssignment.
+	assigned := true
+!
+
+binding
+	^ binding
+!
+
+binding: aScopeVar
+	binding := aScopeVar
+! !
+
+!VariableNode methodsFor: '*Compiler'!
+
+isImmutable
+	^false
+! !
+
+!VariableNode methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitVariableNode: self
+! !
+
+VariableNode subclass: #ClassReferenceNode
+	instanceVariableNames: ''
+	package:'Compiler'!
+
+!ClassReferenceNode methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitClassReferenceNode: self
+! !
+
+Object subclass: #LexicalScope
+	instanceVariableNames: 'node instruction temps args outerScope'
+	package:'Compiler'!
+!LexicalScope commentStamp!
+I represent a lexical scope where variable names are associated with ScopeVars
+Instances are used for block scopes. Method scopes are instances of MethodLexicalScope.
+
+I am attached to a ScopeVar and method/block nodes.
+Each context (method/closure) get a fresh scope that inherits from its outer scope.!
+
+!LexicalScope methodsFor: '*Compiler'!
+
+alias
+	^ '$ctx', self scopeLevel asString
+!
+
+allVariableNames
+	^ self args keys, self temps keys
+!
+
+args
+	^ args ifNil: [ args := Dictionary new ]
+!
+
+bindingFor: aStringOrNode
+	^ self pseudoVars at: aStringOrNode value ifAbsent: [ 
+		self args at: aStringOrNode value ifAbsent: [
+			self temps at: aStringOrNode value ifAbsent: [ nil ]]]
+!
+
+instruction
+	^ instruction
+!
+
+instruction: anIRInstruction
+	instruction := anIRInstruction
+!
+
+lookupVariable: aNode
+	| lookup |
+	lookup := (self bindingFor: aNode).
+	lookup ifNil: [
+		lookup := self outerScope ifNotNil: [ 
+			(self outerScope lookupVariable: aNode) ]].
+	^ lookup
+!
+
+methodScope
+	^ self outerScope ifNotNil: [
+		self outerScope methodScope ]
+!
+
+node
+	"Answer the node in which I am defined"
+	
+	^ node
+!
+
+node: aNode
+	node := aNode
+!
+
+outerScope
+	^ outerScope
+!
+
+outerScope: aLexicalScope
+	outerScope := aLexicalScope
+!
+
+pseudoVars
+	^ self methodScope pseudoVars
+!
+
+scopeLevel
+	self outerScope ifNil: [ ^ 1 ].
+	self isInlined ifTrue: [ ^ self outerScope scopeLevel ].
+    
+	^ self outerScope scopeLevel + 1
+!
+
+temps
+	^ temps ifNil: [ temps := Dictionary new ]
+! !
+
+!LexicalScope methodsFor: '*Compiler'!
+
+addArg: aString
+	self args at: aString put: (ArgVar on: aString).
+	(self args at: aString) scope: self
+!
+
+addTemp: aString
+	self temps at: aString put: (TempVar on: aString).
+	(self temps at: aString) scope: self
+! !
+
+!LexicalScope methodsFor: '*Compiler'!
+
+canInlineNonLocalReturns
+	^ self isInlined and: [ self outerScope canInlineNonLocalReturns ]
+!
+
+isBlockScope
+	^ self isMethodScope not
+!
+
+isInlined
+	^ self instruction notNil and: [
+      	self instruction isInlined ]
+!
+
+isMethodScope
+	^ false
+! !
+
+LexicalScope subclass: #MethodLexicalScope
+	instanceVariableNames: 'iVars pseudoVars unknownVariables localReturn nonLocalReturns'
+	package:'Compiler'!
+!MethodLexicalScope commentStamp!
+I represent a method scope.!
+
+!MethodLexicalScope methodsFor: '*Compiler'!
+
+allVariableNames
+	^ super allVariableNames, self iVars keys
+!
+
+bindingFor: aNode
+	^ (super bindingFor: aNode) ifNil: [
+		self iVars at: aNode value ifAbsent: [ nil ]]
+!
+
+iVars
+	^ iVars ifNil: [ iVars := Dictionary new ]
+!
+
+localReturn
+	^ localReturn ifNil: [ false ]
+!
+
+localReturn: aBoolean
+	localReturn := aBoolean
+!
+
+methodScope
+	^ self
+!
+
+nonLocalReturns
+	^ nonLocalReturns ifNil: [ nonLocalReturns := OrderedCollection new ]
+!
+
+pseudoVars
+	pseudoVars ifNil: [
+		pseudoVars := Dictionary new.
+		Smalltalk current pseudoVariableNames do: [ :each |
+			pseudoVars at: each put: ((PseudoVar on: each)
+				scope: self methodScope;
+				yourself) ]].
+	^ pseudoVars
+!
+
+unknownVariables
+	^ unknownVariables ifNil: [ unknownVariables := OrderedCollection new ]
+! !
+
+!MethodLexicalScope methodsFor: '*Compiler'!
+
+addIVar: aString
+	self iVars at: aString put: (InstanceVar on: aString).
+	(self iVars at: aString) scope: self
+!
+
+addNonLocalReturn: aScope
+	self nonLocalReturns add: aScope
+!
+
+removeNonLocalReturn: aScope
+	self nonLocalReturns remove: aScope ifAbsent: []
+! !
+
+!MethodLexicalScope methodsFor: '*Compiler'!
+
+canInlineNonLocalReturns
+	^ true
+!
+
+hasLocalReturn
+	^ self localReturn
+!
+
+hasNonLocalReturn
+	^ self nonLocalReturns notEmpty
+!
+
+isMethodScope
+	^ true
+! !
+
+Object subclass: #ScopeVar
+	instanceVariableNames: 'scope name'
+	package:'Compiler'!
+!ScopeVar commentStamp!
+I am an entry in a LexicalScope that gets associated with variable nodes of the same name.  
+There are 4 different subclasses of vars: temp vars, local vars, args, and unknown/global vars.!
+
+!ScopeVar methodsFor: '*Compiler'!
+
+alias
+	^ self name asVariableName
+!
+
+name
+	^ name
+!
+
+name: aString
+	name := aString
+!
+
+scope
+	^ scope
+!
+
+scope: aScope
+	scope := aScope
+! !
+
+!ScopeVar methodsFor: '*Compiler'!
+
+isArgVar
+	^ false
+!
+
+isClassRefVar
+	^ false
+!
+
+isInstanceVar
+	^ false
+!
+
+isPseudoVar
+	^ false
+!
+
+isTempVar
+	^ false
+!
+
+isUnknownVar
+	^ false
+!
+
+validateAssignment
+	(self isArgVar or: [ self isPseudoVar ]) ifTrue: [
+		InvalidAssignmentError new
+			variableName: self name;
+			signal]
+! !
+
+!ScopeVar class methodsFor: '*Compiler'!
+
+on: aString
+	^ self new 
+		name: aString;
+		yourself
+! !
+
+ScopeVar subclass: #AliasVar
+	instanceVariableNames: 'node'
+	package:'Compiler'!
+!AliasVar commentStamp!
+I am an internally defined variable by the compiler!
+
+!AliasVar methodsFor: '*Compiler'!
+
+node
+	^ node
+!
+
+node: aNode
+	node := aNode
+! !
+
+ScopeVar subclass: #ArgVar
+	instanceVariableNames: ''
+	package:'Compiler'!
+!ArgVar commentStamp!
+I am an argument of a method or block.!
+
+!ArgVar methodsFor: '*Compiler'!
+
+isArgVar
+	^ true
+! !
+
+ScopeVar subclass: #ClassRefVar
+	instanceVariableNames: ''
+	package:'Compiler'!
+!ClassRefVar commentStamp!
+I am an class reference variable!
+
+!ClassRefVar methodsFor: '*Compiler'!
+
+alias
+	^ '(smalltalk.', self name, ' || ', self name, ')'
+! !
+
+!ClassRefVar methodsFor: '*Compiler'!
+
+isClassRefVar
+	^ true
+! !
+
+ScopeVar subclass: #InstanceVar
+	instanceVariableNames: ''
+	package:'Compiler'!
+!InstanceVar commentStamp!
+I am an instance variable of a method or block.!
+
+!InstanceVar methodsFor: '*Compiler'!
+
+alias
+	^ 'self["@', self name, '"]'
+!
+
+isInstanceVar
+	^ true
+! !
+
+ScopeVar subclass: #PseudoVar
+	instanceVariableNames: ''
+	package:'Compiler'!
+!PseudoVar commentStamp!
+I am an pseudo variable.
+
+The five Smalltalk pseudo variables are: 'self', 'super', 'nil', 'true' and 'false'!
+
+!PseudoVar methodsFor: '*Compiler'!
+
+alias
+	^ self name
+! !
+
+!PseudoVar methodsFor: '*Compiler'!
+
+isPseudoVar
+	^ true
+! !
+
+ScopeVar subclass: #TempVar
+	instanceVariableNames: ''
+	package:'Compiler'!
+!TempVar commentStamp!
+I am an temporary variable of a method or block.!
+
+!TempVar methodsFor: '*Compiler'!
+
+alias
+	^ self scope alias, '.locals.', super alias
+! !
+
+!TempVar methodsFor: '*Compiler'!
+
+isTempVar
+	^ true
+! !
+
+ScopeVar subclass: #UnknownVar
+	instanceVariableNames: ''
+	package:'Compiler'!
+!UnknownVar commentStamp!
+I am an unknown variable. Amber uses unknown variables as JavaScript globals!
+
+!UnknownVar methodsFor: '*Compiler'!
+
+isUnknownVar
+	^ true
+! !
+
+NodeVisitor subclass: #SemanticAnalyzer
+	instanceVariableNames: 'currentScope theClass classReferences messageSends superSends'
+	package:'Compiler'!
+!SemanticAnalyzer commentStamp!
+I semantically analyze the abstract syntax tree and annotate it with informations such as non local returns and variable scopes.!
+
+!SemanticAnalyzer methodsFor: '*Compiler'!
+
+classReferences
+	^ classReferences ifNil: [ classReferences := Set new ]
+!
+
+messageSends
+	^ messageSends ifNil: [ messageSends := Dictionary new ]
+!
+
+superSends
+	^ superSends ifNil: [ superSends := Dictionary new ]
+!
+
+theClass
+	^ theClass
+!
+
+theClass: aClass
+	theClass := aClass
+! !
+
+!SemanticAnalyzer methodsFor: '*Compiler'!
+
+errorShadowingVariable: aString
+	ShadowingVariableError new
+		variableName: aString;
+		signal
+!
+
+errorUnknownVariable: aNode
+	"Throw an error if the variable is undeclared in the global JS scope (i.e. window)"
+
+	| identifier |
+    identifier := aNode value.
+	((#('jQuery' 'window' 'process' 'global') includes: identifier) not and: [ self isVariableGloballyUndefined: identifier ]) ifTrue: [
+			UnknownVariableError new
+				variableName: aNode value;
+				signal ]
+		ifFalse: [
+			currentScope methodScope unknownVariables add: aNode value. ]
+! !
+
+!SemanticAnalyzer methodsFor: '*Compiler'!
+
+newBlockScope
+	^ self newScopeOfClass: LexicalScope
+!
+
+newMethodScope
+	^ self newScopeOfClass: MethodLexicalScope
+!
+
+newScopeOfClass: aLexicalScopeClass
+	^ aLexicalScopeClass new 
+		outerScope: currentScope;
+		yourself
+! !
+
+!SemanticAnalyzer methodsFor: '*Compiler'!
+
+popScope
+	currentScope ifNotNil: [
+		currentScope := currentScope outerScope ]
+!
+
+pushScope: aScope
+	aScope outerScope: currentScope.
+	currentScope := aScope
+!
+
+validateVariableScope: aString
+	"Validate the variable scope in by doing a recursive lookup, up to the method scope"
+
+	(currentScope lookupVariable: aString) ifNotNil: [
+		self errorShadowingVariable: aString ]
+! !
+
+!SemanticAnalyzer methodsFor: '*Compiler'!
+
+isVariableGloballyUndefined: aString
+	<return eval('typeof ' + aString + ' == "undefined"')>
+! !
+
+!SemanticAnalyzer methodsFor: '*Compiler'!
+
+visitAssignmentNode: aNode
+	super visitAssignmentNode: aNode.
+	aNode left beAssigned
+!
+
+visitBlockNode: aNode
+	self pushScope: self newBlockScope.
+	aNode scope: currentScope.
+	currentScope node: aNode.
+	
+	aNode parameters do: [ :each | 
+		self validateVariableScope: each.
+		currentScope addArg: each ].
+
+	super visitBlockNode: aNode.
+	self popScope
+!
+
+visitCascadeNode: aNode
+	"Populate the receiver into all children"
+	aNode nodes do: [ :each | 
+		each receiver: aNode receiver ].
+	super visitCascadeNode: aNode.
+	aNode nodes first superSend ifTrue: [
+		aNode nodes do: [ :each | each superSend: true ]]
+!
+
+visitClassReferenceNode: aNode
+	self classReferences add: aNode value.
+	aNode binding: (ClassRefVar new name: aNode value; yourself)
+!
+
+visitMethodNode: aNode
+	self pushScope: self newMethodScope.
+	aNode scope: currentScope.
+	currentScope node: aNode.
+
+	self theClass allInstanceVariableNames do: [:each | 
+		currentScope addIVar: each ].
+	aNode arguments do: [ :each | 
+		self validateVariableScope: each.
+		currentScope addArg: each ].
+
+	super visitMethodNode: aNode.
+
+	aNode 
+		classReferences: self classReferences;
+		messageSends: self messageSends keys;
+        superSends: self superSends keys.
+	self popScope
+!
+
+visitReturnNode: aNode
+	aNode scope: currentScope.
+	currentScope isMethodScope
+		ifTrue: [ currentScope localReturn: true ]
+		ifFalse: [ currentScope methodScope addNonLocalReturn: currentScope ].
+	super visitReturnNode: aNode
+!
+
+visitSendNode: aNode
+
+	aNode receiver value = 'super' 
+		ifTrue: [
+			aNode superSend: true.
+			aNode receiver value: 'self'.
+			self superSends at: aNode selector ifAbsentPut: [ Set new ].
+			(self superSends at: aNode selector) add: aNode ]
+          
+		ifFalse: [ (IRSendInliner inlinedSelectors includes: aNode selector) ifTrue: [
+			aNode shouldBeInlined: true.
+			aNode receiver shouldBeAliased: true ] ].
+
+	self messageSends at: aNode selector ifAbsentPut: [ Set new ].
+	(self messageSends at: aNode selector) add: aNode.
+
+	aNode index: (self messageSends at: aNode selector) size.
+
+	super visitSendNode: aNode
+!
+
+visitSequenceNode: aNode
+	aNode temps do: [ :each | 
+		self validateVariableScope: each.
+		currentScope addTemp: each ].
+
+	super visitSequenceNode: aNode
+!
+
+visitVariableNode: aNode
+	"Bind a ScopeVar to aNode by doing a lookup in the current scope.
+	If no ScopeVar is found, bind a UnknowVar and throw an error"
+
+	aNode binding: ((currentScope lookupVariable: aNode) ifNil: [ 
+		self errorUnknownVariable: aNode.
+		UnknownVar new name: aNode value; yourself ])
+! !
+
+!SemanticAnalyzer class methodsFor: '*Compiler'!
+
+on: aClass
+	^ self new
+		theClass: aClass;
+		yourself
+! !
+
+NodeVisitor subclass: #IRASTTranslator
+	instanceVariableNames: 'source theClass method sequence nextAlias'
+	package:'Compiler'!
+!IRASTTranslator commentStamp!
+I am the AST (abstract syntax tree) visitor responsible for building the intermediate representation graph.
+I rely on a builder object, instance of IRBuilder.!
+
+!IRASTTranslator methodsFor: '*Compiler'!
+
+method
+	^ method
+!
+
+method: anIRMethod
+	method := anIRMethod
+!
+
+nextAlias
+	nextAlias ifNil: [ nextAlias := 0 ].
+	nextAlias := nextAlias + 1.
+	^ nextAlias asString
+!
+
+sequence
+	^ sequence
+!
+
+sequence: anIRSequence
+	sequence := anIRSequence
+!
+
+source
+	^ source
+!
+
+source: aString
+	source := aString
+!
+
+theClass
+	^ theClass
+!
+
+theClass: aClass
+	theClass := aClass
+!
+
+withSequence: aSequence do: aBlock
+	| outerSequence |
+	outerSequence := self sequence.
+	self sequence: aSequence.
+	aBlock value.
+	self sequence: outerSequence.
+	^ aSequence
+! !
+
+!IRASTTranslator methodsFor: '*Compiler'!
+
+alias: aNode
+	| variable |
+
+	aNode isImmutable ifTrue: [ ^ self visit: aNode ].
+
+	variable := IRVariable new 
+		variable: (AliasVar new name: '$', self nextAlias); 
+		yourself.
+
+	self sequence add: (IRAssignment new
+		add: variable;
+		add: (self visit: aNode);
+		yourself).
+
+	self method internalVariables add: variable.
+
+	^ variable
+!
+
+aliasTemporally: aCollection
+	"https://github.com/NicolasPetton/amber/issues/296
+    
+    If a node is aliased, all preceding ones are aliased as well.
+    The tree is iterated twice. First we get the aliasing dependency, 
+    then the aliasing itself is done"
+
+	| threshold result |
+    threshold := 0.
+    
+    aCollection withIndexDo: [ :each :i |
+        each subtreeNeedsAliasing
+		    ifTrue: [ threshold := i ]].
+
+	result := OrderedCollection new.
+	aCollection withIndexDo: [ :each :i | 
+		result add: (i <= threshold
+			ifTrue: [ self alias: each ]
+			ifFalse: [ self visit: each ])].
+
+    ^result
+!
+
+visitAssignmentNode: aNode
+	| left right assignment |
+	right := self visit: aNode right.
+	left := self visit: aNode left.
+	self sequence add: (IRAssignment new 
+		add: left;
+		add: right;
+		yourself).
+	^ left
+!
+
+visitBlockNode: aNode
+	| closure |
+	closure := IRClosure new
+		arguments: aNode parameters;
+		scope: aNode scope;
+		yourself.
+	aNode scope temps do: [ :each |
+		closure add: (IRTempDeclaration new 
+			name: each name;
+            scope: aNode scope;
+			yourself) ].
+	aNode nodes do: [ :each | closure add: (self visit: each) ].
+	^ closure
+!
+
+visitBlockSequenceNode: aNode
+	^ self
+		withSequence: IRBlockSequence new
+		do: [ 
+			aNode nodes ifNotEmpty: [
+				aNode nodes allButLast do: [ :each | 
+					self sequence add: (self visit: each) ].
+				aNode nodes last isReturnNode 
+					ifFalse: [ self sequence add: (IRBlockReturn new add: (self visit: aNode nodes last); yourself) ]
+					ifTrue: [ self sequence add: (self visit: aNode nodes last) ]]]
+!
+
+visitCascadeNode: aNode
+	| alias |
+
+	aNode receiver isImmutable ifFalse: [ 
+		alias := self alias: aNode receiver.
+		aNode nodes do: [ :each |
+			each receiver: (VariableNode new binding: alias variable) ]].
+
+	aNode nodes allButLast do: [ :each |
+		self sequence add: (self visit: each) ].
+
+	^ self alias: aNode nodes last
+!
+
+visitDynamicArrayNode: aNode
+	| array |
+	array := IRDynamicArray new.
+	(self aliasTemporally: aNode nodes) do: [:each | array add: each].
+	^ array
+!
+
+visitDynamicDictionaryNode: aNode
+	| dictionary |
+	dictionary := IRDynamicDictionary new.
+    (self aliasTemporally: aNode nodes) do: [:each | dictionary add: each].
+	^ dictionary
+!
+
+visitJSStatementNode: aNode
+	^ IRVerbatim new
+		source: aNode source;
+		yourself
+!
+
+visitMethodNode: aNode
+
+	self method: (IRMethod new
+		source: self source;
+        theClass: self theClass;
+		arguments: aNode arguments;
+		selector: aNode selector;
+		messageSends: aNode messageSends;
+        superSends: aNode superSends;
+		classReferences: aNode classReferences;
+		scope: aNode scope;
+		yourself).
+
+	aNode scope temps do: [ :each |
+		self method add: (IRTempDeclaration new
+			name: each name;
+            scope: aNode scope;
+			yourself) ].
+
+	aNode nodes do: [ :each | self method add: (self visit: each) ].
+
+	aNode scope hasLocalReturn ifFalse: [
+		(self method add: IRReturn new) add: (IRVariable new
+			variable: (aNode scope pseudoVars at: 'self');
+			yourself) ].
+
+	^ self method
+!
+
+visitReturnNode: aNode
+	| return |
+	return := aNode nonLocalReturn 
+		ifTrue: [ IRNonLocalReturn new ]
+		ifFalse: [ IRReturn new ].
+	return scope: aNode scope.
+	aNode nodes do: [ :each |
+		return add: (self alias: each) ].
+	^ return
+!
+
+visitSendNode: aNode
+	| send all receiver arguments |
+	send := IRSend new.
+	send 
+		selector: aNode selector;
+		index: aNode index.
+	aNode superSend ifTrue: [ send classSend: self theClass superclass ].
+    
+    all := self aliasTemporally: { aNode receiver }, aNode arguments.
+	receiver := all first.
+	arguments := all allButFirst.
+
+	send add: receiver.
+	arguments do: [ :each | send add: each ].
+
+	^ send
+!
+
+visitSequenceNode: aNode
+	^ self 
+		withSequence: IRSequence new 	
+		do: [
+			aNode nodes do: [ :each | | instruction |
+				instruction := self visit: each.
+				instruction isVariable ifFalse: [
+					self sequence add: instruction ]]]
+!
+
+visitValueNode: aNode
+	^ IRValue new 
+		value: aNode value; 
+		yourself
+!
+
+visitVariableNode: aNode
+	^ IRVariable new 
+		variable: aNode binding; 
+		yourself
+! !
+
+Object subclass: #IRInstruction
+	instanceVariableNames: 'parent instructions'
+	package:'Compiler'!
+!IRInstruction commentStamp!
+I am the abstract root class of the IR (intermediate representation) instructions class hierarchy.
+The IR graph is used to emit JavaScript code using a JSStream.!
+
+!IRInstruction methodsFor: '*Compiler'!
+
+instructions
+	^ instructions ifNil: [ instructions := OrderedCollection new ]
+!
+
+parent
+	^ parent
+!
+
+parent: anIRInstruction
+	parent := anIRInstruction
+! !
+
+!IRInstruction methodsFor: '*Compiler'!
+
+add: anObject
+	anObject parent: self.
+	^ self instructions add: anObject
+!
+
+remove
+	self parent remove: self
+!
+
+remove: anIRInstruction
+	self instructions remove: anIRInstruction
+!
+
+replace: anIRInstruction with: anotherIRInstruction
+	anotherIRInstruction parent: self.
+	self instructions 
+		at: (self instructions indexOf: anIRInstruction)
+		put: anotherIRInstruction
+!
+
+replaceWith: anIRInstruction
+	self parent replace: self with: anIRInstruction
+! !
+
+!IRInstruction methodsFor: '*Compiler'!
+
+canBeAssigned
+	^ true
+!
+
+isClosure
+	^ false
+!
+
+isInlined
+	^ false
+!
+
+isLocalReturn
+	^ false
+!
+
+isReturn
+	^ false
+!
+
+isSend
+	^ false
+!
+
+isSequence
+	^ false
+!
+
+isTempDeclaration
+	^ false
+!
+
+isVariable
+	^ false
+! !
+
+!IRInstruction methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitIRInstruction: self
+! !
+
+!IRInstruction class methodsFor: '*Compiler'!
+
+on: aBuilder
+	^ self new
+		builder: aBuilder;
+		yourself
+! !
+
+IRInstruction subclass: #IRAssignment
+	instanceVariableNames: ''
+	package:'Compiler'!
+
+!IRAssignment methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitIRAssignment: self
+! !
+
+IRInstruction subclass: #IRDynamicArray
+	instanceVariableNames: ''
+	package:'Compiler'!
+
+!IRDynamicArray methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitIRDynamicArray: self
+! !
+
+IRInstruction subclass: #IRDynamicDictionary
+	instanceVariableNames: ''
+	package:'Compiler'!
+
+!IRDynamicDictionary methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitIRDynamicDictionary: self
+! !
+
+IRInstruction subclass: #IRScopedInstruction
+	instanceVariableNames: 'scope'
+	package:'Compiler'!
+
+!IRScopedInstruction methodsFor: '*Compiler'!
+
+scope
+	^ scope
+!
+
+scope: aScope
+	scope := aScope
+! !
+
+IRScopedInstruction subclass: #IRClosure
+	instanceVariableNames: 'arguments'
+	package:'Compiler'!
+
+!IRClosure methodsFor: '*Compiler'!
+
+arguments
+	^ arguments ifNil: [ #() ]
+!
+
+arguments: aCollection
+	arguments := aCollection
+!
+
+scope: aScope
+	super scope: aScope.
+	aScope instruction: self
+!
+
+sequence
+	^ self instructions last
+! !
+
+!IRClosure methodsFor: '*Compiler'!
+
+isClosure
+	^ true
+! !
+
+!IRClosure methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitIRClosure: self
+! !
+
+IRScopedInstruction subclass: #IRMethod
+	instanceVariableNames: 'theClass source selector classReferences messageSends superSends arguments internalVariables'
+	package:'Compiler'!
+!IRMethod commentStamp!
+I am a method instruction!
+
+!IRMethod methodsFor: '*Compiler'!
+
+arguments
+	^ arguments
+!
+
+arguments: aCollection
+	arguments := aCollection
+!
+
+classReferences
+	^ classReferences
+!
+
+classReferences: aCollection
+	classReferences := aCollection
+!
+
+internalVariables
+	^ internalVariables ifNil: [ internalVariables := Set new ]
+!
+
+messageSends
+	^ messageSends
+!
+
+messageSends: aCollection
+	messageSends := aCollection
+!
+
+scope: aScope
+	super scope: aScope.
+	aScope instruction: self
+!
+
+selector
+	^ selector
+!
+
+selector: aString
+	selector := aString
+!
+
+source
+	^ source
+!
+
+source: aString
+	source := aString
+!
+
+superSends
+	^ superSends
+!
+
+superSends: aCollection
+	superSends := aCollection
+!
+
+theClass
+	^ theClass
+!
+
+theClass: aClass
+	theClass := aClass
+! !
+
+!IRMethod methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitIRMethod: self
+! !
+
+IRScopedInstruction subclass: #IRReturn
+	instanceVariableNames: ''
+	package:'Compiler'!
+!IRReturn commentStamp!
+I am a local return instruction.!
+
+!IRReturn methodsFor: '*Compiler'!
+
+canBeAssigned
+	^ false
+!
+
+isBlockReturn
+	^ false
+!
+
+isLocalReturn
+	^ true
+!
+
+isNonLocalReturn
+	^ self isLocalReturn not
+!
+
+isReturn
+	^ true
+! !
+
+!IRReturn methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitIRReturn: self
+! !
+
+IRReturn subclass: #IRBlockReturn
+	instanceVariableNames: ''
+	package:'Compiler'!
+!IRBlockReturn commentStamp!
+Smalltalk blocks return their last statement. I am a implicit block return instruction.!
+
+!IRBlockReturn methodsFor: '*Compiler'!
+
+isBlockReturn
+	^ true
+! !
+
+!IRBlockReturn methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitIRBlockReturn: self
+! !
+
+IRReturn subclass: #IRNonLocalReturn
+	instanceVariableNames: ''
+	package:'Compiler'!
+!IRNonLocalReturn commentStamp!
+I am a non local return instruction.
+Non local returns are handled using a try/catch JS statement.
+
+See IRNonLocalReturnHandling class!
+
+!IRNonLocalReturn methodsFor: '*Compiler'!
+
+isLocalReturn
+	^ false
+! !
+
+!IRNonLocalReturn methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitIRNonLocalReturn: self
+! !
+
+IRScopedInstruction subclass: #IRTempDeclaration
+	instanceVariableNames: 'name'
+	package:'Compiler'!
+
+!IRTempDeclaration methodsFor: '*Compiler'!
+
+name
+	^ name
+!
+
+name: aString
+	name := aString
+! !
+
+!IRTempDeclaration methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitIRTempDeclaration: self
+! !
+
+IRInstruction subclass: #IRSend
+	instanceVariableNames: 'selector classSend index'
+	package:'Compiler'!
+!IRSend commentStamp!
+I am a message send instruction.!
+
+!IRSend methodsFor: '*Compiler'!
+
+classSend
+	^ classSend
+!
+
+classSend: aClass
+	classSend := aClass
+!
+
+index
+	^ index
+!
+
+index: anInteger
+	index := anInteger
+!
+
+javascriptSelector
+	^ self classSend 
+    	ifNil: [ self selector asSelector ]
+      	ifNotNil: [ self selector asSuperSelector ]
+!
+
+selector
+	^ selector
+!
+
+selector: aString
+	selector := aString
+! !
+
+!IRSend methodsFor: '*Compiler'!
+
+isSend
+	^ true
+! !
+
+!IRSend methodsFor: '*Compiler'!
 
-!MethodNode methodsFor: 'visiting'!
+accept: aVisitor
+	^ aVisitor visitIRSend: self
+! !
+
+IRInstruction subclass: #IRSequence
+	instanceVariableNames: ''
+	package:'Compiler'!
+
+!IRSequence methodsFor: '*Compiler'!
+
+isSequence
+	^ true
+! !
+
+!IRSequence methodsFor: '*Compiler'!
 
 accept: aVisitor
-	aVisitor visitMethodNode: self
+	^ aVisitor visitIRSequence: self
 ! !
 
-Node subclass: #ReturnNode
+IRSequence subclass: #IRBlockSequence
 	instanceVariableNames: ''
-	package: 'Compiler'!
+	package:'Compiler'!
 
-!ReturnNode methodsFor: 'visiting'!
+!IRBlockSequence methodsFor: '*Compiler'!
 
 accept: aVisitor
-	aVisitor visitReturnNode: self
+	^ aVisitor visitIRBlockSequence: self
 ! !
 
-Node subclass: #SendNode
-	instanceVariableNames: 'selector arguments receiver'
-	package: 'Compiler'!
+IRInstruction subclass: #IRValue
+	instanceVariableNames: 'value'
+	package:'Compiler'!
+!IRValue commentStamp!
+I am the simplest possible instruction. I represent a value.!
 
-!SendNode methodsFor: 'accessing'!
+!IRValue methodsFor: '*Compiler'!
 
-arguments
-	^arguments ifNil: [arguments := #()]
+value
+	^value
 !
 
-arguments: aCollection
-	arguments := aCollection
+value: aString
+	value := aString
+! !
+
+!IRValue methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitIRValue: self
+! !
+
+IRInstruction subclass: #IRVariable
+	instanceVariableNames: 'variable'
+	package:'Compiler'!
+!IRVariable commentStamp!
+I am a variable instruction.!
+
+!IRVariable methodsFor: '*Compiler'!
+
+variable
+	^ variable
 !
 
-cascadeNodeWithMessages: aCollection
-	| first |
-	first := SendNode new
-	    selector: self selector;
-	    arguments: self arguments;
-	    yourself.
-	^CascadeNode new
-	    receiver: self receiver;
-	    nodes: (Array with: first), aCollection;
-	    yourself
+variable: aScopeVariable
+	variable := aScopeVariable
+! !
+
+!IRVariable methodsFor: '*Compiler'!
+
+isVariable
+	^ true
+! !
+
+!IRVariable methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitIRVariable: self
+! !
+
+IRInstruction subclass: #IRVerbatim
+	instanceVariableNames: 'source'
+	package:'Compiler'!
+
+!IRVerbatim methodsFor: '*Compiler'!
+
+source
+	^ source
 !
 
-receiver
-	^receiver
+source: aString
+	source := aString
+! !
+
+!IRVerbatim methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitIRVerbatim: self
+! !
+
+Object subclass: #IRVisitor
+	instanceVariableNames: ''
+	package:'Compiler'!
+
+!IRVisitor methodsFor: '*Compiler'!
+
+visit: anIRInstruction
+	^ anIRInstruction accept: self
 !
 
-receiver: aNode
-	receiver := aNode
+visitIRAssignment: anIRAssignment
+	^ self visitIRInstruction: anIRAssignment
 !
 
-selector
-	^selector
+visitIRBlockReturn: anIRBlockReturn
+	^ self visitIRReturn: anIRBlockReturn
 !
 
-selector: aString
-	selector := aString
+visitIRBlockSequence: anIRBlockSequence
+	^ self visitIRSequence: anIRBlockSequence
 !
 
-valueForReceiver: anObject
-	^SendNode new
-	    receiver: (self receiver 
-		ifNil: [anObject]
-		ifNotNil: [self receiver valueForReceiver: anObject]);
-	    selector: self selector;
-	    arguments: self arguments;
-	    yourself
+visitIRClosure: anIRClosure
+	^ self visitIRInstruction: anIRClosure
+!
+
+visitIRDynamicArray: anIRDynamicArray
+	^ self visitIRInstruction: anIRDynamicArray
+!
+
+visitIRDynamicDictionary: anIRDynamicDictionary
+	^ self visitIRInstruction: anIRDynamicDictionary
+!
+
+visitIRInlinedClosure: anIRInlinedClosure
+	^ self visitIRClosure: anIRInlinedClosure
+!
+
+visitIRInlinedSequence: anIRInlinedSequence
+	^ self visitIRSequence: anIRInlinedSequence
+!
+
+visitIRInstruction: anIRInstruction
+	anIRInstruction instructions do: [ :each | self visit: each ].
+	^ anIRInstruction
+!
+
+visitIRMethod: anIRMethod
+	^ self visitIRInstruction: anIRMethod
+!
+
+visitIRNonLocalReturn: anIRNonLocalReturn
+	^ self visitIRInstruction: anIRNonLocalReturn
+!
+
+visitIRNonLocalReturnHandling: anIRNonLocalReturnHandling
+	^ self visitIRInstruction: anIRNonLocalReturnHandling
+!
+
+visitIRReturn: anIRReturn
+	^ self visitIRInstruction: anIRReturn
+!
+
+visitIRSend: anIRSend
+	^ self visitIRInstruction: anIRSend
+!
+
+visitIRSequence: anIRSequence
+	^ self visitIRInstruction: anIRSequence
+!
+
+visitIRTempDeclaration: anIRTempDeclaration
+	^ self visitIRInstruction: anIRTempDeclaration
+!
+
+visitIRValue: anIRValue
+	^ self visitIRInstruction: anIRValue
+!
+
+visitIRVariable: anIRVariable
+	^ self visitIRInstruction: anIRVariable
+!
+
+visitIRVerbatim: anIRVerbatim
+	^ self visitIRInstruction: anIRVerbatim
 ! !
 
-!SendNode methodsFor: 'visiting'!
+IRVisitor subclass: #IRJSTranslator
+	instanceVariableNames: 'stream'
+	package:'Compiler'!
+
+!IRJSTranslator methodsFor: '*Compiler'!
 
-accept: aVisitor
-	aVisitor visitSendNode: self
+contents
+	^ self stream contents
+!
+
+stream
+	^ stream
+!
+
+stream: aStream
+	stream := aStream
 ! !
 
-Node subclass: #SequenceNode
-	instanceVariableNames: 'temps'
-	package: 'Compiler'!
+!IRJSTranslator methodsFor: '*Compiler'!
 
-!SequenceNode methodsFor: 'accessing'!
+initialize
+	super initialize.
+	stream := JSStream new.
+! !
 
-temps
-	^temps ifNil: [#()]
+!IRJSTranslator methodsFor: '*Compiler'!
+
+visitIRAssignment: anIRAssignment
+	self visit: anIRAssignment instructions first.
+	self stream nextPutAssignment.
+	self visit: anIRAssignment instructions last.
 !
 
-temps: aCollection
-	temps := aCollection
+visitIRClosure: anIRClosure
+	self stream 
+		nextPutClosureWith: [ 
+        	self stream 
+            	nextPutBlockContextFor: anIRClosure
+                during: [ super visitIRClosure: anIRClosure ] ]
+		arguments: anIRClosure arguments
+!
+
+visitIRDynamicArray: anIRDynamicArray
+	self stream nextPutAll: '['.
+	anIRDynamicArray instructions
+		do: [ :each | self visit: each ]
+		separatedBy: [ self stream nextPutAll: ',' ].
+	stream nextPutAll: ']'
+!
+
+visitIRDynamicDictionary: anIRDynamicDictionary
+	self stream nextPutAll: 'smalltalk.HashedCollection._fromPairs_(['.
+		anIRDynamicDictionary instructions 
+			do: [ :each | self visit: each ]
+			separatedBy: [self stream nextPutAll: ',' ].
+	self stream nextPutAll: '])'
+!
+
+visitIRMethod: anIRMethod
+	self stream
+		nextPutMethodDeclaration: anIRMethod 
+		with: [ self stream 
+			nextPutFunctionWith: [ 
+            	self stream nextPutContextFor: anIRMethod during: [
+				anIRMethod internalVariables notEmpty ifTrue: [
+					self stream nextPutVars: (anIRMethod internalVariables asArray collect: [ :each |
+						each variable alias ]) ].
+				anIRMethod scope hasNonLocalReturn 
+					ifTrue: [
+						self stream nextPutNonLocalReturnHandlingWith: [
+							super visitIRMethod: anIRMethod ]]
+					ifFalse: [ super visitIRMethod: anIRMethod ]]]
+			arguments: anIRMethod arguments ]
+!
+
+visitIRNonLocalReturn: anIRNonLocalReturn
+	self stream nextPutNonLocalReturnWith: [
+		super visitIRNonLocalReturn: anIRNonLocalReturn ]
+!
+
+visitIRReturn: anIRReturn
+	self stream nextPutReturnWith: [
+		super visitIRReturn: anIRReturn ]
+!
+
+visitIRSend: anIRSend
+	anIRSend classSend 
+    	ifNil: [
+			self stream nextPutAll: '_st('.
+			self visit: anIRSend instructions first.
+   		 	self stream nextPutAll: ').', anIRSend selector asSelector, '('.
+			anIRSend instructions allButFirst
+				do: [ :each | self visit: each ]
+				separatedBy: [ self stream nextPutAll: ',' ].
+			self stream nextPutAll: ')' ]
+		ifNotNil: [ 
+			self stream 
+            	nextPutAll: anIRSend classSend asJavascript, '.fn.prototype.';
+				nextPutAll: anIRSend selector asSelector, '.apply(';
+				nextPutAll: '_st('.
+			self visit: anIRSend instructions first.
+			self stream nextPutAll: '), ['.
+			anIRSend instructions allButFirst
+				do: [ :each | self visit: each ]
+				separatedBy: [ self stream nextPutAll: ',' ].
+			self stream nextPutAll: '])' ]
+!
+
+visitIRSequence: anIRSequence
+	self stream nextPutSequenceWith: [
+		anIRSequence instructions do: [ :each |
+			self stream nextPutStatementWith: (self visit: each) ]]
+!
+
+visitIRTempDeclaration: anIRTempDeclaration
+	self stream 
+    	nextPutAll: anIRTempDeclaration scope alias, '.locals.', anIRTempDeclaration name, '=nil;'; 
+        lf
+!
+
+visitIRValue: anIRValue
+	self stream nextPutAll: anIRValue value asJavascript
+!
+
+visitIRVariable: anIRVariable
+	anIRVariable variable name = 'thisContext'
+    	ifTrue: [ self stream nextPutAll: 'smalltalk.getThisContext()' ]
+      	ifFalse: [ self stream nextPutAll: anIRVariable variable alias ]
+!
+
+visitIRVerbatim: anIRVerbatim
+	self stream nextPutStatementWith: [
+		self stream nextPutAll: anIRVerbatim source ]
 ! !
 
-!SequenceNode methodsFor: 'testing'!
+Object subclass: #JSStream
+	instanceVariableNames: 'stream'
+	package:'Compiler'!
 
-asBlockSequenceNode
-	^BlockSequenceNode new
-	    nodes: self nodes;
-	    temps: self temps;
-	    yourself
+!JSStream methodsFor: '*Compiler'!
+
+contents
+	^ stream contents
+! !
+
+!JSStream methodsFor: '*Compiler'!
+
+initialize
+	super initialize.
+	stream := '' writeStream.
+! !
+
+!JSStream methodsFor: '*Compiler'!
+
+lf
+	stream lf
+!
+
+nextPut: aString
+	stream nextPut: aString
+!
+
+nextPutAll: aString
+	stream nextPutAll: aString
+!
+
+nextPutAssignment
+	stream nextPutAll: '='
+!
+
+nextPutBlockContextFor: anIRClosure during: aBlock
+	self 
+    	nextPutAll: 'return smalltalk.withContext(function(', anIRClosure scope alias, ') { '; 
+        nextPutAll: String cr.
+    aBlock value.
+    self nextPutAll: '})'
+!
+
+nextPutClosureWith: aBlock arguments: anArray
+	stream nextPutAll: '(function('.
+	anArray 
+		do: [ :each | stream nextPutAll: each asVariableName ]
+		separatedBy: [ stream nextPut: ',' ].
+	stream nextPutAll: '){'; lf.
+	aBlock value.
+	stream nextPutAll: '})'
+!
+
+nextPutContextFor: aMethod during: aBlock
+	self 
+    	nextPutAll: 'return smalltalk.withContext(function(', aMethod scope alias, ') { '; 
+        nextPutAll: String cr.
+    aBlock value.
+    self 
+    	nextPutAll: '}, self, ';
+        nextPutAll: aMethod selector asJavascript, ', ['.
+    aMethod arguments 
+    	do: [ :each | self nextPutAll: each asVariableName ]
+      	separatedBy: [ self nextPutAll: ','  ].
+    self nextPutAll: '], ';
+        nextPutAll: aMethod theClass asJavascript;
+        nextPutAll: ')'
+!
+
+nextPutFunctionWith: aBlock arguments: anArray
+	stream nextPutAll: 'fn: function('.
+	anArray 
+		do: [ :each | stream nextPutAll: each asVariableName ]
+		separatedBy: [ stream nextPut: ',' ].
+	stream nextPutAll: '){'; lf.
+	stream nextPutAll: 'var self=this;'; lf.
+	aBlock value.
+	stream nextPutAll: '}'
+!
+
+nextPutIf: aBlock with: anotherBlock
+	stream nextPutAll: 'if('.
+	aBlock value.
+	stream nextPutAll: '){'; lf.
+	anotherBlock value.
+	stream nextPutAll: '}'
+!
+
+nextPutIfElse: aBlock with: ifBlock with: elseBlock
+	stream nextPutAll: 'if('.
+	aBlock value.
+	stream nextPutAll: '){'; lf.
+	ifBlock value.
+	stream nextPutAll: '} else {'; lf.
+	elseBlock value.
+	stream nextPutAll: '}'
+!
+
+nextPutMethodDeclaration: aMethod with: aBlock
+	stream 
+		nextPutAll: 'smalltalk.method({'; lf;
+		nextPutAll: 'selector: "', aMethod selector, '",'; lf;
+		nextPutAll: 'source: ', aMethod source asJavascript, ',';lf. 
+	aBlock value.
+	stream 
+		nextPutAll: ',', String lf, 'messageSends: ';
+		nextPutAll: aMethod messageSends asArray asJavascript, ','; lf;
+        nextPutAll: 'args: ', (aMethod arguments collect: [ :each | each value ]) asArray asJavascript, ','; lf;
+		nextPutAll: 'referencedClasses: ['.
+	aMethod classReferences 
+		do: [:each | stream nextPutAll: each asJavascript]
+		separatedBy: [stream nextPutAll: ','].
+	stream 
+		nextPutAll: ']';
+		nextPutAll: '})'
+!
+
+nextPutNonLocalReturnHandlingWith: aBlock
+	stream 
+		nextPutAll: 'var $early={};'; lf;
+		nextPutAll: 'try {'; lf.
+	aBlock value.
+	stream 
+		nextPutAll: '}'; lf;
+		nextPutAll: 'catch(e) {if(e===$early)return e[0]; throw e}'; lf
+!
+
+nextPutNonLocalReturnWith: aBlock
+	stream nextPutAll: 'throw $early=['.
+	aBlock value.
+	stream nextPutAll: ']'
+!
+
+nextPutReturn
+	stream nextPutAll: 'return '
+!
+
+nextPutReturnWith: aBlock
+	self nextPutReturn.
+	aBlock value
+!
+
+nextPutSequenceWith: aBlock
+	"stream 
+		nextPutAll: 'switch(smalltalk.thisContext.pc){'; lf."
+	aBlock value.
+	"stream 
+		nextPutAll: '};'; lf"
+!
+
+nextPutStatement: anInteger with: aBlock
+	stream nextPutAll: 'case ', anInteger asString, ':'; lf.
+	self nextPutStatementWith: aBlock.
+	stream nextPutAll: 'smalltalk.thisContext.pc=', (anInteger + 1) asString, ';'; lf
+!
+
+nextPutStatementWith: aBlock
+	aBlock value.
+	stream nextPutAll: ';'; lf
+!
+
+nextPutVar: aString
+	stream nextPutAll: 'var ', aString, ';'; lf
+!
+
+nextPutVars: aCollection
+	stream nextPutAll: 'var '.
+	aCollection 
+		do: [ :each | stream nextPutAll: each ]
+		separatedBy: [ stream nextPutAll: ',' ].
+	stream nextPutAll: ';'; lf
+! !
+
+!BlockClosure methodsFor: '*Compiler'!
+
+appendToInstruction: anIRInstruction
+    anIRInstruction appendBlock: self
+! !
+
+!String methodsFor: '*Compiler'!
+
+asVariableName
+	^ (Smalltalk current reservedWords includes: self)
+		ifTrue: [ self, '_' ]
+		ifFalse: [ self ]
+! !
+
+IRAssignment subclass: #IRInlinedAssignment
+	instanceVariableNames: ''
+	package:'Compiler'!
+!IRInlinedAssignment commentStamp!
+I represent an inlined assignment instruction.!
+
+!IRInlinedAssignment methodsFor: '*Compiler'!
+
+isInlined
+	^ true
 ! !
 
-!SequenceNode methodsFor: 'visiting'!
+!IRInlinedAssignment methodsFor: '*Compiler'!
 
 accept: aVisitor
-	aVisitor visitSequenceNode: self
+	^ aVisitor visitIRInlinedAssignment: self
 ! !
 
-SequenceNode subclass: #BlockSequenceNode
+IRClosure subclass: #IRInlinedClosure
 	instanceVariableNames: ''
-	package: 'Compiler'!
+	package:'Compiler'!
+!IRInlinedClosure commentStamp!
+I represent an inlined closure instruction.!
 
-!BlockSequenceNode methodsFor: 'testing'!
+!IRInlinedClosure methodsFor: '*Compiler'!
 
-isBlockSequenceNode
-	^true
+isInlined
+	^ true
 ! !
 
-!BlockSequenceNode methodsFor: 'visiting'!
+!IRInlinedClosure methodsFor: '*Compiler'!
 
 accept: aVisitor
-	aVisitor visitBlockSequenceNode: self
+	aVisitor visitIRInlinedClosure: self
 ! !
 
-Node subclass: #ValueNode
-	instanceVariableNames: 'value'
-	package: 'Compiler'!
+IRReturn subclass: #IRInlinedReturn
+	instanceVariableNames: ''
+	package:'Compiler'!
+!IRInlinedReturn commentStamp!
+I represent an inlined local return instruction.!
+
+!IRInlinedReturn methodsFor: '*Compiler'!
 
-!ValueNode methodsFor: 'accessing'!
+isInlined
+	^ true
+! !
+
+!IRInlinedReturn methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitIRInlinedReturn: self
+! !
+
+IRInlinedReturn subclass: #IRInlinedNonLocalReturn
+	instanceVariableNames: ''
+	package:'Compiler'!
+!IRInlinedNonLocalReturn commentStamp!
+I represent an inlined non local return instruction.!
+
+!IRInlinedNonLocalReturn methodsFor: '*Compiler'!
+
+isInlined
+	^ true
+! !
+
+!IRInlinedNonLocalReturn methodsFor: '*Compiler'!
+
+accept: aVisitor
+	^ aVisitor visitIRInlinedNonLocalReturn: self
+! !
+
+IRSend subclass: #IRInlinedSend
+	instanceVariableNames: ''
+	package:'Compiler'!
+!IRInlinedSend commentStamp!
+I am the abstract super class of inlined message send instructions.!
 
-value
-	^value
-!
+!IRInlinedSend methodsFor: '*Compiler'!
 
-value: anObject
-	value := anObject
+isInlined
+	^ true
 ! !
 
-!ValueNode methodsFor: 'testing'!
+!IRInlinedSend methodsFor: '*Compiler'!
 
-isValueNode
-	^true
+accept: aVisitor
+	aVisitor visitInlinedSend: self
 ! !
 
-!ValueNode methodsFor: 'visiting'!
+IRInlinedSend subclass: #IRInlinedIfFalse
+	instanceVariableNames: ''
+	package:'Compiler'!
+
+!IRInlinedIfFalse methodsFor: '*Compiler'!
 
 accept: aVisitor
-	aVisitor visitValueNode: self
+	aVisitor visitIRInlinedIfFalse: self
 ! !
 
-ValueNode subclass: #VariableNode
-	instanceVariableNames: 'assigned'
-	package: 'Compiler'!
-
-!VariableNode methodsFor: 'accessing'!
+IRInlinedSend subclass: #IRInlinedIfNilIfNotNil
+	instanceVariableNames: ''
+	package:'Compiler'!
 
-assigned
-	^assigned ifNil: [false]
-!
+!IRInlinedIfNilIfNotNil methodsFor: '*Compiler'!
 
-assigned: aBoolean
-	assigned := aBoolean
+accept: aVisitor
+	aVisitor visitIRInlinedIfNilIfNotNil: self
 ! !
 
-!VariableNode methodsFor: 'visiting'!
+IRInlinedSend subclass: #IRInlinedIfTrue
+	instanceVariableNames: ''
+	package:'Compiler'!
+
+!IRInlinedIfTrue methodsFor: '*Compiler'!
 
 accept: aVisitor
-	aVisitor visitVariableNode: self
+	aVisitor visitIRInlinedIfTrue: self
 ! !
 
-VariableNode subclass: #ClassReferenceNode
+IRInlinedSend subclass: #IRInlinedIfTrueIfFalse
 	instanceVariableNames: ''
-	package: 'Compiler'!
+	package:'Compiler'!
 
-!ClassReferenceNode methodsFor: 'visiting'!
+!IRInlinedIfTrueIfFalse methodsFor: '*Compiler'!
 
 accept: aVisitor
-	aVisitor visitClassReferenceNode: self
+	aVisitor visitIRInlinedIfTrueIfFalse: self
 ! !
 
-Node subclass: #VerbatimNode
-	instanceVariableNames: 'value'
-	package: 'Compiler'!
-
-!VerbatimNode methodsFor: 'accessing'!
+IRBlockSequence subclass: #IRInlinedSequence
+	instanceVariableNames: ''
+	package:'Compiler'!
+!IRInlinedSequence commentStamp!
+I represent a (block) sequence inside an inlined closure instruction (instance of `IRInlinedClosure`).!
 
-value
-	^value
-!
+!IRInlinedSequence methodsFor: '*Compiler'!
 
-value: anObject
-	value := anObject
+isInlined
+	^ true
 ! !
 
-!VerbatimNode methodsFor: 'visiting'!
+!IRInlinedSequence methodsFor: '*Compiler'!
 
 accept: aVisitor
-	aVisitor visitVerbatimNode: self
+	aVisitor visitIRInlinedSequence: self
 ! !
 
-Object subclass: #NodeVisitor
+IRVisitor subclass: #IRInliner
 	instanceVariableNames: ''
-	package: 'Compiler'!
-
-!NodeVisitor methodsFor: 'visiting'!
+	package:'Compiler'!
+!IRInliner commentStamp!
+I visit an IR tree, inlining message sends and block closures.
 
-visit: aNode
-	aNode accept: self
-!
+Message selectors that can be inlined are answered by `IRSendInliner >> #inlinedSelectors`!
 
-visitAssignmentNode: aNode
-	self visitNode: aNode
-!
+!IRInliner methodsFor: '*Compiler'!
 
-visitBlockNode: aNode
-	self visitNode: aNode
+assignmentInliner
+	^ IRAssignmentInliner new 
+		translator: self;
+		yourself
 !
 
-visitBlockSequenceNode: aNode
-	self visitNode: aNode
+nonLocalReturnInliner
+	^ IRNonLocalReturnInliner new 
+		translator: self;
+		yourself
 !
 
-visitCascadeNode: aNode
-	self visitNode: aNode
+returnInliner
+	^ IRReturnInliner new 
+		translator: self;
+		yourself
 !
 
-visitClassReferenceNode: aNode
-	self visitNode: aNode
-!
+sendInliner
+	^ IRSendInliner new 
+		translator: self;
+		yourself
+! !
 
-visitDynamicArrayNode: aNode
-	self visitNode: aNode
-!
+!IRInliner methodsFor: '*Compiler'!
 
-visitDynamicDictionaryNode: aNode
-	self visitNode: aNode
+shouldInlineAssignment: anIRAssignment
+	^ anIRAssignment isInlined not and: [ 
+		anIRAssignment instructions last isSend and: [	
+			self shouldInlineSend: (anIRAssignment instructions last) ]]
 !
 
-visitJSStatementNode: aNode
-	self visitNode: aNode
+shouldInlineReturn: anIRReturn
+	^ anIRReturn isInlined not and: [ 
+		anIRReturn instructions first isSend and: [	
+			self shouldInlineSend: (anIRReturn instructions first) ]]
 !
 
-visitMethodNode: aNode
-	self visitNode: aNode
-!
+shouldInlineSend: anIRSend
+	^ anIRSend isInlined not and: [
+		IRSendInliner shouldInline: anIRSend ]
+! !
 
-visitNode: aNode
-!
+!IRInliner methodsFor: '*Compiler'!
 
-visitReturnNode: aNode
-	self visitNode: aNode
-!
+transformNonLocalReturn: anIRNonLocalReturn
+	"Replace a non local return into a local return"
 
-visitSendNode: aNode
-	self visitNode: aNode
+	| localReturn |
+	anIRNonLocalReturn scope canInlineNonLocalReturns ifTrue: [
+		anIRNonLocalReturn scope methodScope removeNonLocalReturn: anIRNonLocalReturn scope.
+		localReturn := IRReturn new
+			scope: anIRNonLocalReturn scope;
+			yourself.
+		anIRNonLocalReturn instructions do: [ :each |
+			localReturn add: each ].
+		anIRNonLocalReturn replaceWith: localReturn.
+		^ localReturn ].
+	^ super visitIRNonLocalReturn: anIRNonLocalReturn
 !
 
-visitSequenceNode: aNode
-	self visitNode: aNode
+visitIRAssignment: anIRAssignment
+	^ (self shouldInlineAssignment: anIRAssignment) 
+		ifTrue: [ self assignmentInliner inlineAssignment: anIRAssignment ]
+		ifFalse: [ super visitIRAssignment: anIRAssignment ]
 !
 
-visitValueNode: aNode
-	self visitNode: aNode
+visitIRNonLocalReturn: anIRNonLocalReturn
+	^ (self shouldInlineReturn: anIRNonLocalReturn) 
+		ifTrue: [ self nonLocalReturnInliner inlineReturn: anIRNonLocalReturn ]
+		ifFalse: [ self transformNonLocalReturn: anIRNonLocalReturn ]
 !
 
-visitVariableNode: aNode
-	self visitNode: aNode
+visitIRReturn: anIRReturn
+	^ (self shouldInlineReturn: anIRReturn) 
+		ifTrue: [ self returnInliner inlineReturn: anIRReturn ]
+		ifFalse: [ super visitIRReturn: anIRReturn ]
 !
 
-visitVerbatimNode: aNode
-	self visitNode: aNode
+visitIRSend: anIRSend
+	^ (self shouldInlineSend: anIRSend)
+		ifTrue: [ self sendInliner inlineSend: anIRSend ]
+		ifFalse: [ super visitIRSend: anIRSend ]
 ! !
 
-NodeVisitor subclass: #AbstractCodeGenerator
-	instanceVariableNames: 'currentClass source'
-	package: 'Compiler'!
+IRJSTranslator subclass: #IRInliningJSTranslator
+	instanceVariableNames: ''
+	package:'Compiler'!
+!IRInliningJSTranslator commentStamp!
+I am a specialized JavaScript translator able to write inlined IR instructions to JavaScript stream (`JSStream` instance).!
 
-!AbstractCodeGenerator methodsFor: 'accessing'!
+!IRInliningJSTranslator methodsFor: '*Compiler'!
 
-classNameFor: aClass
-	^aClass isMetaclass
-	    ifTrue: [aClass instanceClass name, '.klass']
-	    ifFalse: [
-		aClass isNil
-		    ifTrue: ['nil']
-		    ifFalse: [aClass name]]
+visitIRInlinedAssignment: anIRInlinedAssignment
+	self visit: anIRInlinedAssignment instructions last
 !
 
-currentClass
-	^currentClass
+visitIRInlinedClosure: anIRInlinedClosure
+	anIRInlinedClosure instructions do: [ :each |
+		self visit: each ]
 !
 
-currentClass: aClass
-	currentClass := aClass
+visitIRInlinedIfFalse: anIRInlinedIfFalse
+	self stream nextPutIf: [ 
+		self stream nextPutAll: '!! smalltalk.assert('.
+		self visit: anIRInlinedIfFalse instructions first.
+		self stream nextPutAll: ')' ]
+		with: [ self visit: anIRInlinedIfFalse instructions last ]
 !
 
-pseudoVariables
-	^#('self' 'super' 'true' 'false' 'nil' 'thisContext')
+visitIRInlinedIfNil: anIRInlinedIfNil
+	self stream nextPutIf: [ 
+		self stream nextPutAll: '($receiver = '. 
+		self visit: anIRInlinedIfNil instructions first.
+		self stream nextPutAll: ') == nil || $receiver == undefined' ]
+		with: [ self visit: anIRInlinedIfNil instructions last ]
 !
 
-safeVariableNameFor: aString
-	^(Smalltalk current reservedWords includes: aString)
-		ifTrue: [aString, '_']
-		ifFalse: [aString]
+visitIRInlinedIfNilIfNotNil: anIRInlinedIfNilIfNotNil
+	self stream 
+		nextPutIfElse: [ 
+			self stream nextPutAll: '($receiver = '. 
+			self visit: anIRInlinedIfNilIfNotNil instructions first.
+			self stream nextPutAll: ') == nil || $receiver == undefined' ]
+		with: [ self visit: anIRInlinedIfNilIfNotNil instructions second ]
+		with: [ self visit: anIRInlinedIfNilIfNotNil instructions third ]
 !
 
-source
-	^source ifNil: ['']
+visitIRInlinedIfTrue: anIRInlinedIfTrue
+	self stream nextPutIf: [ 
+		self stream nextPutAll: 'smalltalk.assert('. 
+		self visit: anIRInlinedIfTrue instructions first.
+		self stream nextPutAll: ')' ]
+		with: [ self visit: anIRInlinedIfTrue instructions last ]
 !
 
-source: aString
-	source := aString
-! !
+visitIRInlinedIfTrueIfFalse: anIRInlinedIfTrueIfFalse
+	self stream 
+		nextPutIfElse: [ 
+			self stream nextPutAll: 'smalltalk.assert('. 
+			self visit: anIRInlinedIfTrueIfFalse instructions first.
+			self stream nextPutAll: ')' ]
+		with: [ self visit: anIRInlinedIfTrueIfFalse instructions second ]
+		with: [ self visit: anIRInlinedIfTrueIfFalse instructions third ]
+!
+
+visitIRInlinedNonLocalReturn: anIRInlinedReturn
+	self stream nextPutStatementWith: [
+		self visit: anIRInlinedReturn instructions last ].
+	self stream nextPutNonLocalReturnWith: [ ]
+!
 
-!AbstractCodeGenerator methodsFor: 'compiling'!
+visitIRInlinedReturn: anIRInlinedReturn
+	self visit: anIRInlinedReturn instructions last
+!
 
-compileNode: aNode
-	self subclassResponsibility
+visitIRInlinedSequence: anIRInlinedSequence
+	anIRInlinedSequence instructions do: [ :each | 
+		self stream nextPutStatementWith: [ self visit: each ]]
 ! !
 
-AbstractCodeGenerator subclass: #FunCodeGenerator
-	instanceVariableNames: 'stream nestedBlocks earlyReturn currentSelector unknownVariables tempVariables messageSends referencedClasses classReferenced argVariables'
-	package: 'Compiler'!
+Object subclass: #IRSendInliner
+	instanceVariableNames: 'send translator'
+	package:'Compiler'!
+!IRSendInliner commentStamp!
+I inline some message sends and block closure arguments. I heavily rely on #perform: to dispatch inlining methods.!
 
-!FunCodeGenerator methodsFor: 'accessing'!
+!IRSendInliner methodsFor: '*Compiler'!
 
-argVariables
-	^argVariables copy
+send
+	^ send
 !
 
-knownVariables
-	^self pseudoVariables 
-		addAll: self tempVariables;
-		addAll: self argVariables;
-		yourself
+send: anIRSend
+	send := anIRSend
 !
 
-tempVariables
-	^tempVariables copy
+translator
+	^ translator
 !
 
-unknownVariables
-	^unknownVariables copy
+translator: anASTTranslator
+	translator := anASTTranslator
 ! !
 
-!FunCodeGenerator methodsFor: 'compiling'!
+!IRSendInliner methodsFor: '*Compiler'!
 
-compileNode: aNode
-	stream := '' writeStream.
-	self visit: aNode.
-	^stream contents
+inliningError: aString
+	InliningError signal: aString
 ! !
 
-!FunCodeGenerator methodsFor: 'initialization'!
+!IRSendInliner methodsFor: '*Compiler'!
 
-initialize
-	super initialize.
-	stream := '' writeStream. 
-	unknownVariables := #().
-	tempVariables := #().
-	argVariables := #().
-	messageSends := #().
-	classReferenced := #()
-! !
-
-!FunCodeGenerator methodsFor: 'optimizations'!
-
-checkClass: aClassName for: receiver
-        stream nextPutAll: '((($receiver = ', receiver, ').klass === smalltalk.', aClassName, ') ? '
-!
-
-inline: aSelector receiver: receiver argumentNodes: aCollection
-        | inlined |
-        inlined := false.
-
-	"-- Booleans --"
-
-	(aSelector = 'ifFalse:') ifTrue: [
-		aCollection first isBlockNode ifTrue: [
-                	self checkClass: 'Boolean' for: receiver.
-                	stream nextPutAll: '(!! $receiver ? '.
-                	self visit: aCollection first.
-          		stream nextPutAll: '() : nil)'.
-                	inlined := true]].
-
-	(aSelector = 'ifTrue:') ifTrue: [
-		aCollection first isBlockNode ifTrue: [
-                	self checkClass: 'Boolean' for: receiver.
-                	stream nextPutAll: '($receiver ? '.
-                	self visit: aCollection first.
-          		stream nextPutAll: '() : nil)'.
-                	inlined := true]].
-
-	(aSelector = 'ifTrue:ifFalse:') ifTrue: [
-		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
-                	self checkClass: 'Boolean' for: receiver.
-                	stream nextPutAll: '($receiver ? '.
-                	self visit: aCollection first.
-          		stream nextPutAll: '() : '.
-          		self visit: aCollection second.
-          		stream nextPutAll: '())'.
-                	inlined := true]].
-
-	(aSelector = 'ifFalse:ifTrue:') ifTrue: [
-		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
-                	self checkClass: 'Boolean' for: receiver.
-                	stream nextPutAll: '(!! $receiver ? '.
-                	self visit: aCollection first.
-          		stream nextPutAll: '() : '.
-          		self visit: aCollection second.
-          		stream nextPutAll: '())'.
-                	inlined := true]].
-
-	"-- Numbers --"
-
-	(aSelector = '<') ifTrue: [
-                self checkClass: 'Number' for: receiver.
-                stream nextPutAll: '$receiver <'.
-                self visit: aCollection first.
-                inlined := true].
-
-	(aSelector = '<=') ifTrue: [
-                self checkClass: 'Number' for: receiver.
-                stream nextPutAll: '$receiver <='.
-                self visit: aCollection first.
-                inlined := true].
-
-	(aSelector = '>') ifTrue: [ 
-                self checkClass: 'Number' for: receiver.
-                stream nextPutAll: '$receiver >'.
-                self visit: aCollection first.
-                inlined := true].
-
-	(aSelector = '>=') ifTrue: [
-                self checkClass: 'Number' for: receiver.
-                stream nextPutAll: '$receiver >='.
-                self visit: aCollection first.
-                inlined := true].
-
-        (aSelector = '+') ifTrue: [
-                self checkClass: 'Number' for: receiver.
-                stream nextPutAll: '$receiver +'.
-                self visit: aCollection first.
-                inlined := true].
-
-        (aSelector = '-') ifTrue: [
-                self checkClass: 'Number' for: receiver.
-                stream nextPutAll: '$receiver -'.
-                self visit: aCollection first.
-                inlined := true].
-
-        (aSelector = '*') ifTrue: [
-                self checkClass: 'Number' for: receiver.
-                stream nextPutAll: '$receiver *'.
-                self visit: aCollection first.
-                inlined := true].
-
-        (aSelector = '/') ifTrue: [
-                self checkClass: 'Number' for: receiver.
-                stream nextPutAll: '$receiver /'.
-                self visit: aCollection first.
-                inlined := true].
-
-        ^inlined
-!
-
-inlineLiteral: aSelector receiverNode: anObject argumentNodes: aCollection
-        | inlined |
-        inlined := false.
- 
-	"-- BlockClosures --"
-
-	(aSelector = 'whileTrue:') ifTrue: [
-          	(anObject isBlockNode and: [aCollection first isBlockNode]) ifTrue: [
-                	stream nextPutAll: '(function(){while('.
-                  	self visit: anObject.
-                  	stream nextPutAll: '()) {'.
-                	self visit: aCollection first.
-          		stream nextPutAll: '()}})()'.
-                	inlined := true]].
-
-	(aSelector = 'whileFalse:') ifTrue: [
-          	(anObject isBlockNode and: [aCollection first isBlockNode]) ifTrue: [
-                	stream nextPutAll: '(function(){while(!!'.
-                  	self visit: anObject.
-                  	stream nextPutAll: '()) {'.
-                	self visit: aCollection first.
-          		stream nextPutAll: '()}})()'.
-                	inlined := true]].
-
-	(aSelector = 'whileTrue') ifTrue: [
-          	anObject isBlockNode ifTrue: [
-                	stream nextPutAll: '(function(){while('.
-                  	self visit: anObject.
-                  	stream nextPutAll: '()) {}})()'.
-                	inlined := true]].
-
-	(aSelector = 'whileFalse') ifTrue: [
-          	anObject isBlockNode ifTrue: [
-                	stream nextPutAll: '(function(){while(!!'.
-                  	self visit: anObject.
-                  	stream nextPutAll: '()) {}})()'.
-                	inlined := true]].
-
-	"-- Numbers --"
-
-	(aSelector = '+') ifTrue: [
-          	(self isNode: anObject ofClass: Number) ifTrue: [
-                  	self visit: anObject.
-                  	stream nextPutAll: ' + '.
-                	self visit: aCollection first.
-                	inlined := true]].
-
-	(aSelector = '-') ifTrue: [
-          	(self isNode: anObject ofClass: Number) ifTrue: [
-                  	self visit: anObject.
-                  	stream nextPutAll: ' - '.
-                	self visit: aCollection first.
-                	inlined := true]].
-
-	(aSelector = '*') ifTrue: [
-          	(self isNode: anObject ofClass: Number) ifTrue: [
-                  	self visit: anObject.
-                  	stream nextPutAll: ' * '.
-                	self visit: aCollection first.
-                	inlined := true]].
-
-	(aSelector = '/') ifTrue: [
-          	(self isNode: anObject ofClass: Number) ifTrue: [
-                  	self visit: anObject.
-                  	stream nextPutAll: ' / '.
-                	self visit: aCollection first.
-                	inlined := true]].
-
-	(aSelector = '<') ifTrue: [
-          	(self isNode: anObject ofClass: Number) ifTrue: [
-                  	self visit: anObject.
-                  	stream nextPutAll: ' < '.
-                	self visit: aCollection first.
-                	inlined := true]].
-
-	(aSelector = '<=') ifTrue: [
-          	(self isNode: anObject ofClass: Number) ifTrue: [
-                  	self visit: anObject.
-                  	stream nextPutAll: ' <= '.
-                	self visit: aCollection first.
-                	inlined := true]].
-
-	(aSelector = '>') ifTrue: [
-          	(self isNode: anObject ofClass: Number) ifTrue: [
-                  	self visit: anObject.
-                  	stream nextPutAll: ' > '.
-                	self visit: aCollection first.
-                	inlined := true]].
-
-	(aSelector = '>=') ifTrue: [
-          	(self isNode: anObject ofClass: Number) ifTrue: [
-                  	self visit: anObject.
-                  	stream nextPutAll: ' >= '.
-                	self visit: aCollection first.
-                	inlined := true]].
-                	   
-	"-- UndefinedObject --"
-
-	(aSelector = 'ifNil:') ifTrue: [
-		aCollection first isBlockNode ifTrue: [
-          		stream nextPutAll: '(($receiver = '.
-          		self visit: anObject.
-          		stream nextPutAll: ') == nil || $receiver == undefined) ? '.
-                  	self visit: aCollection first.
-                  	stream nextPutAll: '() : $receiver'.
-                  	inlined := true]].
-
-	(aSelector = 'ifNotNil:') ifTrue: [
-		aCollection first isBlockNode ifTrue: [
-          		stream nextPutAll: '(($receiver = '.
-          		self visit: anObject.
-          		stream nextPutAll: ') !!= nil && $receiver !!= undefined) ? '.
-                  	self visit: aCollection first.
-                  	stream nextPutAll: '() : nil'.
-                  	inlined := true]].
-
-	(aSelector = 'ifNil:ifNotNil:') ifTrue: [
-		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
-          		stream nextPutAll: '(($receiver = '.
-          		self visit: anObject.
-          		stream nextPutAll: ') == nil || $receiver == undefined) ? '.
-                  	self visit: aCollection first.
-                  	stream nextPutAll: '() : '.
-                  	self visit: aCollection second.
-                  	stream nextPutAll: '()'.
-                  	inlined := true]].
-
-	(aSelector = 'ifNotNil:ifNil:') ifTrue: [
-		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
-          		stream nextPutAll: '(($receiver = '.
-          		self visit: anObject.
-          		stream nextPutAll: ') == nil || $receiver == undefined) ? '.
-                  	self visit: aCollection second.
-                  	stream nextPutAll: '() : '.
-                  	self visit: aCollection first.
-                  	stream nextPutAll: '()'.
-                  	inlined := true]].
-                 
-        ^inlined
-!
-
-isNode: aNode ofClass: aClass
-	^aNode isValueNode and: [
-          	aNode value class = aClass or: [
-          		aNode value = 'self' and: [self currentClass = aClass]]]
-! !
-
-!FunCodeGenerator methodsFor: 'testing'!
-
-performOptimizations
-	^self class performOptimizations
-! !
-
-!FunCodeGenerator methodsFor: 'visiting'!
-
-send: aSelector to: aReceiver arguments: aCollection superSend: aBoolean
-	^String streamContents: [:str || tmp |
-        	tmp := stream.
-		str nextPutAll: 'smalltalk.send('.
-		str nextPutAll: aReceiver.
-		str nextPutAll: ', "', aSelector asSelector, '", ['.
-                stream := str.
-		aCollection
-	    		do: [:each | self visit: each]
-	    		separatedBy: [stream nextPutAll: ', '].
-                stream := tmp.
-                str nextPutAll: ']'.
-		aBoolean ifTrue: [
-			str nextPutAll: ', smalltalk.', (self classNameFor: self currentClass), '.superclass || nil'].
-		str nextPutAll: ')']
+inlinedClosure
+	^ IRInlinedClosure new
 !
 
-visit: aNode
-	aNode accept: self
-!
+inlinedSequence
+	^ IRInlinedSequence new
+! !
 
-visitAssignmentNode: aNode
-	stream nextPutAll: '('.
-	self visit: aNode left.
-	stream nextPutAll: '='.
-	self visit: aNode right.
-	stream nextPutAll: ')'
-!
+!IRSendInliner methodsFor: '*Compiler'!
 
-visitBlockNode: aNode
-	stream nextPutAll: '(function('.
-	aNode parameters 
-	    do: [:each |
-		tempVariables add: each.
-		stream nextPutAll: each]
-	    separatedBy: [stream nextPutAll: ', '].
-	stream nextPutAll: '){'.
-	aNode nodes do: [:each | self visit: each].
-	stream nextPutAll: '})'
+ifFalse: anIRInstruction
+	^ self inlinedSend: IRInlinedIfFalse new with: anIRInstruction
 !
 
-visitBlockSequenceNode: aNode
-	| index |
-	nestedBlocks := nestedBlocks + 1.
-	aNode nodes isEmpty
-	    ifTrue: [
-		stream nextPutAll: 'return nil;']
-	    ifFalse: [
-		aNode temps do: [:each | | temp |
-                    temp := self safeVariableNameFor: each.
-		    tempVariables add: temp.
-		    stream nextPutAll: 'var ', temp, '=nil;'; lf].
-		index := 0.
-		aNode nodes do: [:each |
-		    index := index + 1.
-		    index = aNode nodes size ifTrue: [
-			stream nextPutAll: 'return '].
-		    self visit: each.
-		    stream nextPutAll: ';']].
-	nestedBlocks := nestedBlocks - 1
+ifFalse: anIRInstruction ifTrue: anotherIRInstruction
+	^ self perform: #ifTrue:ifFalse: withArguments: { anotherIRInstruction. anIRInstruction }
 !
 
-visitCascadeNode: aNode
-	| index |
-	index := 0.
-	(tempVariables includes: '$rec') ifFalse: [
-		tempVariables add: '$rec'].
-	stream nextPutAll: '(function($rec){'.
-	aNode nodes do: [:each |
-	    index := index + 1.
-	    index = aNode nodes size ifTrue: [
-		stream nextPutAll: 'return '].
-	    each receiver: (VariableNode new value: '$rec').
-	    self visit: each.
-	    stream nextPutAll: ';'].
-	stream nextPutAll: '})('.
-	self visit: aNode receiver.
-	stream nextPutAll: ')'
+ifNil: anIRInstruction
+	^ self 
+		inlinedSend: IRInlinedIfNilIfNotNil new 
+		with: anIRInstruction
+		with: (IRClosure new
+			scope: anIRInstruction scope copy;
+			add: (IRBlockSequence new
+				add: self send instructions first;
+				yourself);
+			yourself)
 !
 
-visitClassReferenceNode: aNode
-	(referencedClasses includes: aNode value) ifFalse: [
-		referencedClasses add: aNode value].
-	stream nextPutAll: '(smalltalk.', aNode value, ' || ', aNode value, ')'
+ifNil: anIRInstruction ifNotNil: anotherIRInstruction
+	^ self inlinedSend: IRInlinedIfNilIfNotNil new with: anIRInstruction with: anotherIRInstruction
 !
 
-visitDynamicArrayNode: aNode
-	stream nextPutAll: '['.
-	aNode nodes 
-		do: [:each | self visit: each]
-		separatedBy: [stream nextPutAll: ','].
-	stream nextPutAll: ']'
+ifNotNil: anIRInstruction
+	^ self 
+		inlinedSend: IRInlinedIfNilIfNotNil new
+		with: (IRClosure new
+			scope: anIRInstruction scope copy;
+			add: (IRBlockSequence new
+				add: self send instructions first;
+				yourself);
+			yourself)
+		with: anIRInstruction
 !
 
-visitDynamicDictionaryNode: aNode
-	stream nextPutAll: 'smalltalk.HashedCollection._fromPairs_(['.
-		aNode nodes 
-			do: [:each | self visit: each]
-			separatedBy: [stream nextPutAll: ','].
-		stream nextPutAll: '])'
+ifNotNil: anIRInstruction ifNil: anotherIRInstruction
+	^ self inlinedSend: IRInlinedIfNilIfNotNil new with: anotherIRInstruction with: anIRInstruction
 !
 
-visitFailure: aFailure
-	self error: aFailure asString
+ifTrue: anIRInstruction
+	^ self inlinedSend: IRInlinedIfTrue new with: anIRInstruction
 !
 
-visitJSStatementNode: aNode
-	stream nextPutAll: aNode source
+ifTrue: anIRInstruction ifFalse: anotherIRInstruction
+	^ self inlinedSend: IRInlinedIfTrueIfFalse new with: anIRInstruction with: anotherIRInstruction
 !
 
-visitMethodNode: aNode
-	| str currentSelector | 
-	currentSelector := aNode selector asSelector.
-	nestedBlocks := 0.
-	earlyReturn := false.
-	messageSends := #().
-	referencedClasses := #().
-	unknownVariables := #().
-	tempVariables := #().
-	argVariables := #().
-	stream 
-	    nextPutAll: 'smalltalk.method({'; lf;
-	    nextPutAll: 'selector: "', aNode selector, '",'; lf.
-	stream nextPutAll: 'source: ', self source asJavascript, ',';lf.
-	stream nextPutAll: 'fn: function('.
-	aNode arguments 
-	    do: [:each | 
-		argVariables add: each.
-		stream nextPutAll: each]
-	    separatedBy: [stream nextPutAll: ', '].
-	stream 
-	    nextPutAll: '){'; lf;
-	    nextPutAll: 'var self=this;'; lf.
-	str := stream.
-	stream := '' writeStream.
-	aNode nodes do: [:each |
-	    self visit: each].
-	earlyReturn ifTrue: [
-	    str nextPutAll: 'var $early={};'; lf; nextPutAll: 'try{'].
-	str nextPutAll: stream contents.
-	stream := str.
-	stream 
-	    lf; 
-	    nextPutAll: 'return self;'.
-	earlyReturn ifTrue: [
-	    stream lf; nextPutAll: '} catch(e) {if(e===$early)return e[0]; throw e}'].
-	stream nextPutAll: '}'.
-	stream 
-		nextPutAll: ',', String lf, 'messageSends: ';
-		nextPutAll: messageSends asJavascript, ','; lf;
-          	nextPutAll: 'args: ', argVariables asJavascript, ','; lf;
-		nextPutAll: 'referencedClasses: ['.
-	referencedClasses 
-		do: [:each | stream nextPutAll: each printString]
-		separatedBy: [stream nextPutAll: ','].
-	stream nextPutAll: ']'.
-	stream nextPutAll: '})'
-!
+inlineClosure: anIRClosure
+	| inlinedClosure sequence statements |
 
-visitReturnNode: aNode
-	nestedBlocks > 0 ifTrue: [
-	    earlyReturn := true].
-	nestedBlocks > 0
-	    ifTrue: [
-		stream
-		    nextPutAll: '(function(){throw $early=[']
-	    ifFalse: [stream nextPutAll: 'return '].
-	aNode nodes do: [:each |
-	    self visit: each].
-	nestedBlocks > 0 ifTrue: [
-	    stream nextPutAll: ']})()']
-!
+	inlinedClosure := self inlinedClosure.
+	inlinedClosure scope: anIRClosure scope.
 
-visitSendNode: aNode
-        | str receiver superSend inlined |
-        str := stream.
-        (messageSends includes: aNode selector) ifFalse: [
-                messageSends add: aNode selector].
-        stream := '' writeStream.
-        self visit: aNode receiver.
-        superSend := stream contents = 'super'.
-        receiver := superSend ifTrue: ['self'] ifFalse: [stream contents].
-        stream := str.
+	"Add the possible temp declarations"
+	anIRClosure instructions do: [ :each | 
+		each isSequence ifFalse: [
+			inlinedClosure add: each ]].
+
+	"Add a block sequence"
+	sequence := self inlinedSequence.
+	inlinedClosure add: sequence.
+
+	"Get all the statements"
+	statements := anIRClosure instructions last instructions.
 	
-	self performOptimizations 
-		ifTrue: [
-			(self inlineLiteral: aNode selector receiverNode: aNode receiver argumentNodes: aNode arguments) ifFalse: [
-				(self inline: aNode selector receiver: receiver argumentNodes: aNode arguments)
-                			ifTrue: [stream nextPutAll: ' : ', (self send: aNode selector to: '$receiver' arguments: aNode arguments superSend: superSend), ')']
-                			ifFalse: [stream nextPutAll: (self send: aNode selector to: receiver arguments: aNode arguments superSend: superSend)]]]
-		ifFalse: [stream nextPutAll: (self send: aNode selector to: receiver arguments: aNode arguments superSend: superSend)]
-!
+	statements ifNotEmpty: [
+		statements allButLast do: [ :each | sequence add: each ].
 
-visitSequenceNode: aNode
-	aNode temps do: [:each || temp |
-            temp := self safeVariableNameFor: each.
-	    tempVariables add: temp.
-	    stream nextPutAll: 'var ', temp, '=nil;'; lf].
-	aNode nodes do: [:each |
-	    self visit: each.
-	    stream nextPutAll: ';']
-	    separatedBy: [stream lf]
+		"Inlined closures don't have implicit local returns"
+		(statements last isReturn and: [ statements last isBlockReturn ])
+			ifTrue: [ sequence add: statements last instructions first ]
+			ifFalse: [ sequence add: statements last ] ].
+
+	^ inlinedClosure
 !
 
-visitValueNode: aNode
-	stream nextPutAll: aNode value asJavascript
+inlineSend: anIRSend
+	self send: anIRSend.
+	^ self 
+		perform: self send selector 
+		withArguments: self send instructions allButFirst
 !
 
-visitVariableNode: aNode
-	| varName |
-	(self currentClass allInstanceVariableNames includes: aNode value) 
-		ifTrue: [stream nextPutAll: 'self[''@', aNode value, ''']']
-		ifFalse: [
-                  	varName := self safeVariableNameFor: aNode value.
-			(self knownVariables includes: varName) 
-                  		ifFalse: [
-                                  	unknownVariables add: aNode value.
-                                  	aNode assigned 
-                                  		ifTrue: [stream nextPutAll: varName]
-                                  		ifFalse: [stream nextPutAll: '(typeof ', varName, ' == ''undefined'' ? nil : ', varName, ')']]
-                  		ifTrue: [
-                                  	aNode value = 'thisContext'
-                                  		ifTrue: [stream nextPutAll: '(smalltalk.getThisContext())']
-                				ifFalse: [stream nextPutAll: varName]]]
-! !
+inlinedSend: inlinedSend with: anIRInstruction
+	| inlinedClosure |
 
-FunCodeGenerator class instanceVariableNames: 'performOptimizations'!
+	anIRInstruction isClosure ifFalse: [ self inliningError: 'Message argument should be a block' ].
+	anIRInstruction arguments size = 0 ifFalse: [ self inliningError: 'Inlined block should have zero argument' ].
 
-!FunCodeGenerator class methodsFor: 'accessing'!
+	inlinedClosure := self translator visit: (self inlineClosure: anIRInstruction).
 
-performOptimizations
-	^performOptimizations ifNil: [true]
+	inlinedSend
+		add: self send instructions first;
+		add: inlinedClosure.
+
+	self send replaceWith: inlinedSend.
+
+	^ inlinedSend
 !
 
-performOptimizations: aBoolean
-	performOptimizations := aBoolean
-! !
+inlinedSend: inlinedSend with: anIRInstruction with: anotherIRInstruction
+	| inlinedClosure1 inlinedClosure2 |
 
-AbstractCodeGenerator subclass: #ImpCodeGenerator
-	instanceVariableNames: 'stream nestedBlocks earlyReturn currentSelector unknownVariables tempVariables messageSends referencedClasses classReferenced argVariables mutables target lazyVars realVarNames'
-	package: 'Compiler'!
+	anIRInstruction isClosure ifFalse: [ self inliningError: 'Message argument should be a block' ].
+	anIRInstruction arguments size = 0 ifFalse: [ self inliningError: 'Inlined block should have zero argument' ].
 
-!ImpCodeGenerator methodsFor: 'accessing'!
+	anotherIRInstruction isClosure ifFalse: [ self inliningError: 'Message argument should be a block' ].
+	anotherIRInstruction arguments size = 0 ifFalse: [ self inliningError: 'Inlined block should have zero argument' ].
 
-argVariables
-	^argVariables copy
-!
+	inlinedClosure1 := self translator visit: (self inlineClosure: anIRInstruction).
+	inlinedClosure2 := self translator visit: (self inlineClosure: anotherIRInstruction).
 
-knownVariables
-	^self pseudoVariables 
-		addAll: self tempVariables;
-		addAll: self argVariables;
-		yourself
-!
 
-tempVariables
-	^tempVariables copy
-!
+	inlinedSend
+		add: self send instructions first;
+		add: inlinedClosure1;
+		add: inlinedClosure2.
 
-unknownVariables
-	^unknownVariables copy
+	self send replaceWith: inlinedSend.
+	^ inlinedSend
 ! !
 
-!ImpCodeGenerator methodsFor: 'compilation DSL'!
+!IRSendInliner class methodsFor: '*Compiler'!
 
-aboutToModifyState
-| list old |
-	list := mutables.
-	mutables := Set new.
-	old := self switchTarget: nil.
-	list do: [ :each | | value |
-		self switchTarget: each.
-		self realAssign: (lazyVars at: each)
-	].
-	self switchTarget: old
+inlinedSelectors
+	^ #('ifTrue:' 'ifFalse:' 'ifTrue:ifFalse:' 'ifFalse:ifTrue:' 'ifNil:' 'ifNotNil:' 'ifNil:ifNotNil:' 'ifNotNil:ifNil')
 !
 
-ifValueWanted: aBlock
-	target ifNotNil: aBlock
-!
+shouldInline: anIRInstruction
+	(self inlinedSelectors includes: anIRInstruction selector) ifFalse: [ ^ false ].
+	anIRInstruction instructions allButFirst do: [ :each |
+		each isClosure ifFalse: [ ^ false ]].
+	^ true
+! !
 
-isolated: node
- 	^ self visit: node targetBeing: self nextLazyvarName
-!
+IRSendInliner subclass: #IRAssignmentInliner
+	instanceVariableNames: 'assignment'
+	package:'Compiler'!
+!IRAssignmentInliner commentStamp!
+I inline message sends together with assignments by moving them around into the inline closure instructions. 
 
-isolatedUse: node
-| old |
-	old := self switchTarget: self nextLazyvarName.
-	self visit: node.
-	^self useValueNamed: (self switchTarget: old)
-!
+##Example
 
-lazyAssign: aString dependsOnState: aBoolean
-	(lazyVars includesKey: target)
-		ifTrue: [ lazyVars at: target put: aString. aBoolean ifTrue: [ mutables add: target ] ]
-		ifFalse: [ self realAssign: aString ]
-!
+	foo
+		| a |
+		a := true ifTrue: [ 1 ]
 
-lazyAssignExpression: aString
-	self lazyAssign: aString dependsOnState: true
-!
+Will produce:
 
-lazyAssignValue: aString
-	self lazyAssign: aString dependsOnState: false
-!
+	if(smalltalk.assert(true) {
+		a = 1;
+	};!
 
-makeTargetRealVariable
-	(lazyVars includesKey: target) ifTrue: [
-		lazyVars removeKey: target.
-		lazyVars at: 'assigned ',target put: nil. "<-- only to retain size, it is used in nextLazyvarName"
-		realVarNames add: target ].
-!
+!IRAssignmentInliner methodsFor: '*Compiler'!
 
-nextLazyvarName
-	| name |
-	name := '$', lazyVars size asString.
-	lazyVars at: name put: name.
-	^name
+assignment
+	^ assignment
 !
 
-nilIfValueWanted
-	target ifNotNil: [ self lazyAssignValue: 'nil' ]
-!
+assignment: aNode
+	assignment := aNode
+! !
 
-realAssign: aString
-	| closer |
-	aString ifNotEmpty: [
-		self aboutToModifyState.
-		closer := ''.
-		self ifValueWanted: [ stream nextPutAll:
-			(target = '^' ifTrue: ['return '] ifFalse: [
-				target = '!!' ifTrue: [ closer := ']'. 'throw $early=['] ifFalse: [
-					target, '=']]) ].
-		self makeTargetRealVariable.
-		stream nextPutAll: aString, closer, ';', self mylf ]
-!
+!IRAssignmentInliner methodsFor: '*Compiler'!
 
-switchTarget: aString
-	| old |
-	old := target.
-	target := aString.
-	^old
+inlineAssignment: anIRAssignment
+	| inlinedAssignment |
+	self assignment: anIRAssignment.
+	inlinedAssignment := IRInlinedAssignment new.
+	anIRAssignment instructions do: [ :each |
+		inlinedAssignment add: each ].
+	anIRAssignment replaceWith: inlinedAssignment.
+	self inlineSend: inlinedAssignment instructions last.
+	^ inlinedAssignment
 !
 
-useValueNamed: key
-	| val |
-	(realVarNames includes: key) ifTrue: [ ^key ].
-	mutables remove: key.
-	^lazyVars at: key
-!
+inlineClosure: anIRClosure
+	| inlinedClosure statements |
+
+	inlinedClosure := super inlineClosure: anIRClosure.
+	statements := inlinedClosure instructions last instructions.
+	
+	statements ifNotEmpty: [
+		statements last canBeAssigned ifTrue: [
+			statements last replaceWith: (IRAssignment new
+				add: self assignment instructions first;
+				add: statements last copy;
+				yourself) ] ].
 
-visit: aNode targetBeing: aString
-| old |
-	old := self switchTarget: aString.
-	self visit: aNode.
-	^ self switchTarget: old.
+	^ inlinedClosure
 ! !
 
-!ImpCodeGenerator methodsFor: 'compiling'!
+IRSendInliner subclass: #IRNonLocalReturnInliner
+	instanceVariableNames: ''
+	package:'Compiler'!
+
+!IRNonLocalReturnInliner methodsFor: '*Compiler'!
 
-compileNode: aNode
-	stream := '' writeStream.
-	self visit: aNode.
-	^stream contents
+inlinedReturn
+	^ IRInlinedNonLocalReturn new
 ! !
 
-!ImpCodeGenerator methodsFor: 'initialization'!
+!IRNonLocalReturnInliner methodsFor: '*Compiler'!
 
-initialize
-	super initialize.
-	stream := '' writeStream. 
-	unknownVariables := #().
-	tempVariables := #().
-	argVariables := #().
-	messageSends := #().
-	classReferenced := #().
-	mutables := Set new.
-	realVarNames := Set new.
-	lazyVars := HashedCollection new.
-	target := nil
-! !
-
-!ImpCodeGenerator methodsFor: 'optimizations'!
-
-checkClass: aClassName for: receiver
-	self prvCheckClass: aClassName for: receiver.
-	stream nextPutAll: '{'
-!
-
-checkClass: aClassName for: receiver includeIf: aBoolean
-	self prvCheckClass: aClassName for: receiver.
-	stream nextPutAll: (aBoolean ifTrue: ['if(('] ifFalse: ['if(!!(']), (self useValueNamed: receiver), ')) {'
-!
-
-inline: aSelector receiver: receiver argumentNodes: aCollection
-
-	"-- Booleans --"
-
-	(aSelector = 'ifFalse:') ifTrue: [
-		aCollection first isBlockNode ifTrue: [
-			self checkClass: 'Boolean' for: receiver includeIf: false.
-			self prvPutAndElse: [ self visit: aCollection first nodes first ].
-			self prvPutAndElse: [ self nilIfValueWanted ].
-			^true]].
-
-	(aSelector = 'ifTrue:') ifTrue: [
-		aCollection first isBlockNode ifTrue: [
-			self checkClass: 'Boolean' for: receiver includeIf: true.
-			self prvPutAndElse: [ self visit: aCollection first nodes first ].
-			self prvPutAndElse: [ self nilIfValueWanted ].
-			^true]].
-
-	(aSelector = 'ifTrue:ifFalse:') ifTrue: [
-		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
-			self checkClass: 'Boolean' for: receiver includeIf: true.
-			self prvPutAndElse: [ self visit: aCollection first nodes first ].
-			self prvPutAndElse: [ self visit: aCollection second nodes first ].
-			^true]].
-
-	(aSelector = 'ifFalse:ifTrue:') ifTrue: [
-		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
-			self checkClass: 'Boolean' for: receiver includeIf: false.
-			self prvPutAndElse: [ self visit: aCollection first nodes first ].
-			self prvPutAndElse: [ self visit: aCollection second nodes first ].
-			^true]].
-
-	"-- Numbers --"
-
-	(aSelector = '<') ifTrue: [ | operand |
-		operand := self isolatedUse: aCollection first.
-		self checkClass: 'Number' for: receiver.
-		self prvPutAndElse: [
-			self lazyAssignExpression: '(', (self useValueNamed: receiver), '<', operand, ')' ].
-		^{ VerbatimNode new value: operand }].
-
-	(aSelector = '<=') ifTrue: [ | operand |
-		operand := self isolatedUse: aCollection first.
-		self checkClass: 'Number' for: receiver.
-		self prvPutAndElse: [
-			self lazyAssignExpression: '(', (self useValueNamed: receiver), '<=', operand, ')' ].
-		^{ VerbatimNode new value: operand }].
-
-	(aSelector = '>') ifTrue: [ | operand |
-		operand := self isolatedUse: aCollection first.
-		self checkClass: 'Number' for: receiver.
-		self prvPutAndElse: [
-			self lazyAssignExpression: '(', (self useValueNamed: receiver), '>', operand, ')' ].
-		^{ VerbatimNode new value: operand }].
-
-	(aSelector = '>=') ifTrue: [ | operand |
-		operand := self isolatedUse: aCollection first.
-		self checkClass: 'Number' for: receiver.
-		self prvPutAndElse: [
-			self lazyAssignExpression: '(', (self useValueNamed: receiver), '>=', operand, ')' ].
-		^{ VerbatimNode new value: operand }].
-
-        (aSelector = '+') ifTrue: [ | operand |
-		operand := self isolatedUse: aCollection first.
-		self checkClass: 'Number' for: receiver.
-		self prvPutAndElse: [
-			self lazyAssignExpression: '(', (self useValueNamed: receiver), '+', operand, ')' ].
-		^{ VerbatimNode new value: operand }].
-
-        (aSelector = '-') ifTrue: [ | operand |
-		operand := self isolatedUse: aCollection first.
-		self checkClass: 'Number' for: receiver.
-		self prvPutAndElse: [
-			self lazyAssignExpression: '(', (self useValueNamed: receiver), '-', operand, ')' ].
-		^{ VerbatimNode new value: operand }].
-
-        (aSelector = '*') ifTrue: [ | operand |
-		operand := self isolatedUse: aCollection first.
-		self checkClass: 'Number' for: receiver.
-		self prvPutAndElse: [
-			self lazyAssignExpression: '(', (self useValueNamed: receiver), '*', operand, ')' ].
-		^{ VerbatimNode new value: operand }].
-
-        (aSelector = '/') ifTrue: [ | operand |
-		operand := self isolatedUse: aCollection first.
-		self checkClass: 'Number' for: receiver.
-		self prvPutAndElse: [
-			self lazyAssignExpression: '(', (self useValueNamed: receiver), '/', operand, ')' ].
-		^{ VerbatimNode new value: operand }].
-
-        ^nil
-!
-
-inlineLiteral: aSelector receiverNode: anObject argumentNodes: aCollection
-        | inlined |
-        inlined := false.
- 
-	"-- BlockClosures --"
-
-	(aSelector = 'whileTrue:') ifTrue: [
-          	(anObject isBlockNode and: [aCollection first isBlockNode]) ifTrue: [ | old |
-			self prvWhileConditionStatement: 'for(;;){' pre: 'if (!!(' condition: anObject post: ')) {'.
-			stream nextPutAll: 'break}', self mylf.
-			self prvPutAndClose: [ self visit: aCollection first nodes first targetBeing: nil ].
-			inlined := true]].
-
-	(aSelector = 'whileFalse:') ifTrue: [
-          	(anObject isBlockNode and: [aCollection first isBlockNode]) ifTrue: [ | old |
-			self prvWhileConditionStatement: 'for(;;){' pre: 'if ((' condition: anObject post: ')) {'.
-			stream nextPutAll: 'break}', self mylf.
-			self prvPutAndClose: [ self visit: aCollection first nodes first targetBeing: nil ].
-			inlined := true]].
-
-	(aSelector = 'whileTrue') ifTrue: [
-          	anObject isBlockNode ifTrue: [
-			self prvWhileConditionStatement: 'do{' pre: '}while((' condition: anObject post: '));', self mylf.
-			inlined := true]].
-
-	(aSelector = 'whileFalse') ifTrue: [
-          	anObject isBlockNode ifTrue: [
-			self prvWhileConditionStatement: 'do{' pre: '}while(!!(' condition: anObject post: '));', self mylf.
-			inlined := true]].
-
-	"-- Numbers --"
-
-	(#('+' '-' '*' '/' '<' '<=' '>=' '>') includes: aSelector) ifTrue: [
-		(self prvInlineNumberOperator: aSelector on: anObject and: aCollection first) ifTrue: [
-			inlined := true]].
-                	   
-	"-- UndefinedObject --"
-
-	(aSelector = 'ifNil:') ifTrue: [
-		aCollection first isBlockNode ifTrue: [ | rcv |
-			self aboutToModifyState.
-			rcv := self isolatedUse: anObject.
-			rcv = 'super' ifTrue: [ rcv := 'self' ].
-			self makeTargetRealVariable.
-			stream nextPutAll: 'if((', rcv, ') === nil || (', rcv, ') == null) {'.
-			self prvPutAndElse: [ self visit: aCollection first nodes first ].
-			self prvPutAndClose: [ self lazyAssignValue: rcv ].
-			inlined := true]].
-
-	(aSelector = 'ifNotNil:') ifTrue: [
-		aCollection first isBlockNode ifTrue: [ | rcv |
-			self aboutToModifyState.
-			rcv := self isolatedUse: anObject.
-			rcv = 'super' ifTrue: [ rcv := 'self' ].
-			self makeTargetRealVariable.
-			stream nextPutAll: 'if((', rcv, ') !!== nil && (', rcv, ') !!= null) {'.
-			self prvPutAndElse: [ self visit: aCollection first nodes first ].
-			self prvPutAndClose: [ self lazyAssignValue: rcv ].
-			inlined := true]].
-
-	(aSelector = 'ifNil:ifNotNil:') ifTrue: [
-		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [ | rcv |
-			self aboutToModifyState.
-			rcv := self isolatedUse: anObject.
-			rcv = 'super' ifTrue: [ rcv := 'self' ].
-			self makeTargetRealVariable.
-			stream nextPutAll: 'if((', rcv, ') === nil || (', rcv, ') == null) {'.
-			self prvPutAndElse: [ self visit: aCollection first nodes first ].
-			self prvPutAndClose: [ self visit: aCollection second nodes first ].
-			inlined := true]].
-
-	(aSelector = 'ifNotNil:ifNil:') ifTrue: [
-		(aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [ | rcv |
-			self aboutToModifyState.
-			rcv := self isolatedUse: anObject.
-			rcv = 'super' ifTrue: [ rcv := 'self' ].
-			self makeTargetRealVariable.
-			stream nextPutAll: 'if((', rcv, ') !!== nil && (', rcv, ') !!= null) {'.
-			self prvPutAndElse: [ self visit: aCollection first nodes first ].
-			self prvPutAndClose: [ self visit: aCollection second nodes first ].
-			inlined := true]].
-
-	(aSelector = 'isNil') ifTrue: [ | rcv |
-		rcv := self isolatedUse: anObject.
-		rcv = 'super' ifTrue: [ rcv := 'self' ].
-		self lazyAssignValue: '((', rcv, ') === nil || (', rcv, ') == null)'.
-		inlined := true].
-
-	(aSelector = 'notNil') ifTrue: [ | rcv |
-		rcv := self isolatedUse: anObject.
-		rcv = 'super' ifTrue: [ rcv := 'self' ].
-		self lazyAssignValue: '((', rcv, ') !!== nil && (', rcv, ') !!= null)'.
-		inlined := true].
-
-        ^inlined
-!
-
-isNode: aNode ofClass: aClass
-	^aNode isValueNode and: [
-          	aNode value class = aClass or: [
-          		aNode value = 'self' and: [self currentClass = aClass]]]
-!
-
-prvCheckClass: aClassName for: receiver
-	self makeTargetRealVariable.
-	self aboutToModifyState.
-        stream nextPutAll: 'if((', (self useValueNamed: receiver), ').klass === smalltalk.', aClassName, ') '
-!
-
-prvInlineNumberOperator: aSelector on: receiverNode and: operandNode
-	(aSelector = aSelector) ifTrue: [
-		(self isNode: receiverNode ofClass: Number) ifTrue: [
-			| rcv operand |
-			rcv := self isolated: receiverNode.
-			operand := self isolated: operandNode.
-			self lazyAssignValue: ((self useValueNamed: rcv), aSelector, (self useValueNamed: operand)).
-			^true]].
-	^false
-!
+inlineClosure: anIRClosure
+	"| inlinedClosure statements |
+
+	inlinedClosure := super inlineClosure: anIRClosure.
+	statements := inlinedClosure instructions last instructions.
+	
+	statements ifNotEmpty: [
+		statements last replaceWith: (IRNonLocalReturn new
+			add: statements last copy;
+			yourself) ].
+
+	^ inlinedClosure"
 
-prvWhileConditionStatement: stmtString pre: preString condition: anObject post: postString
-	| x |
-	stream nextPutAll: stmtString.
-	x := self isolatedUse: anObject nodes first.
-	x ifEmpty: [ x := '"should not reach - receiver includes ^"' ].
-	stream nextPutAll: preString, x, postString.
-	self nilIfValueWanted
+	^ super inlineCLosure: anIRClosure
 ! !
 
-!ImpCodeGenerator methodsFor: 'output'!
+IRSendInliner subclass: #IRReturnInliner
+	instanceVariableNames: ''
+	package:'Compiler'!
+!IRReturnInliner commentStamp!
+I inline message sends with inlined closure together with a return instruction.!
 
-mylf
-	^String lf, ((Array new: nestedBlocks+2)  join: String tab)
-!
+!IRReturnInliner methodsFor: '*Compiler'!
 
-prvPutAndClose: aBlock
+inlinedReturn
+	^ IRInlinedReturn new
+! !
 
-	aBlock value.
-	stream nextPutAll: '}', self mylf
-!
+!IRReturnInliner methodsFor: '*Compiler'!
 
-prvPutAndElse: aBlock
+inlineClosure: anIRClosure
+	| closure statements |
 
-	aBlock value.
-	stream nextPutAll: '} else {'
+	closure := super inlineClosure: anIRClosure.
+	statements := closure instructions last instructions.
+	
+	statements ifNotEmpty: [
+		statements last isReturn
+			ifFalse: [ statements last replaceWith: (IRReturn new
+				add: statements last copy;
+				yourself)] ].
+
+	^ closure
 !
 
-putTemps: temps
-    temps ifNotEmpty: [
-	stream nextPutAll: 'var '.
-	temps do: [:each | | temp |
-            temp := self safeVariableNameFor: each.
-	    tempVariables add: temp.
-	    stream nextPutAll: temp, '=nil'] separatedBy: [ stream nextPutAll: ',' ].
-	stream nextPutAll: ';', self mylf
-    ]
+inlineReturn: anIRReturn
+	| return |
+	return := self inlinedReturn.
+	anIRReturn instructions do: [ :each |
+		return add: each ].
+	anIRReturn replaceWith: return.
+	self inlineSend: return instructions last.
+	^ return
 ! !
 
-!ImpCodeGenerator methodsFor: 'testing'!
+CodeGenerator subclass: #InliningCodeGenerator
+	instanceVariableNames: ''
+	package:'Compiler'!
+!InliningCodeGenerator commentStamp!
+I am a specialized code generator that uses inlining to produce more optimized JavaScript output!
 
-assert: aBoolean
-	aBoolean ifFalse: [ self error: 'assertion failed' ]
-!
+!InliningCodeGenerator methodsFor: '*Compiler'!
 
-performOptimizations
-	^self class performOptimizations
-! !
+compileNode: aNode
+	| ir stream |
 
-!ImpCodeGenerator methodsFor: 'visiting'!
+	self semanticAnalyzer visit: aNode.
+	ir := self translator visit: aNode.
+	self inliner visit: ir.
 
-send: aSelector to: aReceiver arguments: aCollection superSend: aBoolean
-	| args |
-	args := self isolated: (DynamicArrayNode new nodes: aCollection; yourself).
-	self lazyAssignExpression: (String streamContents: [ :str |
-		str nextPutAll: 'smalltalk.send('.
-		str nextPutAll: (self useValueNamed: aReceiver).
-		str nextPutAll: ', "', aSelector asSelector, '", '.
-		str nextPutAll: (self useValueNamed: args).
-		aBoolean ifTrue: [
-			str nextPutAll: ', smalltalk.', (self classNameFor: self currentClass superclass)].
-		str nextPutAll: ')'
-	])
+	^ self irTranslator
+		visit: ir;
+		contents
 !
 
-sequenceOfNodes: nodes temps: temps
-	nodes isEmpty
-		ifFalse: [ | old index |
-			self putTemps: temps.
-			old :=self switchTarget: nil.
-			index := 0.
-			nodes do: [:each |
-				index := index + 1.
-				index = nodes size ifTrue: [ self switchTarget: old ].
-			self visit: each ]]
-		ifTrue: [ self nilIfValueWanted ]
+inliner
+	^ IRInliner new
 !
 
-visit: aNode
-	aNode accept: self
-!
+irTranslator
+	^ IRInliningJSTranslator new
+! !
 
-visitAssignmentNode: aNode
-| olds oldt |
-	olds := stream.
-	stream := '' writeStream.
-	oldt := self switchTarget: self nextLazyvarName.
-	self visit: aNode left.
-	self assert: (lazyVars at: target) ~= target.
-	self switchTarget: (self useValueNamed: (self switchTarget: nil)).
-	self assert: (lazyVars includesKey: target) not.
-	stream := olds.
-	self visit: aNode right.
-	olds := self switchTarget: oldt.
-	self ifValueWanted: [ self lazyAssignExpression: olds ]
-!
+NodeVisitor subclass: #AIContext
+	instanceVariableNames: 'outerContext pc locals receiver selector'
+	package:'Compiler'!
 
-visitBlockNode: aNode
-| oldt olds oldm |
-	self assert: aNode nodes size = 1.
-	oldt := self switchTarget: '^'.
-	olds := stream.
-	stream := '' writeStream.
-	stream nextPutAll: '(function('.
-	aNode parameters 
-	    do: [:each |
-		tempVariables add: each.
-		stream nextPutAll: each]
-	    separatedBy: [stream nextPutAll: ', '].
-	stream nextPutAll: '){'.
-	nestedBlocks := nestedBlocks + 1.
-	oldm := mutables.
-	mutables := Set new.
-	self visit: aNode nodes first.
-	self assert: mutables isEmpty.
-	mutables := oldm.
-	nestedBlocks := nestedBlocks - 1.
-	stream nextPutAll: '})'.
-	self switchTarget: oldt.
-	oldt := stream contents.
-	stream := olds.
-	self lazyAssignExpression: oldt
-!
+!AIContext methodsFor: '*Compiler'!
 
-visitBlockSequenceNode: aNode
-	self sequenceOfNodes: aNode nodes temps: aNode temps
+initializeFromMethodContext: aMethodContext
+	self pc: aMethodContext pc.
+    self receiver: aMethodContext receiver.
+    self selector: aMethodContext selector.
+    aMethodContext outerContext ifNotNil: [
+		self outerContext: (self class fromMethodContext: aMethodContext outerContext) ].
+    aMethodContext locals keysAndValuesDo: [ :key :value |
+    	self locals at: key put: value ]
 !
 
-visitCascadeNode: aNode
-	| rcv |
-	rcv := self isolated: aNode receiver.
-	self aboutToModifyState.
-	rcv := self useValueNamed: rcv.
-	aNode nodes do: [:each |
-		each receiver: (VerbatimNode new value: rcv) ].
-	self sequenceOfNodes: aNode nodes temps: #()
+locals
+	^ locals ifNil: [ locals := Dictionary new ]
 !
 
-visitClassReferenceNode: aNode
-	(referencedClasses includes: aNode value) ifFalse: [
-		referencedClasses add: aNode value].
-	self lazyAssignExpression: '(smalltalk.', aNode value, ' || ', aNode value, ')'
+outerContext
+	^ outerContext
 !
 
-visitDynamicArrayNode: aNode
-	| args |
-	args :=aNode nodes collect: [ :node | self isolated: node ].
-	self lazyAssignValue: (String streamContents: [ :str |
-		str nextPutAll: '['.
-		args
-	    		do: [:each | str nextPutAll: (self useValueNamed: each) ]
-	    		separatedBy: [str nextPutAll: ', '].
-                str nextPutAll: ']'
-	])
+outerContext: anAIContext
+	outerContext := anAIContext
 !
 
-visitDynamicDictionaryNode: aNode
-	| elements |
-	elements := self isolated: (DynamicArrayNode new nodes: aNode nodes; yourself).
-	self lazyAssignValue: 'smalltalk.HashedCollection._fromPairs_(', (self useValueNamed: elements), ')'
+pc
+	^ pc ifNil: [ pc := 0 ]
 !
 
-visitFailure: aFailure
-	self error: aFailure asString
+pc: anInteger
+	pc := anInteger
 !
 
-visitJSStatementNode: aNode
-	self aboutToModifyState.
-	stream nextPutAll: ';', (aNode source replace: '>>' with: '>'), ';', self mylf
+receiver
+	^ receiver
 !
 
-visitMethodNode: aNode
-	| str currentSelector | 
-	currentSelector := aNode selector asSelector.
-	nestedBlocks := 0.
-	earlyReturn := false.
-	messageSends := #().
-	referencedClasses := #().
-	unknownVariables := #().
-	tempVariables := #().
-	argVariables := #().
-	lazyVars := HashedCollection new.
-	mutables := Set new.
-	realVarNames := Set new.
-	stream 
-	    nextPutAll: 'smalltalk.method({'; lf;
-	    nextPutAll: 'selector: "', aNode selector, '",'; lf.
-	stream nextPutAll: 'source: ', self source asJavascript, ',';lf.
-	stream nextPutAll: 'fn: function('.
-	aNode arguments 
-	    do: [:each | 
-		argVariables add: each.
-		stream nextPutAll: each]
-	    separatedBy: [stream nextPutAll: ', '].
-	stream 
-	    nextPutAll: '){var self=this;', self mylf.
-	str := stream.
-	stream := '' writeStream.
-	self switchTarget: nil.
-	self assert: aNode nodes size = 1.
-	self visit: aNode nodes first.
-	realVarNames ifNotEmpty: [ str nextPutAll: 'var ', (realVarNames asArray join: ','), ';', self mylf ].
-	earlyReturn ifTrue: [
-	    str nextPutAll: 'var $early={}; try{', self mylf].
-	str nextPutAll: stream contents.
-	stream := str.
-	(aNode nodes first nodes notEmpty and: [ |checker|
-	    checker := ReturnNodeChecker new.
-	    checker visit: aNode nodes first nodes last.
-	    checker wasReturnNode]) ifFalse: [ self switchTarget: '^'. self lazyAssignValue: 'self'. self switchTarget: nil ].
-	earlyReturn ifTrue: [
-	    stream nextPutAll: '} catch(e) {if(e===$early) return e[0]; throw e}'].
-	stream nextPutAll: '}'.
-	stream 
-		nextPutAll: ',', String lf, 'messageSends: ';
-		nextPutAll: messageSends asJavascript, ','; lf;
-          	nextPutAll: 'args: ', argVariables asJavascript, ','; lf;
-		nextPutAll: 'referencedClasses: ['.
-	referencedClasses 
-		do: [:each | stream nextPutAll: each printString]
-		separatedBy: [stream nextPutAll: ','].
-	stream nextPutAll: ']'.
-	stream nextPutAll: '})'.
-	self assert: mutables isEmpty
+receiver: anObject
+	receiver := anObject
 !
 
-visitReturnNode: aNode
-	self assert: aNode nodes size = 1.
-	nestedBlocks > 0 ifTrue: [
-	    earlyReturn := true].
-	self
-		visit: aNode nodes first
-		targetBeing: (nestedBlocks > 0 ifTrue: ['!!'] ifFalse: ['^']).
-	self lazyAssignValue: ''
+selector
+	^ selector
 !
 
-visitSendNode: aNode
-        | receiver superSend rcv |
-        (messageSends includes: aNode selector) ifFalse: [
-                messageSends add: aNode selector].
-	
-	self performOptimizations 
-		ifTrue: [
-			(self inlineLiteral: aNode selector receiverNode: aNode receiver argumentNodes: aNode arguments) ifTrue: [ ^self ].
-		].
+selector: aString
+	selector := aString
+! !
 
-	rcv := self isolated: aNode receiver.
-        superSend := (lazyVars at: rcv ifAbsent: []) = 'super'.
-        superSend ifTrue: [ mutables remove: rcv. lazyVars at: rcv put: 'self' ].
+!AIContext class methodsFor: '*Compiler'!
 
-	self performOptimizations 
-		ifTrue: [ | inline |
-			inline := self inline: aNode selector receiver: rcv argumentNodes: aNode arguments.
-			inline ifNotNil: [ | args |
-				args := inline = true ifTrue: [ aNode arguments ] ifFalse: [ inline ].
-				self prvPutAndClose: [ self send: aNode selector to: rcv arguments: args superSend: superSend ].
-				^self ]].
-	self send: aNode selector to: rcv arguments: aNode arguments superSend: superSend
-!
+fromMethodContext: aMethodContext
+	^ self new 
+    	initializeFromMethodContext: aMethodContext;
+        yourself
+! !
 
-visitSequenceNode: aNode
-	aNode nodes isEmpty ifFalse: [
-		self sequenceOfNodes: aNode nodes temps: aNode temps ]
-!
+NodeVisitor subclass: #ASTInterpreter
+	instanceVariableNames: 'currentNode context shouldReturn'
+	package:'Compiler'!
 
-visitValueNode: aNode
-	self lazyAssignValue: aNode value asJavascript
-!
+!ASTInterpreter methodsFor: '*Compiler'!
 
-visitVariableNode: aNode
-	| varName |
-	(self currentClass allInstanceVariableNames includes: aNode value) 
-		ifTrue: [self lazyAssignExpression: 'self[''@', aNode value, ''']']
-		ifFalse: [
-                  	varName := self safeVariableNameFor: aNode value.
-			(self knownVariables includes: varName) 
-                  		ifFalse: [
-                                  	unknownVariables add: aNode value.
-                                  	aNode assigned 
-                                  		ifTrue: [self lazyAssignExpression: varName]
-                                  		ifFalse: [self lazyAssignExpression: '(typeof ', varName, ' == ''undefined'' ? nil : ', varName, ')']]
-                  		ifTrue: [
-                                  	aNode value = 'thisContext'
-                                  		ifTrue: [self lazyAssignExpression: '(smalltalk.getThisContext())']
-                				ifFalse: [(self pseudoVariables includes: varName)
-							ifTrue: [ self lazyAssignValue: varName ]
-							ifFalse: [ self lazyAssignExpression: varName]]]]
+context
+	^ context
 !
 
-visitVerbatimNode: aNode
-	self lazyAssignValue: aNode value
+context: anAIContext
+	context := anAIContext
+! !
+
+!ASTInterpreter methodsFor: '*Compiler'!
+
+initialize
+	super initialize.
+    shouldReturn := false
 ! !
 
-ImpCodeGenerator class instanceVariableNames: 'performOptimizations'!
+!ASTInterpreter methodsFor: '*Compiler'!
 
-!ImpCodeGenerator class methodsFor: 'accessing'!
+interpret: aNode
+	shouldReturn := false.
+    ^ self interpretNode: aNode
+!
 
-performOptimizations
-	^performOptimizations ifNil: [true]
+interpretNode: aNode
+	currentNode := aNode.
+    ^ self visit: aNode
 !
 
-performOptimizations: aBoolean
-	performOptimizations := aBoolean
+messageFromSendNode: aSendNode
+	^ Message new
+    	selector: aSendNode selector;
+        arguments: (aSendNode arguments collect: [ :each |
+        	self interpretNode: each ]);
+        yourself
 ! !
 
-NodeVisitor subclass: #ReturnNodeChecker
-	instanceVariableNames: 'wasReturnNode'
-	package: 'Compiler'!
+!ASTInterpreter methodsFor: '*Compiler'!
 
-!ReturnNodeChecker methodsFor: 'accessing'!
+visitBlockNode: aNode
+    ^ [ self interpretNode: aNode nodes first ]
+!
 
-wasReturnNode
-	^wasReturnNode
-! !
+visitCascadeNode: aNode
+	"TODO: Handle super sends"
+	| receiver |
+    
+    receiver := self interpretNode: aNode receiver.
 
-!ReturnNodeChecker methodsFor: 'initializing'!
+    aNode nodes allButLast
+    	do: [ :each | 
+        	(self messageFromSendNode: each)
+            	sendTo: receiver ].
 
-initialize
-	wasReturnNode := false
-! !
+    ^ (self messageFromSendNode: aNode nodes last)
+            	sendTo: receiver
+!
+
+visitClassReferenceNode: aNode
+	^ Smalltalk current at: aNode value
+!
 
-!ReturnNodeChecker methodsFor: 'visiting'!
+visitJSStatementNode: aNode
+	self halt
+!
 
 visitReturnNode: aNode
-	wasReturnNode := true
+	shouldReturn := true.
+    ^ self interpretNode: aNode nodes first
+!
+
+visitSendNode: aNode
+	"TODO: Handle super sends"
+    
+    ^ (self messageFromSendNode: aNode)
+    	sendTo: (self interpretNode: aNode receiver)
+!
+
+visitSequenceNode: aNode
+	aNode nodes allButLast do: [ :each | | value |
+        value := self interpretNode: each.
+		shouldReturn ifTrue: [ ^ value ] ].
+    ^ self interpretNode: aNode nodes last
+!
+
+visitValueNode: aNode
+	^ aNode value
 ! !
 

+ 31 - 46
st/IDE.st

@@ -156,10 +156,10 @@ ErrorHandler subclass: #DebugErrorHandler
 !DebugErrorHandler methodsFor: 'error handling'!
 
 handleError: anError
-	[Debugger new
+	[ Debugger new
 		error: anError;
-		open] on: Error do: [:error |
-			ErrorHandler new handleError: error]
+		open ] on: Error do: [ :error |
+			ErrorHandler new handleError: error ]
 ! !
 
 !DebugErrorHandler class methodsFor: 'initialization'!
@@ -1311,10 +1311,17 @@ TabWidget subclass: #Debugger
 
 !Debugger methodsFor: 'accessing'!
 
-arguments
-	^self method 
-		ifNil: [selectedContext temps collect: [:each | nil]]
-		ifNotNil: [self method arguments]
+allVariables
+	| all |
+	all := Dictionary new.
+
+	self receiver class allInstanceVariableNames do: [:each |
+		all at: each put: (self receiver instVarAt: each) ].
+    
+    selectedContext locals keysAndValuesDo: [ :key :value |
+    	all at: key put: value ].
+    
+    ^ all
 !
 
 error
@@ -1330,7 +1337,7 @@ label
 !
 
 method
-	^selectedContext receiver class methodAt: selectedContext selector
+	^selectedContext method
 !
 
 receiver
@@ -1374,6 +1381,7 @@ selectContext: aContext
 !
 
 selectVariable: anObject named: aString
+    
 	selectedVariable := anObject.
 	selectedVariableName := aString.
 	inspector contents: [:html | html with: anObject printString].
@@ -1402,7 +1410,7 @@ renderBottomPanelOn: html
 !
 
 renderBoxOn: html
-    self 
+   self 
 	renderTopPanelOn: html;
 	renderBottomPanelOn: html
 !
@@ -1445,7 +1453,7 @@ renderContext: aContext on: html
 	li 
 		with: aContext asString;
 		onClick: [self selectContext: aContext].
-	aContext home ifNotNil: [self renderContext: aContext home on: html]
+	aContext outerContext ifNotNil: [self renderContext: aContext outerContext on: html]
 !
 
 renderTopPanelOn: html
@@ -1495,27 +1503,22 @@ updateStatus
 !
 
 updateVariablesList
-	ul2 contents: [:html | | li |
+	ul2 contents: [ :html | | li |
 		li := html li 
 			with: 'self';
-			onClick: [self selectVariable: self receiver named: 'self'].
-                selectedVariableName = 'self' ifTrue: [
-			li class: 'selected'].
-                self arguments withIndexDo: [:each :index | | param |
-                        param := selectedContext temps at: index.
+			onClick: [ self selectVariable: self receiver named: 'self' ].
+                selectedVariableName = 'self' ifTrue: [ li class: 'selected' ].
+        
+        self allVariables keysAndValuesDo: [:key :value |
                         li := html li 
-				with: each;
-				onClick: [self selectVariable: param named: each].
-                         selectedVariableName = each ifTrue: [
-				li class: 'selected']].
-                self receiver class allInstanceVariableNames do: [:each | | ivar |
-                        ivar := self receiver instVarAt: each.
-                        li := html li 
-				with: each;
-				onClick: [self selectVariable: ivar named: each].
-                         selectedVariableName = each ifTrue: [
-				li class: 'selected']]].
-	selectedVariable ifNil: [inspectButton at: 'disabled' put: true] ifNotNil: [inspectButton removeAt: 'disabled']
+							with: key;
+							onClick: [ self selectVariable: value named: key ].
+                        selectedVariableName = key ifTrue: [
+							li class: 'selected' ] ] ].
+                            
+	selectedVariable 
+    	ifNil: [ inspectButton at: 'disabled' put: true ] 
+        ifNotNil: [ inspectButton removeAt: 'disabled' ]
 ! !
 
 TabWidget subclass: #IDETranscript
@@ -2385,24 +2388,6 @@ inspectOn: anInspector
 		setVariables: variables
 ! !
 
-!Date methodsFor: '*IDE'!
-
-inspectOn: anInspector
-	| variables |
-	variables := Dictionary new.
-	variables at: '#self' put: self.
-	variables at: '#year' put: self year.
-	variables at: '#month' put: self month.
-	variables at: '#day' put: self day.
-	variables at: '#hours' put: self hours.
-	variables at: '#minutes' put: self minutes.
-	variables at: '#seconds' put: self seconds.
-	variables at: '#milliseconds' put: self milliseconds.
-	anInspector 
-		setLabel: self printString;
-		setVariables: variables
-! !
-
 !MethodContext methodsFor: '*IDE'!
 
 inspectOn: anInspector

+ 4 - 7
st/Importer-Exporter.st

@@ -345,16 +345,13 @@ Object subclass: #PackageLoader
 	instanceVariableNames: ''
 	package: 'Importer-Exporter'!
 
-!PackageLoader methodsFor: 'not yet classified'!
+!PackageLoader methodsFor: 'laoding'!
 
 initializePackageNamed: packageName prefix: aString
 
-	(Package named: packageName) classes do: [ :each |
-    	<smalltalk.init(each)>.
-        each initialize. ].
-        
-    (Package named: packageName) 
-    	commitPathJs: '/', aString, '/js';
+	(Package named: packageName) 
+    	setupClasses;
+        commitPathJs: '/', aString, '/js';
         commitPathSt: '/', aString, '/st'
 !
 

+ 116 - 31
st/Kernel-Classes.st

@@ -68,13 +68,29 @@ instanceVariableNames
 	<return self.iVarNames>
 !
 
+lookupSelector: selector
+	"Look up the given selector in my methodDictionary.
+	Return the corresponding method if found.
+	Otherwise chase the superclass chain and try again.
+	Return nil if no method is found."
+    
+	| lookupClass |
+    
+	lookupClass := self.
+	[ lookupClass = nil ] whileFalse: [
+      	(lookupClass includesSelector: selector)
+				ifTrue: [ ^ lookupClass methodAt: selector ].
+			lookupClass := lookupClass superclass ].
+	^ nil
+!
+
 methodAt: aSymbol
-	<return smalltalk.methods(self)[aSymbol._asString()]>
+	^ self methodDictionary at: aSymbol asString
 !
 
 methodDictionary
 	<var dict = smalltalk.HashedCollection._new();
-	var methods = self.fn.prototype.methods;
+	var methods = self.methods;
 	for(var i in methods) {
 		if(methods[i].selector) {
 			dict._at_put_(methods[i].selector, methods[i]);
@@ -158,7 +174,7 @@ withAllSubclasses
 !Behavior methodsFor: 'compiling'!
 
 addCompiledMethod: aMethod
-	<smalltalk.addMethod(aMethod.selector._asSelector(), aMethod, self)>.
+	self basicAddCompiledMethod: aMethod.
     
     SystemAnnouncer current
    		announce: (MethodAdded new
@@ -179,10 +195,7 @@ compile: aString category: anotherString
 !
 
 removeCompiledMethod: aMethod
-	<
-    	smalltalk.removeMethod(aMethod)
-		smalltalk.init(self);
-    >.
+	self basicRemoveCompiledMethod: aMethod.
     
     SystemAnnouncer current
    		announce: (MethodRemoved new
@@ -201,6 +214,19 @@ new
 	^self basicNew initialize
 ! !
 
+!Behavior methodsFor: 'private'!
+
+basicAddCompiledMethod: aMethod
+	<smalltalk.addMethod(aMethod.selector._asSelector(), aMethod, self)>
+!
+
+basicRemoveCompiledMethod: aMethod
+	<
+    	smalltalk.removeMethod(aMethod)
+		smalltalk.init(self);
+    >
+! !
+
 !Behavior methodsFor: 'testing'!
 
 canUnderstand: aSelector
@@ -208,6 +234,10 @@ canUnderstand: aSelector
 		self superclass notNil and: [self superclass canUnderstand: aSelector]]
 !
 
+includesSelector: aSymbol
+	^ self methodDictionary includesKey: aSymbol asString
+!
+
 inheritsFrom: aClass
 	^aClass allSubclasses includes: self
 ! !
@@ -367,23 +397,16 @@ Rather than using ClassBuilder directly to compile a class, use `Class >> subcla
 !ClassBuilder methodsFor: 'class creation'!
 
 class: aClass instanceVariableNames: aString
-	aClass isMetaclass ifFalse: [self error: aClass name, ' is not a metaclass'].
-	aClass basicAt: 'iVarNames' put: (self instanceVariableNamesFor: aString).
+	self basicClass: aClass instanceVariableNames: aString.
     
     SystemAnnouncer current
     	announce: (ClassDefinitionChanged new
         	theClass: aClass;
-            yourself).
-    
-	self setupClass: aClass
+            yourself)
 !
 
 renameClass: aClass to: aString
-	<
-		smalltalk[aString] = aClass;
-		delete smalltalk[aClass.className];
-		aClass.className = aString;
-	>.
+	self basicRenameClass: aClass to: aString.
     
     SystemAnnouncer current
     	announce: (ClassRenamed new
@@ -391,6 +414,10 @@ renameClass: aClass to: aString
             yourself)
 !
 
+setupClass: aClass
+	<smalltalk.init(aClass);>
+!
+
 superclass: aClass subclass: aString
 	^self superclass: aClass subclass: aString instanceVariableNames: '' package: nil
 !
@@ -413,14 +440,47 @@ superclass: aClass subclass: aString instanceVariableNames: aString2 package: aS
 
 !ClassBuilder methodsFor: 'private'!
 
-addSubclassOf: aClass named: aString instanceVariableNames: aCollection
-	<smalltalk.addClass(aString, aClass, aCollection);
-	    return smalltalk[aString]>
+addSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName
+	
+    (Smalltalk current at: aString) ifNotNil: [ 
+    	^ self 
+        	migrateClassNamed: aString 
+            superclass: aClass 
+            instanceVariableNames: aCollection 
+            package: packageName ].
+
+	^ self 
+    	basicAddSubclassOf: aClass 
+        named: aString 
+        instanceVariableNames: aCollection 
+        package: packageName
 !
 
-addSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName
-	<smalltalk.addClass(aString, aClass, aCollection, packageName);
-	    return smalltalk[aString]>
+basicAddSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName
+	<
+		smalltalk.addClass(aString, aClass, aCollection, packageName);
+		return smalltalk[aString]
+	>
+!
+
+basicClass: aClass instanceVariableNames: aString
+
+	aClass isMetaclass ifFalse: [self error: aClass name, ' is not a metaclass'].
+	aClass basicAt: 'iVarNames' put: (self instanceVariableNamesFor: aString).
+    
+	self setupClass: aClass
+!
+
+basicRemoveClass: aClass
+	<smalltalk.removeClass(aClass)>
+!
+
+basicRenameClass: aClass to: aString
+	<
+		smalltalk[aString] = aClass;
+		delete smalltalk[aClass.className];
+		aClass.className = aString;
+	>
 !
 
 copyClass: aClass named: aString
@@ -445,15 +505,42 @@ copyClass: aClass named: aString
 !
 
 instanceVariableNamesFor: aString
-	^(aString tokenize: ' ') reject: [:each | each isEmpty]
+	^(aString tokenize: ' ') reject: [ :each | each isEmpty ]
 !
 
-setupClass: aClass
-	<smalltalk.init(aClass);>
+migrateClassNamed: aString superclass: aClass instanceVariableNames: aCollection package: packageName
+	| oldClass newClass |
+    
+    oldClass := Smalltalk current at: aString.
+    
+    "Rename the class for existing instances"
+	self 
+    	basicRenameClass: oldClass to: 'Old', aString;
+        basicRemoveClass: oldClass.
+        
+    newClass := self 
+		addSubclassOf: aClass
+		named: aString 
+		instanceVariableNames: aCollection
+		package: packageName.
+
+	self setupClass: newClass.
+
+	newClass comment: oldClass comment.
+
+	oldClass methodDictionary values do: [:each |
+		Compiler new install: each source forClass: newClass category: each category].
+
+	oldClass class methodDictionary values do: [:each |
+		Compiler new install: each source forClass: newClass class category: each category].
+
+	self setupClass: newClass.
+    
+	^newClass
 ! !
 
 Object subclass: #ClassCategoryReader
-	instanceVariableNames: 'class category chunkParser'
+	instanceVariableNames: 'class category'
 	package: 'Kernel-Classes'!
 !ClassCategoryReader commentStamp!
 ClassCategoryReader represents a mechanism for retrieving class descriptions stored on a file.!
@@ -479,7 +566,6 @@ scanFrom: aChunkParser
 
 initialize
 	super initialize.
-	chunkParser := ChunkParser new.
 ! !
 
 !ClassCategoryReader methodsFor: 'private'!
@@ -489,10 +575,10 @@ compileMethod: aString
 ! !
 
 Object subclass: #ClassCommentReader
-	instanceVariableNames: 'class chunkParser'
+	instanceVariableNames: 'class'
 	package: 'Kernel-Classes'!
 !ClassCommentReader commentStamp!
-ClassCommentReader represents a mechanism for retrieving class descriptions stored on a file.
+ClassCommentReader represents a mechanism for retrieving class comments stored on a file.
 See `ClassCategoryReader` too.!
 
 !ClassCommentReader methodsFor: 'accessing'!
@@ -514,7 +600,6 @@ scanFrom: aChunkParser
 
 initialize
 	super initialize.
-	chunkParser := ChunkParser new.
 ! !
 
 !ClassCommentReader methodsFor: 'private'!

+ 21 - 27
st/Kernel-Collections.st

@@ -810,9 +810,9 @@ remove: anObject ifAbsent: aBlock
 				self.splice(i,1);
 				return self;
 			}
-		}
-	>.
-	aBlock value
+		};
+        aBlock._value();
+	>
 !
 
 removeFrom: aNumber to: anotherNumber
@@ -995,8 +995,12 @@ unescaped
 !
 
 = aString
-	aString class = self class ifFalse: [^false].
-	<return String(self) === String(aString)>
+	<
+    	if(!! aString._isString || !! aString._isString()) {
+        	return false;
+        }
+    	return String(self) === String(aString)
+    >
 !
 
 == aString
@@ -1039,21 +1043,7 @@ asNumber
 !
 
 asSelector
-	"If you change this method, change smalltalk.convertSelector too (see js/boot.js file)"
-
-	| selector |
-	selector := '_', self.
-	selector := selector replace: ':' with: '_'.
-	selector := selector replace: '[+]' with: '_plus'.
-	selector := selector replace: '-' with: '_minus'.
-	selector := selector replace: '[*]' with: '_star'.
-	selector := selector replace: '[/]' with: '_slash'.
-	selector := selector replace: '>' with: '_gt'.
-	selector := selector replace: '<' with: '_lt'.
-	selector := selector replace: '=' with: '_eq'.
-	selector := selector replace: ',' with: '_comma'.
-	selector := selector replace: '[@]' with: '_at'.
-	^selector
+	<return smalltalk.selector(self)>
 !
 
 asString
@@ -1343,6 +1333,10 @@ asString
 	<return self.value>
 !
 
+asSuperSelector
+	^self asString asSuperSelector
+!
+
 asSymbol
 	^self
 ! !
@@ -1491,14 +1485,14 @@ Object subclass: #Queue
 	instanceVariableNames: 'read readIndex write'
 	package: 'Kernel-Collections'!
 !Queue commentStamp!
-I am a one-sided Queue.
+A Queue am a one-sided queue.
 
-I use two OrderedCollections inside,
+A Queue uses two OrderedCollections inside,
 `read` is at the front, is not modified and only read using `readIndex`.
 `write` is at the back and is appended new items.
 When `read` is exhausted, `write` is promoted to `read` and new `write` is created.
 
-As a consequence, no data moving is done by me; write appending may do data moving
+As a consequence, no data moving is done by the Queue; write appending may do data moving
 when growing `write`, but this is left to engine to implement as good as it chooses to.!
 
 !Queue methodsFor: 'accessing'!
@@ -1508,7 +1502,7 @@ back: anObject
 !
 
 front
-    ^self frontIfAbsent: [ self error: 'Cannot read from empty Queue.']
+    ^self frontIfAbsent: [ self error: 'Cannot read from empty Queue.' ]
 !
 
 frontIfAbsent: aBlock
@@ -1530,9 +1524,9 @@ frontIfAbsent: aBlock
 
 initialize
 	super initialize.
-	read := #().
-    readIndex := 1.
-    write := OrderedCollection new
+	read := OrderedCollection new.
+    write := OrderedCollection new.
+    readIndex := 1
 ! !
 
 Object subclass: #RegularExpression

+ 7 - 1
st/Kernel-Exceptions.st

@@ -21,6 +21,12 @@ messageText: aString
 	messageText := aString
 ! !
 
+!Error methodsFor: 'initialization'!
+
+initialize
+	self messageText: 'Errorclass: ', (self class name).
+! !
+
 !Error methodsFor: 'signaling'!
 
 signal
@@ -109,7 +115,7 @@ log: aString
 logContext: aContext
 	aContext home ifNotNil: [
 		self logContext: aContext home].
-	self log: aContext receiver asString, '>>', aContext selector
+	self log: aContext receiver asString, '>>', aContext selector asString
 !
 
 logError: anError

+ 45 - 9
st/Kernel-Methods.st

@@ -331,7 +331,7 @@ printString
 !
 
 sendTo: anObject
-	^ Smalltalk current send: self selector to: anObject arguments: self arguments
+	^ anObject perform: self selector withArguments: self arguments
 ! !
 
 !Message class methodsFor: 'instance creation'!
@@ -349,17 +349,29 @@ Object subclass: #MethodContext
 !MethodContext commentStamp!
 MethodContext holds all the dynamic state associated with the execution of either a method activation resulting from a message send. That is used to build the call stack while debugging.
   
-MethodContext instances are JavaScript `SmalltalkMethodContext` objects defined in boot.js 
-
-Current limitation: MethodContext instances are not created on Block evaluation. That means it's actually impossible to debug inside a Block.!
+MethodContext instances are JavaScript `SmalltalkMethodContext` objects defined in boot.js!
 
 !MethodContext methodsFor: 'accessing'!
 
-asString
-	^self receiver class printString, ' >> ', self selector
+home
+	<return self.methodContext || self.homeContext>
 !
 
-home
+locals
+	<return self.locals>
+!
+
+method
+	^self methodContext receiver class lookupSelector: self methodContext selector
+!
+
+methodContext
+	self isBlockContext ifFalse: [ ^ self ].
+    
+    ^ self home
+!
+
+outerContext
 	<return self.homeContext>
 !
 
@@ -376,10 +388,34 @@ receiver
 !
 
 selector
-	<return smalltalk.convertSelector(self.selector)>
+	<
+    	if(self.selector) {
+        	return smalltalk.convertSelector(self.selector);
+        } else {
+        	return nil;
+        }
+    >
 !
 
 temps
-	<return self.temps>
+	self deprecatedAPI.
+    
+	^ self locals
+! !
+
+!MethodContext methodsFor: 'converting'!
+
+asString
+	^self isBlockContext 
+    	ifTrue: [ 'a block (in ', self methodContext receiver class printString, ')' ]
+      	ifFalse: [ self receiver class printString, ' >> ', self selector ]
+! !
+
+!MethodContext methodsFor: 'testing'!
+
+isBlockContext
+	"Block context do not have selectors."
+    
+	^ self selector isNil
 ! !
 

+ 149 - 144
st/Kernel-Objects.st

@@ -68,15 +68,11 @@ identityHash
 !
 
 instVarAt: aSymbol
-	| varname |
-	varname := aSymbol asString.
-	<return self['@'+varname]>
+	<return self['@'+aSymbol._asString()]>
 !
 
 instVarAt: aSymbol put: anObject
-	| varname |
-	varname := aSymbol asString.
-	<self['@' + varname] = anObject>
+	<self['@' + aSymbol._asString()] = anObject>
 !
 
 size
@@ -88,7 +84,7 @@ value
 !
 
 yourself
-	^ self
+	^self
 ! !
 
 !Object methodsFor: 'comparing'!
@@ -133,6 +129,12 @@ asJavascript
 
 asString
 	^self printString
+!
+
+test
+	| a |
+    a := 1.
+    self halt
 ! !
 
 !Object methodsFor: 'copying'!
@@ -228,9 +230,7 @@ perform: aSymbol
 !
 
 perform: aSymbol withArguments: aCollection
-	| selector |
-	selector := aSymbol asSelector.
-	<return smalltalk.send(self, selector, aCollection)>
+	<return smalltalk.send(self, aSymbol._asSelector(), aCollection)>
 ! !
 
 !Object methodsFor: 'printing'!
@@ -283,6 +283,10 @@ ifNotNil: aBlock ifNil: anotherBlock
 	^aBlock value
 !
 
+isBoolean
+	^ false
+!
+
 isClass
 	^false
 !
@@ -347,8 +351,12 @@ Boolean instances are weither `true` or `false`.!
 !Boolean methodsFor: 'comparing'!
 
 = aBoolean
-	aBoolean class = self class ifFalse: [^false].
-	<return Boolean(self == true) == aBoolean>
+	<
+    	if(!! aBoolean._isBoolean || !! aBoolean._isBoolean()) {
+        	return false;
+        }
+    	return Boolean(self == true) == aBoolean
+    >
 !
 
 == aBoolean
@@ -441,6 +449,12 @@ printString
 	<return self.toString()>
 ! !
 
+!Boolean methodsFor: 'testing'!
+
+isBoolean
+	^ true
+! !
+
 Object subclass: #Date
 	instanceVariableNames: ''
 	package: 'Kernel-Objects'!
@@ -655,15 +669,11 @@ __Note:__ For keyword-based messages, only the first keyword is kept: `window fo
 !JSObjectProxy methodsFor: 'accessing'!
 
 at: aSymbol
-	| attr |
-	attr := aSymbol asString.
-	<return self['@jsObject'][attr]>
+	<return self['@jsObject'][aSymbol._asString()]>
 !
 
 at: aSymbol put: anObject
-	| attr |
-	attr := aSymbol asString.
-	<self['@jsObject'][attr] = anObject>
+	<self['@jsObject'][aSymbol._asString()] = anObject>
 !
 
 jsObject
@@ -674,16 +684,38 @@ jsObject: aJSObject
 	jsObject := aJSObject
 ! !
 
+!JSObjectProxy methodsFor: 'enumerating'!
+
+keysAndValuesDo: aBlock
+	<
+    	var o = self['@jsObject'];
+    	for(var i in o) {
+			aBlock(i, o[i]);
+		}
+    >
+! !
+
 !JSObjectProxy methodsFor: 'proxy'!
 
+addObjectVariablesTo: aDictionary
+	<
+    	for(var i in self['@jsObject']) {
+			aDictionary._at_put_(i, self['@jsObject'][i]);
+		}
+    >
+!
+
 doesNotUnderstand: aMessage
-	| obj selector jsSelector arguments |
-	obj := self jsObject.
-	selector := aMessage selector.
-	jsSelector := selector asJavaScriptSelector.
-	arguments := aMessage arguments.
-	<if(jsSelector in obj) {return smalltalk.send(obj, jsSelector, arguments)}>.
-	super doesNotUnderstand: aMessage
+    
+   ^ (self canForwardMessage: aMessage) 
+    	ifTrue: [ self forwardMessage: aMessage ]
+        ifFalse: [ ^ super doesNotUnderstand: aMessage ]
+!
+
+forwardMessage: aMessage
+	<
+    	return smalltalk.send(self._jsObject(), aMessage._selector()._asJavaScriptSelector(), aMessage._arguments());
+    >
 !
 
 inspectOn: anInspector
@@ -691,9 +723,7 @@ inspectOn: anInspector
 	variables := Dictionary new.
 	variables at: '#self' put: self jsObject.
 	anInspector setLabel: self printString.
-	<for(var i in self['@jsObject']) {
-		variables._at_put_(i, self['@jsObject'][i]);
-	}>.
+	self addObjectVariablesTo: variables.
 	anInspector setVariables: variables
 !
 
@@ -701,6 +731,19 @@ printString
 	^self jsObject toString
 ! !
 
+!JSObjectProxy methodsFor: 'testing'!
+
+canForwardMessage: aMessage
+	<
+    	var jsSelector = aMessage._selector()._asJavaScriptSelector();
+    	if(jsSelector in self._jsObject()) {
+        	return true
+        } else {
+        	return false;
+        }
+    >
+! !
+
 !JSObjectProxy class methodsFor: 'instance creation'!
 
 on: aJSObject
@@ -759,8 +802,12 @@ identityHash
 	<return self % aNumber>
 !
 
+\\ aNumber
+	<return self % aNumber>
+!
+
 abs
-	^ <Math.abs(self);>
+	<return Math.abs(self);>
 !
 
 max: aNumber
@@ -796,8 +843,12 @@ squared
 !
 
 = aNumber
-	aNumber isNumber ifFalse: [^false]. 
-	<return Number(self) == aNumber>
+	<
+    	if(!! aNumber._isNumber || !! aNumber._isNumber()) {
+        	return false;
+        }
+    	return Number(self) == aNumber
+    >
 !
 
 > aNumber
@@ -876,13 +927,13 @@ to: stop by: step
 !
 
 truncated
-|result|
-
-    self >= 0 
-        ifTrue: [<result = Math.floor(self);>]
-        ifFalse: [<result = (Math.floor(self * (-1)) * (-1));>].
-
-    ^ result
+	<
+    	if(self >>= 0) {
+        	return Math.floor(self);
+        } else {
+        	return Math.floor(self * (-1)) * (-1);
+        };
+    >
 !
 
 | aNumber
@@ -902,8 +953,7 @@ deepCopy
 !Number methodsFor: 'enumerating'!
 
 timesRepeat: aBlock
-	| integer count |
-	integer := self truncated.
+	| count |
 	count := 1.
 	[count > self] whileFalse: [
 	    aBlock value.
@@ -986,7 +1036,7 @@ Object subclass: #Organizer
 !Organizer methodsFor: 'accessing'!
 
 addElement: anObject
-	<self.addElement(anObject)>
+	<self.elements.addElement(anObject)>
 !
 
 elements
@@ -994,7 +1044,7 @@ elements
 !
 
 removeElement: anObject
-	<self.removeElement(anObject)>
+	<self.elements.removeElement(anObject)>
 ! !
 
 Object subclass: #Package
@@ -1060,17 +1110,6 @@ organization
 
 properties
 	^Smalltalk current readJSObject: (self basicAt: 'properties')
-!
-
-properties: aDict
-	"We store it as a javascript object."
-	
-	| object |
-	<object = {};>.
-	aDict keysAndValuesDo: [:key :value |
-		<object[key] = value>.
-	].
-	<return self.properties = object>
 ! !
 
 !Package methodsFor: 'classes'!
@@ -1079,6 +1118,12 @@ classes
 	^ self organization elements
 !
 
+setupClasses
+	self classes
+		do: [ :each | ClassBuilder new setupClass: each ];
+		do: [ :each | each initialize ]
+!
+
 sortedClasses
 	"Answer all classes in the receiver, sorted by superclass/subclasses and by class name for common subclasses (Issue #143)."
 
@@ -1124,16 +1169,20 @@ propertyAt: key put: value
 
 Package class instanceVariableNames: 'defaultCommitPathJs defaultCommitPathSt'!
 
-!Package class methodsFor: 'commit paths'!
+!Package class methodsFor: 'accessing'!
+
+named: aPackageName
 
-commitPathsFromLoader
-	| js st |
-    <var cp = smalltalk['@@commitPath'];
-        if (cp) { js = cp.js; st = cp.st; }>.
-    js ifNotNil: [ self defaultCommitPathJs: js ].
-    st ifNotNil: [ self defaultCommitPathSt: st ].
+	^Smalltalk current packageAt: aPackageName
 !
 
+named: aPackageName ifAbsent: aBlock
+
+	^Smalltalk current packageAt: aPackageName ifAbsent: aBlock
+! !
+
+!Package class methodsFor: 'commit paths'!
+
 defaultCommitPathJs
 	^ defaultCommitPathJs ifNil: [ defaultCommitPathJs := 'js']
 !
@@ -1155,46 +1204,17 @@ resetCommitPaths
         defaultCommitPathSt := nil.
 ! !
 
-!Package class methodsFor: 'initialization'!
-
-initialize
-	super initialize.
-    self commitPathsFromLoader
-! !
-
 !Package class methodsFor: 'loading-storing'!
 
-commitToLocalStorage: aPackageName
-	| key sourceCode |
-	key := 'smalltalk.packages.' , aPackageName.
-	sourceCode := Exporter new exportPackage: aPackageName.
-	<localStorage[key] = escape(sourceCode)>
-!
-
 fetch: aPackageName
 	self fetch: aPackageName prefix: self defaultCommitPathJs, '/'
 !
 
 fetch: aPackageName prefix: aPrefix
-	jQuery getScript: (aPrefix , aPackageName , '.js') onSuccess: [ Package init: aPackageName ]
-!
-
-init: aPackageName
-	(smalltalk classes select: [ :each | <each.pkg.pkgName == aPackageName> ])
-		do: [ :each | <smalltalk.init(each)> ];
-		do: [ :each | each initialize ]
-! !
-
-!Package class methodsFor: 'not yet classified'!
-
-named: aPackageName
-
-	^Smalltalk current packageAt: aPackageName
-!
-
-named: aPackageName ifAbsent: aBlock
-
-	^Smalltalk current packageAt: aPackageName ifAbsent: aBlock
+	jQuery 
+    	getScript: (aPrefix , aPackageName , '.js') 
+        onSuccess: [ 
+        	(Package named: aPackageName) setupClasses ]
 ! !
 
 !Package class methodsFor: 'sorting'!
@@ -1394,31 +1414,12 @@ at: aSymbol
 	<return self[aSymbol._asString()]>
 !
 
-basicParse: aString
-	<return smalltalk.parser.parse(aString)>
-!
-
 parse: aString
 	| result | 
 	self try: [result := self basicParse: aString] catch: [:ex | (self parseError: ex parsing: aString) signal].
 	^result
 !
 
-parseError: anException parsing: aString
-	| row col message lines badLine code |
-	<row = anException.line;
-	col = anException.column;
-	message = anException.message;>.
-	lines := aString lines.
-	badLine := lines at: row.
-	badLine := (badLine copyFrom: 1 to: col - 1), ' ===>', (badLine copyFrom:  col to: badLine size).
-	lines at: row put: badLine.
-	code := String streamContents: [:s |
-                  lines withIndexDo: [:l :i |
-                     s nextPutAll: i asString, ': ', l, String lf]].
-	^ ParseError new messageText: ('Parse error on line ' , row , ' column ' , col , ' : ' , message , ' Below is code with line numbers and ===> marker inserted:' , String lf, code)
-!
-
 readJSObject: anObject
 	<return self.readJSObject(anObject)>
 !
@@ -1426,12 +1427,6 @@ readJSObject: anObject
 reservedWords
 	"JavaScript reserved words"
 	<return self.reservedWords>
-!
-
-send: aSelector to: anObject arguments: aCollection
-	| selector |
-	selector := aSelector asString asSelector.
-	<return self.send(anObject, selector, aCollection)>
 ! !
 
 !Smalltalk methodsFor: 'classes'!
@@ -1440,6 +1435,12 @@ classes
 	<return self.classes()>
 !
 
+deleteClass: aClass
+	"Deletes a class by deleting its binding only. Use #removeClass instead"
+    
+	<self.removeClass(aClass)>
+!
+
 removeClass: aClass
 	aClass isMetaclass ifTrue: [self error: aClass asString, ' is a Metaclass and cannot be removed!!'].
     
@@ -1457,8 +1458,26 @@ removeClass: aClass
             yourself)
 ! !
 
+!Smalltalk methodsFor: 'error handling'!
+
+parseError: anException parsing: aString
+	^ ParseError new messageText: 'Parse error on line ', (anException basicAt: 'line') ,' column ' , (anException basicAt: 'column') ,' : Unexpected character ', (anException basicAt: 'found')
+! !
+
 !Smalltalk methodsFor: 'packages'!
 
+createPackage: packageName
+	"Create and bind a new package with given name and return it."
+       <return smalltalk.addPackage(packageName)>
+!
+
+deletePackage: packageName
+	"Deletes a package by deleting its binding, but does not check if it contains classes etc.
+	To remove a package, use #removePackage instead."
+
+       <delete smalltalk.packages[packageName]>
+!
+
 packageAt: packageName
        <return self.packages[packageName]>
 !
@@ -1493,41 +1512,23 @@ renamePackage: packageName to: newName
 	| pkg |
 	pkg := self packageAt: packageName ifAbsent: [self error: 'Missing package: ', packageName].
 	(self packageAt: newName) ifNotNil: [self error: 'Already exists a package called: ', newName].
-	<smalltalk.packages[newName] = smalltalk.packages[packageName]>.
+    (self basicAt: 'packages') at: newName put: pkg.
 	pkg name: newName.
 	self deletePackage: packageName.
 ! !
 
 !Smalltalk methodsFor: 'private'!
 
-createPackage: packageName
-	"Create and bind a new package with given name and return it."
-
-      <return smalltalk.addPackage(packageName, nil)>
+basicParse: aString
+	<return smalltalk.parser.parse(aString)>
 !
 
 createPackage: packageName properties: aDict
-	"Create and bind a new package with given name and return it."
-
-	| object |
-	<object = {};>.
-	aDict keysAndValuesDo: [:key :value |
-		<object[key] = value>.
-	].
-       <return smalltalk.addPackage(packageName, object)>
-!
-
-deleteClass: aClass
-	"Deletes a class by deleting its binding only. Use #removeClass instead"
+    "Needed to import .st files: they begin with this call."
+    self deprecatedAPI.
     
-	<self.removeClass(aClass)>
-!
-
-deletePackage: packageName
-	"Deletes a package by deleting its binding, but does not check if it contains classes etc.
-	To remove a package, use #removePackage instead."
-
-       <delete smalltalk.packages[packageName]>
+    aDict isEmpty ifFalse: [ self error: 'createPackage:properties: called with nonempty properties' ].
+    ^ self createPackage: packageName
 ! !
 
 Smalltalk class instanceVariableNames: 'current'!
@@ -1596,7 +1597,7 @@ subclass: aString instanceVariableNames: aString2 category: aString3
 
 subclass: aString instanceVariableNames: aString2 package: aString3
 	^ClassBuilder new
-	    superclass: self subclass: aString instanceVariableNames: aString2 package: aString3
+	    superclass: self subclass: aString asString instanceVariableNames: aString2 package: aString3
 ! !
 
 !UndefinedObject methodsFor: 'converting'!
@@ -1657,3 +1658,7 @@ new
 	    self error: 'You cannot create new instances of UndefinedObject. Use nil'
 ! !
 
+nil subclass: #[object Object]
+	instanceVariableNames: ''
+	package: 'Kernel-Objects'!
+

+ 43 - 22
st/Kernel-Tests.st

@@ -131,17 +131,17 @@ testIfTrueIfFalse
 
 testIfTrueIfFalseWithBoxing
  
-	self assert: (true boxed ifTrue: ['alternative block']) = 'alternative block'.
-	self assert: (true boxed ifFalse: ['alternative block']) = nil.
+	self assert: (true yourself ifTrue: ['alternative block']) = 'alternative block'.
+	self assert: (true yourself ifFalse: ['alternative block']) = nil.
 
-	self assert: (false boxed ifTrue: ['alternative block']) = nil.
-	self assert: (false boxed ifFalse: ['alternative block']) = 'alternative block'.
+	self assert: (false yourself ifTrue: ['alternative block']) = nil.
+	self assert: (false yourself ifFalse: ['alternative block']) = 'alternative block'.
 
-	self assert: (false boxed ifTrue: ['alternative block'] ifFalse: ['alternative block2']) = 'alternative block2'.
-	self assert: (false boxed ifFalse: ['alternative block'] ifTrue: ['alternative block2']) = 'alternative block'.
+	self assert: (false yourself ifTrue: ['alternative block'] ifFalse: ['alternative block2']) = 'alternative block2'.
+	self assert: (false yourself ifFalse: ['alternative block'] ifTrue: ['alternative block2']) = 'alternative block'.
 
-	self assert: (true boxed ifTrue: ['alternative block'] ifFalse: ['alternative block2']) = 'alternative block'.
-	self assert: (true boxed ifFalse: ['alternative block'] ifTrue: ['alternative block2']) = 'alternative block2'.
+	self assert: (true yourself ifTrue: ['alternative block'] ifFalse: ['alternative block2']) = 'alternative block'.
+	self assert: (true yourself ifFalse: ['alternative block'] ifTrue: ['alternative block2']) = 'alternative block2'.
 !
 
 testLogic
@@ -180,9 +180,7 @@ testLogicKeywords
 !
 
 testNonBooleanError
-	|b|
-    b := < '' >.
-    self should: [nonBoolean ifTrue: [] ifFalse: []] raise: NonBooleanReceiver
+    self should: [ '' ifTrue: [] ifFalse: [] ] raise: NonBooleanReceiver
 ! !
 
 TestCase subclass: #ClassBuilderTest
@@ -208,6 +206,33 @@ testClassCopy
 	self assert: theClass methodDictionary keys equals: ObjectMock methodDictionary keys
 !
 
+testClassMigration
+	| instance oldClass |
+    
+    oldClass := builder copyClass: ObjectMock named: 'ObjectMock2'.
+    instance := (Smalltalk  current at: 'ObjectMock2') new.
+    
+    "Change the superclass of ObjectMock2"
+    ObjectMock subclass: (Smalltalk current at: 'ObjectMock2')
+    	instanceVariableNames: ''
+        package: 'Kernel-Tests'.
+    
+    self deny: oldClass == ObjectMock2.
+    
+	self assert: ObjectMock2 superclass == ObjectMock.
+	self assert: ObjectMock2 instanceVariableNames isEmpty.
+	self assert: ObjectMock2 selectors equals: oldClass selectors.
+    self assert: ObjectMock2 comment equals: oldClass comment.
+    self assert: ObjectMock2 package name equals: 'Kernel-Tests'.
+    
+	self deny: instance class == ObjectMock2.
+    self assert: instance class name equals: 'OldObjectMock2'.
+    
+    self assert: (Smalltalk current at: 'OldObjectMock2') isNil.
+    
+    Smalltalk current removeClass: ObjectMock2
+!
+
 testInstanceVariableNames
 	self assert: (builder instanceVariableNamesFor: '  hello   world   ') equals: #('hello' 'world')
 ! !
@@ -1106,6 +1131,8 @@ testTruncated
 Object subclass: #ObjectMock
 	instanceVariableNames: 'foo bar'
 	package: 'Kernel-Tests'!
+!ObjectMock commentStamp!
+ObjectMock is there only to perform tests on classes.!
 
 !ObjectMock methodsFor: 'not yet classified'!
 
@@ -1123,6 +1150,10 @@ TestCase subclass: #ObjectTest
 
 !ObjectTest methodsFor: 'tests'!
 
+notDefined
+	<return undefined;>
+!
+
 testBasicAccess
 	| o |
 	o := Object new.
@@ -1189,11 +1220,7 @@ testInstVars
 testNilUndefined
 	"nil in Smalltalk is the undefined object in JS"
 
-	| notDefined |
-    
-    <notDefined = undefined>.
-
-	self assert: nil = notDefined
+	self assert: nil = self notDefined
 !
 
 testYourself
@@ -1436,9 +1463,3 @@ testIsNil
 	self deny: nil notNil.
 ! !
 
-!Boolean methodsFor: '*Kernel-Tests'!
-
-boxed
-	^self
-! !
-

+ 1 - 3
st/Kernel-Transcript.st

@@ -19,9 +19,7 @@ cr
 !
 
 show: anObject
-	| string |
-	string := anObject asString.
-	<console.log(String(string))>
+	<console.log(String(string._asString()))>
 ! !
 
 !ConsoleTranscript class methodsFor: 'initialization'!

+ 28 - 9
st/Makefile

@@ -30,7 +30,7 @@ boot.js init.js:
 # $@ is the target
 # $< is the prerequisite
 parser.js: ../js/parser.pegjs
-	pegjs -e smalltalk.parser $< $@
+	pegjs --track-line-and-column --cache -e smalltalk.parser $< $@
 
 # Then we compile Kernel-*.st files depending on having boot.js, init.js and parser.js
 # $< means the first dependency - in other words Kernel-*.st
@@ -57,9 +57,18 @@ Kernel-Announcements.js: Kernel-Announcements.st boot.js init.js parser.js
 
 # ...and Compiler, but using the new Kernel from above.
 # We only need to depend on Kernel js files since it in turn depends on boot.js etc
+Compiler.st: Importer-Exporter.st Compiler-Exceptions.st Compiler-Core.st \
+    Compiler-AST.st Compiler-Semantic.st Compiler-IR.st Compiler-Inlining.st \
+    Compiler-Interpreter.st
+	echo "Smalltalk current createPackage: 'Compiler' properties: #{}!" >$@
+	sed -e '/^Smalltalk current createPackage:.*!$$/ d' \
+      -e 's/package: '"'[^':]*'"'!/package:'"'Compiler'"'!/' \
+      -e 's/ methodsFor: '"'[^']*'"'!$$/ methodsFor: '"'"'*Compiler'"'"'!/' \
+      $^ >>$@
+
 Compiler.js: Compiler.st Kernel-Objects.js Kernel-Classes.js Kernel-Methods.js Kernel-Collections.js \
 	Kernel-Exceptions.js Kernel-Transcript.js
-	$(AMBERC) $(FLAGS) $<
+	$(AMBERC) $(FLAGS) -l Importer-Exporter,Compiler-Exceptions,Compiler-Core,Compiler-AST,Compiler-Semantic,Compiler-IR,Compiler-Inlining $<
 
 # ...now that we have a new Kernel and Compiler we use them
 # to compile the rest of st files presuming that they only depend on Kernel, like
@@ -73,31 +82,41 @@ Compiler.js: Compiler.st Kernel-Objects.js Kernel-Classes.js Kernel-Methods.js K
 #
 # NOTE: With the new dependency model in class Package etc this will change!
 #
-Canvas.js: Canvas.st
+Canvas.js: Canvas.st Compiler.js
 	$(AMBERC) $(FLAGS) $<
 
 # IDE uses JQuery
-IDE.js: IDE.st Canvas.js
+IDE.js: IDE.st Canvas.js Compiler.js
 	$(AMBERC) $(FLAGS) -l Canvas $<
 
-TrySmalltalk.js: TrySmalltalk.st IDE.js
+TrySmalltalk.js: TrySmalltalk.st IDE.js Compiler.js
 	$(AMBERC) $(FLAGS) -l Canvas,IDE $<
 
 # Some Examples use SUnit and also IDE
-Examples.js: Examples.st SUnit.js IDE.js
+Examples.js: Examples.st SUnit.js IDE.js Compiler.js
 	$(AMBERC) $(FLAGS) -l SUnit,Canvas,IDE $<
 
 # Tests typically also use SUnit
-Kernel-Tests.js: Kernel-Tests.st SUnit.js
+Kernel-Tests.js: Kernel-Tests.st SUnit.js Compiler.js
+	$(AMBERC) $(FLAGS) -l SUnit $<
+
+Compiler-Tests.js: Compiler-Tests.st SUnit.js Compiler.js
 	$(AMBERC) $(FLAGS) -l SUnit $<
 
-Compiler-Tests.js: Compiler-Tests.st SUnit.js
+SUnit-Tests.js: SUnit-Tests.st SUnit.js Compiler.js
 	$(AMBERC) $(FLAGS) -l SUnit $<
 
 # Documentation
-Documentation.js: Documentation.st Canvas.js
+Documentation.js: Documentation.st Canvas.js Compiler.js
 	$(AMBERC) $(FLAGS) -l Canvas $<;
 
+#Helios
+Helios-Core.js: Helios-Core.st Canvas.js Compiler.js
+	$(AMBERC) $(FLAGS) -l Canvas $<;
+
+Helios-Browser.js: Helios-Browser.st Helios-Core.js Compiler.js
+	$(AMBERC) $(FLAGS) -l Helios-Core $<;
+
 # Installing is simply copying all js files to js directory.
 install: all
 	cp *.js $(JS)

+ 16 - 0
st/SUnit.st

@@ -358,6 +358,22 @@ initialize
 	total := 0
 ! !
 
+!TestResult methodsFor: 'running'!
+
+nextRunDo: aBlock
+"Runs aBlock with index of next run
+or does nothing if no more runs"
+^self runs == self total
+	ifFalse: [ aBlock value: self runs + 1 ]
+!
+
+runCase: aTestCase
+	[[	self increaseRuns.
+    	aTestCase runCase]
+	on: TestFailure do: [:ex | self addFailure: aTestCase]]
+	on: Error do: [:ex | self addError: aTestCase]
+! !
+
 Object subclass: #TestSuiteRunner
 	instanceVariableNames: 'suite result announcer runNextTest'
 	package: 'SUnit'!

+ 1 - 1
test/run_build.sh

@@ -3,7 +3,7 @@ cd `dirname ${0}`/..
 
 
 # Create the build file
-cat js/boot.js js/Kernel-Announcements.js js/Kernel-Classes.js js/Kernel-Collections.js  js/Kernel-Exceptions.js js/Kernel-Methods.js js/Kernel-Objects.js js/Kernel-Transcript.js js/Compiler-AST.js js/Compiler-Core.js js/Compiler-Exceptions.js js/Compiler-IR.js js/Compiler-Inlining.js js/Compiler-Semantic.js js/SUnit.js js/Kernel-Tests.js js/Compiler-Tests.js js/SUnit-Tests.js test/Test.js js/parser.js js/init.js > test/run.js
+cat js/boot.js js/Kernel-Announcements.js js/Kernel-Classes.js js/Kernel-Collections.js  js/Kernel-Exceptions.js js/Kernel-Methods.js js/Kernel-Objects.js js/Kernel-Transcript.js js/Compiler-AST.js js/Compiler-Core.js js/Compiler-Exceptions.js js/Compiler-IR.js js/Compiler-Inlining.js js/Compiler-Interpreter.js js/Compiler-Semantic.js js/SUnit.js js/Kernel-Tests.js js/Compiler-Tests.js js/SUnit-Tests.js test/Test.js js/parser.js js/init.js > test/run.js
 
 
 #run it!

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff