Browse Source

merge upstream

Laurent Laffont 13 years ago
parent
commit
3f079cc8a5
14 changed files with 8050 additions and 130 deletions
  1. 2 0
      bin/server
  2. 3 3
      js/IDE.deploy.js
  3. 9 9
      js/IDE.js
  4. 224 2
      js/Kernel-Tests.deploy.js
  5. 255 2
      js/Kernel-Tests.js
  6. 153 36
      js/Kernel.deploy.js
  7. 215 56
      js/Kernel.js
  8. 226 0
      server/FileServer.deploy.js
  9. 317 0
      server/FileServer.js
  10. 561 0
      server/FileServer.st
  11. 5856 0
      server/server.js
  12. 6 3
      st/IDE.st
  13. 165 3
      st/Kernel-Tests.st
  14. 58 16
      st/Kernel.st

+ 2 - 0
bin/server

@@ -0,0 +1,2 @@
+#!/bin/bash
+node server/server.js

+ 3 - 3
js/IDE.deploy.js

@@ -1117,7 +1117,7 @@ smalltalk.method({
 selector: 'addInstanceVariableNamed:toClass:',
 fn: function (aString, aClass){
 var self=this;
-smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_addSubclassOf_named_instanceVariableNames_", [smalltalk.send(aClass, "_superclass", []), smalltalk.send(aClass, "_name", []), (function($rec){smalltalk.send($rec, "_add_", [aString]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(smalltalk.send(aClass, "_instanceVariableNames", []), "_copy", []))]);
+smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_addSubclassOf_named_instanceVariableNames_module_", [smalltalk.send(aClass, "_superclass", []), smalltalk.send(aClass, "_name", []), (function($rec){smalltalk.send($rec, "_add_", [aString]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(smalltalk.send(aClass, "_instanceVariableNames", []), "_copy", [])), smalltalk.send(smalltalk.send(aClass, "_module", []), "_name", [])]);
 return self;}
 }),
 smalltalk.Browser);
@@ -1691,7 +1691,7 @@ selector: 'openBrowserOn:',
 fn: function (aMethod){
 var self=this;
 var browser=nil;
-browser=smalltalk.send((smalltalk.Browser || Browser), "_openOn_", [(($receiver = smalltalk.send(smalltalk.send(aMethod, "_class", []), "_isMetaclass", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(aMethod, "_methodClass", []), "_instanceClass", []);})() : (function(){return smalltalk.send(aMethod, "_methodClass", []);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(aMethod, "_methodClass", []), "_instanceClass", []);}), (function(){return smalltalk.send(aMethod, "_methodClass", []);})])]);
+browser=smalltalk.send((smalltalk.Browser || Browser), "_openOn_", [(($receiver = smalltalk.send(smalltalk.send(aMethod, "_methodClass", []), "_isMetaclass", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(aMethod, "_methodClass", []), "_instanceClass", []);})() : (function(){return smalltalk.send(aMethod, "_methodClass", []);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(aMethod, "_methodClass", []), "_instanceClass", []);}), (function(){return smalltalk.send(aMethod, "_methodClass", []);})])]);
 (($receiver = smalltalk.send(smalltalk.send(aMethod, "_methodClass", []), "_isMetaclass", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(browser, "_selectTab_", ["class"]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(browser, "_selectTab_", ["class"]);})]);
 (function($rec){smalltalk.send($rec, "_selectProtocol_", [smalltalk.send(aMethod, "_category", [])]);return smalltalk.send($rec, "_selectMethod_", [aMethod]);})(browser);
 return self;}
@@ -2065,7 +2065,7 @@ smalltalk.method({
 selector: 'clear',
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send((typeof textarea == 'undefined' ? nil : textarea), "_asJQuery", []), "_val_", [""]);
+smalltalk.send(self, "_val_", [""]);
 return self;}
 }),
 smalltalk.SourceArea);

+ 9 - 9
js/IDE.js

@@ -1578,11 +1578,11 @@ selector: 'addInstanceVariableNamed:toClass:',
 category: 'actions',
 fn: function (aString, aClass){
 var self=this;
-smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_addSubclassOf_named_instanceVariableNames_", [smalltalk.send(aClass, "_superclass", []), smalltalk.send(aClass, "_name", []), (function($rec){smalltalk.send($rec, "_add_", [aString]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(smalltalk.send(aClass, "_instanceVariableNames", []), "_copy", []))]);
+smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_addSubclassOf_named_instanceVariableNames_module_", [smalltalk.send(aClass, "_superclass", []), smalltalk.send(aClass, "_name", []), (function($rec){smalltalk.send($rec, "_add_", [aString]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(smalltalk.send(aClass, "_instanceVariableNames", []), "_copy", [])), smalltalk.send(smalltalk.send(aClass, "_module", []), "_name", [])]);
 return self;},
 args: ["aString", "aClass"],
-source: unescape('addInstanceVariableNamed%3A%20aString%20toClass%3A%20aClass%0A%09ClassBuilder%20new%0A%09%09addSubclassOf%3A%20aClass%20superclass%20named%3A%20aClass%20name%20instanceVariableNames%3A%20%28aClass%20instanceVariableNames%20copy%20add%3A%20aString%3B%20yourself%29'),
-messageSends: ["addSubclassOf:named:instanceVariableNames:", "new", "superclass", "name", "add:", "yourself", "copy", "instanceVariableNames"],
+source: unescape('addInstanceVariableNamed%3A%20aString%20toClass%3A%20aClass%0A%09ClassBuilder%20new%0A%09%09addSubclassOf%3A%20aClass%20superclass%20%0A%09%09named%3A%20aClass%20name%20%0A%09%09instanceVariableNames%3A%20%28aClass%20instanceVariableNames%20copy%20add%3A%20aString%3B%20yourself%29%0A%09%09module%3A%20aClass%20module%20name'),
+messageSends: ["addSubclassOf:named:instanceVariableNames:module:", "new", "superclass", "name", "add:", "yourself", "copy", "instanceVariableNames", "module"],
 referencedClasses: [smalltalk.ClassBuilder]
 }),
 smalltalk.Browser);
@@ -2397,13 +2397,13 @@ category: 'actions',
 fn: function (aMethod){
 var self=this;
 var browser=nil;
-browser=smalltalk.send((smalltalk.Browser || Browser), "_openOn_", [(($receiver = smalltalk.send(smalltalk.send(aMethod, "_class", []), "_isMetaclass", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(aMethod, "_methodClass", []), "_instanceClass", []);})() : (function(){return smalltalk.send(aMethod, "_methodClass", []);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(aMethod, "_methodClass", []), "_instanceClass", []);}), (function(){return smalltalk.send(aMethod, "_methodClass", []);})])]);
+browser=smalltalk.send((smalltalk.Browser || Browser), "_openOn_", [(($receiver = smalltalk.send(smalltalk.send(aMethod, "_methodClass", []), "_isMetaclass", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(aMethod, "_methodClass", []), "_instanceClass", []);})() : (function(){return smalltalk.send(aMethod, "_methodClass", []);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(aMethod, "_methodClass", []), "_instanceClass", []);}), (function(){return smalltalk.send(aMethod, "_methodClass", []);})])]);
 (($receiver = smalltalk.send(smalltalk.send(aMethod, "_methodClass", []), "_isMetaclass", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(browser, "_selectTab_", ["class"]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(browser, "_selectTab_", ["class"]);})]);
 (function($rec){smalltalk.send($rec, "_selectProtocol_", [smalltalk.send(aMethod, "_category", [])]);return smalltalk.send($rec, "_selectMethod_", [aMethod]);})(browser);
 return self;},
 args: ["aMethod"],
-source: unescape('openBrowserOn%3A%20aMethod%0A%20%20%20%20%20%20%20%7C%20browser%20%7C%0A%20%20%20%20%20%20%20browser%20%3A%3D%20Browser%20openOn%3A%20%28aMethod%20class%20isMetaclass%20%0A%09%09ifTrue%3A%20%5BaMethod%20methodClass%20instanceClass%5D%20ifFalse%3A%20%5BaMethod%20methodClass%5D%29.%0A%20%20%20%20%20%20%20aMethod%20methodClass%20isMetaclass%20ifTrue%3A%20%5Bbrowser%20selectTab%3A%20%23class%5D.%0A%20%20%20%20%20%20%20browser%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectProtocol%3A%20aMethod%20category%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectMethod%3A%20aMethod'),
-messageSends: ["openOn:", "ifTrue:ifFalse:", "isMetaclass", "class", "instanceClass", "methodClass", "ifTrue:", "selectTab:", "selectProtocol:", "category", "selectMethod:"],
+source: unescape('openBrowserOn%3A%20aMethod%0A%20%20%20%20%20%20%20%7C%20browser%20%7C%0A%20%20%20%20%20%20%20browser%20%3A%3D%20Browser%20openOn%3A%20%28aMethod%20methodClass%20isMetaclass%20%0A%09%09ifTrue%3A%20%5BaMethod%20methodClass%20instanceClass%5D%20ifFalse%3A%20%5BaMethod%20methodClass%5D%29.%0A%20%20%20%20%20%20%20aMethod%20methodClass%20isMetaclass%20ifTrue%3A%20%5Bbrowser%20selectTab%3A%20%23class%5D.%0A%20%20%20%20%20%20%20browser%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectProtocol%3A%20aMethod%20category%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20selectMethod%3A%20aMethod'),
+messageSends: ["openOn:", "ifTrue:ifFalse:", "isMetaclass", "methodClass", "instanceClass", "ifTrue:", "selectTab:", "selectProtocol:", "category", "selectMethod:"],
 referencedClasses: [smalltalk.Browser]
 }),
 smalltalk.ReferencesBrowser);
@@ -2931,11 +2931,11 @@ selector: 'clear',
 category: 'actions',
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send((typeof textarea == 'undefined' ? nil : textarea), "_asJQuery", []), "_val_", [""]);
+smalltalk.send(self, "_val_", [""]);
 return self;},
 args: [],
-source: unescape('clear%0A%20%20%20%20textarea%20asJQuery%20val%3A%20%27%27'),
-messageSends: ["val:", "asJQuery"],
+source: unescape('clear%0A%20%20%20%20%20%20self%20val%3A%20%27%27'),
+messageSends: ["val:"],
 referencedClasses: []
 }),
 smalltalk.SourceArea);

+ 224 - 2
js/Kernel-Tests.deploy.js

@@ -16,7 +16,7 @@ smalltalk.method({
 selector: 'testStreamContents',
 fn: function (){
 var self=this;
-smalltalk.send(self, "_assert_equals_", ["hello world", smalltalk.send(smalltalk.String, "_streamContents_", [(function(aStream){return (function($rec){smalltalk.send($rec, "_nextPutAll_", ["hello"]);smalltalk.send($rec, "_space", []);return smalltalk.send($rec, "_nextPutAll_", ["world"]);})(aStream);})])]);
+smalltalk.send(self, "_assert_equals_", ["hello world", smalltalk.send((smalltalk.String || String), "_streamContents_", [(function(aStream){return (function($rec){smalltalk.send($rec, "_nextPutAll_", ["hello"]);smalltalk.send($rec, "_space", []);return smalltalk.send($rec, "_nextPutAll_", ["world"]);})(aStream);})])]);
 return self;}
 }),
 smalltalk.StringTest);
@@ -33,6 +33,21 @@ return self;}
 }),
 smalltalk.StringTest);
 
+smalltalk.addMethod(
+'_testEquality',
+smalltalk.method({
+selector: 'testEquality',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [smalltalk.send("hello", "__eq", ["hello"])]);
+smalltalk.send(self, "_deny_", [smalltalk.send("hello", "__eq", ["world"])]);
+smalltalk.send(self, "_assert_", [smalltalk.send("hello", "__eq", [smalltalk.send("hello", "_yourself", [])])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send("hello", "_yourself", []), "__eq", ["hello"])]);
+smalltalk.send(self, "_deny_", [smalltalk.send("", "__eq", [(0)])]);
+return self;}
+}),
+smalltalk.StringTest);
+
 
 
 smalltalk.addClass('DictionaryTest', smalltalk.TestCase, [], 'Kernel-Tests');
