Parcourir la source

Merge remote branch 'upstream/master'

Göran Krampe il y a 13 ans
Parent
commit
8c87e52cf5
16 fichiers modifiés avec 5349 ajouts et 676 suppressions
  1. 3 0
      bin/amber
  2. 2 2
      js/Compiler.deploy.js
  3. 2 2
      js/Compiler.js
  4. 1 1
      js/IDE.deploy.js
  5. 1 1
      js/IDE.js
  6. 390 20
      js/Kernel.deploy.js
  7. 531 32
      js/Kernel.js
  8. 183 183
      js/amber.js
  9. 417 417
      js/boot.js
  10. 8 0
      repl/Makefile
  11. 125 0
      repl/REPL.js
  12. 52 0
      repl/REPL.st
  13. 3392 0
      repl/amber.js
  14. 1 1
      server/Makefile
  15. 15 2
      st/IDE.st
  16. 226 15
      st/Kernel.st

+ 3 - 0
bin/amber

@@ -0,0 +1,3 @@
+#!/bin/bash
+cd `dirname $0`/..
+node ./repl/amber.js

+ 2 - 2
js/Compiler.deploy.js

@@ -17,11 +17,11 @@ smalltalk.method({
 selector: 'nextChunk',
 fn: function (){
 var self=this;
-try{var char=nil;
+try{var char_=nil;
 var result=nil;
 var chunk=nil;
 result=smalltalk.send("", "_writeStream", []);
-(function(){while((function(){char=smalltalk.send(self['@stream'], "_next", []);return smalltalk.send(char, "_notNil", []);})()) {(function(){((($receiver = smalltalk.send(char, "__eq", [unescape("%21")])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return ((($receiver = smalltalk.send(smalltalk.send(self['@stream'], "_peek", []), "__eq", [unescape("%21")])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self['@stream'], "_next", []);})() : (function(){return (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])}})})();})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self['@stream'], "_next", []);}), (function(){return (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])}})})();})]));})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return ((($receiver = smalltalk.send(smalltalk.send(self['@stream'], "_peek", []), "__eq", [unescape("%21")])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self['@stream'], "_next", []);})() : (function(){return (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])}})})();})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self['@stream'], "_next", []);}), (function(){return (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])}})})();})]));})]));return smalltalk.send(result, "_nextPut_", [char]);})()}})();
+(function(){while((function(){char_=smalltalk.send(self['@stream'], "_next", []);return smalltalk.send(char_, "_notNil", []);})()) {(function(){((($receiver = smalltalk.send(char_, "__eq", [unescape("%21")])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return ((($receiver = smalltalk.send(smalltalk.send(self['@stream'], "_peek", []), "__eq", [unescape("%21")])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self['@stream'], "_next", []);})() : (function(){return (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])}})})();})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self['@stream'], "_next", []);}), (function(){return (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])}})})();})]));})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return ((($receiver = smalltalk.send(smalltalk.send(self['@stream'], "_peek", []), "__eq", [unescape("%21")])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self['@stream'], "_next", []);})() : (function(){return (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])}})})();})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self['@stream'], "_next", []);}), (function(){return (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])}})})();})]));})]));return smalltalk.send(result, "_nextPut_", [char_]);})()}})();
 (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return nil}})})();
 return self;
 } catch(e) {if(e.name === 'stReturn' && e.selector === '_nextChunk'){return e.fn()} throw(e)}}

+ 2 - 2
js/Compiler.js

@@ -23,11 +23,11 @@ selector: unescape('nextChunk'),
 category: 'reading',
 fn: function (){
 var self=this;
-try{var char=nil;
+try{var char_=nil;
 var result=nil;
 var chunk=nil;
 result=smalltalk.send("", "_writeStream", []);
-(function(){while((function(){char=smalltalk.send(self['@stream'], "_next", []);return smalltalk.send(char, "_notNil", []);})()) {(function(){((($receiver = smalltalk.send(char, "__eq", [unescape("%21")])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return ((($receiver = smalltalk.send(smalltalk.send(self['@stream'], "_peek", []), "__eq", [unescape("%21")])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self['@stream'], "_next", []);})() : (function(){return (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])}})})();})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self['@stream'], "_next", []);}), (function(){return (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])}})})();})]));})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return ((($receiver = smalltalk.send(smalltalk.send(self['@stream'], "_peek", []), "__eq", [unescape("%21")])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self['@stream'], "_next", []);})() : (function(){return (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])}})})();})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self['@stream'], "_next", []);}), (function(){return (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])}})})();})]));})]));return smalltalk.send(result, "_nextPut_", [char]);})()}})();
+(function(){while((function(){char_=smalltalk.send(self['@stream'], "_next", []);return smalltalk.send(char_, "_notNil", []);})()) {(function(){((($receiver = smalltalk.send(char_, "__eq", [unescape("%21")])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return ((($receiver = smalltalk.send(smalltalk.send(self['@stream'], "_peek", []), "__eq", [unescape("%21")])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self['@stream'], "_next", []);})() : (function(){return (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])}})})();})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self['@stream'], "_next", []);}), (function(){return (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])}})})();})]));})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return ((($receiver = smalltalk.send(smalltalk.send(self['@stream'], "_peek", []), "__eq", [unescape("%21")])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self['@stream'], "_next", []);})() : (function(){return (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])}})})();})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self['@stream'], "_next", []);}), (function(){return (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return smalltalk.send(smalltalk.send(result, "_contents", []), "_trimBoth", [])}})})();})]));})]));return smalltalk.send(result, "_nextPut_", [char_]);})()}})();
 (function(){throw({name: 'stReturn', selector: '_nextChunk', fn: function(){return nil}})})();
 return self;
 } catch(e) {if(e.name === 'stReturn' && e.selector === '_nextChunk'){return e.fn()} throw(e)}},

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


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


+ 390 - 20
js/Kernel.deploy.js

@@ -607,17 +607,6 @@ return self;}
 }),
 smalltalk.Smalltalk);
 
-smalltalk.addMethod(
-'_readJSON_',
-smalltalk.method({
-selector: 'readJSON:',
-fn: function (anObject){
-var self=this;
-return self.readJSObject(anObject);
-return self;}
-}),
-smalltalk.Smalltalk);
-
 smalltalk.addMethod(
 '_at_',
 smalltalk.method({
@@ -802,6 +791,17 @@ return self;}
 }),
 smalltalk.Smalltalk);
 
+smalltalk.addMethod(
+'_readJSObject_',
+smalltalk.method({
+selector: 'readJSObject:',
+fn: function (anObject){
+var self=this;
+return self.readJSObject(anObject);
+return self;}
+}),
+smalltalk.Smalltalk);
+
 
 smalltalk.Smalltalk.klass.iVarNames = ['current'];
 smalltalk.addMethod(
@@ -823,7 +823,7 @@ smalltalk.method({
 selector: 'name',
 fn: function (){
 var self=this;
-return self.pkgName || nil;
+return self.pkgName;
 return self;}
 }),
 smalltalk.Package);
@@ -889,12 +889,7 @@ smalltalk.method({
 selector: 'properties',
 fn: function (){
 var self=this;
-var result=nil;
-result=smalltalk.send((smalltalk.Dictionary || Dictionary), "_new", []);
-for (var i in self.properties) {
-		result._at_put_(i, self.properties[i]);
-	}
-	return result;;
+return smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_readJSObject_", [smalltalk.send(self, "_basicAt_", ["properties"])]);
 return self;}
 }),
 smalltalk.Package);
@@ -930,7 +925,7 @@ smalltalk.method({
 selector: 'jsProperties',
 fn: function (){
 var self=this;
-return self.properties || nil;
+return self.properties;
 return self;}
 }),
 smalltalk.Package);
@@ -2253,6 +2248,17 @@ return self;}
 }),
 smalltalk.BlockClosure);
 
+smalltalk.addMethod(
+'_numArgs',
+smalltalk.method({
+selector: 'numArgs',
+fn: function (){
+var self=this;
+return self.length;
+return self;}
+}),
+smalltalk.BlockClosure);
+
 
 
 smalltalk.addClass('Boolean', smalltalk.Object, [], 'Kernel');
@@ -5307,6 +5313,23 @@ return self;}
 }),
 smalltalk.ClassBuilder);
 
+smalltalk.addMethod(
+'_copyClass_named_',
+smalltalk.method({
+selector: 'copyClass:named:',
+fn: function (aClass, aString){
+var self=this;
+var newClass=nil;
+newClass=smalltalk.send(self, "_addSubclassOf_named_instanceVariableNames_package_", [smalltalk.send(aClass, "_superclass", []), aString, smalltalk.send(aClass, "_instanceVariableNames", []), smalltalk.send(smalltalk.send(aClass, "_package", []), "_name", [])]);
+smalltalk.send(self, "_setupClass_", [newClass]);
+smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_methodDictionary", []), "_values", []), "_do_", [(function(each){smalltalk.send(newClass, "_addCompiledMethod_", [smalltalk.send(smalltalk.send((smalltalk.Compiler || Compiler), "_new", []), "_load_forClass_", [smalltalk.send(each, "_source", []), newClass])]);return smalltalk.send(smalltalk.send(smalltalk.send(newClass, "_methodDictionary", []), "_at_", [smalltalk.send(each, "_selector", [])]), "_category_", [smalltalk.send(each, "_category", [])]);})]);
+smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aClass, "_class", []), "_methodDictionary", []), "_values", []), "_do_", [(function(each){smalltalk.send(smalltalk.send(newClass, "_class", []), "_addCompiledMethod_", [smalltalk.send(smalltalk.send((smalltalk.Compiler || Compiler), "_new", []), "_load_forClass_", [smalltalk.send(each, "_source", []), smalltalk.send(newClass, "_class", [])])]);return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(newClass, "_class", []), "_methodDictionary", []), "_at_", [smalltalk.send(each, "_selector", [])]), "_category_", [smalltalk.send(each, "_category", [])]);})]);
+smalltalk.send(self, "_setupClass_", [newClass]);
+return newClass;
+return self;}
+}),
+smalltalk.ClassBuilder);
+
 
 
 smalltalk.addClass('ClassCategoryReader', smalltalk.Object, ['class', 'category', 'chunkParser'], 'Kernel');
