瀏覽代碼

Get ready for moving local vars into the context

Nicolas Petton 11 年之前
父節點
當前提交
53f25163c1

+ 19 - 9
js/Compiler-Semantic.deploy.js

@@ -872,15 +872,13 @@ smalltalk.method({
 selector: "errorUnknownVariable:",
 fn: function (aNode){
 var self=this;
-return smalltalk.withContext(function($ctx) { var $1,$2;
-var notDefined;
-notDefined=eval('typeof ' + aNode._value() + ' == "undefined"');
-;
-if(smalltalk.assert(notDefined)){
-$1=_st((smalltalk.UnknownVariableError || UnknownVariableError))._new();
-_st($1)._variableName_(_st(aNode)._value());
-$2=_st($1)._signal();
-$2;
+return smalltalk.withContext(function($ctx) { var $1,$2,$3;
+$1=_st(self)._isVariableGloballyUndefined_(_st(aNode)._value());
+if(smalltalk.assert($1)){
+$2=_st((smalltalk.UnknownVariableError || UnknownVariableError))._new();
+_st($2)._variableName_(_st(aNode)._value());
+$3=_st($2)._signal();
+$3;
 } else {
 _st(_st(_st(self["@currentScope"])._methodScope())._unknownVariables())._add_(_st(aNode)._value());
 };
@@ -888,6 +886,18 @@ return self}, self, "errorUnknownVariable:", [aNode], smalltalk.SemanticAnalyzer
 }),
 smalltalk.SemanticAnalyzer);
 
+smalltalk.addMethod(
+"_isVariableGloballyUndefined_",
+smalltalk.method({
+selector: "isVariableGloballyUndefined:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx) { return eval('typeof ' + aString + ' == "undefined"');
+;
+return self}, self, "isVariableGloballyUndefined:", [aString], smalltalk.SemanticAnalyzer)}
+}),
+smalltalk.SemanticAnalyzer);
+
 smalltalk.addMethod(
 "_messageSends",
 smalltalk.method({

+ 26 - 11
js/Compiler-Semantic.js

@@ -1194,26 +1194,41 @@ selector: "errorUnknownVariable:",
 category: 'error handling',
 fn: function (aNode){
 var self=this;
-return smalltalk.withContext(function($ctx) { var $1,$2;
-var notDefined;
-notDefined=eval('typeof ' + aNode._value() + ' == "undefined"');
-;
-if(smalltalk.assert(notDefined)){
-$1=_st((smalltalk.UnknownVariableError || UnknownVariableError))._new();
-_st($1)._variableName_(_st(aNode)._value());
-$2=_st($1)._signal();
-$2;
+return smalltalk.withContext(function($ctx) { var $1,$2,$3;
+$1=_st(self)._isVariableGloballyUndefined_(_st(aNode)._value());
+if(smalltalk.assert($1)){
+$2=_st((smalltalk.UnknownVariableError || UnknownVariableError))._new();
+_st($2)._variableName_(_st(aNode)._value());
+$3=_st($2)._signal();
+$3;
 } else {
 _st(_st(_st(self["@currentScope"])._methodScope())._unknownVariables())._add_(_st(aNode)._value());
 };
 return self}, self, "errorUnknownVariable:", [aNode], smalltalk.SemanticAnalyzer)},
 args: ["aNode"],
-source: "errorUnknownVariable: aNode\x0a\x09\x22Throw an error if the variable is undeclared in the global JS scope (i.e. window)\x22\x0a\x0a\x09| notDefined |\x0a\x0a\x09notDefined := <eval('typeof ' + aNode._value() + ' == \x22undefined\x22')>.\x0a\x0a\x09notDefined\x0a\x09\x09ifTrue: [ \x0a\x09\x09\x09UnknownVariableError new\x0a\x09\x09\x09\x09variableName: aNode value;\x0a\x09\x09\x09\x09signal ]\x0a\x09\x09ifFalse: [\x0a\x09\x09\x09currentScope methodScope unknownVariables add: aNode value. ]",
-messageSends: ["ifTrue:ifFalse:", "variableName:", "value", "new", "signal", "add:", "unknownVariables", "methodScope"],
+source: "errorUnknownVariable: aNode\x0a\x09\x22Throw an error if the variable is undeclared in the global JS scope (i.e. window)\x22\x0a\x0a\x09(self isVariableGloballyUndefined: aNode value)\x0a\x09\x09ifTrue: [ \x0a\x09\x09\x09UnknownVariableError new\x0a\x09\x09\x09\x09variableName: aNode value;\x0a\x09\x09\x09\x09signal ]\x0a\x09\x09ifFalse: [\x0a\x09\x09\x09currentScope methodScope unknownVariables add: aNode value. ]",
+messageSends: ["ifTrue:ifFalse:", "variableName:", "value", "new", "signal", "add:", "unknownVariables", "methodScope", "isVariableGloballyUndefined:"],
 referencedClasses: ["UnknownVariableError"]
 }),
 smalltalk.SemanticAnalyzer);
 
+smalltalk.addMethod(
+"_isVariableGloballyUndefined_",
+smalltalk.method({
+selector: "isVariableGloballyUndefined:",
+category: 'testing',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx) { return eval('typeof ' + aString + ' == "undefined"');
+;
+return self}, self, "isVariableGloballyUndefined:", [aString], smalltalk.SemanticAnalyzer)},
+args: ["aString"],
+source: "isVariableGloballyUndefined: aString\x0a\x09<return eval('typeof ' + aString + ' == \x22undefined\x22')>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SemanticAnalyzer);
+
 smalltalk.addMethod(
 "_messageSends",
 smalltalk.method({

+ 108 - 49
js/Kernel-Objects.deploy.js

@@ -332,9 +332,7 @@ smalltalk.method({
 selector: "instVarAt:",
 fn: function (aSymbol){
 var self=this;
-return smalltalk.withContext(function($ctx) { var varname;
-varname=_st(aSymbol)._asString();
-return self['@'+varname];
+return smalltalk.withContext(function($ctx) { return self['@'+aSymbol._asString()];
 ;
 return self}, self, "instVarAt:", [aSymbol], smalltalk.Object)}
 }),
@@ -346,9 +344,7 @@ smalltalk.method({
 selector: "instVarAt:put:",
 fn: function (aSymbol,anObject){
 var self=this;
-return smalltalk.withContext(function($ctx) { var varname;
-varname=_st(aSymbol)._asString();
-self['@' + varname] = anObject;
+return smalltalk.withContext(function($ctx) { self['@' + aSymbol._asString()] = anObject;
 ;
 return self}, self, "instVarAt:put:", [aSymbol,anObject], smalltalk.Object)}
 }),
@@ -510,9 +506,7 @@ smalltalk.method({
 selector: "perform:withArguments:",
 fn: function (aSymbol,aCollection){
 var self=this;
-return smalltalk.withContext(function($ctx) { var selector;
-selector=_st(aSymbol)._asSelector();
-return smalltalk.send(self, selector, aCollection);
+return smalltalk.withContext(function($ctx) { return smalltalk.send(self, aSymbol._asSelector(), aCollection);
 ;
 return self}, self, "perform:withArguments:", [aSymbol,aCollection], smalltalk.Object)}
 }),
@@ -1054,6 +1048,19 @@ return $1;
 }),
 smalltalk.CompiledMethod);
 
+smalltalk.addMethod(
+"_printString",
+smalltalk.method({
+selector: "printString",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx) { var $1;
+$1=_st(_st(_st(_st(self)._methodClass())._name()).__comma(" >> ")).__comma(_st(self)._selector());
+return $1;
+}, self, "printString", [], smalltalk.CompiledMethod)}
+}),
+smalltalk.CompiledMethod);
+
 smalltalk.addMethod(
 "_protocol",
 smalltalk.method({
@@ -1637,9 +1644,7 @@ smalltalk.method({
 selector: "at:",
 fn: function (aSymbol){
 var self=this;
-return smalltalk.withContext(function($ctx) { var attr;
-attr=_st(aSymbol)._asString();
-return self['@jsObject'][attr];
+return smalltalk.withContext(function($ctx) { return self['@jsObject'][aSymbol._asString()];
 ;
 return self}, self, "at:", [aSymbol], smalltalk.JSObjectProxy)}
 }),
@@ -1651,21 +1656,32 @@ smalltalk.method({
 selector: "at:put:",
 fn: function (aSymbol,anObject){
 var self=this;
-return smalltalk.withContext(function($ctx) { var attr;
-attr=_st(aSymbol)._asString();
-self['@jsObject'][attr] = anObject;
+return smalltalk.withContext(function($ctx) { self['@jsObject'][aSymbol._asString()] = anObject;
 ;
 return self}, self, "at:put:", [aSymbol,anObject], smalltalk.JSObjectProxy)}
 }),
 smalltalk.JSObjectProxy);
 
+smalltalk.addMethod(
+"_canUnderstand_",
+smalltalk.method({
+selector: "canUnderstand:",
+fn: function (aSelector){
+var self=this;
+return smalltalk.withContext(function($ctx) { return self._jsObject()[aSelector._asJavaScriptSelector()] != undefined;
+;
+return self}, self, "canUnderstand:", [aSelector], smalltalk.JSObjectProxy)}
+}),
+smalltalk.JSObjectProxy);
+
 smalltalk.addMethod(
 "_doesNotUnderstand_",
 smalltalk.method({
 selector: "doesNotUnderstand:",
 fn: function (aMessage){
 var self=this;
-return smalltalk.withContext(function($ctx) { var obj;
+return smalltalk.withContext(function($ctx) { var $1,$2;
+var obj;
 var selector;
 var jsSelector;
 var arguments;
@@ -1673,8 +1689,11 @@ obj=_st(self)._jsObject();
 selector=_st(aMessage)._selector();
 jsSelector=_st(selector)._asJavaScriptSelector();
 arguments=_st(aMessage)._arguments();
-if(obj[jsSelector] != undefined) {return smalltalk.send(obj, jsSelector, arguments)};
-;
+$1=_st(self)._canUnderstand_(selector);
+if(smalltalk.assert($1)){
+$2=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._basicSend_to_arguments_(jsSelector,obj,arguments);
+return $2;
+};
 smalltalk.Object.fn.prototype._doesNotUnderstand_.apply(_st(self), [aMessage]);
 return self}, self, "doesNotUnderstand:", [aMessage], smalltalk.JSObjectProxy)}
 }),
@@ -1687,18 +1706,32 @@ selector: "inspectOn:",
 fn: function (anInspector){
 var self=this;
 return smalltalk.withContext(function($ctx) { var variables;
-variables=_st((smalltalk.Dictionary || Dictionary))._new();
+variables=_st(self)._inspectorVariables();
 _st(variables)._at_put_("#self",_st(self)._jsObject());
 _st(anInspector)._setLabel_(_st(self)._printString());
-for(var i in self['@jsObject']) {
-		variables._at_put_(i, self['@jsObject'][i]);
-	};
-;
 _st(anInspector)._setVariables_(variables);
 return self}, self, "inspectOn:", [anInspector], smalltalk.JSObjectProxy)}
 }),
 smalltalk.JSObjectProxy);
 
+smalltalk.addMethod(
+"_inspectorVariables",
+smalltalk.method({
+selector: "inspectorVariables",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx) { 
+    	var variables = smalltalk.Dictionary._new();
+        for(var i in self['@jsObject']) {
+			variables._at_put_(i, self['@jsObject'][i]);
+		};
+        return variables
+    ;
+;
+return self}, self, "inspectorVariables", [], smalltalk.JSObjectProxy)}
+}),
+smalltalk.JSObjectProxy);
+
 smalltalk.addMethod(
 "_jsObject",
 smalltalk.method({
@@ -2378,18 +2411,15 @@ smalltalk.method({
 selector: "truncated",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx) { var $1;
-var result;
-$1=_st(self).__gt_eq((0));
-if(smalltalk.assert($1)){
-result = Math.floor(self);;
-;
-} else {
-result = (Math.floor(self * (-1)) * (-1));;
+return smalltalk.withContext(function($ctx) { 
+    	if(self >= 0) {
+        	return Math.floor(self);
+        } else {
+        	return Math.floor(self * (-1)) * (-1);
+        }
+    ;
 ;
-};
-return result;
-}, self, "truncated", [], smalltalk.Number)}
+return self}, self, "truncated", [], smalltalk.Number)}
 }),
 smalltalk.Number);
 
@@ -2650,8 +2680,7 @@ smalltalk.method({
 selector: "properties:",
 fn: function (aDict){
 var self=this;
-return smalltalk.withContext(function($ctx) { var object;
-object = {};;
+return smalltalk.withContext(function($ctx) { var object = {};;
 ;
 _st(aDict)._keysAndValuesDo_((function(key,value){
 return object[key] = value;
@@ -3159,6 +3188,18 @@ return self}, self, "basicParse:", [aString], smalltalk.Smalltalk)}
 }),
 smalltalk.Smalltalk);
 
+smalltalk.addMethod(
+"_basicSend_to_arguments_",
+smalltalk.method({
+selector: "basicSend:to:arguments:",
+fn: function (aSelector,anObject,aCollection){
+var self=this;
+return smalltalk.withContext(function($ctx) { return self.send(anObject, aSelector, aCollection);
+;
+return self}, self, "basicSend:to:arguments:", [aSelector,anObject,aCollection], smalltalk.Smalltalk)}
+}),
+smalltalk.Smalltalk);
+
 smalltalk.addMethod(
 "_classes",
 smalltalk.method({
@@ -3189,8 +3230,7 @@ smalltalk.method({
 selector: "createPackage:properties:",
 fn: function (packageName,aDict){
 var self=this;
-return smalltalk.withContext(function($ctx) { var object;
-object = {};;
+return smalltalk.withContext(function($ctx) { var object = {};;
 ;
 _st(aDict)._keysAndValuesDo_((function(key,value){
 return object[key] = value;
@@ -3252,6 +3292,18 @@ return $1;
 }),
 smalltalk.Smalltalk);
 
+smalltalk.addMethod(
+"_packageAt_put_",
+smalltalk.method({
+selector: "packageAt:put:",
+fn: function (packageName,aPackage){
+var self=this;
+return smalltalk.withContext(function($ctx) { return self.packages[packageName] = aPackage;
+;
+return self}, self, "packageAt:put:", [packageName,aPackage], smalltalk.Smalltalk)}
+}),
+smalltalk.Smalltalk);
+
 smalltalk.addMethod(
 "_packages",
 smalltalk.method({
@@ -3295,10 +3347,9 @@ var message;
 var lines;
 var badLine;
 var code;
-row = anException.line;
-	col = anException.column;
-	message = anException.message;;
-;
+row=_st(anException)._basicAt_("line");
+col=_st(anException)._basicAt_("column");
+message=_st(anException)._basicAt_("message");
 lines=_st(aString)._lines();
 badLine=_st(lines)._at_(row);
 badLine=_st(_st(_st(badLine)._copyFrom_to_((1),_st(col).__minus((1)))).__comma(" ===>")).__comma(_st(badLine)._copyFrom_to_(col,_st(badLine)._size()));
@@ -3398,8 +3449,7 @@ $1;
 } else {
 _st(self)._error_(_st("Already exists a package called: ").__comma(newName));
 };
-smalltalk.packages[newName] = smalltalk.packages[packageName];
-;
+_st(self)._packageAt_put_(newName,pkg);
 _st(pkg)._name_(newName);
 _st(self)._deletePackage_(packageName);
 return self}, self, "renamePackage:to:", [packageName,newName], smalltalk.Smalltalk)}
@@ -3424,11 +3474,10 @@ smalltalk.method({
 selector: "send:to:arguments:",
 fn: function (aSelector,anObject,aCollection){
 var self=this;
-return smalltalk.withContext(function($ctx) { var selector;
-selector=_st(_st(aSelector)._asString())._asSelector();
-return self.send(anObject, selector, aCollection);
-;
-return self}, self, "send:to:arguments:", [aSelector,anObject,aCollection], smalltalk.Smalltalk)}
+return smalltalk.withContext(function($ctx) { var $1;
+$1=_st(self)._basicSend_to_arguments_(_st(_st(aSelector)._asString())._asSelector(),anObject,aCollection);
+return $1;
+}, self, "send:to:arguments:", [aSelector,anObject,aCollection], smalltalk.Smalltalk)}
 }),
 smalltalk.Smalltalk);
 
@@ -3448,6 +3497,16 @@ smalltalk.Smalltalk.klass);
 
 
 smalltalk.addClass('UndefinedObject', smalltalk.Object, [], 'Kernel-Objects');
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+fn: function (aVisitor){
+var self=this;
+return smalltalk.withContext(function($ctx) { return self}, self, "accept:", [aVisitor], smalltalk.UndefinedObject)}
+}),
+smalltalk.UndefinedObject);
+
 smalltalk.addMethod(
 "_asJSON",
 smalltalk.method({

+ 164 - 75
js/Kernel-Objects.js

@@ -459,14 +459,12 @@ selector: "instVarAt:",
 category: 'accessing',
 fn: function (aSymbol){
 var self=this;
-return smalltalk.withContext(function($ctx) { var varname;
-varname=_st(aSymbol)._asString();
-return self['@'+varname];
+return smalltalk.withContext(function($ctx) { return self['@'+aSymbol._asString()];
 ;
 return self}, self, "instVarAt:", [aSymbol], smalltalk.Object)},
 args: ["aSymbol"],
-source: "instVarAt: aSymbol\x0a\x09| varname |\x0a\x09varname := aSymbol asString.\x0a\x09<return self['@'+varname]>",
-messageSends: ["asString"],
+source: "instVarAt: aSymbol\x0a\x09<return self['@'+aSymbol._asString()]>",
+messageSends: [],
 referencedClasses: []
 }),
 smalltalk.Object);
@@ -478,14 +476,12 @@ selector: "instVarAt:put:",
 category: 'accessing',
 fn: function (aSymbol,anObject){
 var self=this;
-return smalltalk.withContext(function($ctx) { var varname;
-varname=_st(aSymbol)._asString();
-self['@' + varname] = anObject;
+return smalltalk.withContext(function($ctx) { self['@' + aSymbol._asString()] = anObject;
 ;
 return self}, self, "instVarAt:put:", [aSymbol,anObject], smalltalk.Object)},
 args: ["aSymbol", "anObject"],
-source: "instVarAt: aSymbol put: anObject\x0a\x09| varname |\x0a\x09varname := aSymbol asString.\x0a\x09<self['@' + varname] = anObject>",
-messageSends: ["asString"],
+source: "instVarAt: aSymbol put: anObject\x0a\x09<self['@' + aSymbol._asString()] = anObject>",
+messageSends: [],
 referencedClasses: []
 }),
 smalltalk.Object);
@@ -707,14 +703,12 @@ selector: "perform:withArguments:",
 category: 'message handling',
 fn: function (aSymbol,aCollection){
 var self=this;
-return smalltalk.withContext(function($ctx) { var selector;
-selector=_st(aSymbol)._asSelector();
-return smalltalk.send(self, selector, aCollection);
+return smalltalk.withContext(function($ctx) { return smalltalk.send(self, aSymbol._asSelector(), aCollection);
 ;
 return self}, self, "perform:withArguments:", [aSymbol,aCollection], smalltalk.Object)},
 args: ["aSymbol", "aCollection"],
-source: "perform: aSymbol withArguments: aCollection\x0a\x09| selector |\x0a\x09selector := aSymbol asSelector.\x0a\x09<return smalltalk.send(self, selector, aCollection)>",
-messageSends: ["asSelector"],
+source: "perform: aSymbol withArguments: aCollection\x0a\x09<return smalltalk.send(self, aSymbol._asSelector(), aCollection)>",
+messageSends: [],
 referencedClasses: []
 }),
 smalltalk.Object);
@@ -1452,6 +1446,24 @@ referencedClasses: []
 }),
 smalltalk.CompiledMethod);
 
+smalltalk.addMethod(
+"_printString",
+smalltalk.method({
+selector: "printString",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx) { var $1;
+$1=_st(_st(_st(_st(self)._methodClass())._name()).__comma(" >> ")).__comma(_st(self)._selector());
+return $1;
+}, self, "printString", [], smalltalk.CompiledMethod)},
+args: [],
+source: "printString\x0a\x09^ self methodClass name, ' >> ', self selector",
+messageSends: [",", "selector", "name", "methodClass"],
+referencedClasses: []
+}),
+smalltalk.CompiledMethod);
+
 smalltalk.addMethod(
 "_protocol",
 smalltalk.method({
@@ -2268,14 +2280,12 @@ selector: "at:",
 category: 'accessing',
 fn: function (aSymbol){
 var self=this;
-return smalltalk.withContext(function($ctx) { var attr;
-attr=_st(aSymbol)._asString();
-return self['@jsObject'][attr];
+return smalltalk.withContext(function($ctx) { return self['@jsObject'][aSymbol._asString()];
 ;
 return self}, self, "at:", [aSymbol], smalltalk.JSObjectProxy)},
 args: ["aSymbol"],
-source: "at: aSymbol\x0a\x09| attr |\x0a\x09attr := aSymbol asString.\x0a\x09<return self['@jsObject'][attr]>",
-messageSends: ["asString"],
+source: "at: aSymbol\x0a\x09<return self['@jsObject'][aSymbol._asString()]>",
+messageSends: [],
 referencedClasses: []
 }),
 smalltalk.JSObjectProxy);
@@ -2287,14 +2297,29 @@ selector: "at:put:",
 category: 'accessing',
 fn: function (aSymbol,anObject){
 var self=this;
-return smalltalk.withContext(function($ctx) { var attr;
-attr=_st(aSymbol)._asString();
-self['@jsObject'][attr] = anObject;
+return smalltalk.withContext(function($ctx) { self['@jsObject'][aSymbol._asString()] = anObject;
 ;
 return self}, self, "at:put:", [aSymbol,anObject], smalltalk.JSObjectProxy)},
 args: ["aSymbol", "anObject"],
-source: "at: aSymbol put: anObject\x0a\x09| attr |\x0a\x09attr := aSymbol asString.\x0a\x09<self['@jsObject'][attr] = anObject>",
-messageSends: ["asString"],
+source: "at: aSymbol put: anObject\x0a\x09<self['@jsObject'][aSymbol._asString()] = anObject>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.JSObjectProxy);
+
+smalltalk.addMethod(
+"_canUnderstand_",
+smalltalk.method({
+selector: "canUnderstand:",
+category: 'proxy',
+fn: function (aSelector){
+var self=this;
+return smalltalk.withContext(function($ctx) { return self._jsObject()[aSelector._asJavaScriptSelector()] != undefined;
+;
+return self}, self, "canUnderstand:", [aSelector], smalltalk.JSObjectProxy)},
+args: ["aSelector"],
+source: "canUnderstand: aSelector\x0a\x09<return self._jsObject()[aSelector._asJavaScriptSelector()] != undefined>",
+messageSends: [],
 referencedClasses: []
 }),
 smalltalk.JSObjectProxy);
@@ -2306,7 +2331,8 @@ selector: "doesNotUnderstand:",
 category: 'proxy',
 fn: function (aMessage){
 var self=this;
-return smalltalk.withContext(function($ctx) { var obj;
+return smalltalk.withContext(function($ctx) { var $1,$2;
+var obj;
 var selector;
 var jsSelector;
 var arguments;
@@ -2314,14 +2340,17 @@ obj=_st(self)._jsObject();
 selector=_st(aMessage)._selector();
 jsSelector=_st(selector)._asJavaScriptSelector();
 arguments=_st(aMessage)._arguments();
-if(obj[jsSelector] != undefined) {return smalltalk.send(obj, jsSelector, arguments)};
-;
+$1=_st(self)._canUnderstand_(selector);
+if(smalltalk.assert($1)){
+$2=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._basicSend_to_arguments_(jsSelector,obj,arguments);
+return $2;
+};
 smalltalk.Object.fn.prototype._doesNotUnderstand_.apply(_st(self), [aMessage]);
 return self}, self, "doesNotUnderstand:", [aMessage], smalltalk.JSObjectProxy)},
 args: ["aMessage"],
-source: "doesNotUnderstand: aMessage\x0a\x09| obj selector jsSelector arguments |\x0a\x09obj := self jsObject.\x0a\x09selector := aMessage selector.\x0a\x09jsSelector := selector asJavaScriptSelector.\x0a\x09arguments := aMessage arguments.\x0a\x09<if(obj[jsSelector] != undefined) {return smalltalk.send(obj, jsSelector, arguments)}>.\x0a\x09super doesNotUnderstand: aMessage",
-messageSends: ["jsObject", "selector", "asJavaScriptSelector", "arguments", "doesNotUnderstand:"],
-referencedClasses: []
+source: "doesNotUnderstand: aMessage\x0a\x09| obj selector jsSelector arguments |\x0a\x09obj := self jsObject.\x0a\x09selector := aMessage selector.\x0a\x09jsSelector := selector asJavaScriptSelector.\x0a\x09arguments := aMessage arguments.\x0a    (self canUnderstand: selector) ifTrue: [\x0a      \x09^ Smalltalk current basicSend: jsSelector to: obj arguments: arguments ].\x0a\x09super doesNotUnderstand: aMessage",
+messageSends: ["jsObject", "selector", "asJavaScriptSelector", "arguments", "ifTrue:", "basicSend:to:arguments:", "current", "canUnderstand:", "doesNotUnderstand:"],
+referencedClasses: ["Smalltalk"]
 }),
 smalltalk.JSObjectProxy);
 
@@ -2333,19 +2362,38 @@ category: 'proxy',
 fn: function (anInspector){
 var self=this;
 return smalltalk.withContext(function($ctx) { var variables;
-variables=_st((smalltalk.Dictionary || Dictionary))._new();
+variables=_st(self)._inspectorVariables();
 _st(variables)._at_put_("#self",_st(self)._jsObject());
 _st(anInspector)._setLabel_(_st(self)._printString());
-for(var i in self['@jsObject']) {
-		variables._at_put_(i, self['@jsObject'][i]);
-	};
-;
 _st(anInspector)._setVariables_(variables);
 return self}, self, "inspectOn:", [anInspector], smalltalk.JSObjectProxy)},
 args: ["anInspector"],
-source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Dictionary new.\x0a\x09variables at: '#self' put: self jsObject.\x0a\x09anInspector setLabel: self printString.\x0a\x09<for(var i in self['@jsObject']) {\x0a\x09\x09variables._at_put_(i, self['@jsObject'][i]);\x0a\x09}>.\x0a\x09anInspector setVariables: variables",
-messageSends: ["new", "at:put:", "jsObject", "setLabel:", "printString", "setVariables:"],
-referencedClasses: ["Dictionary"]
+source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := self inspectorVariables.\x0a\x09variables at: '#self' put: self jsObject.\x0a\x09anInspector setLabel: self printString.\x0a\x09anInspector setVariables: variables",
+messageSends: ["inspectorVariables", "at:put:", "jsObject", "setLabel:", "printString", "setVariables:"],
+referencedClasses: []
+}),
+smalltalk.JSObjectProxy);
+
+smalltalk.addMethod(
+"_inspectorVariables",
+smalltalk.method({
+selector: "inspectorVariables",
+category: 'proxy',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx) { 
+    	var variables = smalltalk.Dictionary._new();
+        for(var i in self['@jsObject']) {
+			variables._at_put_(i, self['@jsObject'][i]);
+		};
+        return variables
+    ;
+;
+return self}, self, "inspectorVariables", [], smalltalk.JSObjectProxy)},
+args: [],
+source: "inspectorVariables\x0a\x09<\x0a    \x09var variables = smalltalk.Dictionary._new();\x0a        for(var i in self['@jsObject']) {\x0a\x09\x09\x09variables._at_put_(i, self['@jsObject'][i]);\x0a\x09\x09};\x0a        return variables\x0a    >",
+messageSends: [],
+referencedClasses: []
 }),
 smalltalk.JSObjectProxy);
 
@@ -3265,21 +3313,18 @@ selector: "truncated",
 category: 'converting',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx) { var $1;
-var result;
-$1=_st(self).__gt_eq((0));
-if(smalltalk.assert($1)){
-result = Math.floor(self);;
-;
-} else {
-result = (Math.floor(self * (-1)) * (-1));;
+return smalltalk.withContext(function($ctx) { 
+    	if(self >= 0) {
+        	return Math.floor(self);
+        } else {
+        	return Math.floor(self * (-1)) * (-1);
+        }
+    ;
 ;
-};
-return result;
-}, self, "truncated", [], smalltalk.Number)},
+return self}, self, "truncated", [], smalltalk.Number)},
 args: [],
-source: "truncated\x0a|result|\x0a\x0a    self >= 0 \x0a        ifTrue: [<result = Math.floor(self);>]\x0a        ifFalse: [<result = (Math.floor(self * (-1)) * (-1));>].\x0a\x0a    ^ result",
-messageSends: ["ifTrue:ifFalse:", ">="],
+source: "truncated\x0a\x09<\x0a    \x09if(self >>= 0) {\x0a        \x09return Math.floor(self);\x0a        } else {\x0a        \x09return Math.floor(self * (-1)) * (-1);\x0a        }\x0a    >",
+messageSends: [],
 referencedClasses: []
 }),
 smalltalk.Number);