@@ -42,7 +57,40 @@ smalltalk.method({
 selector: 'testPrintString',
 fn: function (){
 var self=this;
-smalltalk.send(self, "_assert_equals_", [unescape("a%20Dictionary%28%27firstname%27%20-%3E%20%27James%27%20%2C%20%27lastname%27%20-%3E%20%27Bond%27%29"), (function($rec){smalltalk.send($rec, "_at_put_", ["firstname", "James"]);smalltalk.send($rec, "_at_put_", ["lastname", "Bond"]);return smalltalk.send($rec, "_printString", []);})(smalltalk.send(smalltalk.Dictionary, "_new", []))]);
+smalltalk.send(self, "_assert_equals_", [unescape("a%20Dictionary%28%27firstname%27%20-%3E%20%27James%27%20%2C%20%27lastname%27%20-%3E%20%27Bond%27%29"), (function($rec){smalltalk.send($rec, "_at_put_", ["firstname", "James"]);smalltalk.send($rec, "_at_put_", ["lastname", "Bond"]);return smalltalk.send($rec, "_printString", []);})(smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []))]);
+return self;}
+}),
+smalltalk.DictionaryTest);
+
+smalltalk.addMethod(
+'_testEquality',
+smalltalk.method({
+selector: 'testEquality',
+fn: function (){
+var self=this;
+var d1=nil;
+var d2=nil;
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []), "__eq", [smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", [])])]);
+d1=(function($rec){smalltalk.send($rec, "_at_put_", [(1), (2)]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+d2=(function($rec){smalltalk.send($rec, "_at_put_", [(1), (2)]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+smalltalk.send(self, "_assert_", [smalltalk.send(d1, "__eq", [d2])]);
+d2=(function($rec){smalltalk.send($rec, "_at_put_", [(1), (3)]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+smalltalk.send(self, "_deny_", [smalltalk.send(d1, "__eq", [d2])]);
+d2=(function($rec){smalltalk.send($rec, "_at_put_", [(2), (2)]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+smalltalk.send(self, "_deny_", [smalltalk.send(d1, "__eq", [d2])]);
+d2=(function($rec){smalltalk.send($rec, "_at_put_", [(1), (2)]);smalltalk.send($rec, "_at_put_", [(3), (4)]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+smalltalk.send(self, "_deny_", [smalltalk.send(d1, "__eq", [d2])]);
+return self;}
+}),
+smalltalk.DictionaryTest);
+
+smalltalk.addMethod(
+'_testDynamicDictionaries',
+smalltalk.method({
+selector: 'testDynamicDictionaries',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.Dictionary._fromPairs_([smalltalk.send((1), "__minus_gt", ["hello"]),smalltalk.send((2), "__minus_gt", ["world"])]), "__eq", [smalltalk.send((smalltalk.Dictionary || Dictionary), "_with_with_", [smalltalk.send((1), "__minus_gt", ["hello"]), smalltalk.send((2), "__minus_gt", ["world"])])])]);
 return self;}
 }),
 smalltalk.DictionaryTest);
@@ -64,6 +112,180 @@ return self;}
 }),
 smalltalk.BooleanTest);
 
+smalltalk.addMethod(
+'_testEquality',
+smalltalk.method({
+selector: 'testEquality',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_deny_", [smalltalk.send((0), "__eq", [false])]);
+smalltalk.send(self, "_deny_", [smalltalk.send(false, "__eq", [(0)])]);
+smalltalk.send(self, "_deny_", [smalltalk.send("", "__eq", [false])]);
+smalltalk.send(self, "_deny_", [smalltalk.send(false, "__eq", [""])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(true, "__eq", [true])]);
+smalltalk.send(self, "_deny_", [smalltalk.send(false, "__eq", [true])]);
+smalltalk.send(self, "_deny_", [smalltalk.send(true, "__eq", [false])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(false, "__eq", [false])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(true, "_yourself", []), "__eq", [true])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(true, "_yourself", []), "__eq", [smalltalk.send(true, "_yourself", [])])]);
+return self;}
+}),
+smalltalk.BooleanTest);
+
+smalltalk.addMethod(
+'_testLogicKeywords',
+smalltalk.method({
+selector: 'testLogicKeywords',
+fn: function (){
+var self=this;
+(function($rec){smalltalk.send($rec, "_assert_", [smalltalk.send(true, "_and_", [(function(){return true;})])]);smalltalk.send($rec, "_deny_", [smalltalk.send(true, "_and_", [(function(){return false;})])]);smalltalk.send($rec, "_deny_", [smalltalk.send(false, "_and_", [(function(){return true;})])]);return smalltalk.send($rec, "_deny_", [smalltalk.send(false, "_and_", [(function(){return false;})])]);})(self);
+(function($rec){smalltalk.send($rec, "_assert_", [smalltalk.send(true, "_or_", [(function(){return true;})])]);smalltalk.send($rec, "_assert_", [smalltalk.send(true, "_or_", [(function(){return false;})])]);smalltalk.send($rec, "_assert_", [smalltalk.send(false, "_or_", [(function(){return true;})])]);return smalltalk.send($rec, "_deny_", [smalltalk.send(false, "_or_", [(function(){return false;})])]);})(self);
+(function($rec){smalltalk.send($rec, "_assert_", [smalltalk.send(true, "_and_", [(function(){return (1) > (0);})])]);smalltalk.send($rec, "_deny_", [smalltalk.send((1) > (0), "_and_", [(function(){return false;})])]);return smalltalk.send($rec, "_deny_", [smalltalk.send((1) > (0), "_and_", [(function(){return (1) > (2);})])]);})(self);
+(function($rec){smalltalk.send($rec, "_assert_", [smalltalk.send(false, "_or_", [(function(){return (1) > (0);})])]);smalltalk.send($rec, "_assert_", [smalltalk.send((1) > (0), "_or_", [(function(){return false;})])]);return smalltalk.send($rec, "_assert_", [smalltalk.send((1) > (0), "_or_", [(function(){return (1) > (2);})])]);})(self);
+return self;}
+}),
+smalltalk.BooleanTest);
+
+smalltalk.addMethod(
+'_testIfTrueIfFalse',
+smalltalk.method({
+selector: 'testIfTrueIfFalse',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = true).klass === smalltalk.Boolean) ? ($receiver ? (function(){return "alternative block";})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return "alternative block";})]), "__eq", ["alternative block"])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = true).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return "alternative block";})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return "alternative block";})]), "__eq", [nil])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = false).klass === smalltalk.Boolean) ? ($receiver ? (function(){return "alternative block";})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return "alternative block";})]), "__eq", [nil])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = false).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return "alternative block";})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return "alternative block";})]), "__eq", ["alternative block"])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = false).klass === smalltalk.Boolean) ? ($receiver ? (function(){return "alternative block";})() : (function(){return "alternative block2";})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return "alternative block";}), (function(){return "alternative block2";})]), "__eq", ["alternative block2"])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = false).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return "alternative block";})() : (function(){return "alternative block2";})()) : smalltalk.send($receiver, "_ifFalse_ifTrue_", [(function(){return "alternative block";}), (function(){return "alternative block2";})]), "__eq", ["alternative block"])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = true).klass === smalltalk.Boolean) ? ($receiver ? (function(){return "alternative block";})() : (function(){return "alternative block2";})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return "alternative block";}), (function(){return "alternative block2";})]), "__eq", ["alternative block"])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = true).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return "alternative block";})() : (function(){return "alternative block2";})()) : smalltalk.send($receiver, "_ifFalse_ifTrue_", [(function(){return "alternative block";}), (function(){return "alternative block2";})]), "__eq", ["alternative block2"])]);
+return self;}
+}),
+smalltalk.BooleanTest);
+
+
+
+smalltalk.addClass('NumberTest', smalltalk.TestCase, [], 'Kernel-Tests');
+smalltalk.addMethod(
+'_testEquality',
+smalltalk.method({
+selector: 'testEquality',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [smalltalk.send((1), "__eq", [(1)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((0), "__eq", [(0)])]);
+smalltalk.send(self, "_deny_", [smalltalk.send((1), "__eq", [(0)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((1), "_yourself", []), "__eq", [(1)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((1), "__eq", [smalltalk.send((1), "_yourself", [])])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((1), "_yourself", []), "__eq", [smalltalk.send((1), "_yourself", [])])]);
+smalltalk.send(self, "_deny_", [smalltalk.send((0), "__eq", [false])]);
+smalltalk.send(self, "_deny_", [smalltalk.send(false, "__eq", [(0)])]);
+smalltalk.send(self, "_deny_", [smalltalk.send("", "__eq", [(0)])]);
+smalltalk.send(self, "_deny_", [smalltalk.send((0), "__eq", [""])]);
+return self;}
+}),
+smalltalk.NumberTest);
+
+smalltalk.addMethod(
+'_testArithmetic',
+smalltalk.method({
+selector: 'testArithmetic',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [smalltalk.send((1.5) + (1), "__eq", [(2.5)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((2) - (1), "__eq", [(1)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((-2) - (1), "__eq", [(-3)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((12) / (2), "__eq", [(6)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((3) * (4), "__eq", [(12)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = (1) + (2)).klass === smalltalk.Number) ? $receiver *(3) : smalltalk.send($receiver, "__star", [(3)]), "__eq", [(9)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((1) + (2) * (3), "__eq", [(7)])]);
+return self;}
+}),
+smalltalk.NumberTest);
+
+smalltalk.addMethod(
+'_testRounded',
+smalltalk.method({
+selector: 'testRounded',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((3), "_rounded", []), "__eq", [(3)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((3.212), "_rounded", []), "__eq", [(3)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((3.51), "_rounded", []), "__eq", [(4)])]);
+return self;}
+}),
+smalltalk.NumberTest);
+
+smalltalk.addMethod(
+'_testNegated',
+smalltalk.method({
+selector: 'testNegated',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((3), "_negated", []), "__eq", [(-3)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((-3), "_negated", []), "__eq", [(3)])]);
+return self;}
+}),
+smalltalk.NumberTest);
+
+smalltalk.addMethod(
+'_testComparison',
+smalltalk.method({
+selector: 'testComparison',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [(3) > (2)]);
+smalltalk.send(self, "_assert_", [(2) < (3)]);
+smalltalk.send(self, "_deny_", [(3) < (2)]);
+smalltalk.send(self, "_deny_", [(2) > (3)]);
+smalltalk.send(self, "_assert_", [(3) >= (3)]);
+smalltalk.send(self, "_assert_", [(3.1) >= (3)]);
+smalltalk.send(self, "_assert_", [(3) <= (3)]);
+smalltalk.send(self, "_assert_", [(3) <= (3.1)]);
+return self;}
+}),
+smalltalk.NumberTest);
+
+smalltalk.addMethod(
+'_testTruncated',
+smalltalk.method({
+selector: 'testTruncated',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((3), "_truncated", []), "__eq", [(3)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((3.212), "_truncated", []), "__eq", [(3)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((3.51), "_truncated", []), "__eq", [(3)])]);
+return self;}
+}),
+smalltalk.NumberTest);
+
+
+
+smalltalk.addClass('NumberTest', smalltalk.TestCase, [], 'Kernel-Tests');
+smalltalk.addMethod(
+'_testPrintShowingDecimalPlaces',
+smalltalk.method({
+selector: 'testPrintShowingDecimalPlaces',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_equals_", ["23.00", smalltalk.send((23), "_printShowingDecimalPlaces_", [(2)])]);
+smalltalk.send(self, "_assert_equals_", ["23.57", smalltalk.send((23.5698), "_printShowingDecimalPlaces_", [(2)])]);
+smalltalk.send(self, "_assert_equals_", [unescape("-234.56700"), smalltalk.send(smalltalk.send((234.567), "_negated", []), "_printShowingDecimalPlaces_", [(5)])]);
+smalltalk.send(self, "_assert_equals_", ["23", smalltalk.send((23.4567), "_printShowingDecimalPlaces_", [(0)])]);
+smalltalk.send(self, "_assert_equals_", ["24", smalltalk.send((23.5567), "_printShowingDecimalPlaces_", [(0)])]);
+smalltalk.send(self, "_assert_equals_", [unescape("-23"), smalltalk.send(smalltalk.send((23.4567), "_negated", []), "_printShowingDecimalPlaces_", [(0)])]);
+smalltalk.send(self, "_assert_equals_", [unescape("-24"), smalltalk.send(smalltalk.send((23.5567), "_negated", []), "_printShowingDecimalPlaces_", [(0)])]);
+smalltalk.send(self, "_assert_equals_", ["100000000.0", smalltalk.send((100000000), "_printShowingDecimalPlaces_", [(1)])]);
+smalltalk.send(self, "_assert_equals_", ["0.98000", smalltalk.send((0.98), "_printShowingDecimalPlaces_", [(5)])]);
+smalltalk.send(self, "_assert_equals_", [unescape("-0.98"), smalltalk.send(smalltalk.send((0.98), "_negated", []), "_printShowingDecimalPlaces_", [(2)])]);
+smalltalk.send(self, "_assert_equals_", ["2.57", smalltalk.send((2.567), "_printShowingDecimalPlaces_", [(2)])]);
+smalltalk.send(self, "_assert_equals_", [unescape("-2.57"), smalltalk.send((-2.567), "_printShowingDecimalPlaces_", [(2)])]);
+smalltalk.send(self, "_assert_equals_", ["0.00", smalltalk.send((0), "_printShowingDecimalPlaces_", [(2)])]);
+return self;}
+}),
+smalltalk.NumberTest);
+
 
 
 smalltalk.addClass('NumberTest', smalltalk.TestCase, [], 'Kernel-Tests');

+ 255 - 2
js/Kernel-Tests.js

@@ -48,6 +48,26 @@ referencedClasses: []
 }),
 smalltalk.StringTest);
 
+smalltalk.addMethod(
+'_testEquality',
+smalltalk.method({
+selector: 'testEquality',
+category: 'tests',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [smalltalk.send("hello", "__eq", ["hello"])]);
+smalltalk.send(self, "_deny_", [smalltalk.send("hello", "__eq", ["world"])]);
+smalltalk.send(self, "_assert_", [smalltalk.send("hello", "__eq", [smalltalk.send("hello", "_yourself", [])])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send("hello", "_yourself", []), "__eq", ["hello"])]);
+smalltalk.send(self, "_deny_", [smalltalk.send("", "__eq", [(0)])]);
+return self;},
+args: [],
+source: unescape('testEquality%0A%09self%20assert%3A%20%27hello%27%20%3D%20%27hello%27.%0A%09self%20deny%3A%20%27hello%27%20%3D%20%27world%27.%0A%0A%09self%20assert%3A%20%27hello%27%20%20%3D%20%27hello%27%20yourself.%0A%09self%20assert%3A%20%27hello%27%20yourself%20%3D%20%27hello%27.%0A%0A%09%22test%20JS%20falsy%20value%22%0A%09self%20deny%3A%20%27%27%20%3D%200'),
+messageSends: ["assert:", unescape("%3D"), "deny:", "yourself"],
+referencedClasses: []
+}),
+smalltalk.StringTest);
+
 
 
 smalltalk.addClass('DictionaryTest', smalltalk.TestCase, [], 'Kernel-Tests');
@@ -61,12 +81,55 @@ var self=this;
 smalltalk.send(self, "_assert_equals_", [unescape("a%20Dictionary%28%27firstname%27%20-%3E%20%27James%27%20%2C%20%27lastname%27%20-%3E%20%27Bond%27%29"), (function($rec){smalltalk.send($rec, "_at_put_", ["firstname", "James"]);smalltalk.send($rec, "_at_put_", ["lastname", "Bond"]);return smalltalk.send($rec, "_printString", []);})(smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []))]);
 return self;},
 args: [],
-source: unescape('testPrintString%0A%09self%20%0A%09%09assert%3A%20%27a%20Dictionary%28%27%27firstname%27%27%20-%3E%20%27%27James%27%27%20%2C%20%27%27lastname%27%27%20-%3E%20%27%27Bond%27%27%29%27%20%0A%09%09equals%3A%20%28Dictionary%20new%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09at%3A%27firstname%27%20put%3A%20%27James%27%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09at%3A%27lastname%27%20put%3A%20%27Bond%27%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09printString%29'),
+source: unescape('testPrintString%0A%09self%0A%09%09assert%3A%20%27a%20Dictionary%28%27%27firstname%27%27%20-%3E%20%27%27James%27%27%20%2C%20%27%27lastname%27%27%20-%3E%20%27%27Bond%27%27%29%27%20%0A%09%09equals%3A%20%28Dictionary%20new%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09at%3A%27firstname%27%20put%3A%20%27James%27%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09at%3A%27lastname%27%20put%3A%20%27Bond%27%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09printString%29'),
 messageSends: ["assert:equals:", "at:put:", "printString", "new"],
 referencedClasses: [smalltalk.Dictionary]
 }),
 smalltalk.DictionaryTest);
 