@@ -6481,7 +6504,9 @@ smalltalk.method({
 selector: 'show:',
 fn: function (anObject){
 var self=this;
-console.log(String(anObject._asString()));
+var string=nil;
+string=smalltalk.send(anObject, "_asString", []);
+console.log(String(string));
 return self;}
 }),
 smalltalk.ConsoleTranscript);
@@ -6510,3 +6535,348 @@ return self;}
 smalltalk.ConsoleTranscript.klass);
 
 
+smalltalk.addClass('Dictionary2', smalltalk.Dictionary, ['keys'], 'Kernel');
+smalltalk.addMethod(
+'__eq',
+smalltalk.method({
+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}})})();})]));
+((($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)}}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_shallowCopy',
+smalltalk.method({
+selector: 'shallowCopy',
+fn: function (){
+var self=this;
+var copy=nil;
+copy=smalltalk.send(smalltalk.send(self, "_class", []), "_new", []);
+smalltalk.send(self, "_associationsDo_", [(function(each){return smalltalk.send(copy, "_at_put_", [smalltalk.send(each, "_key", []), smalltalk.send(each, "_value", [])]);})]);
+return copy;
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_initialize',
+smalltalk.method({
+selector: 'initialize',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_initialize", [], smalltalk.Dictionary);
+self['@keys']=[];
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_size',
+smalltalk.method({
+selector: 'size',
+fn: function (){
+var self=this;
+return smalltalk.send(self['@keys'], "_size", []);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_associations',
+smalltalk.method({
+selector: 'associations',
+fn: function (){
+var self=this;
+var associations=nil;
+associations=[];
+smalltalk.send(self['@keys'], "_do_", [(function(each){return smalltalk.send(associations, "_add_", [smalltalk.send((smalltalk.Association || Association), "_key_value_", [each, smalltalk.send(self, "_at_", [each])])]);})]);
+return associations;
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_keys',
+smalltalk.method({
+selector: 'keys',
+fn: function (){
+var self=this;
+return smalltalk.send(self['@keys'], "_copy", []);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_values',
+smalltalk.method({
+selector: 'values',
+fn: function (){
+var self=this;
+return smalltalk.send(self['@keys'], "_collect_", [(function(each){return smalltalk.send(self, "_at_", [each]);})]);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_at_put_',
+smalltalk.method({
+selector: 'at:put:',
+fn: function (aKey, aValue){
+var self=this;
+((($receiver = smalltalk.send(self['@keys'], "_includes_", [aKey])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){return smalltalk.send(self['@keys'], "_add_", [aKey]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){return smalltalk.send(self['@keys'], "_add_", [aKey]);})]));
+return smalltalk.send(self, "_basicAt_put_", [aKey, aValue]);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_at_ifAbsent_',
+smalltalk.method({
+selector: 'at:ifAbsent:',
+fn: function (aKey, aBlock){
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(self, "_keys", []), "_includes_", [aKey]), "_ifTrue_ifFalse_", [(function(){return smalltalk.send(self, "_basicAt_", [aKey]);}), aBlock]);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_at_ifAbsentPut_',
+smalltalk.method({
+selector: 'at:ifAbsentPut:',
+fn: function (aKey, aBlock){
+var self=this;
+return smalltalk.send(self, "_at_ifAbsent_", [aKey, (function(){return smalltalk.send(self, "_at_put_", [aKey, smalltalk.send(aBlock, "_value", [])]);})]);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_at_ifPresent_',
+smalltalk.method({
+selector: 'at:ifPresent:',
+fn: function (aKey, aBlock){
+var self=this;
+return (($receiver = smalltalk.send(self, "_basicAt_", [aKey])) != nil && $receiver != undefined) ? (function(){return smalltalk.send(aBlock, "_value_", [smalltalk.send(self, "_at_", [aKey])]);})() : nil;
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_at_ifPresent_ifAbsent_',
+smalltalk.method({
+selector: 'at:ifPresent:ifAbsent:',
+fn: function (aKey, aBlock, anotherBlock){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_basicAt_", [aKey]), "_ifNil_ifNotNil_", [anotherBlock, (function(){return smalltalk.send(aBlock, "_value_", [smalltalk.send(self, "_at_", [aKey])]);})]);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_add_',
+smalltalk.method({
+selector: 'add:',
+fn: function (anAssociation){
+var self=this;
+smalltalk.send(self, "_at_put_", [smalltalk.send(anAssociation, "_key", []), smalltalk.send(anAssociation, "_value", [])]);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_addAll_',
+smalltalk.method({
+selector: 'addAll:',
+fn: function (aDictionary){
+var self=this;
+smalltalk.send(self, "_addAll_", [smalltalk.send(aDictionary, "_associations", [])], smalltalk.Dictionary);
+return aDictionary;
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'__comma',
+smalltalk.method({
+selector: ',',
+fn: function (aCollection){
+var self=this;
+smalltalk.send(self, "_shouldNotImplement", []);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_copyFrom_to_',
+smalltalk.method({
+selector: 'copyFrom:to:',
+fn: function (anIndex, anotherIndex){
+var self=this;
+smalltalk.send(self, "_shouldNotImplement", []);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_associationsDo_',
+smalltalk.method({
+selector: 'associationsDo:',
+fn: function (aBlock){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_associations", []), "_do_", [aBlock]);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_keysAndValuesDo_',
+smalltalk.method({
+selector: 'keysAndValuesDo:',
+fn: function (aBlock){
+var self=this;
+smalltalk.send(self, "_associationsDo_", [(function(each){return smalltalk.send(aBlock, "_value_value_", [smalltalk.send(each, "_key", []), smalltalk.send(each, "_value", [])]);})]);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_do_',
+smalltalk.method({
+selector: 'do:',
+fn: function (aBlock){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_values", []), "_do_", [aBlock]);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_select_',
+smalltalk.method({
+selector: 'select:',
+fn: function (aBlock){
+var self=this;
+var newDict=nil;
+newDict=smalltalk.send(smalltalk.send(self, "_class", []), "_new", []);
+smalltalk.send(self, "_keysAndValuesDo_", [(function(key, value){return ((($receiver = smalltalk.send(aBlock, "_value_", [value])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(newDict, "_at_put_", [key, value]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(newDict, "_at_put_", [key, value]);})]));})]);
+return newDict;
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_collect_',
+smalltalk.method({
+selector: 'collect:',
+fn: function (aBlock){
+var self=this;
+var newDict=nil;
+newDict=smalltalk.send(smalltalk.send(self, "_class", []), "_new", []);
+smalltalk.send(self, "_keysAndValuesDo_", [(function(key, value){return smalltalk.send(newDict, "_at_put_", [key, smalltalk.send(aBlock, "_value_", [value])]);})]);
+return newDict;
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_detect_ifNone_',
+smalltalk.method({
+selector: 'detect:ifNone:',
+fn: function (aBlock, anotherBlock){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_values", []), "_detect_ifNone_", [aBlock, anotherBlock]);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_includes_',
+smalltalk.method({
+selector: 'includes:',
+fn: function (anObject){
+var self=this;
+return smalltalk.send(smalltalk.send(self, "_values", []), "_includes_", [anObject]);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_remove_',
+smalltalk.method({
+selector: 'remove:',
+fn: function (aKey){
+var self=this;
+smalltalk.send(self, "_removeKey_", [aKey]);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_removeKey_',
+smalltalk.method({
+selector: 'removeKey:',
+fn: function (aKey){
+var self=this;
+smalltalk.send(self['@keys'], "_remove_", [aKey]);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_at_',
+smalltalk.method({
+selector: 'at:',
+fn: function (aKey){
+var self=this;
+return smalltalk.send(self, "_at_ifAbsent_", [aKey, (function(){return smalltalk.send(self, "_errorNotFound", []);})]);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_asJSONObject',
+smalltalk.method({
+selector: 'asJSONObject',
+fn: function (){
+var self=this;
+var object=nil;
+object=smalltalk.send((smalltalk.Object || Object), "_new", []);
+smalltalk.send(self, "_keysAndValuesDo_", [(function(key, value){return smalltalk.send(object, "_basicAt_put_", [key, smalltalk.send(value, "_asJSONObject", [])]);})]);
+return object;
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_printString',
+smalltalk.method({
+selector: 'printString',
+fn: function (){
+var self=this;
+return smalltalk.send((smalltalk.String || String), "_streamContents_", [(function(aStream){(function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(self, "_printString", [], smalltalk.Dictionary)]);return smalltalk.send($rec, "_nextPutAll_", [unescape("%28")]);})(aStream);smalltalk.send(smalltalk.send(self, "_associations", []), "_do_separatedBy_", [(function(anAssociation){return (function($rec){smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(anAssociation, "_key", []), "_printString", [])]);smalltalk.send($rec, "_nextPutAll_", [unescape("%20-%3E%20")]);return smalltalk.send($rec, "_nextPutAll_", [smalltalk.send(smalltalk.send(anAssociation, "_value", []), "_printString", [])]);})(aStream);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [unescape("%20%2C%20")]);})]);return smalltalk.send(aStream, "_nextPutAll_", [unescape("%29")]);})]);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+smalltalk.addMethod(
+'_storeOn_',
+smalltalk.method({
+selector: 'storeOn:',
+fn: function (aStream){
+var self=this;
+smalltalk.send(aStream, "_nextPutAll_", [unescape("%23%7B")]);
+smalltalk.send(smalltalk.send(self, "_associations", []), "_do_separatedBy_", [(function(each){return smalltalk.send(each, "_storeOn_", [aStream]);}), (function(){return smalltalk.send(aStream, "_nextPutAll_", [". "]);})]);
+smalltalk.send(aStream, "_nextPutAll_", [unescape("%7D")]);
+return self;}
+}),
+smalltalk.Dictionary2);
+
+
+

Fichier diff supprimé car celui-ci est trop grand
+ 531 - 32
js/Kernel.js


+ 183 - 183
js/amber.js

@@ -1,193 +1,193 @@
 /* Amber package loading
-   usage example:
-   amber.load({
-     files: ['MyCategory1.js', 'MyCategory2.js'],
-     ready: function() {smalltalk.Browser._open()}
-   })
+	usage example:
+	amber.load({
+		files: ['MyCategory1.js', 'MyCategory2.js'],
+		ready: function() {smalltalk.Browser._open()}
+	})
 */
 
 
 amber = (function() {
-    var that = {};
-
-    var scripts = document.getElementsByTagName("script");
-    var src     = scripts[ scripts.length - 1 ].src;
-    var home    = src.split("/").slice(0, -2).join("/") + "/";
-    var nocache = '?' + (new Date()).getTime();
-
-    var debug;
-    var deploy;
-
-    var localStorageSource = [];
-    var localPackages;
-    var spec;
-
-    that.load = function(obj) {
-	spec = obj || {};
-
-	// In deployment mode, only the compressed version of Kernel
-	// and Canvas are loaded
-	deploy = spec.deploy || false;
-	debug = spec.debug || false;
-
-	// Specify a version string to avoid wrong browser caching
-	if (spec.version) {
-	    nocache = '?' + spec.version;
-	}
-	
-	loadDependencies();
-	loadJS('boot.js');
-	
-	populateLocalPackages();
-
-	if (deploy) {
-	    loadPackages([
-		'Kernel.deploy',
-		'Canvas.deploy'
-	    ]);
-	} else {
-	    loadIDEDependencies();
-	    loadCSS('amber.css');
-	    
-	    loadPackages([
-		'Kernel',
-		'Canvas',
-		'Compiler',
-		'parser',
-		'IDE',
-		'SUnit',
-		'Examples',
-		'Benchfib',
-		'Kernel-Tests'
-	    ]);
-	}
-
-	var additionalFiles = spec.packages || spec.files;
-	    if (additionalFiles) {
-		loadPackages(additionalFiles, spec.prefix);
-	    }
-
-	    // Always load all local packages
-	    for (name in localPackages) {
-		log('Local package:  ' + name);
-		localStorageSource.push(localPackages[name]);
-	    }
-
-	    // Be sure to setup & initialize smalltalk classes
-	    loadJS('init.js');
-	    initializeSmalltalk();
-    };
-
-    function loadPackages(names, prefix){
-	var name, url;
-	var prefix = prefix || 'js';
-	
-	for (var i=0; i < names.length; i++) {
-	    name = names[i].split(/\.js$/)[0];
-	    
-	    // Only load package from the server if it isn't stored in
-	    // localStorage
-	    if (!(name in localPackages)) {
-		log('Server package: ' + name);
-		loadJS(name + '.js', prefix);
-	    }
-	}
-    };
-
-    function loadJS(name, prefix) {
-	var prefix = prefix || 'js';
-	var name = name;
-	
-	if (!deploy) {
-	    name = name + nocache;
-	}
-
-	var url = home + prefix + '/' + name;
-	var scriptString = '<script src="' + url + '" type="text/javascript"></script>';
-	document.write(scriptString);
-    };
-
-    function loadCSS(name, prefix) {
-	var prefix = prefix || 'css';
-	var name = name;
-	if (!deploy) {
-	    name = name + nocache;
-	}
-
-	var url = home + prefix + '/' + name;
-
-	var link = document.createElement("link");
-	link.setAttribute("rel", "stylesheet");
-	link.setAttribute("type", "text/css");
-	link.setAttribute("href", url);
-	document.getElementsByTagName("head")[0].appendChild(link);
-    };
-
-    function loadDependencies() {
-	loadJS('lib/jQuery/jquery-1.6.4.min.js');
-	loadJS('lib/jQuery/jquery-ui-1.8.9.custom.min.js');
-    };
-    
-    function loadIDEDependencies() {
-	loadJS('lib/jQuery/jquery.textarea.js');
-	loadJS('lib/CodeMirror/lib/codemirror.js');
-	loadCSS('lib/CodeMirror/lib/codemirror.css', 'js');
-	loadJS('lib/CodeMirror/mode/smalltalk/smalltalk.js');
-	loadCSS('lib/CodeMirror/theme/amber.css', 'js');
-    };
-
-    // This will be called after JS files have been loaded
-    function initializeSmalltalk() {
-	
-	window.smalltalkReady = function() {
-	    
-	    for (var i=0; i < localStorageSource.length; i++) {
-		eval(localStorageSource[i]);
-	    }
-	    
-	    if (deploy) {
-		smalltalk.setDeploymentMode();
-	    }
-	    
-	    if (spec.ready) {
-		spec.ready();
-	    }
-	}
-    };
-
-    function populateLocalPackages(){
-	var localStorageRE = /^smalltalk\.packages\.(.*)$/;
-	localPackages = {};
-
-	var match, key;
-	
-	for(var i=0; i < localStorage.length; i++) {
-	    key = localStorage.key(i);
-	    
-	    if (match = key.match(localStorageRE)) {
-		localPackages[match[1]] = localStorage[key];
-	    }
-	}
-
-	return localPackages;
-    };
-
-    function clearLocalPackages() {
-	for (var name in localPackages) {
-	    log('Removing ' + name + ' from local storage');
-	    localStorage.removeItem('smalltalk.packages.' + name);
-	}
-    };
-
-    function log(string) {
-	if (debug) {
-	    console.log(string);
+	var that = {};
+
+	var scripts = document.getElementsByTagName("script");
+	var src     = scripts[ scripts.length - 1 ].src;
+	var home    = src.split("/").slice(0, -2).join("/") + "/";
+	var nocache = '?' + (new Date()).getTime();
+
+	var debug;
+	var deploy;
+
+	var localStorageSource = [];
+	var localPackages;
+	var spec;
+
+	that.load = function(obj) {
+		spec = obj || {};
+
+		// In deployment mode, only the compressed version of Kernel
+		// and Canvas are loaded
+		deploy = spec.deploy || false;
+		debug = spec.debug || false;
+
+		// Specify a version string to avoid wrong browser caching
+		if (spec.version) {
+			nocache = '?' + spec.version;
+		}
+
+		loadDependencies();
+		loadJS('boot.js');
+
+		populateLocalPackages();
+
+		if (deploy) {
+			loadPackages([
+					'Kernel.deploy',
+					'Canvas.deploy'
+					]);
+		} else {
+			loadIDEDependencies();
+			loadCSS('amber.css');
+
+			loadPackages([
+				'Kernel',
+				'Canvas',
+				'Compiler',
+				'parser',
+				'IDE',
+				'SUnit',
+				'Examples',
+				'Benchfib',
+				'Kernel-Tests'
+			]);
+		}
+
+		var additionalFiles = spec.packages || spec.files;
+		if (additionalFiles) {
+			loadPackages(additionalFiles, spec.prefix);
+		}
+
+		// Always load all local packages
+		for (name in localPackages) {
+			log('Local package:  ' + name);
+			localStorageSource.push(localPackages[name]);
+		}
+
+		// Be sure to setup & initialize smalltalk classes
+		loadJS('init.js');
+		initializeSmalltalk();
+	};
+
+	function loadPackages(names, prefix){
+		var name, url;
+		var prefix = prefix || 'js';
+
+		for (var i=0; i < names.length; i++) {
+			name = names[i].split(/\.js$/)[0];
+
+			// Only load package from the server if it isn't stored in
+			// localStorage
+			if (!(name in localPackages)) {
+				log('Server package: ' + name);
+				loadJS(name + '.js', prefix);
+			}
+		}
+	};
+
+	function loadJS(name, prefix) {
+		var prefix = prefix || 'js';
+		var name = name;
+
+		if (!deploy) {
+			name = name + nocache;
+		}
+
+		var url = home + prefix + '/' + name;
+		var scriptString = '<script src="' + url + '" type="text/javascript"></script>';
+		document.write(scriptString);
+	};
+
+	function loadCSS(name, prefix) {
+		var prefix = prefix || 'css';
+		var name = name;
+		if (!deploy) {
+			name = name + nocache;
+		}
+
+		var url = home + prefix + '/' + name;
+
+		var link = document.createElement("link");
+		link.setAttribute("rel", "stylesheet");
+		link.setAttribute("type", "text/css");
+		link.setAttribute("href", url);
+		document.getElementsByTagName("head")[0].appendChild(link);
+	};
+
+	function loadDependencies() {
+		loadJS('lib/jQuery/jquery-1.6.4.min.js');
+		loadJS('lib/jQuery/jquery-ui-1.8.9.custom.min.js');
+	};
+
+	function loadIDEDependencies() {
+		loadJS('lib/jQuery/jquery.textarea.js');
+		loadJS('lib/CodeMirror/lib/codemirror.js');
+		loadCSS('lib/CodeMirror/lib/codemirror.css', 'js');
+		loadJS('lib/CodeMirror/mode/smalltalk/smalltalk.js');
+		loadCSS('lib/CodeMirror/theme/amber.css', 'js');
+	};
+
+	// This will be called after JS files have been loaded
+	function initializeSmalltalk() {
+
+		window.smalltalkReady = function() {
+
+			for (var i=0; i < localStorageSource.length; i++) {
+				eval(localStorageSource[i]);
+			}
+
+			if (deploy) {
+				smalltalk.setDeploymentMode();
+			}
+
+			if (spec.ready) {
+				spec.ready();
+			}
+		}
+	};
+
+	function populateLocalPackages(){
+		var localStorageRE = /^smalltalk\.packages\.(.*)$/;
+		localPackages = {};
+
+		var match, key;
+
+		for(var i=0; i < localStorage.length; i++) {
+			key = localStorage.key(i);
+
+			if (match = key.match(localStorageRE)) {
+				localPackages[match[1]] = localStorage[key];
+			}
+		}
+
+		return localPackages;
+	};
+
+	function clearLocalPackages() {
+		for (var name in localPackages) {
+			log('Removing ' + name + ' from local storage');
+			localStorage.removeItem('smalltalk.packages.' + name);
+		}
+	};
+
+	function log(string) {
+		if (debug) {
+			console.log(string);
+		}
 	}
-    }
 
-    return that;
+	return that;
 })();
 
 window.loadAmber = function(spec) {
-    amber.load(spec);
-}
+	amber.load(spec);
+}

+ 417 - 417
js/boot.js

@@ -36,13 +36,13 @@
 /* Make that console is defined */
 
 if (typeof console === "undefined") {
-    this.console = {
-	log: function() {},
-	warn: function() {},
-	info: function() {},
-	debug: function() {},
-	error: function() {}
-    };
+	this.console = {
+		log: function() {},
+		warn: function() {},
+		info: function() {},
+		debug: function() {},
+		error: function() {}
+	};
 }
 
 
@@ -53,472 +53,472 @@ function SmalltalkBehavior(){};
 function SmalltalkClass(){};
 function SmalltalkPackage(){};
 function SmalltalkMetaclass(){
-    this.meta = true;
+	this.meta = true;
 };
 function SmalltalkMethod(){};
 function SmalltalkNil(){};
 
 function Smalltalk(){
 
-    var st = this;
-
-    /* This is the current call context object. While it is publicly available,
-       Use smalltalk.getThisContext() instead which will answer a safe copy of 
-       the current context */
-
-    st.thisContext = undefined;
-
-    /* List of all reserved words in JavaScript. They may not be used as variables
-       in Smalltalk. */
-
-    st.reservedWords = ['break', 'case', 'catch', 'class', 'continue', 'debugger', 
-			'default', 'delete', 'do', 'else', 'finally', 'for', 'function', 
-			'if', 'in', 'instanceof', 'new', 'private', 'protected', 
-			'public', 'return', 'static', 'switch', 'this', 'throw',
-			'try', 'typeof', 'var', 'void', 'while', 'with', 'yield'];
-    
-    /* We hold all Packages in a separate Object */
-
-    st.packages = {};
-
-    /* Smalltalk package creation. To add a Package, use smalltalk.addPackage() */
-
-    function pkg(spec) {
-	var that      = new SmalltalkPackage();
-	that.pkgName  = spec.pkgName;
-	that.properties = spec.properties || [];
-	return that;
-    };
-
-    /* Smalltalk class creation. A class is an instance of an automatically 
-       created metaclass object. Newly created classes (not their metaclass) 
-       should be added to the smalltalk object, see smalltalk.addClass().
-       Superclass linking is *not* handled here, see smalltalk.init()  */
-
-    function klass(spec) {
-	var spec = spec || {};
-	var that;
-	if(spec.meta) {
-	    that = new SmalltalkMetaclass();
-	} else {
-	    that = new (klass({meta: true})).fn;
-	    that.klass.instanceClass = that;
-	    that.className = spec.className;
-	    that.klass.className = that.className + ' class';
-	}
-	
-	that.fn = spec.fn || function(){};
-	that.superclass = spec.superclass;
-	that.iVarNames = spec.iVarNames || [];
-	if(that.superclass) {
-	    that.klass.superclass = that.superclass.klass;
-	}
-	that.pkg = spec.pkg;
-	that.fn.prototype.methods = {};
-	that.fn.prototype.inheritedMethods = {};
-	that.fn.prototype.klass = that;
-
-	return that;
-    };
-
-    /* Smalltalk method object. To add a method to a class,
-       use smalltalk.addMethod() */
-
-    st.method = function(spec) {
-	var that = new SmalltalkMethod();
-	that.selector          = spec.selector;
-	that.jsSelector        = spec.jsSelector;
-	that.args              = spec.args || {};
-	that.category          = spec.category;
-	that.source            = spec.source;
-	that.messageSends      = spec.messageSends || [];
-	that.referencedClasses = spec.referencedClasses || [];
-	that.fn                = spec.fn;
-	return that
-    };
-
-    /* Initialize a class in its class hierarchy. Handle both class and
-       metaclasses. */
-
-    st.init = function(klass) {
-	var subclasses = st.subclasses(klass);
-	var methods;
-
-	if(klass.superclass && klass.superclass !== nil) {
-	    methods = st.methods(klass.superclass);
-
-	    //Methods linking
-	    for(var i in methods) {
-		if(!klass.fn.prototype.methods[i]) {
-		    klass.fn.prototype.inheritedMethods[i] = methods[i];
-		    klass.fn.prototype[methods[i].jsSelector] = methods[i].fn;
+	var st = this;
+
+	/* This is the current call context object. While it is publicly available,
+	   Use smalltalk.getThisContext() instead which will answer a safe copy of 
+	   the current context */
+
+	st.thisContext = undefined;
+
+	/* List of all reserved words in JavaScript. They may not be used as variables
+	   in Smalltalk. */
+
+	st.reservedWords = ['break', 'case', 'catch', 'char', 'class', 'continue', 'debugger', 
+		'default', 'delete', 'do', 'else', 'finally', 'for', 'function', 
+		'if', 'in', 'instanceof', 'new', 'private', 'protected', 
+		'public', 'return', 'static', 'switch', 'this', 'throw',
+		'try', 'typeof', 'var', 'void', 'while', 'with', 'yield'];
+
+	/* We hold all Packages in a separate Object */
+
+	st.packages = {};
+
+	/* Smalltalk package creation. To add a Package, use smalltalk.addPackage() */
+
+	function pkg(spec) {
+		var that      = new SmalltalkPackage();
+		that.pkgName  = spec.pkgName;
+		that.properties = spec.properties || {};
+		return that;
+	};
+
+	/* Smalltalk class creation. A class is an instance of an automatically 
+	   created metaclass object. Newly created classes (not their metaclass) 
+	   should be added to the smalltalk object, see smalltalk.addClass().
+	   Superclass linking is *not* handled here, see smalltalk.init()  */
+
+	function klass(spec) {
+		var spec = spec || {};
+		var that;
+		if(spec.meta) {
+			that = new SmalltalkMetaclass();
+		} else {
+			that = new (klass({meta: true})).fn;
+			that.klass.instanceClass = that;
+			that.className = spec.className;
+			that.klass.className = that.className + ' class';
 		}
-	    }
-	}
 
-	for(var i=0;i<subclasses.length;i++) {
-     	    st.init(subclasses[i]);
-	}
-	if(klass.klass && !klass.meta) {
-	    st.init(klass.klass);
-	}
-    };
+		that.fn = spec.fn || function(){};
+		that.superclass = spec.superclass;
+		that.iVarNames = spec.iVarNames || [];
+		if(that.superclass) {
+			that.klass.superclass = that.superclass.klass;
+		}
+		that.pkg = spec.pkg;
+		that.fn.prototype.methods = {};
+		that.fn.prototype.inheritedMethods = {};
+		that.fn.prototype.klass = that;
+
+		return that;
+	};
+
+	/* Smalltalk method object. To add a method to a class,
+	   use smalltalk.addMethod() */
+
+	st.method = function(spec) {
+		var that = new SmalltalkMethod();
+		that.selector          = spec.selector;
+		that.jsSelector        = spec.jsSelector;
+		that.args              = spec.args || {};
+		that.category          = spec.category;
+		that.source            = spec.source;
+		that.messageSends      = spec.messageSends || [];
+		that.referencedClasses = spec.referencedClasses || [];
+		that.fn                = spec.fn;
+		return that
+	};
+
+	/* Initialize a class in its class hierarchy. Handle both class and
+	   metaclasses. */
+
+	st.init = function(klass) {
+		var subclasses = st.subclasses(klass);
+		var methods;
+
+		if(klass.superclass && klass.superclass !== nil) {
+			methods = st.methods(klass.superclass);
+
+			//Methods linking
+			for(var i in methods) {
+				if(!klass.fn.prototype.methods[i]) {
+					klass.fn.prototype.inheritedMethods[i] = methods[i];
+					klass.fn.prototype[methods[i].jsSelector] = methods[i].fn;
+				}
+			}
+		}
 
-    /* Answer all registered Packages as Array */
+		for(var i=0;i<subclasses.length;i++) {
+			st.init(subclasses[i]);
+		}
+		if(klass.klass && !klass.meta) {
+			st.init(klass.klass);
+		}
+	};
 
-    st.packages.all = function() {
-	var packages = [];
-	for(var i in st.packages) {
-          if (!st.packages.hasOwnProperty(i) || typeof(st.packages[i]) === "function") continue;
-	    packages.push(st.packages[i]);
-	}
-	return packages
-    };
+	/* Answer all registered Packages as Array */
 
-    /* Answer all registered Smalltalk classes */
+	st.packages.all = function() {
+		var packages = [];
+		for(var i in st.packages) {
+			if (!st.packages.hasOwnProperty(i) || typeof(st.packages[i]) === "function") continue;
+			packages.push(st.packages[i]);
+		}
+		return packages
+	};
 
-    st.classes = function() {
-	var classes = [];
-	for(var i in st) {
-	    if(i.search(/^[A-Z]/g) != -1) {
-		classes.push(st[i]);
-	    }
-	}
-	return classes
-    };
+	/* Answer all registered Smalltalk classes */
+
+	st.classes = function() {
+		var classes = [];
+		for(var i in st) {
+			if(i.search(/^[A-Z]/g) != -1) {
+				classes.push(st[i]);
+			}
+		}
+		return classes
+	};
 
-    /* Answer all methods (included inherited ones) of klass. */
+	/* Answer all methods (included inherited ones) of klass. */
 
-    st.methods = function(klass) {
-	var methods = {};
-	for(var i in klass.fn.prototype.methods) {
-	    methods[i] = klass.fn.prototype.methods[i]
-	}
-	for(var i in klass.fn.prototype.inheritedMethods) {
-	    methods[i] = klass.fn.prototype.inheritedMethods[i]
-	}
-	return methods;
-    }
-
-    /* Answer the direct subclasses of klass. */
-
-    st.subclasses = function(klass) {
-	var subclasses = [];
-	var classes = st.classes();
-	for(var i in classes) {
-	    if(classes[i].fn) {
-		//Metaclasses
-		if(classes[i].klass && classes[i].klass.superclass === klass) {
-		    subclasses.push(classes[i].klass);
+	st.methods = function(klass) {
+		var methods = {};
+		for(var i in klass.fn.prototype.methods) {
+			methods[i] = klass.fn.prototype.methods[i]
 		}
-		//Classes
-		if(classes[i].superclass === klass) {
-		    subclasses.push(classes[i]);
+		for(var i in klass.fn.prototype.inheritedMethods) {
+			methods[i] = klass.fn.prototype.inheritedMethods[i]
 		}
-	    }
-	}
-	return subclasses;
-    };
-
-    /* Create a new class wrapping a JavaScript constructor, and add it to the 
-       global smalltalk object. Package is lazily created if it does not exist with given name. */
-
-    st.mapClassName = function(className, pkgName, fn, superclass) {
-	var pkg = st.addPackage(pkgName, null);
-	st[className] = klass({
-	    className:  className, 
-	    superclass: superclass,
-	    pkg:        pkg, 
-	    fn:         fn
-	});
-    };
-
-    /* Add a package to the smalltalk.packages object, creating a new one if needed.
-       If pkgName is null or empty we return nil, which is an allowed package for a class.
-       If package already exists we still update the properties of it. */
-
-    st.addPackage = function(pkgName, properties) {
-	if(!pkgName) {return nil;}
-	if(!(st.packages[pkgName])) {
-	    st.packages[pkgName] = pkg({
-		pkgName: pkgName,
-		properties: properties
-	    });
-	} else {
-	    if(properties) {
-		st.packages[pkgName].properties = properties;
-	    }	
-	}
-	return st.packages[pkgName];
-    };
-
-    /* Add a class to the smalltalk object, creating a new one if needed.
-       Package is lazily created if it does not exist with given name.*/
-
-    st.addClass = function(className, superclass, iVarNames, pkgName) {
-	var pkg = st.addPackage(pkgName, null);
-	if(st[className]) {
-	    st[className].superclass = superclass;
-	    st[className].iVarNames = iVarNames;
-	    st[className].pkg = pkg || st[className].pkg;
-	} else {    
-	    st[className] = klass({
-		className: className, 
-		superclass: superclass,
-		pkg: pkg,
-		iVarNames: iVarNames
-	    });
+		return methods;
 	}
-    };
 
-    /* Add a method to a class */
+	/* Answer the direct subclasses of klass. */
+
+	st.subclasses = function(klass) {
+		var subclasses = [];
+		var classes = st.classes();
+		for(var i in classes) {
+			if(classes[i].fn) {
+				//Metaclasses
+				if(classes[i].klass && classes[i].klass.superclass === klass) {
+					subclasses.push(classes[i].klass);
+				}
+				//Classes
+				if(classes[i].superclass === klass) {
+					subclasses.push(classes[i]);
+				}
+			}
+		}
+		return subclasses;
+	};
+
+	/* Create a new class wrapping a JavaScript constructor, and add it to the 
+	   global smalltalk object. Package is lazily created if it does not exist with given name. */
+
+	st.mapClassName = function(className, pkgName, fn, superclass) {
+		var pkg = st.addPackage(pkgName);
+		st[className] = klass({
+			className:  className, 
+			superclass: superclass,
+			pkg:        pkg, 
+			fn:         fn
+		});
+	};
+
+	/* Add a package to the smalltalk.packages object, creating a new one if needed.
+	   If pkgName is null or empty we return nil, which is an allowed package for a class.
+	   If package already exists we still update the properties of it. */
+
+	st.addPackage = function(pkgName, properties) {
+		if(!pkgName) {return nil;}
+		if(!(st.packages[pkgName])) {
+			st.packages[pkgName] = pkg({
+				pkgName: pkgName,
+				properties: properties
+			});
+		} else {
+			if(properties) {
+				st.packages[pkgName].properties = properties;
+			}	
+		}
+		return st.packages[pkgName];
+	};
+
+	/* Add a class to the smalltalk object, creating a new one if needed.
+	   Package is lazily created if it does not exist with given name.*/
+
+	st.addClass = function(className, superclass, iVarNames, pkgName) {
+		var pkg = st.addPackage(pkgName);
+		if(st[className]) {
+			st[className].superclass = superclass;
+			st[className].iVarNames = iVarNames;
+			st[className].pkg = pkg || st[className].pkg;
+		} else {    
+			st[className] = klass({
+				className: className, 
+				superclass: superclass,
+				pkg: pkg,
+				iVarNames: iVarNames
+			});
+		}
+	};
 
-    st.addMethod = function(jsSelector, method, klass) {
-	klass.fn.prototype[jsSelector] = method.fn;
-	klass.fn.prototype.methods[method.selector] = method;
-	method.methodClass = klass;
-	method.jsSelector = jsSelector;
-    };
+	/* Add a method to a class */
 
-    /* Handles Smalltalk message send. Automatically converts undefined to the nil object.
-       If the receiver does not understand the selector, call its #doesNotUnderstand: method */
+	st.addMethod = function(jsSelector, method, klass) {
+		klass.fn.prototype[jsSelector] = method.fn;
+		klass.fn.prototype.methods[method.selector] = method;
+		method.methodClass = klass;
+		method.jsSelector = jsSelector;
+	};
 
-    sendWithoutContext = function(receiver, selector, args, klass) {
-	if(receiver === undefined || receiver === null) {
-	    receiver = nil;
-	}
-	if(!klass && receiver.klass && receiver[selector]) {
-	    return receiver[selector].apply(receiver, args);
-	} else if(klass && klass.fn.prototype[selector]) {
-	    return klass.fn.prototype[selector].apply(receiver, args)
-	}
-	return messageNotUnderstood(receiver, selector, args);
-    };
+	/* Handles Smalltalk message send. Automatically converts undefined to the nil object.
+	   If the receiver does not understand the selector, call its #doesNotUnderstand: method */
 
+	sendWithoutContext = function(receiver, selector, args, klass) {
+		if(receiver === undefined || receiver === null) {
+			receiver = nil;
+		}
+		if(!klass && receiver.klass && receiver[selector]) {
+			return receiver[selector].apply(receiver, args);
+		} else if(klass && klass.fn.prototype[selector]) {
+			return klass.fn.prototype[selector].apply(receiver, args)
+		}
+		return messageNotUnderstood(receiver, selector, args);
+	};
 
-    /* Handles unhandled errors during message sends */
 
-    sendWithContext = function(receiver, selector, args, klass) {
-	if(st.thisContext) {
-	     return withContextSend(receiver, selector, args, klass);
-	} else {
-	    try {return withContextSend(receiver, selector, args, klass)}
-	    catch(error) {
-		// Reset the context stack in any case
-		st.thisContext = undefined;
-		if(error.smalltalkError) {
-		    handleError(error);
+	/* Handles unhandled errors during message sends */
+
+	sendWithContext = function(receiver, selector, args, klass) {
+		if(st.thisContext) {
+			return withContextSend(receiver, selector, args, klass);
 		} else {
-		    throw(error);
+			try {return withContextSend(receiver, selector, args, klass)}
+			catch(error) {
+				// Reset the context stack in any case
+				st.thisContext = undefined;
+				if(error.smalltalkError) {
+					handleError(error);
+				} else {
+					throw(error);
+				}
+			}
 		}
-	    }
-	}
-    };
+	};
 
-    /* Same as sendWithoutContext but creates a methodContext. */
+	/* Same as sendWithoutContext but creates a methodContext. */
 
-    withContextSend = function(receiver, selector, args, klass) {
-	var call, context;
-	if(receiver === undefined || receiver === null) {
-	    receiver = nil;
-	}
-	if(!klass && receiver.klass && receiver[selector]) {
-	    context = pushContext(receiver, selector, args);
-	    call = receiver[selector].apply(receiver, args);
-	    popContext(context);
-	    return call;
-	} else if(klass && klass.fn.prototype[selector]) {
-	    context = pushContext(receiver, selector, args);
-	    call = klass.fn.prototype[selector].apply(receiver, args);
-	    popContext(context);
-	    return call;
+	withContextSend = function(receiver, selector, args, klass) {
+		var call, context;
+		if(receiver === undefined || receiver === null) {
+			receiver = nil;
+		}
+		if(!klass && receiver.klass && receiver[selector]) {
+			context = pushContext(receiver, selector, args);
+			call = receiver[selector].apply(receiver, args);
+			popContext(context);
+			return call;
+		} else if(klass && klass.fn.prototype[selector]) {
+			context = pushContext(receiver, selector, args);
+			call = klass.fn.prototype[selector].apply(receiver, args);
+			popContext(context);
+			return call;
+		}
+		return messageNotUnderstood(receiver, selector, args);
+	};
+
+	/* Handles Smalltalk errors. Triggers the registered ErrorHandler 
+	   (See the Smalltalk class ErrorHandler and its subclasses */
+
+	function handleError(error) {
+		st.thisContext = undefined;
+		smalltalk.ErrorHandler._current()._handleError_(error);
 	}
-	return messageNotUnderstood(receiver, selector, args);
-    };
 
-    /* Handles Smalltalk errors. Triggers the registered ErrorHandler 
-       (See the Smalltalk class ErrorHandler and its subclasses */
-    
-    function handleError(error) {
-	st.thisContext = undefined;
-	smalltalk.ErrorHandler._current()._handleError_(error);
-    }
+	/* Handles #dnu: *and* JavaScript method calls.
+	   if the receiver has no klass, we consider it a JS object (outside of the
+	   Amber system). Else assume that the receiver understands #doesNotUnderstand: */
+
+	function messageNotUnderstood(receiver, selector, args) {
+		/* Handles JS method calls. */
+		if(receiver.klass === undefined || receiver.allowJavaScriptCalls) {
+			return callJavaScriptMethod(receiver, selector, args);
+		}
 
-    /* Handles #dnu: *and* JavaScript method calls.
-       if the receiver has no klass, we consider it a JS object (outside of the
-       Amber system). Else assume that the receiver understands #doesNotUnderstand: */
+		/* Handles not understood messages. Also see the Amber counter-part 
+		   Object>>doesNotUnderstand: */
 
-    function messageNotUnderstood(receiver, selector, args) {
-	/* Handles JS method calls. */
-	if(receiver.klass === undefined || receiver.allowJavaScriptCalls) {
-	    return callJavaScriptMethod(receiver, selector, args);
-	}
+		return receiver._doesNotUnderstand_(
+				st.Message._new()
+				._selector_(st.convertSelector(selector))
+				._arguments_(args)
+				);
+	};
 
-	/* Handles not understood messages. Also see the Amber counter-part 
-	   Object>>doesNotUnderstand: */
-	
-	return receiver._doesNotUnderstand_(
-	    st.Message._new()
-		._selector_(st.convertSelector(selector))
-		._arguments_(args)
-	);
-    };
-
-    function callJavaScriptMethod(receiver, selector, args) {
 	/* Call a method of a JS object, or answer a property if it exists.
 	   Else try wrapping a JSObjectProxy around the receiver.
- 
+
 	   Converts keyword-based selectors by using the first
 	   keyword only, but keeping all message arguments.
 
 	   Example:
 	   "self do: aBlock with: anObject" -> "self.do(aBlock, anObject)" */
 
-	var jsSelector = selector._asJavaScriptSelector();
-	var jsProperty = receiver[jsSelector];
-	if(typeof jsProperty === "function") {
-	    return jsProperty.apply(receiver, args);
-	} else if(jsProperty !== undefined) {
-	    if(args[0]) {
-		receiver[jsSelector] = args[0];
-		return nil;
-	    } else {
-		return jsProperty
-	    }
-	}
-	
-	return st.send(st.JSObjectProxy._on_(receiver), selector, args);
-    };
+	function callJavaScriptMethod(receiver, selector, args) {
+		var jsSelector = selector._asJavaScriptSelector();
+		var jsProperty = receiver[jsSelector];
+		if(typeof jsProperty === "function") {
+			return jsProperty.apply(receiver, args);
+		} else if(jsProperty !== undefined) {
+			if(args[0]) {
+				receiver[jsSelector] = args[0];
+				return nil;
+			} else {
+				return jsProperty
+			}
+		}
 
+		return st.send(st.JSObjectProxy._on_(receiver), selector, args);
+	};
 
-    /* Reuse old contexts stored in oldContexts */
 
-    st.oldContexts = [];
+	/* Reuse old contexts stored in oldContexts */
 
-	
-    /* Handle thisContext pseudo variable */
-    
-    st.getThisContext = function() {
-	if(st.thisContext) {
-	    return st.thisContext.copy();
-	} else {
-	    return undefined;
-	}
-    }
+	st.oldContexts = [];
 
-    pushContext = function(receiver, selector, temps) {
-	if(st.thisContext) {
-	    return st.thisContext = st.thisContext.newContext(receiver, selector, temps);
-	} else {
-	    return st.thisContext = new SmalltalkMethodContext(receiver, selector, temps);
-	}
-    };
 
-    popContext = function(context) {
-	if(context) {
-	    context.removeYourself();
+	/* Handle thisContext pseudo variable */
+
+	st.getThisContext = function() {
+		if(st.thisContext) {
+			return st.thisContext.copy();
+		} else {
+			return undefined;
+		}
 	}
-    };
 
-    /* Convert a string to a valid smalltalk selector.
-       if you modify the following functions, also change String>>asSelector
-       accordingly */
+	pushContext = function(receiver, selector, temps) {
+		if(st.thisContext) {
+			return st.thisContext = st.thisContext.newContext(receiver, selector, temps);
+		} else {
+			return st.thisContext = new SmalltalkMethodContext(receiver, selector, temps);
+		}
+	};
 
-    st.convertSelector = function(selector) {
-	if(selector.match(/__/)) {
-	    return convertBinarySelector(selector);
-	} else {
-	    return convertKeywordSelector(selector);
-	}
-    };
-
-    function convertKeywordSelector(selector) {
-	return selector.replace(/^_/, '').replace(/_/g, ':');
-    };
-
-    function convertBinarySelector(selector) {
-	return selector
-	    .replace(/^_/, '')
-	    .replace(/_plus/, '+')
-	    .replace(/_minus/, '-')
-	    .replace(/_star/, '*')
-	    .replace(/_slash/, '/')
-	    .replace(/_gt/, '>')
-	    .replace(/_lt/, '<')
-	    .replace(/_eq/, '=')
-	    .replace(/_comma/, ',')
-	    .replace(/_at/, '@')
-    };
-
-    /* Converts a JavaScript object to valid Smalltalk Object */
-    st.readJSObject = function(js) {
-	var object = js;
-	var readObject = (js.constructor === Object);
-	var readArray = (js.constructor === Array);
-	
-	if(readObject) {
-	    object = smalltalk.Dictionary._new();
-	}
-	for(var i in js) {
-	    if(readObject) {
-		object._at_put_(i, st.readJSObject(js[i]));
-	    } 
-	    if(readArray) {
-		object[i] = st.readJSObject(js[i]);
-	    }
-	}
-	return object;
-    };
+	popContext = function(context) {
+		if(context) {
+			context.removeYourself();
+		}
+	};
 
-    /* Toggle deployment mode (no context will be handled during message send */
-    st.setDeploymentMode = function() {
-	st.send = sendWithoutContext;
-    };
+	/* Convert a string to a valid smalltalk selector.
+	   if you modify the following functions, also change String>>asSelector
+	   accordingly */
 
-    st.setDevelopmentMode = function() {
-	st.send = sendWithContext;
-    }
+	st.convertSelector = function(selector) {
+		if(selector.match(/__/)) {
+			return convertBinarySelector(selector);
+		} else {
+			return convertKeywordSelector(selector);
+		}
+	};
+
+	function convertKeywordSelector(selector) {
+		return selector.replace(/^_/, '').replace(/_/g, ':');
+	};
+
+	function convertBinarySelector(selector) {
+		return selector
+			.replace(/^_/, '')
+			.replace(/_plus/, '+')
+			.replace(/_minus/, '-')
+			.replace(/_star/, '*')
+			.replace(/_slash/, '/')
+			.replace(/_gt/, '>')
+			.replace(/_lt/, '<')
+			.replace(/_eq/, '=')
+			.replace(/_comma/, ',')
+			.replace(/_at/, '@')
+	};
+
+	/* Converts a JavaScript object to valid Smalltalk Object */
+	st.readJSObject = function(js) {
+		var object = js;
+		var readObject = (js.constructor === Object);
+		var readArray = (js.constructor === Array);
+
+		if(readObject) {
+			object = smalltalk.Dictionary._new();
+		}
+		for(var i in js) {
+			if(readObject) {
+				object._at_put_(i, st.readJSObject(js[i]));
+			} 
+			if(readArray) {
+				object[i] = st.readJSObject(js[i]);
+			}
+		}
+		return object;
+	};
 
-    /* Set development mode by default */
-    st.setDevelopmentMode();
+	/* Toggle deployment mode (no context will be handled during message send */
+	st.setDeploymentMode = function() {
+		st.send = sendWithoutContext;
+	};
+
+	st.setDevelopmentMode = function() {
+		st.send = sendWithContext;
+	}
+
+	/* Set development mode by default */
+	st.setDevelopmentMode();
 }
 
 function SmalltalkMethodContext(receiver, selector, temps, home) {
-    var that = this;
-    that.receiver = receiver;
-    that.selector = selector;
-    that.temps = temps || {};
-    that.homeContext = home;
-
-    that.copy = function() {
-	var home = that.homeContext;
-	if(home) {home = home.copy()}
-	return new SmalltalkMethodContext(
-	    that.receiver, 
-	    that.selector, 
-	    that.temps, 
-	    home
-	);
-    }
-
-    that.newContext = function(receiver, selector, temps) {
-	var c = smalltalk.oldContexts.pop();
-	if(c) {
-	    c.homeContext = that;
-	    c.receiver = receiver;
-	    c.selector = selector;
-	    c.temps = temps || {};
-	} else {
-	    c = new SmalltalkMethodContext(receiver, selector, temps, that);
+	var that = this;
+	that.receiver = receiver;
+	that.selector = selector;
+	that.temps = temps || {};
+	that.homeContext = home;
+
+	that.copy = function() {
+		var home = that.homeContext;
+		if(home) {home = home.copy()}
+		return new SmalltalkMethodContext(
+				that.receiver, 
+				that.selector, 
+				that.temps, 
+				home
+				);
+	}
+
+	that.newContext = function(receiver, selector, temps) {
+		var c = smalltalk.oldContexts.pop();
+		if(c) {
+			c.homeContext = that;
+			c.receiver = receiver;
+			c.selector = selector;
+			c.temps = temps || {};
+		} else {
+			c = new SmalltalkMethodContext(receiver, selector, temps, that);
+		}
+		return c;
+	}
+
+	that.removeYourself = function() {
+		smalltalk.thisContext = that.homeContext;
+		that.homeContext = undefined;
+		smalltalk.oldContexts.push(that);
 	}
-	return c;
-    }
-
-    that.removeYourself = function() {
-	smalltalk.thisContext = that.homeContext;
-	that.homeContext = undefined;
-	smalltalk.oldContexts.push(that);
-    }
 }
 
 /* Global Smalltalk objects. */
@@ -527,7 +527,7 @@ var nil = new SmalltalkNil();
 var smalltalk = new Smalltalk();
 
 if(this.jQuery) {
-    this.jQuery.allowJavaScriptCalls = true;
+	this.jQuery.allowJavaScriptCalls = true;
 }
 
 /****************************************************************************************/

+ 8 - 0
repl/Makefile

@@ -0,0 +1,8 @@
+repl.js: REPL.st
+	../bin/amberc -m Repl -l Compiler,parser REPL.st amber
+
+run: repl.js
+	./amber
+
+clean:
+	rm -f amber.js

+ 125 - 0
repl/REPL.js

@@ -0,0 +1,125 @@
+smalltalk.addPackage('REPL', {});
+smalltalk.addClass('Repl', smalltalk.Object, ['readline', 'interface', 'util'], 'REPL');
+smalltalk.addMethod(
+unescape('_prompt'),
+smalltalk.method({
+selector: unescape('prompt'),
+category: 'accessing',
+fn: function (){
+var self=this;
+return unescape("amber%20%3E%3E%20");
+return self;},
+args: [],
+source: unescape('prompt%0A%09%5E%27amber%20%3E%3E%20%27'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+unescape('_createInterface'),
+smalltalk.method({
+selector: unescape('createInterface'),
+category: 'actions',
+fn: function (){
+var self=this;
+self['@interface']=smalltalk.send(self['@readline'], "_createInterface_stdout_", [smalltalk.send((typeof process == 'undefined' ? nil : process), "_stdin", []), smalltalk.send((typeof process == 'undefined' ? nil : process), "_stdout", [])]);
+smalltalk.send(self['@interface'], "_on_do_", ["line", (function(buffer){return smalltalk.send(self, "_eval_", [buffer]);})]);
+smalltalk.send(self['@interface'], "_on_do_", ["close", (function(){return smalltalk.send(self, "_close", []);})]);
+smalltalk.send(self, "_setPrompt", []);
+smalltalk.send(self['@interface'], "_prompt", []);
+return self;},
+args: [],
+source: unescape('createInterface%0A%09%22No%20completion%20for%20now%22%0A%09interface%20%3A%3D%20readline%20createInterface%3A%20process%20stdin%20stdout%3A%20process%20stdout.%0A%09interface%20on%3A%20%27line%27%20do%3A%20%5B%3Abuffer%20%20%7C%20self%20eval%3A%20buffer%5D.%0A%09interface%20on%3A%20%27close%27%20do%3A%20%5Bself%20close%5D.%0A%09self%20setPrompt.%0A%09interface%20prompt'),
+messageSends: ["createInterface:stdout:", "stdin", "stdout", "on:do:", "eval:", "close", "setPrompt", "prompt"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+unescape('_setPrompt'),
+smalltalk.method({
+selector: unescape('setPrompt'),
+category: 'actions',
+fn: function (){
+var self=this;
+smalltalk.send(self['@interface'], "_setPrompt_", [smalltalk.send(self, "_prompt", [])]);
+return self;},
+args: [],
+source: unescape('setPrompt%0A%09interface%20setPrompt%3A%20self%20prompt'),
+messageSends: ["setPrompt:", "prompt"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+unescape('_close'),
+smalltalk.method({
+selector: unescape('close'),
+category: 'actions',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send((typeof process == 'undefined' ? nil : process), "_stdin", []), "_destroy", []);
+return self;},
+args: [],
+source: unescape('close%0A%09process%20stdin%20destroy'),
+messageSends: ["destroy", "stdin"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+unescape('_eval_'),
+smalltalk.method({
+selector: unescape('eval%3A'),
+category: 'actions',
+fn: function (buffer){
+var self=this;
+var result=nil;
+((($receiver = smalltalk.send(buffer, "_isEmpty", [])).klass === smalltalk.Boolean) ? (! $receiver ? (function(){result=smalltalk.send(smalltalk.send((smalltalk.Compiler || Compiler), "_new", []), "_loadExpression_", [buffer]);return smalltalk.send((smalltalk.Transcript || Transcript), "_show_", [result]);})() : nil) : smalltalk.send($receiver, "_ifFalse_", [(function(){result=smalltalk.send(smalltalk.send((smalltalk.Compiler || Compiler), "_new", []), "_loadExpression_", [buffer]);return smalltalk.send((smalltalk.Transcript || Transcript), "_show_", [result]);})]));
+smalltalk.send(self, "_setPrompt", []);
+smalltalk.send(self['@interface'], "_prompt", []);
+return self;},
+args: ["buffer"],
+source: unescape('eval%3A%20buffer%0A%09%7C%20result%20%7C%0A%09buffer%20isEmpty%20ifFalse%3A%20%5B%0A%09%09result%20%3A%3D%20Compiler%20new%20loadExpression%3A%20buffer.%0A%09%09Transcript%20show%3A%20result%5D.%0A%09self%20setPrompt.%0A%09interface%20prompt'),
+messageSends: ["ifFalse:", "isEmpty", "loadExpression:", "new", "show:", "setPrompt", "prompt"],
+referencedClasses: ["Compiler", "Transcript"]
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+unescape('_initialize'),
+smalltalk.method({
+selector: unescape('initialize'),
+category: 'initialization',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_initialize", [], smalltalk.Object);
+self['@readline']=smalltalk.send((typeof require == 'undefined' ? nil : require), "_value_", ["readline"]);
+self['@util']=smalltalk.send((typeof require == 'undefined' ? nil : require), "_value_", ["util"]);
+return self;},
+args: [],
+source: unescape('initialize%0A%09super%20initialize.%0A%09readline%20%3A%3D%20require%20value%3A%20%27readline%27.%0A%09util%20%3A%3D%20require%20value%3A%20%27util%27'),
+messageSends: ["initialize", "value:"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+
+smalltalk.addMethod(
+unescape('_main'),
+smalltalk.method({
+selector: unescape('main'),
+category: 'not yet classified',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send(self, "_new", []), "_createInterface", []);
+return self;},
+args: [],
+source: unescape('main%0A%09self%20new%20createInterface'),
+messageSends: ["createInterface", "new"],
+referencedClasses: []
+}),
+smalltalk.Repl.klass);
+
+

+ 52 - 0
repl/REPL.st

@@ -0,0 +1,52 @@
+Object subclass: #Repl
+	instanceVariableNames: 'readline interface util'
+	category: 'REPL'!
+
+!Repl methodsFor: 'accessing'!
+
+prompt
+	^'amber >> '
+! !
+
+!Repl methodsFor: 'actions'!
+
+createInterface
+	"No completion for now"
+	interface := readline createInterface: process stdin stdout: process stdout.
+	interface on: 'line' do: [:buffer  | self eval: buffer].
+	interface on: 'close' do: [self close].
+	self setPrompt.
+	interface prompt
+!
+
+setPrompt
+	interface setPrompt: self prompt
+!
+
+close
+	process stdin destroy
+!
+
+eval: buffer
+	| result |
+	buffer isEmpty ifFalse: [
+		result := Compiler new loadExpression: buffer.
+		Transcript show: result].
+	self setPrompt.
+	interface prompt
+! !
+
+!Repl methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	readline := require value: 'readline'.
+	util := require value: 'util'
+! !
+
+!Repl class methodsFor: 'not yet classified'!
+
+main
+	self new createInterface
+! !
+

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


+ 1 - 1
server/Makefile

@@ -5,4 +5,4 @@ run: server.js
 	./server
 
 clean:
-	rm -f FileServer.js server.js
+	rm -f FileServer.js

+ 15 - 2
st/IDE.st

@@ -1,5 +1,4 @@
 Smalltalk current createPackage: 'IDE' properties: #{}!
-
 Widget subclass: #TabManager
 	instanceVariableNames: 'selectedTab tabs opened ul input'
 	category: 'IDE'!
@@ -762,6 +761,17 @@ addNewClass
 			resetClassesList;
 			updateClassesList.
 		self selectClass: (Smalltalk current at: className)]
+!
+
+copyClass
+	| className |
+	className := window prompt: 'Copy class'.
+	(className notNil and: [className notEmpty]) ifTrue: [
+		ClassBuilder new copyClass: self selectedClass named: className.
+          	 self 
+			resetClassesList;
+			updateClassesList.
+		self selectClass: (Smalltalk current at: className)]
 ! !
 
 !Browser methodsFor: 'initialization'!
@@ -948,6 +958,9 @@ updateSourceAndButtons
 		html button
 			with: 'Rename class';
 			onClick: [self renameClass].
+		html button
+			with: 'Copy class';
+			onClick: [self copyClass].
 		html button
 			with: 'Remove class';
 			onClick: [self removeClass].
@@ -1406,7 +1419,7 @@ setEditorOn: aTextarea
 	<self['@editor'] = CodeMirror.fromTextArea(aTextarea, {
 		theme: 'jtalk',
                 lineNumbers: true,
-                enterMode: 'classic',
+                enterMode: 'flat',
                 matchBrackets: true,
                 electricChars: false
 	})>

+ 226 - 15
st/Kernel.st

@@ -277,10 +277,6 @@ classes
 	<return self.classes()>
 !
 
-readJSON: anObject
-	<return self.readJSObject(anObject)>
-!
-
 at: aString
 	<return self[aString]>
 !
@@ -313,6 +309,10 @@ parseError: anException parsing: aString
 reservedWords
 	"JavaScript reserved words"
 	<return self.reservedWords>
+!
+
+readJSObject: anObject
+	<return self.readJSObject(anObject)>
 ! !
 
 !Smalltalk methodsFor: 'classes'!
@@ -419,7 +419,7 @@ String where the method category "*IDE" defines #inspectOn: which thus is a meth
 !Package methodsFor: 'accessing'!
 
 name
-	<return self.pkgName || nil>
+	<return self.pkgName>
 !
 
 name: aString
@@ -435,14 +435,7 @@ dependencies: anArray
 !
 
 properties
-	"It is stored as a javascript object."
-
-	| result |
-	result := Dictionary new.
-	<for (var i in self.properties) {
-		result._at_put_(i, self.properties[i]);
-	}
-	return result;>
+	^Smalltalk current readJSObject: (self basicAt: 'properties')
 !
 
 properties: aDict
@@ -476,7 +469,7 @@ propertiesAsJSON
 !
 
 jsProperties
-	<return self.properties || nil>
+	<return self.properties>
 !
 
 jsProperties: aJSObject
@@ -806,6 +799,11 @@ Object subclass: #Number
 	instanceVariableNames: ''
 	category: 'Kernel'!
 
+!Number methodsFor: ''!
+
+
+! !
+
 !Number methodsFor: 'arithmetic'!
 
 + aNumber
@@ -1047,6 +1045,10 @@ Object subclass: #BlockClosure
 
 compiledSource
 	<return self.toString()>
+!
+
+numArgs
+	<return self.length>
 ! !
 
 !BlockClosure methodsFor: 'controlling'!
@@ -2647,6 +2649,29 @@ setupClass: aClass
 addSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName
 	<smalltalk.addClass(aString, aClass, aCollection, packageName);
 	    return smalltalk[aString]>
+!
+
+copyClass: aClass named: aString
+	| newClass |
+
+	newClass := self 
+		addSubclassOf: aClass superclass
+		named: aString 
+		instanceVariableNames: aClass instanceVariableNames 
+		package: aClass package name.
+
+	self setupClass: newClass.
+
+	aClass methodDictionary values do: [:each |
+		newClass addCompiledMethod: (Compiler new load: each source forClass: newClass).
+		(newClass methodDictionary at: each selector) category: each category].
+
+	aClass class methodDictionary values do: [:each |
+		newClass class addCompiledMethod: (Compiler new load: each source forClass: newClass class).
+		(newClass class methodDictionary at: each selector) category: each category].
+
+	self setupClass: newClass.
+	^newClass
 ! !
 
 Object subclass: #ClassCategoryReader
@@ -3270,7 +3295,9 @@ cr
 !
 
 show: anObject
-	<console.log(String(anObject._asString()))>
+	| string |
+	string := anObject asString.
+	<console.log(String(string))>
 ! !
 
 !ConsoleTranscript class methodsFor: 'initialization'!
@@ -3279,3 +3306,187 @@ initialize
 	Transcript register: self new
 ! !
 
+Dictionary subclass: #Dictionary2
+	instanceVariableNames: 'keys'
+	category: 'Kernel'!
+
+!Dictionary2 methodsFor: 'accessing'!
+
+size
+	^keys size
+!
+
+associations
+	| associations |
+	associations := #().
+	keys do: [:each |
+	    associations add: (Association key: each value: (self at: each))].
+	^associations
+!
+
+keys
+	^keys copy
+!
+
+values
+    	^keys collect: [:each | self at: each]
+!
+
+at: aKey put: aValue
+	(keys includes: aKey) ifFalse: [keys add: aKey].
+	^self basicAt: aKey put: aValue
+!
+
+at: aKey ifAbsent: aBlock
+	^(self keys includes: aKey)
+		ifTrue: [self basicAt: aKey]
+		ifFalse: aBlock
+!
+
+at: aKey ifAbsentPut: aBlock
+    	^self at: aKey ifAbsent: [
+    	    self at: aKey put: aBlock value]
+!
+
+at: aKey ifPresent: aBlock
+	^(self basicAt: aKey) ifNotNil: [aBlock value: (self at: aKey)]
+!
+
+at: aKey ifPresent: aBlock ifAbsent: anotherBlock
+	^(self basicAt: aKey)
+	    ifNil: anotherBlock
+	    ifNotNil: [aBlock value: (self at: aKey)]
+!
+
+at: aKey
+	^self at: aKey ifAbsent: [self errorNotFound]
+! !
+
+!Dictionary2 methodsFor: 'adding/removing'!
+
+add: anAssociation
+    	self at: anAssociation key put: anAssociation value
+!
+
+addAll: aDictionary
+    	super addAll: aDictionary associations.
+    	^aDictionary
+!
+
+remove: aKey
+    self removeKey: aKey
+!
+
+removeKey: aKey
+    keys remove: aKey
+! !
+
+!Dictionary2 methodsFor: 'comparing'!
+
+= aDictionary
+	self class = aDictionary class ifFalse: [^false].
+	self size = aDictionary size ifFalse: [^false].
+	^self associations = aDictionary associations
+! !
+
+!Dictionary2 methodsFor: 'converting'!
+
+asJSONObject
+	| object |
+	object := Object new.
+	self keysAndValuesDo: [:key :value |
+		object basicAt: key put: value asJSONObject].
+	^object
+! !
+
+!Dictionary2 methodsFor: 'copying'!
+
+shallowCopy
+	| copy |
+	copy := self class new.
+	self associationsDo: [:each |
+	    copy at: each key  put: each value].
+	^copy
+!
+
+, aCollection
+	self shouldNotImplement
+!
+
+copyFrom: anIndex to: anotherIndex
+	self shouldNotImplement
+! !
+
+!Dictionary2 methodsFor: 'enumerating'!
+
+associationsDo: aBlock
+    	self associations do: aBlock
+!
+
+keysAndValuesDo: aBlock
+    	self associationsDo: [:each |
+    	    aBlock value: each key value: each value]
+!
+
+do: aBlock
+    	self values do: aBlock
+!
+
+select: aBlock
+    	| newDict |
+    	newDict := self class new.
+    	self keysAndValuesDo: [:key :value |
+    	    (aBlock value: value) ifTrue: [newDict at: key put: value]].
+    	^newDict
+!
+
+collect: aBlock
+    	| newDict |
+    	newDict := self class new.
+    	self keysAndValuesDo: [:key :value |
+    	    newDict at: key put: (aBlock value: value)].
+    	^newDict
+!
+
+detect: aBlock ifNone: anotherBlock
+	^self values detect: aBlock ifNone: anotherBlock
+!
+
+includes: anObject
+	^self values includes: anObject
+! !
+
+!Dictionary2 methodsFor: 'initialization'!
+
+initialize
+    	super initialize.
+    	keys := #()
+! !
+
+!Dictionary2 methodsFor: 'printing'!
+
+printString
+	^ String streamContents: [:aStream|  
+                                  		aStream 
+                                  			nextPutAll: super printString;
+                                  			nextPutAll: '('.
+                                  		self associations 
+                                  			do: [:anAssociation|  
+                                                                      	aStream 
+                                                                      		nextPutAll: anAssociation key printString;
+                                                                      		nextPutAll: ' -> ';
+                                                                      		nextPutAll: anAssociation value printString]
+                                  
+                                 			separatedBy: [aStream nextPutAll: ' , '].
+                                  		aStream nextPutAll: ')'.
+                                 ]
+!
+
+storeOn: aStream
+	aStream nextPutAll: '#{'.
+	self associations
+		do: [:each | each storeOn: aStream]
+		separatedBy: [ aStream nextPutAll: '. '].
+	aStream nextPutAll: '}'
+! !
+

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