@@ -3638,8 +3683,7 @@ selector: "properties:",
 category: 'accessing',
 fn: function (aDict){
 var self=this;
-return smalltalk.withContext(function($ctx) { var object;
-object = {};;
+return smalltalk.withContext(function($ctx) { var object = {};;
 ;
 _st(aDict)._keysAndValuesDo_((function(key,value){
 return object[key] = value;
@@ -3649,7 +3693,7 @@ return self.properties = object;
 ;
 return self}, self, "properties:", [aDict], smalltalk.Package)},
 args: ["aDict"],
-source: "properties: aDict\x0a\x09\x22We store it as a javascript object.\x22\x0a\x09\x0a\x09| object |\x0a\x09<object = {};>.\x0a\x09aDict keysAndValuesDo: [:key :value |\x0a\x09\x09<object[key] = value>.\x0a\x09].\x0a\x09<return self.properties = object>",
+source: "properties: aDict\x0a\x09\x22We store it as a javascript object.\x22\x0a\x09\x0a\x09<var object = {};>.\x0a\x09aDict keysAndValuesDo: [:key :value |\x0a\x09\x09<object[key] = value>.\x0a\x09].\x0a\x09<return self.properties = object>",
 messageSends: ["keysAndValuesDo:"],
 referencedClasses: []
 }),
@@ -4324,6 +4368,23 @@ referencedClasses: []
 }),
 smalltalk.Smalltalk);
 