+smalltalk.addMethod(
+'_testEquality',
+smalltalk.method({
+selector: 'testEquality',
+category: 'tests',
+fn: function (){
+var self=this;
+var d1=nil;
+var d2=nil;
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []), "__eq", [smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", [])])]);
+d1=(function($rec){smalltalk.send($rec, "_at_put_", [(1), (2)]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+d2=(function($rec){smalltalk.send($rec, "_at_put_", [(1), (2)]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+smalltalk.send(self, "_assert_", [smalltalk.send(d1, "__eq", [d2])]);
+d2=(function($rec){smalltalk.send($rec, "_at_put_", [(1), (3)]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+smalltalk.send(self, "_deny_", [smalltalk.send(d1, "__eq", [d2])]);
+d2=(function($rec){smalltalk.send($rec, "_at_put_", [(2), (2)]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+smalltalk.send(self, "_deny_", [smalltalk.send(d1, "__eq", [d2])]);
+d2=(function($rec){smalltalk.send($rec, "_at_put_", [(1), (2)]);smalltalk.send($rec, "_at_put_", [(3), (4)]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []));
+smalltalk.send(self, "_deny_", [smalltalk.send(d1, "__eq", [d2])]);
+return self;},
+args: [],
+source: unescape('testEquality%0A%09%7C%20d1%20d2%20%7C%0A%0A%09self%20assert%3A%20Dictionary%20new%20%3D%20Dictionary%20new.%0A%09%09%0A%09d1%20%3A%3D%20Dictionary%20new%20at%3A%201%20put%3A%202%3B%20yourself.%0A%09d2%20%3A%3D%20Dictionary%20new%20at%3A%201%20put%3A%202%3B%20yourself.%0A%09self%20assert%3A%20d1%20%3D%20d2.%0A%0A%09d2%20%3A%3D%20Dictionary%20new%20at%3A%201%20put%3A%203%3B%20yourself.%0A%09self%20deny%3A%20d1%20%3D%20d2.%0A%0A%09d2%20%3A%3D%20Dictionary%20new%20at%3A%202%20put%3A%202%3B%20yourself.%0A%09self%20deny%3A%20d1%20%3D%20d2.%0A%0A%09d2%20%3A%3D%20Dictionary%20new%20at%3A%201%20put%3A%202%3B%20at%3A%203%20put%3A%204%3B%20yourself.%0A%09self%20deny%3A%20d1%20%3D%20d2.'),
+messageSends: ["assert:", unescape("%3D"), "new", "at:put:", "yourself", "deny:"],
+referencedClasses: [smalltalk.Dictionary]
+}),
+smalltalk.DictionaryTest);
+
+smalltalk.addMethod(
+'_testDynamicDictionaries',
+smalltalk.method({
+selector: 'testDynamicDictionaries',
+category: 'tests',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.Dictionary._fromPairs_([smalltalk.send((1), "__minus_gt", ["hello"]),smalltalk.send((2), "__minus_gt", ["world"])]), "__eq", [smalltalk.send((smalltalk.Dictionary || Dictionary), "_with_with_", [smalltalk.send((1), "__minus_gt", ["hello"]), smalltalk.send((2), "__minus_gt", ["world"])])])]);
+return self;},
+args: [],
+source: unescape('testDynamicDictionaries%0A%09self%20assert%3A%20%23%7B1%20-%3E%20%27hello%27.%202%20-%3E%20%27world%27%7D%20%3D%20%28Dictionary%20with%3A%201%20-%3E%20%27hello%27%20with%3A%202%20-%3E%20%27world%27%29'),
+messageSends: ["assert:", unescape("%3D"), unescape("-%3E"), "with:with:"],
+referencedClasses: [smalltalk.Dictionary]
+}),
+smalltalk.DictionaryTest);
+
 
 
 smalltalk.addClass('BooleanTest', smalltalk.TestCase, [], 'Kernel-Tests');
@@ -83,15 +146,205 @@ var self=this;
 (function($rec){smalltalk.send($rec, "_assert_", [smalltalk.send(false, "_|", [(1) > (0)])]);smalltalk.send($rec, "_assert_", [smalltalk.send((1) > (0), "_|", [false])]);return smalltalk.send($rec, "_assert_", [smalltalk.send((1) > (0), "_|", [(1) > (2)])]);})(self);
 return self;},
 args: [],
-source: unescape('testLogic%0A%0A%09%22Trivial%20logic%20table%22%0A%09self%20assert%3A%20%28true%20%26%20true%29%3B%20deny%3A%20%28true%20%26%20false%29%3B%20deny%3A%20%28false%20%26%20true%29%3B%20deny%3A%20%28false%20%26%20false%29.%0A%09self%20assert%3A%20%28true%20%7C%20true%29%3B%20assert%3A%20%28true%20%7C%20false%29%3B%20assert%3A%20%28false%20%7C%20true%29%3B%20deny%3A%20%28false%20%7C%20false%29.%0A%20%20%20%20%20%20%20%20%22Checking%20that%20expressions%20work%20fine%20too%22%0A%09self%20assert%3A%20%28true%20%26%20%281%20%3E%200%29%29%3B%20deny%3A%20%28%281%20%3E%200%29%20%26%20false%29%3B%20deny%3A%20%28%281%20%3E%200%29%20%26%20%281%20%3E%202%29%29.%0A%20%20%20%20%20%20%20%20self%20assert%3A%20%28false%20%7C%20%281%20%3E%200%29%29%3B%20assert%3A%20%28%281%20%3E%200%29%20%7C%20false%29%3B%20assert%3A%20%28%281%20%3E%200%29%20%7C%20%281%20%3E%202%29%29'),
+source: unescape('testLogic%0A%20%0A%09%22Trivial%20logic%20table%22%0A%09self%20assert%3A%20%28true%20%26%20true%29%3B%20deny%3A%20%28true%20%26%20false%29%3B%20deny%3A%20%28false%20%26%20true%29%3B%20deny%3A%20%28false%20%26%20false%29.%0A%09self%20assert%3A%20%28true%20%7C%20true%29%3B%20assert%3A%20%28true%20%7C%20false%29%3B%20assert%3A%20%28false%20%7C%20true%29%3B%20deny%3A%20%28false%20%7C%20false%29.%0A%20%20%20%20%20%20%20%20%22Checking%20that%20expressions%20work%20fine%20too%22%0A%09self%20assert%3A%20%28true%20%26%20%281%20%3E%200%29%29%3B%20deny%3A%20%28%281%20%3E%200%29%20%26%20false%29%3B%20deny%3A%20%28%281%20%3E%200%29%20%26%20%281%20%3E%202%29%29.%0A%20%20%20%20%20%20%20%20self%20assert%3A%20%28false%20%7C%20%281%20%3E%200%29%29%3B%20assert%3A%20%28%281%20%3E%200%29%20%7C%20false%29%3B%20assert%3A%20%28%281%20%3E%200%29%20%7C%20%281%20%3E%202%29%29'),
 messageSends: ["assert:", unescape("%26"), "deny:", unescape("%7C"), unescape("%3E")],
 referencedClasses: []
 }),
 smalltalk.BooleanTest);
 
+smalltalk.addMethod(
+'_testEquality',
+smalltalk.method({
+selector: 'testEquality',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_deny_", [(0) == false]);
+smalltalk.send(self, "_deny_", [smalltalk.send(false, "__eq", [(0)])]);
+smalltalk.send(self, "_deny_", [smalltalk.send("", "__eq", [false])]);
+smalltalk.send(self, "_deny_", [smalltalk.send(false, "__eq", [""])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(true, "__eq", [true])]);
+smalltalk.send(self, "_deny_", [smalltalk.send(false, "__eq", [true])]);
+smalltalk.send(self, "_deny_", [smalltalk.send(true, "__eq", [false])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(false, "__eq", [false])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(true, "_yourself", []), "__eq", [true])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send(true, "_yourself", []), "__eq", [smalltalk.send(true, "_yourself", [])])]);
+return self;},
+args: [],
+source: unescape('testEquality%0A%09%22We%27re%20on%20top%20of%20JS...just%20be%20sure%20to%20check%20the%20basics%21%22%0A%0A%09self%20deny%3A%200%20%3D%20false.%20%0A%09self%20deny%3A%20false%20%3D%200.%0A%09self%20deny%3A%20%27%27%20%3D%20false.%0A%09self%20deny%3A%20false%20%3D%20%27%27.%0A%0A%09self%20assert%3A%20true%20%3D%20true.%0A%09self%20deny%3A%20false%20%3D%20true.%0A%09self%20deny%3A%20true%20%3D%20false.%0A%09self%20assert%3A%20false%20%3D%20false.%0A%0A%09%22JS%20may%20do%20some%20type%20coercing%20after%20sending%20a%20message%22%0A%09self%20assert%3A%20true%20yourself%20%3D%20true.%0A%09self%20assert%3A%20true%20yourself%20%3D%20true%20yourself'),
+messageSends: ["deny:", unescape("%3D"), "assert:", "yourself"],
+referencedClasses: []
+}),
+smalltalk.BooleanTest);
+
+smalltalk.addMethod(
+'_testLogicKeywords',
+smalltalk.method({
+selector: 'testLogicKeywords',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+(function($rec){smalltalk.send($rec, "_assert_", [smalltalk.send(true, "_and_", [(function(){return true;})])]);smalltalk.send($rec, "_deny_", [smalltalk.send(true, "_and_", [(function(){return false;})])]);smalltalk.send($rec, "_deny_", [smalltalk.send(false, "_and_", [(function(){return true;})])]);return smalltalk.send($rec, "_deny_", [smalltalk.send(false, "_and_", [(function(){return false;})])]);})(self);
+(function($rec){smalltalk.send($rec, "_assert_", [smalltalk.send(true, "_or_", [(function(){return true;})])]);smalltalk.send($rec, "_assert_", [smalltalk.send(true, "_or_", [(function(){return false;})])]);smalltalk.send($rec, "_assert_", [smalltalk.send(false, "_or_", [(function(){return true;})])]);return smalltalk.send($rec, "_deny_", [smalltalk.send(false, "_or_", [(function(){return false;})])]);})(self);
+(function($rec){smalltalk.send($rec, "_assert_", [smalltalk.send(true, "_and_", [(function(){return (1) > (0);})])]);smalltalk.send($rec, "_deny_", [smalltalk.send((1) > (0), "_and_", [(function(){return false;})])]);return smalltalk.send($rec, "_deny_", [smalltalk.send((1) > (0), "_and_", [(function(){return (1) > (2);})])]);})(self);
+(function($rec){smalltalk.send($rec, "_assert_", [smalltalk.send(false, "_or_", [(function(){return (1) > (0);})])]);smalltalk.send($rec, "_assert_", [smalltalk.send((1) > (0), "_or_", [(function(){return false;})])]);return smalltalk.send($rec, "_assert_", [smalltalk.send((1) > (0), "_or_", [(function(){return (1) > (2);})])]);})(self);
+return self;},
+args: [],
+source: unescape('testLogicKeywords%0A%20%0A%09%22Trivial%20logic%20table%22%0A%09self%20%0A%09%09assert%3A%20%28true%20and%3A%20%5B%20true%5D%29%3B%20%0A%09%09deny%3A%20%28true%20and%3A%20%5B%20false%20%5D%29%3B%20%0A%09%09deny%3A%20%28false%20and%3A%20%5B%20true%20%5D%29%3B%20%0A%09%09deny%3A%20%28false%20and%3A%20%5B%20false%20%5D%29.%0A%09self%20%0A%09%09assert%3A%20%28true%20or%3A%20%5B%20true%20%5D%29%3B%20%0A%09%09assert%3A%20%28true%20or%3A%20%5B%20false%20%5D%29%3B%20%0A%09%09assert%3A%20%28false%20or%3A%20%5B%20true%20%5D%29%3B%20%0A%09%09deny%3A%20%28false%20or%3A%20%5B%20false%20%5D%29.%0A%20%20%20%20%20%20%20%20%0A%09%22Checking%20that%20expressions%20work%20fine%20too%22%0A%09self%20%0A%09%09assert%3A%20%28true%20and%3A%20%5B%201%20%3E%200%20%5D%29%3B%20%0A%09%09deny%3A%20%28%281%20%3E%200%29%20and%3A%20%5B%20false%20%5D%29%3B%20%0A%09%09deny%3A%20%28%281%20%3E%200%29%20and%3A%20%5B%201%20%3E%202%20%5D%29.%0A%20%20%20%20%20%20%20%20self%20%0A%09%09assert%3A%20%28false%20or%3A%20%5B%201%20%3E%200%20%5D%29%3B%20%0A%09%09assert%3A%20%28%281%20%3E%200%29%20or%3A%20%5B%20false%20%5D%29%3B%20%0A%09%09assert%3A%20%28%281%20%3E%200%29%20or%3A%20%5B%201%20%3E%202%20%5D%29'),
+messageSends: ["assert:", "and:", "deny:", "or:", unescape("%3E")],
+referencedClasses: []
+}),
+smalltalk.BooleanTest);
+
+smalltalk.addMethod(
+'_testIfTrueIfFalse',
+smalltalk.method({
+selector: 'testIfTrueIfFalse',
+category: 'not yet classified',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = true).klass === smalltalk.Boolean) ? ($receiver ? (function(){return "alternative block";})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return "alternative block";})]), "__eq", ["alternative block"])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = true).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return "alternative block";})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return "alternative block";})]), "__eq", [nil])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = false).klass === smalltalk.Boolean) ? ($receiver ? (function(){return "alternative block";})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return "alternative block";})]), "__eq", [nil])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = false).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return "alternative block";})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return "alternative block";})]), "__eq", ["alternative block"])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = false).klass === smalltalk.Boolean) ? ($receiver ? (function(){return "alternative block";})() : (function(){return "alternative block2";})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return "alternative block";}), (function(){return "alternative block2";})]), "__eq", ["alternative block2"])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = false).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return "alternative block";})() : (function(){return "alternative block2";})()) : smalltalk.send($receiver, "_ifFalse_ifTrue_", [(function(){return "alternative block";}), (function(){return "alternative block2";})]), "__eq", ["alternative block"])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = true).klass === smalltalk.Boolean) ? ($receiver ? (function(){return "alternative block";})() : (function(){return "alternative block2";})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return "alternative block";}), (function(){return "alternative block2";})]), "__eq", ["alternative block"])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = true).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return "alternative block";})() : (function(){return "alternative block2";})()) : smalltalk.send($receiver, "_ifFalse_ifTrue_", [(function(){return "alternative block";}), (function(){return "alternative block2";})]), "__eq", ["alternative block2"])]);
+return self;},
+args: [],
+source: unescape('testIfTrueIfFalse%0A%20%0A%09self%20assert%3A%20%28true%20ifTrue%3A%20%5B%27alternative%20block%27%5D%29%20%3D%20%27alternative%20block%27.%0A%09self%20assert%3A%20%28true%20ifFalse%3A%20%5B%27alternative%20block%27%5D%29%20%3D%20nil.%0A%0A%09self%20assert%3A%20%28false%20ifTrue%3A%20%5B%27alternative%20block%27%5D%29%20%3D%20nil.%0A%09self%20assert%3A%20%28false%20ifFalse%3A%20%5B%27alternative%20block%27%5D%29%20%3D%20%27alternative%20block%27.%0A%0A%09self%20assert%3A%20%28false%20ifTrue%3A%20%5B%27alternative%20block%27%5D%20ifFalse%3A%20%5B%27alternative%20block2%27%5D%29%20%3D%20%27alternative%20block2%27.%0A%09self%20assert%3A%20%28false%20ifFalse%3A%20%5B%27alternative%20block%27%5D%20ifTrue%3A%20%5B%27alternative%20block2%27%5D%29%20%3D%20%27alternative%20block%27.%0A%0A%09self%20assert%3A%20%28true%20ifTrue%3A%20%5B%27alternative%20block%27%5D%20ifFalse%3A%20%5B%27alternative%20block2%27%5D%29%20%3D%20%27alternative%20block%27.%0A%09self%20assert%3A%20%28true%20ifFalse%3A%20%5B%27alternative%20block%27%5D%20ifTrue%3A%20%5B%27alternative%20block2%27%5D%29%20%3D%20%27alternative%20block2%27.'),
+messageSends: ["assert:", unescape("%3D"), "ifTrue:", "ifFalse:", "ifTrue:ifFalse:", "ifFalse:ifTrue:"],
+referencedClasses: []
+}),
+smalltalk.BooleanTest);
+
 
 
 smalltalk.addClass('NumberTest', smalltalk.TestCase, [], 'Kernel-Tests');
