Ver Fonte

Fixed inlined js node interpretation

Nicolas Petton há 11 anos atrás
pai
commit
09d27f8ff4

+ 19 - 4
js/Compiler-Interpreter.deploy.js

@@ -210,10 +210,25 @@ smalltalk.method({
 selector: "eval:",
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=_st(_st((smalltalk.Compiler || Compiler))._new())._eval_(_st(_st("(function() { ").__comma(aString)).__comma(" })()"));
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"eval:",{aString:aString}, smalltalk.ASTInterpreter)})}
+var source,function_;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+source=_st((smalltalk.String || String))._streamContents_((function(str){
+return smalltalk.withContext(function($ctx2) {
_st(str)._nextPutAll_("(function(");
+_st(_st(_st(_st(self)._context())._locals())._keys())._do_separatedBy_((function(each){
+return smalltalk.withContext(function($ctx3) {
return _st(str)._nextPutAll_(each);
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx3) {
return _st(str)._nextPutAll_(",");
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+$1=str;
+_st($1)._nextPutAll_("){ return (function() {");
+_st($1)._nextPutAll_(aString);
+$2=_st($1)._nextPutAll_("})() })");
+return $2;
+}, function($ctx2) {$ctx2.fillBlock({str:str},$ctx1)})}));
+function_=_st(_st((smalltalk.Compiler || Compiler))._new())._eval_(source);
+$3=_st(function_)._valueWithPossibleArguments_(_st(_st(_st(self)._context())._locals())._values());
+return $3;
+}, function($ctx1) {$ctx1.fill(self,"eval:",{aString:aString,source:source,function_:function_}, smalltalk.ASTInterpreter)})}
 }),
 smalltalk.ASTInterpreter);
 

+ 22 - 7
js/Compiler-Interpreter.js

@@ -281,14 +281,29 @@ selector: "eval:",
 category: 'interpreting',
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=_st(_st((smalltalk.Compiler || Compiler))._new())._eval_(_st(_st("(function() { ").__comma(aString)).__comma(" })()"));
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"eval:",{aString:aString}, smalltalk.ASTInterpreter)})},
+var source,function_;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+source=_st((smalltalk.String || String))._streamContents_((function(str){
+return smalltalk.withContext(function($ctx2) {
_st(str)._nextPutAll_("(function(");
+_st(_st(_st(_st(self)._context())._locals())._keys())._do_separatedBy_((function(each){
+return smalltalk.withContext(function($ctx3) {
return _st(str)._nextPutAll_(each);
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx3) {
return _st(str)._nextPutAll_(",");
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+$1=str;
+_st($1)._nextPutAll_("){ return (function() {");
+_st($1)._nextPutAll_(aString);
+$2=_st($1)._nextPutAll_("})() })");
+return $2;
+}, function($ctx2) {$ctx2.fillBlock({str:str},$ctx1)})}));
+function_=_st(_st((smalltalk.Compiler || Compiler))._new())._eval_(source);
+$3=_st(function_)._valueWithPossibleArguments_(_st(_st(_st(self)._context())._locals())._values());
+return $3;
+}, function($ctx1) {$ctx1.fill(self,"eval:",{aString:aString,source:source,function_:function_}, smalltalk.ASTInterpreter)})},
 args: ["aString"],
-source: "eval: aString\x0a\x09\x22Evaluate aString as JS source inside an immediately evaluated JS function. \x0a    aString is not sandboxed.\x22\x0a    \x0a    ^ Compiler new eval: '(function() { ', aString, ' })()'",
-messageSends: ["eval:", ",", "new"],
-referencedClasses: ["Compiler"]
+source: "eval: aString\x0a\x09\x22Evaluate aString as JS source inside an JS function. \x0a    aString is not sandboxed.\x22\x0a    \x0a    | source function |\x0a    \x0a    source := String streamContents: [ :str |\x0a    \x09str nextPutAll: '(function('.\x0a        self context locals keys \x0a        \x09do: [ :each | str nextPutAll: each ]\x0a          \x09separatedBy: [ str nextPutAll: ',' ].\x0a        str \x0a        \x09nextPutAll: '){ return (function() {';\x0a        \x09nextPutAll: aString;\x0a            nextPutAll: '})() })' ].\x0a            \x0a\x09function := Compiler new eval: source.\x0a    \x0a\x09^ function valueWithPossibleArguments: self context locals values",
+messageSends: ["streamContents:", "nextPutAll:", "do:separatedBy:", "keys", "locals", "context", "eval:", "new", "valueWithPossibleArguments:", "values"],
+referencedClasses: ["String", "Compiler"]
 }),
 smalltalk.ASTInterpreter);
 