+smalltalk.addMethod(
+"_basicSend_to_arguments_",
+smalltalk.method({
+selector: "basicSend:to:arguments:",
+category: 'accessing',
+fn: function (aSelector,anObject,aCollection){
+var self=this;
+return smalltalk.withContext(function($ctx) { return self.send(anObject, aSelector, aCollection);
+;
+return self}, self, "basicSend:to:arguments:", [aSelector,anObject,aCollection], smalltalk.Smalltalk)},
+args: ["aSelector", "anObject", "aCollection"],
+source: "basicSend: aSelector to: anObject arguments: aCollection\x0a\x09<return self.send(anObject, aSelector, aCollection)>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Smalltalk);
+
 smalltalk.addMethod(
 "_classes",
 smalltalk.method({
@@ -4365,8 +4426,7 @@ selector: "createPackage:properties:",
 category: 'private',
 fn: function (packageName,aDict){
 var self=this;
-return smalltalk.withContext(function($ctx) { var object;
-object = {};;
+return smalltalk.withContext(function($ctx) { var object = {};;
 ;
 _st(aDict)._keysAndValuesDo_((function(key,value){
 return object[key] = value;
@@ -4376,7 +4436,7 @@ return smalltalk.addPackage(packageName, object);
 ;
 return self}, self, "createPackage:properties:", [packageName,aDict], smalltalk.Smalltalk)},
 args: ["packageName", "aDict"],
-source: "createPackage: packageName properties: aDict\x0a\x09\x22Create and bind a new package with given name and return it.\x22\x0a\x0a\x09| object |\x0a\x09<object = {};>.\x0a\x09aDict keysAndValuesDo: [:key :value |\x0a\x09\x09<object[key] = value>.\x0a\x09].\x0a       <return smalltalk.addPackage(packageName, object)>",
+source: "createPackage: packageName properties: aDict\x0a\x09\x22Create and bind a new package with given name and return it.\x22\x0a\x0a\x09<var object = {};>.\x0a\x09aDict keysAndValuesDo: [:key :value |\x0a\x09\x09<object[key] = value>.\x0a\x09].\x0a       <return smalltalk.addPackage(packageName, object)>",
 messageSends: ["keysAndValuesDo:"],
 referencedClasses: []
 }),
@@ -4452,6 +4512,23 @@ referencedClasses: []
 }),
 smalltalk.Smalltalk);
 
+smalltalk.addMethod(
+"_packageAt_put_",
+smalltalk.method({
+selector: "packageAt:put:",
+category: 'packages',
+fn: function (packageName,aPackage){
+var self=this;
+return smalltalk.withContext(function($ctx) { return self.packages[packageName] = aPackage;
+;
+return self}, self, "packageAt:put:", [packageName,aPackage], smalltalk.Smalltalk)},
+args: ["packageName", "aPackage"],
+source: "packageAt: packageName put: aPackage\x0a       <return self.packages[packageName] = aPackage>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Smalltalk);
+
 smalltalk.addMethod(
 "_packages",
 smalltalk.method({
@@ -4506,10 +4583,9 @@ var message;
 var lines;
 var badLine;
 var code;
-row = anException.line;
-	col = anException.column;
-	message = anException.message;;
-;
+row=_st(anException)._basicAt_("line");
+col=_st(anException)._basicAt_("column");
+message=_st(anException)._basicAt_("message");
 lines=_st(aString)._lines();
 badLine=_st(lines)._at_(row);
 badLine=_st(_st(_st(badLine)._copyFrom_to_((1),_st(col).__minus((1)))).__comma(" ===>")).__comma(_st(badLine)._copyFrom_to_(col,_st(badLine)._size()));
@@ -4523,8 +4599,8 @@ $1=_st(_st((smalltalk.ParseError || ParseError))._new())._messageText_(_st(_st(_
 return $1;
 }, self, "parseError:parsing:", [anException,aString], smalltalk.Smalltalk)},
 args: ["anException", "aString"],
-source: "parseError: anException parsing: aString\x0a\x09| row col message lines badLine code |\x0a\x09<row = anException.line;\x0a\x09col = anException.column;\x0a\x09message = anException.message;>.\x0a\x09lines := aString lines.\x0a\x09badLine := lines at: row.\x0a\x09badLine := (badLine copyFrom: 1 to: col - 1), ' ===>', (badLine copyFrom:  col to: badLine size).\x0a\x09lines at: row put: badLine.\x0a\x09code := String streamContents: [:s |\x0a                  lines withIndexDo: [:l :i |\x0a                     s nextPutAll: i asString, ': ', l, String lf]].\x0a\x09^ ParseError new messageText: ('Parse error on line ' , row , ' column ' , col , ' : ' , message , ' Below is code with line numbers and ===> marker inserted:' , String lf, code)",
-messageSends: ["lines", "at:", ",", "copyFrom:to:", "size", "-", "at:put:", "streamContents:", "withIndexDo:", "nextPutAll:", "lf", "asString", "messageText:", "new"],
+source: "parseError: anException parsing: aString\x0a\x09| row col message lines badLine code |\x0a\x09row := anException basicAt: 'line'.\x0a    col := anException basicAt: 'column'.\x0a    message := anException basicAt: 'message'.\x0a\x09lines := aString lines.\x0a\x09badLine := lines at: row.\x0a\x09badLine := (badLine copyFrom: 1 to: col - 1), ' ===>', (badLine copyFrom:  col to: badLine size).\x0a\x09lines at: row put: badLine.\x0a\x09code := String streamContents: [:s |\x0a                  lines withIndexDo: [:l :i |\x0a                     s nextPutAll: i asString, ': ', l, String lf]].\x0a\x09^ ParseError new messageText: ('Parse error on line ' , row , ' column ' , col , ' : ' , message , ' Below is code with line numbers and ===> marker inserted:' , String lf, code)",
+messageSends: ["basicAt:", "lines", "at:", ",", "copyFrom:to:", "size", "-", "at:put:", "streamContents:", "withIndexDo:", "nextPutAll:", "lf", "asString", "messageText:", "new"],
 referencedClasses: ["String", "ParseError"]
 }),
 smalltalk.Smalltalk);
@@ -4634,14 +4710,13 @@ $1;
 } else {
 _st(self)._error_(_st("Already exists a package called: ").__comma(newName));
 };
-smalltalk.packages[newName] = smalltalk.packages[packageName];
-;
+_st(self)._packageAt_put_(newName,pkg);
 _st(pkg)._name_(newName);
 _st(self)._deletePackage_(packageName);
 return self}, self, "renamePackage:to:", [packageName,newName], smalltalk.Smalltalk)},
 args: ["packageName", "newName"],
-source: "renamePackage: packageName to: newName\x0a\x09\x22Rename a package.\x22\x0a\x0a\x09| pkg |\x0a\x09pkg := self packageAt: packageName ifAbsent: [self error: 'Missing package: ', packageName].\x0a\x09(self packageAt: newName) ifNotNil: [self error: 'Already exists a package called: ', newName].\x0a\x09<smalltalk.packages[newName] = smalltalk.packages[packageName]>.\x0a\x09pkg name: newName.\x0a\x09self deletePackage: packageName.",
-messageSends: ["packageAt:ifAbsent:", "error:", ",", "ifNotNil:", "packageAt:", "name:", "deletePackage:"],
+source: "renamePackage: packageName to: newName\x0a\x09\x22Rename a package.\x22\x0a\x0a\x09| pkg |\x0a\x09pkg := self packageAt: packageName ifAbsent: [self error: 'Missing package: ', packageName].\x0a\x09(self packageAt: newName) ifNotNil: [self error: 'Already exists a package called: ', newName].\x0a\x09self packageAt: newName put: pkg.\x0a\x09pkg name: newName.\x0a\x09self deletePackage: packageName.",
+messageSends: ["packageAt:ifAbsent:", "error:", ",", "ifNotNil:", "packageAt:", "packageAt:put:", "name:", "deletePackage:"],
 referencedClasses: []
 }),
 smalltalk.Smalltalk);
@@ -4670,14 +4745,13 @@ selector: "send:to:arguments:",
 category: 'accessing',
 fn: function (aSelector,anObject,aCollection){
 var self=this;
-return smalltalk.withContext(function($ctx) { var selector;
-selector=_st(_st(aSelector)._asString())._asSelector();
-return self.send(anObject, selector, aCollection);
-;
-return self}, self, "send:to:arguments:", [aSelector,anObject,aCollection], smalltalk.Smalltalk)},
+return smalltalk.withContext(function($ctx) { var $1;
+$1=_st(self)._basicSend_to_arguments_(_st(_st(aSelector)._asString())._asSelector(),anObject,aCollection);
+return $1;
+}, self, "send:to:arguments:", [aSelector,anObject,aCollection], smalltalk.Smalltalk)},
 args: ["aSelector", "anObject", "aCollection"],
-source: "send: aSelector to: anObject arguments: aCollection\x0a\x09| selector |\x0a\x09selector := aSelector asString asSelector.\x0a\x09<return self.send(anObject, selector, aCollection)>",
-messageSends: ["asSelector", "asString"],
+source: "send: aSelector to: anObject arguments: aCollection\x0a\x09^ self basicSend: aSelector asString asSelector to: anObject arguments: aCollection",
+messageSends: ["basicSend:to:arguments:", "asSelector", "asString"],
 referencedClasses: []
 }),
 smalltalk.Smalltalk);