+smalltalk.addMethod(
+'_testEquality',
+smalltalk.method({
+selector: 'testEquality',
+category: 'tests',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [(1) == (1)]);
+smalltalk.send(self, "_assert_", [(0) == (0)]);
+smalltalk.send(self, "_deny_", [(1) == (0)]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((1), "_yourself", []), "__eq", [(1)])]);
+smalltalk.send(self, "_assert_", [(1) == smalltalk.send((1), "_yourself", [])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((1), "_yourself", []), "__eq", [smalltalk.send((1), "_yourself", [])])]);
+smalltalk.send(self, "_deny_", [(0) == false]);
+smalltalk.send(self, "_deny_", [smalltalk.send(false, "__eq", [(0)])]);
+smalltalk.send(self, "_deny_", [smalltalk.send("", "__eq", [(0)])]);
+smalltalk.send(self, "_deny_", [(0) == ""]);
+return self;},
+args: [],
+source: unescape('testEquality%0A%09self%20assert%3A%201%20%3D%201.%0A%09self%20assert%3A%200%20%3D%200.%0A%09self%20deny%3A%201%20%3D%200.%0A%0A%09self%20assert%3A%201%20yourself%20%3D%201.%0A%09self%20assert%3A%201%20%3D%201%20yourself.%0A%09self%20assert%3A%201%20yourself%20%3D%201%20yourself.%0A%09%0A%09self%20deny%3A%200%20%3D%20false.%0A%09self%20deny%3A%20false%20%3D%200.%0A%09self%20deny%3A%20%27%27%20%3D%200.%0A%09self%20deny%3A%200%20%3D%20%27%27'),
+messageSends: ["assert:", unescape("%3D"), "deny:", "yourself"],
+referencedClasses: []
+}),
+smalltalk.NumberTest);
+
+smalltalk.addMethod(
+'_testArithmetic',
+smalltalk.method({
+selector: 'testArithmetic',
+category: 'tests',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [smalltalk.send((1.5) + (1), "__eq", [(2.5)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((2) - (1), "__eq", [(1)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((-2) - (1), "__eq", [(-3)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((12) / (2), "__eq", [(6)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((3) * (4), "__eq", [(12)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((($receiver = (1) + (2)).klass === smalltalk.Number) ? $receiver *(3) : smalltalk.send($receiver, "__star", [(3)]), "__eq", [(9)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send((1) + (2) * (3), "__eq", [(7)])]);
+return self;},
+args: [],
+source: unescape('testArithmetic%0A%09%0A%09%22We%20rely%20on%20JS%20here%2C%20so%20we%20won%27t%20test%20complex%20behavior%2C%20just%20check%20if%20%0A%09message%20sends%20are%20corrects%22%0A%0A%09self%20assert%3A%201.5%20+%201%20%3D%202.5.%0A%09self%20assert%3A%202%20-%201%20%3D%201.%0A%09self%20assert%3A%20-2%20-%201%20%3D%20-3.%0A%09self%20assert%3A%2012%20/%202%20%3D%206.%0A%09self%20assert%3A%203%20*%204%20%3D%2012.%0A%0A%09%22Simple%20parenthesis%20and%20execution%20order%22%0A%0A%09self%20assert%3A%201%20+%202%20*%203%20%3D%209.%0A%09self%20assert%3A%201%20+%20%282%20*%203%29%20%3D%207'),
+messageSends: ["assert:", unescape("%3D"), unescape("+"), unescape("-"), unescape("/"), unescape("*")],
+referencedClasses: []
+}),
+smalltalk.NumberTest);
+
+smalltalk.addMethod(
+'_testRounded',
+smalltalk.method({
+selector: 'testRounded',
+category: 'tests',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((3), "_rounded", []), "__eq", [(3)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((3.212), "_rounded", []), "__eq", [(3)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((3.51), "_rounded", []), "__eq", [(4)])]);
+return self;},
+args: [],
+source: unescape('testRounded%0A%09%0A%09self%20assert%3A%203%20rounded%20%3D%203.%0A%09self%20assert%3A%203.212%20rounded%20%3D%203.%0A%09self%20assert%3A%203.51%20rounded%20%3D%204'),
+messageSends: ["assert:", unescape("%3D"), "rounded"],
+referencedClasses: []
+}),
+smalltalk.NumberTest);
+
+smalltalk.addMethod(
+'_testNegated',
+smalltalk.method({
+selector: 'testNegated',
+category: 'tests',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((3), "_negated", []), "__eq", [(-3)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((-3), "_negated", []), "__eq", [(3)])]);
+return self;},
+args: [],
+source: unescape('testNegated%0A%09self%20assert%3A%203%20negated%20%3D%20-3.%0A%09self%20assert%3A%20-3%20negated%20%3D%203'),
+messageSends: ["assert:", unescape("%3D"), "negated"],
+referencedClasses: []
+}),
+smalltalk.NumberTest);
+
+smalltalk.addMethod(
+'_testComparison',
+smalltalk.method({
+selector: 'testComparison',
+category: 'tests',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [(3) > (2)]);
+smalltalk.send(self, "_assert_", [(2) < (3)]);
+smalltalk.send(self, "_deny_", [(3) < (2)]);
+smalltalk.send(self, "_deny_", [(2) > (3)]);
+smalltalk.send(self, "_assert_", [(3) >= (3)]);
+smalltalk.send(self, "_assert_", [(3.1) >= (3)]);
+smalltalk.send(self, "_assert_", [(3) <= (3)]);
+smalltalk.send(self, "_assert_", [(3) <= (3.1)]);
+return self;},
+args: [],
+source: unescape('testComparison%0A%0A%09self%20assert%3A%203%20%3E%202.%0A%09self%20assert%3A%202%20%3C%203.%0A%09%0A%09self%20deny%3A%203%20%3C%202.%0A%09self%20deny%3A%202%20%3E%203.%0A%0A%09self%20assert%3A%203%20%3E%3D%203.%0A%09self%20assert%3A%203.1%20%3E%3D%203.%0A%09self%20assert%3A%203%20%3C%3D%203.%0A%09self%20assert%3A%203%20%3C%3D%203.1'),
+messageSends: ["assert:", unescape("%3E"), unescape("%3C"), "deny:", unescape("%3E%3D"), unescape("%3C%3D")],
+referencedClasses: []
+}),
+smalltalk.NumberTest);
+
+smalltalk.addMethod(
+'_testTruncated',
+smalltalk.method({
+selector: 'testTruncated',
+category: 'tests',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((3), "_truncated", []), "__eq", [(3)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((3.212), "_truncated", []), "__eq", [(3)])]);
+smalltalk.send(self, "_assert_", [smalltalk.send(smalltalk.send((3.51), "_truncated", []), "__eq", [(3)])]);
+return self;},
+args: [],
+source: unescape('testTruncated%0A%09%0A%09self%20assert%3A%203%20truncated%20%3D%203.%0A%09self%20assert%3A%203.212%20truncated%20%3D%203.%0A%09self%20assert%3A%203.51%20truncated%20%3D%203'),
+messageSends: ["assert:", unescape("%3D"), "truncated"],
+referencedClasses: []
+}),
+smalltalk.NumberTest);
+
 smalltalk.addMethod(
 '_testPrintShowingDecimalPlaces',
 smalltalk.method({

+ 153 - 36
js/Kernel.deploy.js

@@ -5,7 +5,7 @@ smalltalk.method({
 selector: '=',
 fn: function (anObject){
 var self=this;
-return self == anObject;
+return smalltalk.send(self, "__eq_eq", [anObject]);
 return self;}
 }),
 smalltalk.Object);
@@ -526,6 +526,28 @@ return self;}
 }),
 smalltalk.Object);
 
+smalltalk.addMethod(
+'__eq_eq',
+smalltalk.method({
+selector: '==',
+fn: function (anObject){
+var self=this;
+return self === anObject;
+return self;}
+}),
+smalltalk.Object);
+
+smalltalk.addMethod(
+'_~~',
+smalltalk.method({
+selector: '~~',
+fn: function (anObject){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "__eq_eq", [anObject]), "__eq", [false]);
+return self;}
+}),
+smalltalk.Object);
+
 
 smalltalk.addMethod(
 '_initialize',
@@ -1299,17 +1321,6 @@ smalltalk.CompiledMethod);
 
 
 smalltalk.addClass('Number', smalltalk.Object, [], 'Kernel');