+ 1 - 0
js/Compiler-Tests.deploy.js

@@ -116,6 +116,7 @@ selector: "testInlinedJSStatement",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_equals_(_st(self)._interpret_("foo <return 2+3>"),(5));
+_st(self)._assert_equals_(_st(self)._interpret_withArguments_("foo: anInteger <return 2 + anInteger>",smalltalk.HashedCollection._fromPairs_([_st("anInteger").__minus_gt((3))])),(5));
 return self}, function($ctx1) {$ctx1.fill(self,"testInlinedJSStatement",{}, smalltalk.ASTInterpreterTest)})}
 }),
 smalltalk.ASTInterpreterTest);

+ 3 - 2
js/Compiler-Tests.js

@@ -157,10 +157,11 @@ category: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_equals_(_st(self)._interpret_("foo <return 2+3>"),(5));
+_st(self)._assert_equals_(_st(self)._interpret_withArguments_("foo: anInteger <return 2 + anInteger>",smalltalk.HashedCollection._fromPairs_([_st("anInteger").__minus_gt((3))])),(5));
 return self}, function($ctx1) {$ctx1.fill(self,"testInlinedJSStatement",{}, smalltalk.ASTInterpreterTest)})},
 args: [],
-source: "testInlinedJSStatement\x0a\x09self assert: (self interpret: 'foo <return 2+3>') equals: 5.\x0a    \x22self \x0a    \x09assert: (self \x0a    \x09\x09interpret: 'foo: anInteger <return 2 + anInteger>' \x0a        \x09withArguments: #{ 'anInteger' -> 3}) \x0a\x09\x09equals: 5\x22",
-messageSends: ["assert:equals:", "interpret:"],
+source: "testInlinedJSStatement\x0a\x09self assert: (self interpret: 'foo <return 2+3>') equals: 5.\x0a    \x0a    self \x0a    \x09assert: (self \x0a    \x09\x09interpret: 'foo: anInteger <return 2 + anInteger>' \x0a        \x09withArguments: #{ 'anInteger' -> 3}) \x0a\x09\x09equals: 5",
+messageSends: ["assert:equals:", "interpret:", "interpret:withArguments:", "->"],
 referencedClasses: []
 }),
 smalltalk.ASTInterpreterTest);

+ 16 - 2
st/Compiler-Interpreter.st

@@ -87,10 +87,24 @@ initialize
 !ASTInterpreter methodsFor: 'interpreting'!
 
 eval: aString
-	"Evaluate aString as JS source inside an immediately evaluated JS function. 
+	"Evaluate aString as JS source inside an JS function. 
     aString is not sandboxed."
     
-    ^ Compiler new eval: '(function() { ', aString, ' })()'
+    | source function |
+    
+    source := String streamContents: [ :str |
+    	str nextPutAll: '(function('.
+        self context locals keys 
+        	do: [ :each | str nextPutAll: each ]
+          	separatedBy: [ str nextPutAll: ',' ].
+        str 
+        	nextPutAll: '){ return (function() {';
+        	nextPutAll: aString;
+            nextPutAll: '})() })' ].
+            
+	function := Compiler new eval: source.
+    
+	^ function valueWithPossibleArguments: self context locals values
 !
 
 interpret: aNode

+ 3 - 2
st/Compiler-Tests.st

@@ -57,11 +57,12 @@ testCascade
 
 testInlinedJSStatement
 	self assert: (self interpret: 'foo <return 2+3>') equals: 5.
-    "self 
+    
+    self 
     	assert: (self 
     		interpret: 'foo: anInteger <return 2 + anInteger>' 
         	withArguments: #{ 'anInteger' -> 3}) 
-		equals: 5"
+		equals: 5
 ! !
 
 TestCase subclass: #CodeGeneratorTest