@@ -4704,6 +4778,21 @@ smalltalk.Smalltalk.klass);
 
 smalltalk.addClass('UndefinedObject', smalltalk.Object, [], 'Kernel-Objects');
 smalltalk.UndefinedObject.comment="UndefinedObject describes the behavior of its sole instance, `nil`. `nil` represents a prior value for variables that have not been initialized, or for results which are meaningless.\x0a\x0a`nil` is the Smalltalk representation of the `undefined` JavaScript object."
+smalltalk.addMethod(
+"_accept_",
+smalltalk.method({
+selector: "accept:",
+category: 'converting',
+fn: function (aVisitor){
+var self=this;
+return smalltalk.withContext(function($ctx) { return self}, self, "accept:", [aVisitor], smalltalk.UndefinedObject)},
+args: ["aVisitor"],
+source: "accept: aVisitor",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.UndefinedObject);
+
 smalltalk.addMethod(
 "_asJSON",
 smalltalk.method({

+ 5 - 9
js/Kernel-Tests.deploy.js

@@ -328,15 +328,12 @@ smalltalk.method({
 selector: "testNonBooleanError",
 fn: function (){
 var self=this;
-var b;
-b= '' ;
-;
-smalltalk.send(self,"_should_raise_",[(function(){
-if(smalltalk.assert(self["@nonBoolean"])){
+return smalltalk.withContext(function($ctx) { _st(self)._should_raise_((function(){
+if(smalltalk.assert("")){
 } else {
 };
-}),(smalltalk.NonBooleanReceiver || NonBooleanReceiver)]);
-return self}
+}),(smalltalk.NonBooleanReceiver || NonBooleanReceiver));
+return self}, self, "testNonBooleanError", [], smalltalk.BooleanTest)}
 }),
 smalltalk.BooleanTest);
 
@@ -2089,8 +2086,7 @@ selector: "testNilUndefined",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx) { var notDefined;
-notDefined = undefined;
-;
+notDefined=_st(window)._at_("__this_is_undefined");
 _st(self)._assert_(_st(nil).__eq(notDefined));
 return self}, self, "testNilUndefined", [], smalltalk.ObjectTest)}
 }),

