Browse Source

ASTInterpreter: fix inner cascades

Herbert Vojčík 8 years ago
parent
commit
0652ad9f5c
4 changed files with 34 additions and 6 deletions
  1. 3 4
      src/Compiler-Interpreter.js
  2. 2 2
      src/Compiler-Interpreter.st
  3. 24 0
      src/Compiler-Tests.js
  4. 5 0
      src/Compiler-Tests.st

+ 3 - 4
src/Compiler-Interpreter.js

@@ -3456,7 +3456,7 @@ $ctx2.sendIdx["pop"]=1;
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)});
 //>>excludeEnd("ctx");
 }));
-receiver=self._peek();
+receiver=self._pop();
 message=self._messageFromSendNode_arguments_(aNode,$recv(args)._reversed());
 result=self._sendMessage_to_superSend_(message,receiver,$recv(aNode)._superSend());
 $1=$recv($recv(aNode)._isCascadeSendNode())._and_((function(){
@@ -3469,7 +3469,6 @@ return $recv($recv(aNode)._isLastChild())._not();
 //>>excludeEnd("ctx");
 }));
 if(!$core.assert($1)){
-self._pop();
 self._push_(result);
 };
 return self;
@@ -3479,10 +3478,10 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["aNode"],
-source: "visitSendNode: aNode\x0a\x09| receiver args message result |\x0a\x09\x0a\x09args := aNode arguments collect: [ :each | self pop ].\x0a\x09receiver := self peek.\x0a\x09\x0a\x09message := self\x0a\x09\x09messageFromSendNode: aNode\x0a\x09\x09arguments: args reversed.\x0a\x09\x0a\x09result := self sendMessage: message to: receiver superSend: aNode superSend.\x0a\x09\x0a\x09\x22For cascade sends, push the reciever if the send is not the last one\x22\x0a\x09(aNode isCascadeSendNode and: [ aNode isLastChild not ])\x0a\x09\x09ifFalse: [ self pop; push: result ]",
+source: "visitSendNode: aNode\x0a\x09| receiver args message result |\x0a\x09\x0a\x09args := aNode arguments collect: [ :each | self pop ].\x0a\x09receiver := self pop.\x0a\x09\x0a\x09message := self\x0a\x09\x09messageFromSendNode: aNode\x0a\x09\x09arguments: args reversed.\x0a\x09\x0a\x09result := self sendMessage: message to: receiver superSend: aNode superSend.\x0a\x09\x0a\x09\x22For cascade sends, push the reciever if the send is not the last one\x22\x0a\x09(aNode isCascadeSendNode and: [ aNode isLastChild not ])\x0a\x09\x09ifFalse: [ self push: result ]",
 referencedClasses: [],
 //>>excludeEnd("ide");
-messageSends: ["collect:", "arguments", "pop", "peek", "messageFromSendNode:arguments:", "reversed", "sendMessage:to:superSend:", "superSend", "ifFalse:", "and:", "isCascadeSendNode", "not", "isLastChild", "push:"]
+messageSends: ["collect:", "arguments", "pop", "messageFromSendNode:arguments:", "reversed", "sendMessage:to:superSend:", "superSend", "ifFalse:", "and:", "isCascadeSendNode", "not", "isLastChild", "push:"]
 }),
 $globals.ASTInterpreter);
 

+ 2 - 2
src/Compiler-Interpreter.st

@@ -888,7 +888,7 @@ visitSendNode: aNode
 	| receiver args message result |
 	
 	args := aNode arguments collect: [ :each | self pop ].
-	receiver := self peek.
+	receiver := self pop.
 	
 	message := self
 		messageFromSendNode: aNode
@@ -898,7 +898,7 @@ visitSendNode: aNode
 	
 	"For cascade sends, push the reciever if the send is not the last one"
 	(aNode isCascadeSendNode and: [ aNode isLastChild not ])
-		ifFalse: [ self pop; push: result ]
+		ifFalse: [ self push: result ]
 !
 
 visitSequenceNode: aNode

+ 24 - 0
src/Compiler-Tests.js

@@ -907,6 +907,30 @@ messageSends: ["should:return:"]
 }),
 $globals.CodeGeneratorTest);
 
+$core.addMethod(
+$core.method({
+selector: "testInnerCascades",
+protocol: 'tests',
+fn: function (){
+var self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+self._should_return_("foo ^ Array new add: (3 squared; negated); add: (4 negated; squared); yourself",[(-3), (16)]);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testInnerCascades",{},$globals.CodeGeneratorTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testInnerCascades\x0a\x09\x0a\x09self should: 'foo ^ Array new add: (3 squared; negated); add: (4 negated; squared); yourself' return: #(-3 16)",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["should:return:"]
+}),
+$globals.CodeGeneratorTest);
+
 $core.addMethod(
 $core.method({
 selector: "testInnerTemporalDependentElementsOrdered",

+ 5 - 0
src/Compiler-Tests.st

@@ -248,6 +248,11 @@ testGlobalVar
 	self should: 'foo ^ NonExistingVar' return: nil
 !
 
+testInnerCascades
+	
+	self should: 'foo ^ Array new add: (3 squared; negated); add: (4 negated; squared); yourself' return: #(-3 16)
+!
+
 testInnerTemporalDependentElementsOrdered
 	self should: 'foo
 	| x |