-smalltalk.addMethod(
-'__eq',
-smalltalk.method({
-selector: '=',
-fn: function (aNumber){
-var self=this;
-return Number(self) == aNumber;
-return self;}
-}),
-smalltalk.Number);
-
 smalltalk.addMethod(
 '__gt',
 smalltalk.method({
@@ -1644,6 +1655,35 @@ return self;}
 smalltalk.Number);
 
 smalltalk.addMethod(
+<<<<<<< HEAD
+=======
+'__eq',
+smalltalk.method({
+selector: '=',
+fn: function (aNumber){
+var self=this;
+try{(($receiver = smalltalk.send(smalltalk.send(aNumber, "_class", []), "__eq", [smalltalk.send(self, "_class", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]);
+return Number(self) == aNumber;
+return self;
+} catch(e) {if(e.name === 'stReturn' && e.selector === '__eq'){return e.fn()} throw(e)}}
+}),
+smalltalk.Number);
+
+smalltalk.addMethod(
+'__eq_eq',
+smalltalk.method({
+selector: '==',
+fn: function (aNumber){
+var self=this;
+try{(($receiver = smalltalk.send(smalltalk.send(aNumber, "_class", []), "__eq", [smalltalk.send(self, "_class", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq_eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq_eq', fn: function(){return false}})})();})]);
+return Number(self) === Number(aNumber);
+return self;
+} catch(e) {if(e.name === 'stReturn' && e.selector === '__eq_eq'){return e.fn()} throw(e)}}
+}),
+smalltalk.Number);
+
+smalltalk.addMethod(
+>>>>>>> upstream/master
 '_printShowingDecimalPlaces_',
 smalltalk.method({
 selector: 'printShowingDecimalPlaces:',
@@ -1847,17 +1887,6 @@ smalltalk.BlockClosure);
 
 
 smalltalk.addClass('Boolean', smalltalk.Object, [], 'Kernel');
-smalltalk.addMethod(
-'__eq',
-smalltalk.method({
-selector: '=',
-fn: function (aBoolean){
-var self=this;
-return Boolean(self == true) == aBoolean;
-return self;}
-}),
-smalltalk.Boolean);
-
 smalltalk.addMethod(
 '_shallowCopy',
 smalltalk.method({
@@ -2019,6 +2048,32 @@ return self;}
 }),
 smalltalk.Boolean);
 
+smalltalk.addMethod(
+'__eq',
+smalltalk.method({
+selector: '=',
+fn: function (aBoolean){
+var self=this;
+try{(($receiver = smalltalk.send(smalltalk.send(aBoolean, "_class", []), "__eq", [smalltalk.send(self, "_class", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]);
+return Boolean(self == true) == aBoolean;
+return self;
+} catch(e) {if(e.name === 'stReturn' && e.selector === '__eq'){return e.fn()} throw(e)}}
+}),
+smalltalk.Boolean);
+
+smalltalk.addMethod(
+'__eq_eq',
+smalltalk.method({
+selector: '==',
+fn: function (aBoolean){
+var self=this;
+try{(($receiver = smalltalk.send(smalltalk.send(aBoolean, "_class", []), "__eq", [smalltalk.send(self, "_class", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq_eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq_eq', fn: function(){return false}})})();})]);
+return Boolean(self == true) === Boolean(aBoolean == true);
+return self;
+} catch(e) {if(e.name === 'stReturn' && e.selector === '__eq_eq'){return e.fn()} throw(e)}}
+}),
+smalltalk.Boolean);
+
 
 
 smalltalk.addClass('Date', smalltalk.Object, [], 'Kernel');
@@ -2950,6 +3005,28 @@ return self;}
 }),
 smalltalk.Collection);
 
+smalltalk.addMethod(
+'_ifNotEmpty_',
+smalltalk.method({
+selector: 'ifNotEmpty:',
+fn: function (aBlock){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_notEmpty", []), "_ifTrue_", [aBlock]);
+return self;}
+}),
+smalltalk.Collection);
+
+smalltalk.addMethod(
+'_ifEmpty_',
+smalltalk.method({
+selector: 'ifEmpty:',
+fn: function (aBlock){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_isEmpty", []), "_ifTrue_", [aBlock]);
+return self;}
+}),
+smalltalk.Collection);
+
 
 smalltalk.addMethod(
 '_streamClass',
@@ -3230,17 +3307,6 @@ smalltalk.SequenceableCollection);
 
 
 smalltalk.addClass('String', smalltalk.SequenceableCollection, [], 'Kernel');
-smalltalk.addMethod(
-'__eq',
-smalltalk.method({
-selector: '=',
-fn: function (aString){
-var self=this;
-return String(self) == aString;
-return self;}
-}),
-smalltalk.String);
-
 smalltalk.addMethod(
 '_size',
 smalltalk.method({
@@ -3773,6 +3839,32 @@ return self;}
 }),
 smalltalk.String);
 
+smalltalk.addMethod(
+'__eq',
+smalltalk.method({
+selector: '=',
+fn: function (aString){
+var self=this;
+try{(($receiver = smalltalk.send(smalltalk.send(aString, "_class", []), "__eq", [smalltalk.send(self, "_class", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]);
+return String(self) == aString;
+return self;
+} catch(e) {if(e.name === 'stReturn' && e.selector === '__eq'){return e.fn()} throw(e)}}
+}),
+smalltalk.String);
+
+smalltalk.addMethod(
+'__eq_eq',
+smalltalk.method({
+selector: '==',
+fn: function (aString){
+var self=this;
+try{(($receiver = smalltalk.send(smalltalk.send(aString, "_class", []), "__eq", [smalltalk.send(self, "_class", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq_eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq_eq', fn: function(){return false}})})();})]);
+return String(self) === String(aString);
+return self;
+} catch(e) {if(e.name === 'stReturn' && e.selector === '__eq_eq'){return e.fn()} throw(e)}}
+}),
+smalltalk.String);
+
 
 smalltalk.addMethod(
 '_streamClass',
@@ -4108,6 +4200,20 @@ return self;}
 }),
 smalltalk.Array);
 
+smalltalk.addMethod(
+'__eq',
+smalltalk.method({
+selector: '=',
+fn: function (aCollection){
+var self=this;
+try{(($receiver = smalltalk.send(smalltalk.send(smalltalk.send(self, "_class", []), "__eq", [smalltalk.send(aCollection, "_class", [])]), "_and_", [(function(){return smalltalk.send(smalltalk.send(self, "_size", []), "__eq", [smalltalk.send(aCollection, "_size", [])]);})])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]);
+smalltalk.send(self, "_withIndexDo_", [(function(each, i){return (($receiver = smalltalk.send(smalltalk.send(aCollection, "_at_", [i]), "__eq", [each])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]);})]);
+(function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return true}})})();
+return self;
+} catch(e) {if(e.name === 'stReturn' && e.selector === '__eq'){return e.fn()} throw(e)}}
+}),
+smalltalk.Array);
+
 
 
 smalltalk.addClass('RegularExpression', smalltalk.Object, [], 'Kernel');
@@ -4372,8 +4478,8 @@ selector: '=',
 fn: function (aDictionary){
 var self=this;
 try{(($receiver = smalltalk.send(smalltalk.send(self, "_class", []), "__eq", [smalltalk.send(aDictionary, "_class", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]);
-smalltalk.send(self, "_associationsDo_", [(function(assoc){return (($receiver = smalltalk.send(smalltalk.send(aDictionary, "_at_ifAbsent_", [smalltalk.send(assoc, "_key", []), (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]), "__eq", [smalltalk.send(assoc, "_value", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]);})]);
-(function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return true}})})();
+(($receiver = smalltalk.send(smalltalk.send(self, "_size", []), "__eq", [smalltalk.send(aDictionary, "_size", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]);
+(function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return smalltalk.send(smalltalk.send(self, "_associations", []), "__eq", [smalltalk.send(aDictionary, "_associations", [])])}})})();
 return self;
 } catch(e) {if(e.name === 'stReturn' && e.selector === '__eq'){return e.fn()} throw(e)}}
 }),
@@ -5788,5 +5894,16 @@ return self;}
 }),
 smalltalk.Set);
 
+smalltalk.addMethod(
+'__eq',
+smalltalk.method({
+selector: '=',
+fn: function (aCollection){
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(self, "_class", []), "__eq", [smalltalk.send(aCollection, "_class", [])]), "_and_", [(function(){return smalltalk.send(self['@elements'], "__eq", [smalltalk.send(aCollection, "_asArray", [])]);})]);
+return self;}
+}),
+smalltalk.Set);
+
 
 

+ 215 - 56
js/Kernel.js

@@ -6,11 +6,11 @@ selector: '=',
 category: 'comparing',
 fn: function (anObject){
 var self=this;
-return self == anObject;
+return smalltalk.send(self, "__eq_eq", [anObject]);
 return self;},
 args: ["anObject"],
-source: unescape('%3D%20anObject%0A%09%3Creturn%20self%20%3D%3D%20anObject%3E'),
-messageSends: [],
+source: unescape('%3D%20anObject%0A%09%5Eself%20%3D%3D%20anObject'),
+messageSends: [unescape("%3D%3D")],
 referencedClasses: []
 }),
 smalltalk.Object);
@@ -756,6 +756,38 @@ referencedClasses: [smalltalk.Date]
 }),
 smalltalk.Object);
 
+smalltalk.addMethod(
+'__eq_eq',
+smalltalk.method({
+selector: '==',
+category: 'comparing',
+fn: function (anObject){
+var self=this;
+return self === anObject;
+return self;},
+args: ["anObject"],
+source: unescape('%3D%3D%20anObject%0A%09%3Creturn%20self%20%3D%3D%3D%20anObject%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Object);
+
+smalltalk.addMethod(
+'_~~',
+smalltalk.method({
+selector: '~~',
+category: 'comparing',
+fn: function (anObject){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "__eq_eq", [anObject]), "__eq", [false]);
+return self;},
+args: ["anObject"],
+source: unescape('%7E%7E%20anObject%0A%09%5E%28self%20%3D%3D%20anObject%29%20%3D%20false'),
+messageSends: [unescape("%3D"), unescape("%3D%3D")],
+referencedClasses: []
+}),
+smalltalk.Object);
+
 
 smalltalk.addMethod(
 '_initialize',
@@ -1849,22 +1881,6 @@ smalltalk.CompiledMethod);
 
 
 smalltalk.addClass('Number', smalltalk.Object, [], 'Kernel');
-smalltalk.addMethod(
-'__eq',
-smalltalk.method({
-selector: '=',
-category: 'comparing',
-fn: function (aNumber){
-var self=this;
-return Number(self) == aNumber;
-return self;},
-args: ["aNumber"],
-source: unescape('%3D%20aNumber%0A%09%22Inlined%20in%20the%20Compiler%22%0A%09%3Creturn%20Number%28self%29%20%3D%3D%20aNumber%3E'),
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.Number);
-
 smalltalk.addMethod(
 '__gt',
 smalltalk.method({
@@ -2343,6 +2359,42 @@ referencedClasses: []
 }),
 smalltalk.Number);
 
+smalltalk.addMethod(
+'__eq',
+smalltalk.method({
+selector: '=',
+category: 'comparing',
+fn: function (aNumber){
+var self=this;
+try{(($receiver = smalltalk.send(smalltalk.send(aNumber, "_class", []), "__eq", [smalltalk.send(self, "_class", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]);
+return Number(self) == aNumber;
+return self;
+} catch(e) {if(e.name === 'stReturn' && e.selector === '__eq'){return e.fn()} throw(e)}},
+args: ["aNumber"],
+source: unescape('%3D%20aNumber%0A%09aNumber%20class%20%3D%20self%20class%20ifFalse%3A%20%5B%5Efalse%5D.%20%0A%09%3Creturn%20Number%28self%29%20%3D%3D%20aNumber%3E'),
+messageSends: ["ifFalse:", unescape("%3D"), "class"],
+referencedClasses: []
+}),
+smalltalk.Number);
+
+smalltalk.addMethod(
+'__eq_eq',
+smalltalk.method({
+selector: '==',
+category: 'comparing',
+fn: function (aNumber){
+var self=this;
+try{(($receiver = smalltalk.send(smalltalk.send(aNumber, "_class", []), "__eq", [smalltalk.send(self, "_class", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq_eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq_eq', fn: function(){return false}})})();})]);
+return Number(self) === Number(aNumber);
+return self;
+} catch(e) {if(e.name === 'stReturn' && e.selector === '__eq_eq'){return e.fn()} throw(e)}},
+args: ["aNumber"],
+source: unescape('%3D%3D%20aNumber%0A%09aNumber%20class%20%3D%20self%20class%20ifFalse%3A%20%5B%5Efalse%5D.%20%0A%09%3Creturn%20Number%28self%29%20%3D%3D%3D%20Number%28aNumber%29%3E'),
+messageSends: ["ifFalse:", unescape("%3D"), "class"],
+referencedClasses: []
+}),
+smalltalk.Number);
+
 smalltalk.addMethod(
 '_printShowingDecimalPlaces_',
 smalltalk.method({
@@ -2637,22 +2689,6 @@ smalltalk.BlockClosure);
 
 
 smalltalk.addClass('Boolean', smalltalk.Object, [], 'Kernel');
-smalltalk.addMethod(
-'__eq',
-smalltalk.method({
-selector: '=',
-category: 'comparing',
-fn: function (aBoolean){
-var self=this;
-return Boolean(self == true) == aBoolean;
-return self;},
-args: ["aBoolean"],
-source: unescape('%3D%20aBoolean%0A%09%3Creturn%20Boolean%28self%20%3D%3D%20true%29%20%3D%3D%20aBoolean%3E'),
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.Boolean);
-
 smalltalk.addMethod(
 '_shallowCopy',
 smalltalk.method({
@@ -2823,7 +2859,7 @@ smalltalk.addMethod(
 '_asJSONObject',
 smalltalk.method({
 selector: 'asJSONObject',
-category: 'comparing',
+category: 'converting',
 fn: function (){
 var self=this;
 return self;
@@ -2879,6 +2915,42 @@ referencedClasses: []
 }),
 smalltalk.Boolean);
 
+smalltalk.addMethod(
+'__eq',
+smalltalk.method({
+selector: '=',
+category: 'comparing',
+fn: function (aBoolean){
+var self=this;
+try{(($receiver = smalltalk.send(smalltalk.send(aBoolean, "_class", []), "__eq", [smalltalk.send(self, "_class", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]);
+return Boolean(self == true) == aBoolean;
+return self;
+} catch(e) {if(e.name === 'stReturn' && e.selector === '__eq'){return e.fn()} throw(e)}},
+args: ["aBoolean"],
+source: unescape('%3D%20aBoolean%0A%09aBoolean%20class%20%3D%20self%20class%20ifFalse%3A%20%5B%5Efalse%5D.%0A%09%3Creturn%20Boolean%28self%20%3D%3D%20true%29%20%3D%3D%20aBoolean%3E'),
+messageSends: ["ifFalse:", unescape("%3D"), "class"],
+referencedClasses: []
+}),
+smalltalk.Boolean);
+
+smalltalk.addMethod(
+'__eq_eq',
+smalltalk.method({
+selector: '==',
+category: 'comparing',
+fn: function (aBoolean){
+var self=this;
+try{(($receiver = smalltalk.send(smalltalk.send(aBoolean, "_class", []), "__eq", [smalltalk.send(self, "_class", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq_eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq_eq', fn: function(){return false}})})();})]);
+return Boolean(self == true) === Boolean(aBoolean == true);
+return self;
+} catch(e) {if(e.name === 'stReturn' && e.selector === '__eq_eq'){return e.fn()} throw(e)}},
+args: ["aBoolean"],
+source: unescape('%3D%3D%20aBoolean%0A%09aBoolean%20class%20%3D%20self%20class%20ifFalse%3A%20%5B%5Efalse%5D.%0A%09%3Creturn%20Boolean%28self%20%3D%3D%20true%29%20%3D%3D%3D%20Boolean%28aBoolean%20%3D%3D%20true%29%3E'),
+messageSends: ["ifFalse:", unescape("%3D"), "class"],
+referencedClasses: []
+}),
+smalltalk.Boolean);
+
 
 
 smalltalk.addClass('Date', smalltalk.Object, [], 'Kernel');
@@ -4216,6 +4288,38 @@ referencedClasses: [smalltalk.Set]
 }),
 smalltalk.Collection);
 
+smalltalk.addMethod(
+'_ifNotEmpty_',
+smalltalk.method({
+selector: 'ifNotEmpty:',
+category: 'testing',
+fn: function (aBlock){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_notEmpty", []), "_ifTrue_", [aBlock]);
+return self;},
+args: ["aBlock"],
+source: unescape('ifNotEmpty%3A%20aBlock%0A%09self%20notEmpty%20ifTrue%3A%20aBlock.'),
+messageSends: ["ifTrue:", "notEmpty"],
+referencedClasses: []
+}),
+smalltalk.Collection);
+
+smalltalk.addMethod(
+'_ifEmpty_',
+smalltalk.method({
+selector: 'ifEmpty:',
+category: 'testing',
+fn: function (aBlock){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_isEmpty", []), "_ifTrue_", [aBlock]);
+return self;},
+args: ["aBlock"],
+source: unescape('ifEmpty%3A%20aBlock%0A%09self%20isEmpty%20ifTrue%3A%20aBlock.'),
+messageSends: ["ifTrue:", "isEmpty"],
+referencedClasses: []
+}),
+smalltalk.Collection);
+
 
 smalltalk.addMethod(
 '_streamClass',
@@ -4616,22 +4720,6 @@ smalltalk.SequenceableCollection);
 
 
 smalltalk.addClass('String', smalltalk.SequenceableCollection, [], 'Kernel');
-smalltalk.addMethod(
-'__eq',
-smalltalk.method({
-selector: '=',
-category: 'comparing',
-fn: function (aString){
-var self=this;
-return String(self) == aString;
-return self;},
-args: ["aString"],
-source: unescape('%3D%20aString%0A%09%3Creturn%20String%28self%29%20%3D%3D%20aString%3E'),
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.String);
-
 smalltalk.addMethod(
 '_size',
 smalltalk.method({
@@ -5389,6 +5477,42 @@ referencedClasses: []
 }),
 smalltalk.String);
 
+smalltalk.addMethod(
+'__eq',
+smalltalk.method({
+selector: '=',
+category: 'comparing',
+fn: function (aString){
+var self=this;
+try{(($receiver = smalltalk.send(smalltalk.send(aString, "_class", []), "__eq", [smalltalk.send(self, "_class", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]);
+return String(self) == aString;
+return self;
+} catch(e) {if(e.name === 'stReturn' && e.selector === '__eq'){return e.fn()} throw(e)}},
+args: ["aString"],
+source: unescape('%3D%20aString%0A%09aString%20class%20%3D%20self%20class%20ifFalse%3A%20%5B%5Efalse%5D.%0A%09%3Creturn%20String%28self%29%20%3D%3D%20aString%3E'),
+messageSends: ["ifFalse:", unescape("%3D"), "class"],
+referencedClasses: []
+}),
+smalltalk.String);
+
+smalltalk.addMethod(
+'__eq_eq',
+smalltalk.method({
+selector: '==',
+category: 'comparing',
+fn: function (aString){
+var self=this;
+try{(($receiver = smalltalk.send(smalltalk.send(aString, "_class", []), "__eq", [smalltalk.send(self, "_class", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq_eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq_eq', fn: function(){return false}})})();})]);
+return String(self) === String(aString);
+return self;
+} catch(e) {if(e.name === 'stReturn' && e.selector === '__eq_eq'){return e.fn()} throw(e)}},
+args: ["aString"],
+source: unescape('%3D%3D%20aString%0A%09aString%20class%20%3D%20self%20class%20ifFalse%3A%20%5B%5Efalse%5D.%0A%09%3Creturn%20String%28self%29%20%3D%3D%3D%20String%28aString%29%3E'),
+messageSends: ["ifFalse:", unescape("%3D"), "class"],
+referencedClasses: []
+}),
+smalltalk.String);
+
 
 smalltalk.addMethod(
 '_streamClass',
@@ -5859,6 +5983,25 @@ referencedClasses: []
 }),
 smalltalk.Array);
 
+smalltalk.addMethod(
+'__eq',
+smalltalk.method({
+selector: '=',
+category: 'comparing',
+fn: function (aCollection){
+var self=this;
+try{(($receiver = smalltalk.send(smalltalk.send(smalltalk.send(self, "_class", []), "__eq", [smalltalk.send(aCollection, "_class", [])]), "_and_", [(function(){return smalltalk.send(smalltalk.send(self, "_size", []), "__eq", [smalltalk.send(aCollection, "_size", [])]);})])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]);
+smalltalk.send(self, "_withIndexDo_", [(function(each, i){return (($receiver = smalltalk.send(smalltalk.send(aCollection, "_at_", [i]), "__eq", [each])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]);})]);
+(function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return true}})})();
+return self;
+} catch(e) {if(e.name === 'stReturn' && e.selector === '__eq'){return e.fn()} throw(e)}},
+args: ["aCollection"],
+source: unescape('%3D%20aCollection%0A%09%28self%20class%20%3D%20aCollection%20class%20and%3A%20%5B%0A%20%20%20%20%20%20%20%20%09self%20size%20%3D%20aCollection%20size%5D%29%20ifFalse%3A%20%5B%5Efalse%5D.%0A%09self%20withIndexDo%3A%20%5B%3Aeach%20%3Ai%20%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%28aCollection%20at%3A%20i%29%20%3D%20each%20ifFalse%3A%20%5B%5Efalse%5D%5D.%0A%09%5Etrue'),
+messageSends: ["ifFalse:", "and:", unescape("%3D"), "class", "size", "withIndexDo:", "at:"],
+referencedClasses: []
+}),
+smalltalk.Array);
+
 
 
 smalltalk.addClass('RegularExpression', smalltalk.Object, [], 'Kernel');
@@ -6234,13 +6377,13 @@ category: 'comparing',
 fn: function (aDictionary){
 var self=this;
 try{(($receiver = smalltalk.send(smalltalk.send(self, "_class", []), "__eq", [smalltalk.send(aDictionary, "_class", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]);
-smalltalk.send(self, "_associationsDo_", [(function(assoc){return (($receiver = smalltalk.send(smalltalk.send(aDictionary, "_at_ifAbsent_", [smalltalk.send(assoc, "_key", []), (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]), "__eq", [smalltalk.send(assoc, "_value", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]);})]);
-(function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return true}})})();
+(($receiver = smalltalk.send(smalltalk.send(self, "_size", []), "__eq", [smalltalk.send(aDictionary, "_size", [])])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return (function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return false}})})();})]);
+(function(){throw({name: 'stReturn', selector: '__eq', fn: function(){return smalltalk.send(smalltalk.send(self, "_associations", []), "__eq", [smalltalk.send(aDictionary, "_associations", [])])}})})();
 return self;
 } catch(e) {if(e.name === 'stReturn' && e.selector === '__eq'){return e.fn()} throw(e)}},
 args: ["aDictionary"],
-source: unescape('%3D%20aDictionary%0A%09self%20class%20%3D%20aDictionary%20class%20ifFalse%3A%20%5B%5Efalse%5D.%0A%09self%20associationsDo%3A%20%5B%3Aassoc%20%7C%0A%09%20%20%20%20%28aDictionary%20at%3A%20assoc%20key%20ifAbsent%3A%20%5B%5Efalse%5D%29%20%3D%20assoc%20value%20%0A%09%09ifFalse%3A%20%5B%5Efalse%5D%5D.%0A%09%5Etrue'),
-messageSends: ["ifFalse:", unescape("%3D"), "class", "associationsDo:", "at:ifAbsent:", "key", "value"],
+source: unescape('%3D%20aDictionary%0A%09self%20class%20%3D%20aDictionary%20class%20ifFalse%3A%20%5B%5Efalse%5D.%0A%09self%20size%20%3D%20aDictionary%20size%20ifFalse%3A%20%5B%5Efalse%5D.%0A%09%5Eself%20associations%20%3D%20aDictionary%20associations'),
+messageSends: ["ifFalse:", unescape("%3D"), "class", "size", "associations"],
 referencedClasses: []
 }),
 smalltalk.Dictionary);
@@ -8244,5 +8387,21 @@ referencedClasses: []
 }),
 smalltalk.Set);
 
+smalltalk.addMethod(
+'__eq',
+smalltalk.method({
+selector: '=',
+category: 'comparing',
+fn: function (aCollection){
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(self, "_class", []), "__eq", [smalltalk.send(aCollection, "_class", [])]), "_and_", [(function(){return smalltalk.send(self['@elements'], "__eq", [smalltalk.send(aCollection, "_asArray", [])]);})]);
+return self;},
+args: ["aCollection"],
+source: unescape('%3D%20aCollection%0A%09%5Eself%20class%20%3D%20aCollection%20class%20and%3A%20%5B%0A%20%20%20%20%20%20%20%20%09elements%20%3D%20aCollection%20asArray%5D'),
+messageSends: ["and:", unescape("%3D"), "class", "asArray"],
+referencedClasses: []
+}),
+smalltalk.Set);
+
 
 

File diff suppressed because it is too large
+ 226 - 0
server/FileServer.deploy.js


File diff suppressed because it is too large
+ 317 - 0
server/FileServer.js


+ 561 - 0
server/FileServer.st

@@ -0,0 +1,561 @@
+Object subclass: #FileServer
+	instanceVariableNames: 'path http fs url port basePath sys'
+	category: 'FileServer'!
+
+!FileServer methodsFor: 'accessing'!
+
+basePath
+	^basePath ifNil: ['./']
+!
+
+basePath: aString
+	basePath := aString
+!
+
+port
+	^self class port
+! !
+
+!FileServer methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	path := self require: 'path'.
+	http := self require: 'http'.
+	fs := self require: 'fs'.
+	sys := self require: 'sys'.
+	url := self require: 'url'
+! !
+
+!FileServer methodsFor: 'private'!
+
+require: aModuleString
+	"call to the require function"
+	^require value: aModuleString
+!
+
+writeData: data toFileNamed: aFilename
+	console log: aFilename
+! !
+
+!FileServer methodsFor: 'request handling'!
+
+respondNotFoundTo: aResponse
+	aResponse 
+		writeHead: 404 options: #{'Content-Type' -> 'text/plain'};
+		write: '404 Not found';
+		end
+!
+
+handleRequest: aRequest respondTo: aResponse
+	aRequest method = 'PUT'
+		ifTrue: [self handlePUTRequest: aRequest respondTo: aResponse]
+		ifFalse: [self handleGETRequest: aRequest respondTo: aResponse]
+!
+
+handleGETRequest: aRequest respondTo: aResponse
+	| uri filename |
+	uri := (url parse: aRequest url) pathname.
+	filename := path join: self basePath with: uri.
+	path exists: filename do: [:boolean | 
+		boolean 
+			ifFalse: [self respondNotFoundTo: aResponse]
+			ifTrue: [self respondFileNamed: filename to: aResponse]]
+!
+
+handlePUTRequest: aRequest respondTo: aResponse
+	| stream |
+	stream := fs createWriteStream: '.', aRequest url.
+
+	aRequest setEncoding: 'utf8'.
+	aRequest on: #data do: [:data | stream write: data].
+
+	aRequest on: #end do: [
+		stream end.
+		self respondOKTo: aResponse]
+!
+
+respondFileNamed: aFilename to: aResponse
+	| type filename |
+
+	filename := aFilename.
+	(fs statSync: aFilename) isDirectory ifTrue: [
+        	filename := filename, 'index.html'].
+
+	fs readFile: filename do: [:ex :file |
+		ex notNil 
+			ifTrue: [self respondInternalErrorTo: aResponse]
+			ifFalse: [
+        			type := self class mimeTypeFor: filename.
+				aResponse 
+                          		writeHead: 200 options:  #{'Content-Type' -> type};
+					write: file binary: 'binary';
+                          		end]]
+!
+
+respondInternalErrorTo: aResponse
+	aResponse 
+		writeHead: 500 options: #{'Content-Type' -> 'text/plain'};
+		write: '500 Internal server error';
+		end
+!
+
+respondOKTo: aResponse
+	aResponse 
+		writeHead: 200 options: #{'Content-Type' -> 'text/plain'};
+		end
+! !
+
+!FileServer methodsFor: 'starting'!
+
+startOn: aPort
+	port := aPort.
+	self start
+!
+
+start
+	(http createServer: [:request :response |
+	 	self handleRequest: request respondTo: response]) listen: self port.
+	console log: 'Starting file server on port ', self port asString
+! !
+
+FileServer class instanceVariableNames: 'port mimeTypes'!
+
+!FileServer class methodsFor: 'accessing'!
+
+port
+	^port ifNil: [4000]
+!
+
+port: aNumber
+	port := aNumber
+!
+
+defaultMimeTypes
+	^ #{
+		'%' -> 'application/x-trash'.
+		'323' -> 'text/h323'.
+		'abw' -> 'application/x-abiword'.
+		'ai' -> 'application/postscript'.
+		'aif' -> 'audio/x-aiff'.
+		'aifc' -> 'audio/x-aiff'.
+		'aiff' -> 'audio/x-aiff'.
+		'alc' -> 'chemical/x-alchemy'.
+		'art' -> 'image/x-jg'.
+		'asc' -> 'text/plain'.
+		'asf' -> 'video/x-ms-asf'.
+		'asn' -> 'chemical/x-ncbi-asn1-spec'.
+		'aso' -> 'chemical/x-ncbi-asn1-binary'.
+		'asx' -> 'video/x-ms-asf'.
+		'au' -> 'audio/basic'.
+		'avi' -> 'video/x-msvideo'.
+		'b' -> 'chemical/x-molconn-Z'.
+		'bak' -> 'application/x-trash'.
+		'bat' -> 'application/x-msdos-program'.
+		'bcpio' -> 'application/x-bcpio'.
+		'bib' -> 'text/x-bibtex'.
+		'bin' -> 'application/octet-stream'.
+		'bmp' -> 'image/x-ms-bmp'.
+		'book' -> 'application/x-maker'.
+		'bsd' -> 'chemical/x-crossfire'.
+		'c' -> 'text/x-csrc'.
+		'c++' -> 'text/x-c++src'.
+		'c3d' -> 'chemical/x-chem3d'.
+		'cac' -> 'chemical/x-cache'.
+		'cache' -> 'chemical/x-cache'.
+		'cascii' -> 'chemical/x-cactvs-binary'.
+		'cat' -> 'application/vnd.ms-pki.seccat'.
+		'cbin' -> 'chemical/x-cactvs-binary'.
+		'cc' -> 'text/x-c++src'.
+		'cdf' -> 'application/x-cdf'.
+		'cdr' -> 'image/x-coreldraw'.
+		'cdt' -> 'image/x-coreldrawtemplate'.
+		'cdx' -> 'chemical/x-cdx'.
+		'cdy' -> 'application/vnd.cinderella'.
+		'cef' -> 'chemical/x-cxf'.
+		'cer' -> 'chemical/x-cerius'.
+		'chm' -> 'chemical/x-chemdraw'.
+		'chrt' -> 'application/x-kchart'.
+		'cif' -> 'chemical/x-cif'.
+		'class' -> 'application/java-vm'.
+		'cls' -> 'text/x-tex'.
+		'cmdf' -> 'chemical/x-cmdf'.
+		'cml' -> 'chemical/x-cml'.
+		'cod' -> 'application/vnd.rim.cod'.
+		'com' -> 'application/x-msdos-program'.
+		'cpa' -> 'chemical/x-compass'.
+		'cpio' -> 'application/x-cpio'.
+		'cpp' -> 'text/x-c++src'.
+		'cpt' -> 'image/x-corelphotopaint'.
+		'crl' -> 'application/x-pkcs7-crl'.
+		'crt' -> 'application/x-x509-ca-cert'.
+		'csf' -> 'chemical/x-cache-csf'.
+		'csh' -> 'text/x-csh'.
+		'csm' -> 'chemical/x-csml'.
+		'csml' -> 'chemical/x-csml'.
+		'css' -> 'text/css'.
+		'csv' -> 'text/comma-separated-values'.
+		'ctab' -> 'chemical/x-cactvs-binary'.
+		'ctx' -> 'chemical/x-ctx'.
+		'cu' -> 'application/cu-seeme'.
+		'cub' -> 'chemical/x-gaussian-cube'.
+		'cxf' -> 'chemical/x-cxf'.
+		'cxx' -> 'text/x-c++src'.
+		'dat' -> 'chemical/x-mopac-input'.
+		'dcr' -> 'application/x-director'.
+		'deb' -> 'application/x-debian-package'.
+		'dif' -> 'video/dv'.
+		'diff' -> 'text/plain'.
+		'dir' -> 'application/x-director'.
+		'djv' -> 'image/vnd.djvu'.
+		'djvu' -> 'image/vnd.djvu'.
+		'dl' -> 'video/dl'.
+		'dll' -> 'application/x-msdos-program'.
+		'dmg' -> 'application/x-apple-diskimage'.
+		'dms' -> 'application/x-dms'.
+		'doc' -> 'application/msword'.
+		'dot' -> 'application/msword'.
+		'dv' -> 'video/dv'.
+		'dvi' -> 'application/x-dvi'.
+		'dx' -> 'chemical/x-jcamp-dx'.
+		'dxr' -> 'application/x-director'.
+		'emb' -> 'chemical/x-embl-dl-nucleotide'.
+		'embl' -> 'chemical/x-embl-dl-nucleotide'.
+		'ent' -> 'chemical/x-pdb'.
+		'eps' -> 'application/postscript'.
+		'etx' -> 'text/x-setext'.
+		'exe' -> 'application/x-msdos-program'.
+		'ez' -> 'application/andrew-inset'.
+		'fb' -> 'application/x-maker'.
+		'fbdoc' -> 'application/x-maker'.
+		'fch' -> 'chemical/x-gaussian-checkpoint'.
+		'fchk' -> 'chemical/x-gaussian-checkpoint'.
+		'fig' -> 'application/x-xfig'.
+		'flac' -> 'application/x-flac'.
+		'fli' -> 'video/fli'.
+		'fm' -> 'application/x-maker'.
+		'frame' -> 'application/x-maker'.
+		'frm' -> 'application/x-maker'.
+		'gal' -> 'chemical/x-gaussian-log'.
+		'gam' -> 'chemical/x-gamess-input'.
+		'gamin' -> 'chemical/x-gamess-input'.
+		'gau' -> 'chemical/x-gaussian-input'.
+		'gcd' -> 'text/x-pcs-gcd'.
+		'gcf' -> 'application/x-graphing-calculator'.
+		'gcg' -> 'chemical/x-gcg8-sequence'.
+		'gen' -> 'chemical/x-genbank'.
+		'gf' -> 'application/x-tex-gf'.
+		'gif' -> 'image/gif'.
+		'gjc' -> 'chemical/x-gaussian-input'.
+		'gjf' -> 'chemical/x-gaussian-input'.
+		'gl' -> 'video/gl'.
+		'gnumeric' -> 'application/x-gnumeric'.
+		'gpt' -> 'chemical/x-mopac-graph'.
+		'gsf' -> 'application/x-font'.
+		'gsm' -> 'audio/x-gsm'.
+		'gtar' -> 'application/x-gtar'.
+		'h' -> 'text/x-chdr'.
+		'h++' -> 'text/x-c++hdr'.
+		'hdf' -> 'application/x-hdf'.
+		'hh' -> 'text/x-c++hdr'.
+		'hin' -> 'chemical/x-hin'.
+		'hpp' -> 'text/x-c++hdr'.
+		'hqx' -> 'application/mac-binhex40'.
+		'hs' -> 'text/x-haskell'.
+		'hta' -> 'application/hta'.
+		'htc' -> 'text/x-component'.
+		'htm' -> 'text/html'.
+		'html' -> 'text/html'.
+		'hxx' -> 'text/x-c++hdr'.
+		'ica' -> 'application/x-ica'.
+		'ice' -> 'x-conference/x-cooltalk'.
+		'ico' -> 'image/x-icon'.
+		'ics' -> 'text/calendar'.
+		'icz' -> 'text/calendar'.
+		'ief' -> 'image/ief'.
+		'iges' -> 'model/iges'.
+		'igs' -> 'model/iges'.
+		'iii' -> 'application/x-iphone'.
+		'inp' -> 'chemical/x-gamess-input'.
+		'ins' -> 'application/x-internet-signup'.
+		'iso' -> 'application/x-iso9660-image'.
+		'isp' -> 'application/x-internet-signup'.
+		'ist' -> 'chemical/x-isostar'.
+		'istr' -> 'chemical/x-isostar'.
+		'jad' -> 'text/vnd.sun.j2me.app-descriptor'.
+		'jar' -> 'application/java-archive'.
+		'java' -> 'text/x-java'.
+		'jdx' -> 'chemical/x-jcamp-dx'.
+		'jmz' -> 'application/x-jmol'.
+		'jng' -> 'image/x-jng'.
+		'jnlp' -> 'application/x-java-jnlp-file'.
+		'jpe' -> 'image/jpeg'.
+		'jpeg' -> 'image/jpeg'.
+		'jpg' -> 'image/jpeg'.
+		'js' -> 'application/javascript'.
+		'kar' -> 'audio/midi'.
+		'key' -> 'application/pgp-keys'.
+		'kil' -> 'application/x-killustrator'.
+		'kin' -> 'chemical/x-kinemage'.
+		'kpr' -> 'application/x-kpresenter'.
+		'kpt' -> 'application/x-kpresenter'.
+		'ksp' -> 'application/x-kspread'.
+		'kwd' -> 'application/x-kword'.
+		'kwt' -> 'application/x-kword'.
+		'latex' -> 'application/x-latex'.
+		'lha' -> 'application/x-lha'.
+		'lhs' -> 'text/x-literate-haskell'.
+		'lsf' -> 'video/x-la-asf'.
+		'lsx' -> 'video/x-la-asf'.
+		'ltx' -> 'text/x-tex'.
+		'lzh' -> 'application/x-lzh'.
+		'lzx' -> 'application/x-lzx'.
+		'm3u' -> 'audio/x-mpegurl'.
+		'm4a' -> 'audio/mpeg'.
+		'maker' -> 'application/x-maker'.
+		'man' -> 'application/x-troff-man'.
+		'mcif' -> 'chemical/x-mmcif'.
+		'mcm' -> 'chemical/x-macmolecule'.
+		'mdb' -> 'application/msaccess'.
+		'me' -> 'application/x-troff-me'.
+		'mesh' -> 'model/mesh'.
+		'mid' -> 'audio/midi'.
+		'midi' -> 'audio/midi'.
+		'mif' -> 'application/x-mif'.
+		'mm' -> 'application/x-freemind'.
+		'mmd' -> 'chemical/x-macromodel-input'.
+		'mmf' -> 'application/vnd.smaf'.
+		'mml' -> 'text/mathml'.
+		'mmod' -> 'chemical/x-macromodel-input'.
+		'mng' -> 'video/x-mng'.
+		'moc' -> 'text/x-moc'.
+		'mol' -> 'chemical/x-mdl-molfile'.
+		'mol2' -> 'chemical/x-mol2'.
+		'moo' -> 'chemical/x-mopac-out'.
+		'mop' -> 'chemical/x-mopac-input'.
+		'mopcrt' -> 'chemical/x-mopac-input'.
+		'mov' -> 'video/quicktime'.
+		'movie' -> 'video/x-sgi-movie'.
+		'mp2' -> 'audio/mpeg'.
+		'mp3' -> 'audio/mpeg'.
+		'mp4' -> 'video/mp4'.
+		'mpc' -> 'chemical/x-mopac-input'.
+		'mpe' -> 'video/mpeg'.
+		'mpeg' -> 'video/mpeg'.
+		'mpega' -> 'audio/mpeg'.
+		'mpg' -> 'video/mpeg'.
+		'mpga' -> 'audio/mpeg'.
+		'ms' -> 'application/x-troff-ms'.
+		'msh' -> 'model/mesh'.
+		'msi' -> 'application/x-msi'.
+		'mvb' -> 'chemical/x-mopac-vib'.
+		'mxu' -> 'video/vnd.mpegurl'.
+		'nb' -> 'application/mathematica'.
+		'nc' -> 'application/x-netcdf'.
+		'nwc' -> 'application/x-nwc'.
+		'o' -> 'application/x-object'.
+		'oda' -> 'application/oda'.
+		'odb' -> 'application/vnd.oasis.opendocument.database'.
+		'odc' -> 'application/vnd.oasis.opendocument.chart'.
+		'odf' -> 'application/vnd.oasis.opendocument.formula'.
+		'odg' -> 'application/vnd.oasis.opendocument.graphics'.
+		'odi' -> 'application/vnd.oasis.opendocument.image'.
+		'odm' -> 'application/vnd.oasis.opendocument.text-master'.
+		'odp' -> 'application/vnd.oasis.opendocument.presentation'.
+		'ods' -> 'application/vnd.oasis.opendocument.spreadsheet'.
+		'odt' -> 'application/vnd.oasis.opendocument.text'.
+		'ogg' -> 'application/ogg'.
+		'old' -> 'application/x-trash'.
+		'oth' -> 'application/vnd.oasis.opendocument.text-web'.
+		'oza' -> 'application/x-oz-application'.
+		'p' -> 'text/x-pascal'.
+		'p7r' -> 'application/x-pkcs7-certreqresp'.
+		'pac' -> 'application/x-ns-proxy-autoconfig'.
+		'pas' -> 'text/x-pascal'.
+		'pat' -> 'image/x-coreldrawpattern'.
+		'pbm' -> 'image/x-portable-bitmap'.
+		'pcf' -> 'application/x-font'.
+		'pcf.Z' -> 'application/x-font'.
+		'pcx' -> 'image/pcx'.
+		'pdb' -> 'chemical/x-pdb'.
+		'pdf' -> 'application/pdf'.
+		'pfa' -> 'application/x-font'.
+		'pfb' -> 'application/x-font'.
+		'pgm' -> 'image/x-portable-graymap'.
+		'pgn' -> 'application/x-chess-pgn'.
+		'pgp' -> 'application/pgp-signature'.
+		'pk' -> 'application/x-tex-pk'.
+		'pl' -> 'text/x-perl'.
+		'pls' -> 'audio/x-scpls'.
+		'pm' -> 'text/x-perl'.
+		'png' -> 'image/png'.
+		'pnm' -> 'image/x-portable-anymap'.
+		'pot' -> 'text/plain'.
+		'ppm' -> 'image/x-portable-pixmap'.
+		'pps' -> 'application/vnd.ms-powerpoint'.
+		'ppt' -> 'application/vnd.ms-powerpoint'.
+		'prf' -> 'application/pics-rules'.
+		'prt' -> 'chemical/x-ncbi-asn1-ascii'.
+		'ps' -> 'application/postscript'.
+		'psd' -> 'image/x-photoshop'.
+		'psp' -> 'text/x-psp'.
+		'py' -> 'text/x-python'.
+		'pyc' -> 'application/x-python-code'.
+		'pyo' -> 'application/x-python-code'.
+		'qt' -> 'video/quicktime'.
+		'qtl' -> 'application/x-quicktimeplayer'.
+		'ra' -> 'audio/x-realaudio'.
+		'ram' -> 'audio/x-pn-realaudio'.
+		'rar' -> 'application/rar'.
+		'ras' -> 'image/x-cmu-raster'.
+		'rd' -> 'chemical/x-mdl-rdfile'.
+		'rdf' -> 'application/rdf+xml'.
+		'rgb' -> 'image/x-rgb'.
+		'rm' -> 'audio/x-pn-realaudio'.
+		'roff' -> 'application/x-troff'.
+		'ros' -> 'chemical/x-rosdal'.
+		'rpm' -> 'application/x-redhat-package-manager'.
+		'rss' -> 'application/rss+xml'.
+		'rtf' -> 'text/rtf'.
+		'rtx' -> 'text/richtext'.
+		'rxn' -> 'chemical/x-mdl-rxnfile'.
+		'sct' -> 'text/scriptlet'.
+		'sd' -> 'chemical/x-mdl-sdfile'.
+		'sd2' -> 'audio/x-sd2'.
+		'sda' -> 'application/vnd.stardivision.draw'.
+		'sdc' -> 'application/vnd.stardivision.calc'.
+		'sdd' -> 'application/vnd.stardivision.impress'.
+		'sdf' -> 'chemical/x-mdl-sdfile'.
+		'sdp' -> 'application/vnd.stardivision.impress'.
+		'sdw' -> 'application/vnd.stardivision.writer'.
+		'ser' -> 'application/java-serialized-object'.
+		'sgf' -> 'application/x-go-sgf'.
+		'sgl' -> 'application/vnd.stardivision.writer-global'.
+		'sh' -> 'text/x-sh'.
+		'shar' -> 'application/x-shar'.
+		'shtml' -> 'text/html'.
+		'sid' -> 'audio/prs.sid'.
+		'sik' -> 'application/x-trash'.
+		'silo' -> 'model/mesh'.
+		'sis' -> 'application/vnd.symbian.install'.
+		'sit' -> 'application/x-stuffit'.
+		'skd' -> 'application/x-koan'.
+		'skm' -> 'application/x-koan'.
+		'skp' -> 'application/x-koan'.
+		'skt' -> 'application/x-koan'.
+		'smf' -> 'application/vnd.stardivision.math'.
+		'smi' -> 'application/smil'.
+		'smil' -> 'application/smil'.
+		'snd' -> 'audio/basic'.
+		'spc' -> 'chemical/x-galactic-spc'.
+		'spl' -> 'application/x-futuresplash'.
+		'src' -> 'application/x-wais-source'.
+		'stc' -> 'application/vnd.sun.xml.calc.template'.
+		'std' -> 'application/vnd.sun.xml.draw.template'.
+		'sti' -> 'application/vnd.sun.xml.impress.template'.
+		'stl' -> 'application/vnd.ms-pki.stl'.
+		'stw' -> 'application/vnd.sun.xml.writer.template'.
+		'sty' -> 'text/x-tex'.
+		'sv4cpio' -> 'application/x-sv4cpio'.
+		'sv4crc' -> 'application/x-sv4crc'.
+		'svg' -> 'image/svg+xml'.
+		'svgz' -> 'image/svg+xml'.
+		'sw' -> 'chemical/x-swissprot'.
+		'swf' -> 'application/x-shockwave-flash'.
+		'swfl' -> 'application/x-shockwave-flash'.
+		'sxc' -> 'application/vnd.sun.xml.calc'.
+		'sxd' -> 'application/vnd.sun.xml.draw'.
+		'sxg' -> 'application/vnd.sun.xml.writer.global'.
+		'sxi' -> 'application/vnd.sun.xml.impress'.
+		'sxm' -> 'application/vnd.sun.xml.math'.
+		'sxw' -> 'application/vnd.sun.xml.writer'.
+		't' -> 'application/x-troff'.
+		'tar' -> 'application/x-tar'.
+		'taz' -> 'application/x-gtar'.
+		'tcl' -> 'text/x-tcl'.
+		'tex' -> 'text/x-tex'.
+		'texi' -> 'application/x-texinfo'.
+		'texinfo' -> 'application/x-texinfo'.
+		'text' -> 'text/plain'.
+		'tgf' -> 'chemical/x-mdl-tgf'.
+		'tgz' -> 'application/x-gtar'.
+		'tif' -> 'image/tiff'.
+		'tiff' -> 'image/tiff'.
+		'tk' -> 'text/x-tcl'.
+		'tm' -> 'text/texmacs'.
+		'torrent' -> 'application/x-bittorrent'.
+		'tr' -> 'application/x-troff'.
+		'ts' -> 'text/texmacs'.
+		'tsp' -> 'application/dsptype'.
+		'tsv' -> 'text/tab-separated-values'.
+		'txt' -> 'text/plain'.
+		'udeb' -> 'application/x-debian-package'.
+		'uls' -> 'text/iuls'.
+		'ustar' -> 'application/x-ustar'.
+		'val' -> 'chemical/x-ncbi-asn1-binary'.
+		'vcd' -> 'application/x-cdlink'.
+		'vcf' -> 'text/x-vcard'.
+		'vcs' -> 'text/x-vcalendar'.
+		'vmd' -> 'chemical/x-vmd'.
+		'vms' -> 'chemical/x-vamas-iso14976'.
+		'vor' -> 'application/vnd.stardivision.writer'.
+		'vrm' -> 'x-world/x-vrml'.
+		'vrml' -> 'x-world/x-vrml'.
+		'vsd' -> 'application/vnd.visio'.
+		'wad' -> 'application/x-doom'.
+		'wav' -> 'audio/x-wav'.
+		'wax' -> 'audio/x-ms-wax'.
+		'wbmp' -> 'image/vnd.wap.wbmp'.
+		'wbxml' -> 'application/vnd.wap.wbxml'.
+		'wk' -> 'application/x-123'.
+		'wm' -> 'video/x-ms-wm'.
+		'wma' -> 'audio/x-ms-wma'.
+		'wmd' -> 'application/x-ms-wmd'.
+		'wml' -> 'text/vnd.wap.wml'.
+		'wmlc' -> 'application/vnd.wap.wmlc'.
+		'wmls' -> 'text/vnd.wap.wmlscript'.
+		'wmlsc' -> 'application/vnd.wap.wmlscriptc'.
+		'wmv' -> 'video/x-ms-wmv'.
+		'wmx' -> 'video/x-ms-wmx'.
+		'wmz' -> 'application/x-ms-wmz'.
+		'wp5' -> 'application/wordperfect5.1'.
+		'wpd' -> 'application/wordperfect'.
+		'wrl' -> 'x-world/x-vrml'.
+		'wsc' -> 'text/scriptlet'.
+		'wvx' -> 'video/x-ms-wvx'.
+		'wz' -> 'application/x-wingz'.
+		'xbm' -> 'image/x-xbitmap'.
+		'xcf' -> 'application/x-xcf'.
+		'xht' -> 'application/xhtml+xml'.
+		'xhtml' -> 'application/xhtml+xml'.
+		'xlb' -> 'application/vnd.ms-excel'.
+		'xls' -> 'application/vnd.ms-excel'.
+		'xlt' -> 'application/vnd.ms-excel'.
+		'xml' -> 'application/xml'.
+		'xpi' -> 'application/x-xpinstall'.
+		'xpm' -> 'image/x-xpixmap'.
+		'xsl' -> 'application/xml'.
+		'xtel' -> 'chemical/x-xtel'.
+		'xul' -> 'application/vnd.mozilla.xul+xml'.
+		'xwd' -> 'image/x-xwindowdump'.
+		'xyz' -> 'chemical/x-xyz'.
+		'zip' -> 'application/zip'.
+		'zmt' -> 'chemical/x-mopac-input'.
+		'~' -> 'application/x-trash'
+	}
+!
+
+mimeTypes
+	^mimeTypes ifNil: [mimeTypes := self defaultMimeTypes]
+!
+
+mimeTypeFor: aString
+	^self mimeTypes at: (aString replace: '.*[\.]' with: '') ifAbsent: ['text/plain']
+! !
+
+!FileServer class methodsFor: 'initialization'!
+
+main
+	^self new startOn: self port
+! !
+

File diff suppressed because it is too large
+ 5856 - 0
server/server.js


+ 6 - 3
st/IDE.st

@@ -745,7 +745,10 @@ renameClass
 
 addInstanceVariableNamed: aString toClass: aClass
 	ClassBuilder new
-		addSubclassOf: aClass superclass named: aClass name instanceVariableNames: (aClass instanceVariableNames copy add: aString; yourself)
+		addSubclassOf: aClass superclass 
+		named: aClass name 
+		instanceVariableNames: (aClass instanceVariableNames copy add: aString; yourself)
+		module: aClass module name
 !
 
 searchReferencesOf: aString
@@ -1200,7 +1203,7 @@ referencedClasses
 
 openBrowserOn: aMethod
        | browser |
-       browser := Browser openOn: (aMethod class isMetaclass 
+       browser := Browser openOn: (aMethod methodClass isMetaclass 
 		ifTrue: [aMethod methodClass instanceClass] ifFalse: [aMethod methodClass]).
        aMethod methodClass isMetaclass ifTrue: [browser selectTab: #class].
        browser
@@ -1420,7 +1423,7 @@ currentLineOrSelection
 !SourceArea methodsFor: 'actions'!
 
 clear
-    textarea asJQuery val: ''
+      self val: ''
 !
 
 doIt

+ 165 - 3
st/Kernel-Tests.st

@@ -19,6 +19,17 @@ testStreamContents
 testIncludesSubString
 	self assert: ('jtalk' includesSubString: 'alk').
 	self deny: ('jtalk' includesSubString: 'zork').
+!
+
+testEquality
+	self assert: 'hello' = 'hello'.
+	self deny: 'hello' = 'world'.
+
+	self assert: 'hello'  = 'hello' yourself.
+	self assert: 'hello' yourself = 'hello'.
+
+	"test JS falsy value"
+	self deny: '' = 0
 ! !
 
 TestCase subclass: #DictionaryTest
@@ -28,12 +39,35 @@ TestCase subclass: #DictionaryTest
 !DictionaryTest methodsFor: 'tests'!
 
 testPrintString
-	self 
+	self
 		assert: 'a Dictionary(''firstname'' -> ''James'' , ''lastname'' -> ''Bond'')' 
 		equals: (Dictionary new 
                          	at:'firstname' put: 'James';
                         	at:'lastname' put: 'Bond';
                         	printString)
+!
+
+testEquality
+	| d1 d2 |
+
+	self assert: Dictionary new = Dictionary new.
+		
+	d1 := Dictionary new at: 1 put: 2; yourself.
+	d2 := Dictionary new at: 1 put: 2; yourself.
+	self assert: d1 = d2.
+
+	d2 := Dictionary new at: 1 put: 3; yourself.
+	self deny: d1 = d2.
+
+	d2 := Dictionary new at: 2 put: 2; yourself.
+	self deny: d1 = d2.
+
+	d2 := Dictionary new at: 1 put: 2; at: 3 put: 4; yourself.
+	self deny: d1 = d2.
+!
+
+testDynamicDictionaries
+	self assert: #{1 -> 'hello'. 2 -> 'world'} = (Dictionary with: 1 -> 'hello' with: 2 -> 'world')
 ! !
 
 TestCase subclass: #BooleanTest
@@ -43,13 +77,142 @@ TestCase subclass: #BooleanTest
 !BooleanTest methodsFor: 'not yet classified'!
 
 testLogic
-
+ 
 	"Trivial logic table"
 	self assert: (true & true); deny: (true & false); deny: (false & true); deny: (false & false).
 	self assert: (true | true); assert: (true | false); assert: (false | true); deny: (false | false).
         "Checking that expressions work fine too"
 	self assert: (true & (1 > 0)); deny: ((1 > 0) & false); deny: ((1 > 0) & (1 > 2)).
         self assert: (false | (1 > 0)); assert: ((1 > 0) | false); assert: ((1 > 0) | (1 > 2))
+!
+
+testEquality
+	"We're on top of JS...just be sure to check the basics!!"
+
+	self deny: 0 = false. 
+	self deny: false = 0.
+	self deny: '' = false.
+	self deny: false = ''.
+
+	self assert: true = true.
+	self deny: false = true.
+	self deny: true = false.
+	self assert: false = false.
+
+	"JS may do some type coercing after sending a message"
+	self assert: true yourself = true.
+	self assert: true yourself = true yourself
+!
+
+testLogicKeywords
+ 
+	"Trivial logic table"
+	self 
+		assert: (true and: [ true]); 
+		deny: (true and: [ false ]); 
+		deny: (false and: [ true ]); 
+		deny: (false and: [ false ]).
+	self 
+		assert: (true or: [ true ]); 
+		assert: (true or: [ false ]); 
+		assert: (false or: [ true ]); 
+		deny: (false or: [ false ]).
+        
+	"Checking that expressions work fine too"
+	self 
+		assert: (true and: [ 1 > 0 ]); 
+		deny: ((1 > 0) and: [ false ]); 
+		deny: ((1 > 0) and: [ 1 > 2 ]).
+        self 
+		assert: (false or: [ 1 > 0 ]); 
+		assert: ((1 > 0) or: [ false ]); 
+		assert: ((1 > 0) or: [ 1 > 2 ])
+!
+
+testIfTrueIfFalse
+ 
+	self assert: (true ifTrue: ['alternative block']) = 'alternative block'.
+	self assert: (true ifFalse: ['alternative block']) = nil.
+
+	self assert: (false ifTrue: ['alternative block']) = nil.
+	self assert: (false ifFalse: ['alternative block']) = 'alternative block'.
+
+	self assert: (false ifTrue: ['alternative block'] ifFalse: ['alternative block2']) = 'alternative block2'.
+	self assert: (false ifFalse: ['alternative block'] ifTrue: ['alternative block2']) = 'alternative block'.
+
+	self assert: (true ifTrue: ['alternative block'] ifFalse: ['alternative block2']) = 'alternative block'.
+	self assert: (true ifFalse: ['alternative block'] ifTrue: ['alternative block2']) = 'alternative block2'.
+! !
+
+TestCase subclass: #NumberTest
+	instanceVariableNames: ''
+	category: 'Kernel-Tests'!
+
+!NumberTest methodsFor: 'tests'!
+
+testEquality
+	self assert: 1 = 1.
+	self assert: 0 = 0.
+	self deny: 1 = 0.
+
+	self assert: 1 yourself = 1.
+	self assert: 1 = 1 yourself.
+	self assert: 1 yourself = 1 yourself.
+	
+	self deny: 0 = false.
+	self deny: false = 0.
+	self deny: '' = 0.
+	self deny: 0 = ''
+!
+
+testArithmetic
+	
+	"We rely on JS here, so we won't test complex behavior, just check if 
+	message sends are corrects"
+
+	self assert: 1.5 + 1 = 2.5.
+	self assert: 2 - 1 = 1.
+	self assert: -2 - 1 = -3.
+	self assert: 12 / 2 = 6.
+	self assert: 3 * 4 = 12.
+
+	"Simple parenthesis and execution order"
+
+	self assert: 1 + 2 * 3 = 9.
+	self assert: 1 + (2 * 3) = 7
+!
+
+testRounded
+	
+	self assert: 3 rounded = 3.
+	self assert: 3.212 rounded = 3.
+	self assert: 3.51 rounded = 4
+!
+
+testNegated
+	self assert: 3 negated = -3.
+	self assert: -3 negated = 3
+!
+
+testComparison
+
+	self assert: 3 > 2.
+	self assert: 2 < 3.
+	
+	self deny: 3 < 2.
+	self deny: 2 > 3.
+
+	self assert: 3 >= 3.
+	self assert: 3.1 >= 3.
+	self assert: 3 <= 3.
+	self assert: 3 <= 3.1
+!
+
+testTruncated
+	
+	self assert: 3 truncated = 3.
+	self assert: 3.212 truncated = 3.
+	self assert: 3.51 truncated = 3
 ! !
 
 TestCase subclass: #NumberTest
@@ -73,4 +236,3 @@ testPrintShowingDecimalPlaces
 	self assert: '-2.57' equals: (-2.567 printShowingDecimalPlaces: 2).
 	self assert: '0.00' equals: (0 printShowingDecimalPlaces: 2).
 ! !
-

+ 58 - 16
st/Kernel.st

@@ -39,11 +39,19 @@ basicDelete: aString
 !Object methodsFor: 'comparing'!
 
 = anObject
-	<return self == anObject>
+	^self == anObject
 !
 
 ~= anObject
 	^(self = anObject) = false
+!
+
+== anObject
+	<return self === anObject>
+!
+
+~~ anObject
+	^(self == anObject) = false
 ! !
 
 !Object methodsFor: 'converting'!
@@ -656,11 +664,6 @@ negated
 
 !Number methodsFor: 'comparing'!
 
-= aNumber
-	"Inlined in the Compiler"
-	<return Number(self) == aNumber>
-!
-
 > aNumber
 	"Inlined in the Compiler"
 	<return self >> aNumber>
@@ -679,6 +682,16 @@ negated
 <= aNumber
 	"Inlined in the Compiler"
 	<return self <= aNumber>
+!
+
+= aNumber
+	aNumber class = self class ifFalse: [^false]. 
+	<return Number(self) == aNumber>
+!
+
+== aNumber
+	aNumber class = self class ifFalse: [^false]. 
+	<return Number(self) === Number(aNumber)>
 ! !
 
 !Number methodsFor: 'converting'!
@@ -884,11 +897,13 @@ Object subclass: #Boolean
 !Boolean methodsFor: 'comparing'!
 
 = aBoolean
+	aBoolean class = self class ifFalse: [^false].
 	<return Boolean(self == true) == aBoolean>
 !
 
-asJSONObject
-	^self
+== aBoolean
+	aBoolean class = self class ifFalse: [^false].
+	<return Boolean(self == true) === Boolean(aBoolean == true)>
 ! !
 
 !Boolean methodsFor: 'controlling'!
@@ -955,6 +970,12 @@ not
 	>
 ! !
 
+!Boolean methodsFor: 'converting'!
+
+asJSONObject
+	^self
+! !
+
 !Boolean methodsFor: 'copying'!
 
 shallowCopy
@@ -1580,10 +1601,6 @@ remove: anObject
 
 !String methodsFor: 'comparing'!
 
-= aString
-	<return String(self) == aString>
-!
-
 > aString
 	<return String(self) >> aString>
 !
@@ -1598,6 +1615,16 @@ remove: anObject
 
 <= aString
 	<return String(self) <= aString>
+!
+
+= aString
+	aString class = self class ifFalse: [^false].
+	<return String(self) == aString>
+!
+
+== aString
+	aString class = self class ifFalse: [^false].
+	<return String(self) === String(aString)>
 ! !
 
 !String methodsFor: 'converting'!
@@ -1903,6 +1930,16 @@ removeFrom: aNumber to: anotherNumber
 	<self.splice(aNumber - 1,anotherNumber - 1)>
 ! !
 
+!Array methodsFor: 'comparing'!
+
+= aCollection
+	(self class = aCollection class and: [
+        	self size = aCollection size]) ifFalse: [^false].
+	self withIndexDo: [:each :i |
+                 (aCollection at: i) = each ifFalse: [^false]].
+	^true
+! !
+
 !Array methodsFor: 'converting'!
 
 asJavascript
@@ -2186,10 +2223,8 @@ removeKey: aKey
 
 = aDictionary
 	self class = aDictionary class ifFalse: [^false].
-	self associationsDo: [:assoc |
-	    (aDictionary at: assoc key ifAbsent: [^false]) = assoc value 
-		ifFalse: [^false]].
-	^true
+	self size = aDictionary size ifFalse: [^false].
+	^self associations = aDictionary associations
 ! !
 
 !Dictionary methodsFor: 'converting'!
@@ -2836,6 +2871,13 @@ remove: anObject
 	elements remove: anObject
 ! !
 
+!Set methodsFor: 'comparing'!
+
+= aCollection
+	^self class = aCollection class and: [
+        	elements = aCollection asArray]
+! !
+
 !Set methodsFor: 'converting'!
 
 asArray

Some files were not shown because too many files changed in this diff