+ 8 - 12
js/Kernel-Tests.js

@@ -394,17 +394,14 @@ selector: "testNonBooleanError",
 category: 'tests',
 fn: function (){
 var self=this;
-var b;
-b= '' ;
-;
-smalltalk.send(self,"_should_raise_",[(function(){
-if(smalltalk.assert(self["@nonBoolean"])){
+return smalltalk.withContext(function($ctx) { _st(self)._should_raise_((function(){
+if(smalltalk.assert("")){
 } else {
 };
-}),(smalltalk.NonBooleanReceiver || NonBooleanReceiver)]);
-return self},
+}),(smalltalk.NonBooleanReceiver || NonBooleanReceiver));
+return self}, self, "testNonBooleanError", [], smalltalk.BooleanTest)},
 args: [],
-source: "testNonBooleanError\x0a\x09|b|\x0a    b := < '' >.\x0a    self should: [nonBoolean ifTrue: [] ifFalse: []] raise: NonBooleanReceiver",
+source: "testNonBooleanError\x0a    self should: ['' ifTrue: [] ifFalse: []] raise: NonBooleanReceiver",
 messageSends: ["should:raise:", "ifTrue:ifFalse:"],
 referencedClasses: ["NonBooleanReceiver"]
 }),
@@ -2725,13 +2722,12 @@ category: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx) { var notDefined;
-notDefined = undefined;
-;
+notDefined=_st(window)._at_("__this_is_undefined");
 _st(self)._assert_(_st(nil).__eq(notDefined));
 return self}, self, "testNilUndefined", [], smalltalk.ObjectTest)},
 args: [],
-source: "testNilUndefined\x0a\x09\x22nil in Smalltalk is the undefined object in JS\x22\x0a\x0a\x09| notDefined |\x0a    \x0a    <notDefined = undefined>.\x0a\x0a\x09self assert: nil = notDefined",
-messageSends: ["assert:", "="],
+source: "testNilUndefined\x0a\x09\x22nil in Smalltalk is the undefined object in JS\x22\x0a\x0a\x09| notDefined |\x0a    \x0a    notDefined := window at: '__this_is_undefined'.\x0a\x0a\x09self assert: nil = notDefined",
+messageSends: ["at:", "assert:", "="],
 referencedClasses: []
 }),
 smalltalk.ObjectTest);

+ 1 - 3
js/Kernel-Transcript.deploy.js

@@ -36,9 +36,7 @@ smalltalk.method({
 selector: "show:",
 fn: function (anObject){
 var self=this;
-return smalltalk.withContext(function($ctx) { var string;
-string=_st(anObject)._asString();
-console.log(String(string));
+return smalltalk.withContext(function($ctx) { console.log(String(string._asString()));
 ;
 return self}, self, "show:", [anObject], smalltalk.ConsoleTranscript)}
 }),

+ 3 - 5
js/Kernel-Transcript.js

@@ -52,14 +52,12 @@ selector: "show:",
 category: 'printing',
 fn: function (anObject){
 var self=this;
-return smalltalk.withContext(function($ctx) { var string;
-string=_st(anObject)._asString();
-console.log(String(string));
+return smalltalk.withContext(function($ctx) { console.log(String(string._asString()));
 ;
 return self}, self, "show:", [anObject], smalltalk.ConsoleTranscript)},
 args: ["anObject"],
-source: "show: anObject\x0a\x09| string |\x0a\x09string := anObject asString.\x0a\x09<console.log(String(string))>",
-messageSends: ["asString"],
+source: "show: anObject\x0a\x09<console.log(String(string._asString()))>",
+messageSends: [],
 referencedClasses: []
 }),
 smalltalk.ConsoleTranscript);

+ 7 - 5
st/Compiler-Semantic.st

@@ -408,11 +408,7 @@ errorShadowingVariable: aString
 errorUnknownVariable: aNode
 	"Throw an error if the variable is undeclared in the global JS scope (i.e. window)"
 
-	| notDefined |
-
-	notDefined := <eval('typeof ' + aNode._value() + ' == "undefined"')>.
-
-	notDefined
+	(self isVariableGloballyUndefined: aNode value)
 		ifTrue: [ 
 			UnknownVariableError new
 				variableName: aNode value;
@@ -456,6 +452,12 @@ validateVariableScope: aString
 		self errorShadowingVariable: aString ]
 ! !
 
+!SemanticAnalyzer methodsFor: 'testing'!
+
+isVariableGloballyUndefined: aString
+	<return eval('typeof ' + aString + ' == "undefined"')>
+! !
+
 !SemanticAnalyzer methodsFor: 'visiting'!
 
 visitAssignmentNode: aNode

+ 51 - 38
st/Kernel-Objects.st

@@ -68,15 +68,11 @@ identityHash
 !
 
 instVarAt: aSymbol
-	| varname |
-	varname := aSymbol asString.
-	<return self['@'+varname]>
+	<return self['@'+aSymbol._asString()]>
 !
 
 instVarAt: aSymbol put: anObject
-	| varname |
-	varname := aSymbol asString.
-	<self['@' + varname] = anObject>
+	<self['@' + aSymbol._asString()] = anObject>
 !
 
 size
@@ -229,9 +225,7 @@ perform: aSymbol
 !
 
 perform: aSymbol withArguments: aCollection
-	| selector |
-	selector := aSymbol asSelector.
-	<return smalltalk.send(self, selector, aCollection)>
+	<return smalltalk.send(self, aSymbol._asSelector(), aCollection)>
 ! !
 
 !Object methodsFor: 'printing'!
@@ -503,6 +497,10 @@ methodClass
 	^self basicAt: 'methodClass'
 !
 
+printString
+	^ self methodClass name, ' >> ', self selector
+!
+
 protocol
 	^ self category
 !
@@ -741,15 +739,11 @@ __Note:__ For keyword-based messages, only the first keyword is kept: `window fo
 !JSObjectProxy methodsFor: 'accessing'!
 
 at: aSymbol
-	| attr |
-	attr := aSymbol asString.
-	<return self['@jsObject'][attr]>
+	<return self['@jsObject'][aSymbol._asString()]>
 !
 
 at: aSymbol put: anObject
-	| attr |
-	attr := aSymbol asString.
-	<self['@jsObject'][attr] = anObject>
+	<self['@jsObject'][aSymbol._asString()] = anObject>
 !
 
 jsObject
@@ -762,27 +756,39 @@ jsObject: aJSObject
 
 !JSObjectProxy methodsFor: 'proxy'!
 
+canUnderstand: aSelector
+	<return self._jsObject()[aSelector._asJavaScriptSelector()] !!= undefined>
+!
+
 doesNotUnderstand: aMessage
 	| obj selector jsSelector arguments |
 	obj := self jsObject.
 	selector := aMessage selector.
 	jsSelector := selector asJavaScriptSelector.
 	arguments := aMessage arguments.
-	<if(obj[jsSelector] !!= undefined) {return smalltalk.send(obj, jsSelector, arguments)}>.
+    (self canUnderstand: selector) ifTrue: [
+      	^ Smalltalk current basicSend: jsSelector to: obj arguments: arguments ].
 	super doesNotUnderstand: aMessage
 !
 
 inspectOn: anInspector
 	| variables |
-	variables := Dictionary new.
+	variables := self inspectorVariables.
 	variables at: '#self' put: self jsObject.
 	anInspector setLabel: self printString.
-	<for(var i in self['@jsObject']) {
-		variables._at_put_(i, self['@jsObject'][i]);
-	}>.
 	anInspector setVariables: variables
 !
 
+inspectorVariables
+	<
+    	var variables = smalltalk.Dictionary._new();
+        for(var i in self['@jsObject']) {
+			variables._at_put_(i, self['@jsObject'][i]);
+		};
+        return variables
+    >
+!
+
 printString
 	^self jsObject toString
 ! !
@@ -966,13 +972,13 @@ to: stop by: step
 !
 
 truncated
-|result|
-
-    self >= 0 
-        ifTrue: [<result = Math.floor(self);>]
-        ifFalse: [<result = (Math.floor(self * (-1)) * (-1));>].
-
-    ^ result
+	<
+    	if(self >>= 0) {
+        	return Math.floor(self);
+        } else {
+        	return Math.floor(self * (-1)) * (-1);
+        }
+    >
 !
 
 | aNumber
@@ -1165,8 +1171,7 @@ properties
 properties: aDict
 	"We store it as a javascript object."
 	
-	| object |
-	<object = {};>.
+	<var object = {};>.
 	aDict keysAndValuesDo: [:key :value |
 		<object[key] = value>.
 	].
@@ -1483,6 +1488,10 @@ basicParse: aString
 	<return smalltalk.parser.parse(aString)>
 !
 
+basicSend: aSelector to: anObject arguments: aCollection
+	<return self.send(anObject, aSelector, aCollection)>
+!
+
 parse: aString
 	| result | 
 	self try: [result := self basicParse: aString] catch: [:ex | (self parseError: ex parsing: aString) signal].
@@ -1491,9 +1500,9 @@ parse: aString
 
 parseError: anException parsing: aString
 	| row col message lines badLine code |
-	<row = anException.line;
-	col = anException.column;
-	message = anException.message;>.
+	row := anException basicAt: 'line'.
+    col := anException basicAt: 'column'.
+    message := anException basicAt: 'message'.
 	lines := aString lines.
 	badLine := lines at: row.
 	badLine := (badLine copyFrom: 1 to: col - 1), ' ===>', (badLine copyFrom:  col to: badLine size).
@@ -1514,9 +1523,7 @@ reservedWords
 !
 
 send: aSelector to: anObject arguments: aCollection
-	| selector |
-	selector := aSelector asString asSelector.
-	<return self.send(anObject, selector, aCollection)>
+	^ self basicSend: aSelector asString asSelector to: anObject arguments: aCollection
 ! !
 
 !Smalltalk methodsFor: 'classes'!
@@ -1552,6 +1559,10 @@ packageAt: packageName ifAbsent: aBlock
        ^(self packageAt: packageName) ifNil: aBlock
 !
 
+packageAt: packageName put: aPackage
+       <return self.packages[packageName] = aPackage>
+!
+
 packages
 	"Return all Package instances in the system."
 
@@ -1578,7 +1589,7 @@ renamePackage: packageName to: newName
 	| pkg |
 	pkg := self packageAt: packageName ifAbsent: [self error: 'Missing package: ', packageName].
 	(self packageAt: newName) ifNotNil: [self error: 'Already exists a package called: ', newName].
-	<smalltalk.packages[newName] = smalltalk.packages[packageName]>.
+	self packageAt: newName put: pkg.
 	pkg name: newName.
 	self deletePackage: packageName.
 ! !
@@ -1594,8 +1605,7 @@ createPackage: packageName
 createPackage: packageName properties: aDict
 	"Create and bind a new package with given name and return it."
 
-	| object |
-	<object = {};>.
+	<var object = {};>.
 	aDict keysAndValuesDo: [:key :value |
 		<object[key] = value>.
 	].
@@ -1650,6 +1660,9 @@ subclass: aString instanceVariableNames: aString2 package: aString3
 
 !UndefinedObject methodsFor: 'converting'!
 
+accept: aVisitor
+!
+
 asJSON
 	^null
 ! !

+ 2 - 4
st/Kernel-Tests.st

@@ -153,9 +153,7 @@ testLogicKeywords
 !
 
 testNonBooleanError
-	|b|
-    b := < '' >.
-    self should: [nonBoolean ifTrue: [] ifFalse: []] raise: NonBooleanReceiver
+    self should: ['' ifTrue: [] ifFalse: []] raise: NonBooleanReceiver
 ! !
 
 TestCase subclass: #ClassBuilderTest
@@ -1100,7 +1098,7 @@ testNilUndefined
 
 	| notDefined |
     
-    <notDefined = undefined>.
+    notDefined := window at: '__this_is_undefined'.
 
 	self assert: nil = notDefined
 !

+ 1 - 3
st/Kernel-Transcript.st

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