Przeglądaj źródła

ASTInterpreter: fix inner cascades

Herbert Vojčík 8 lat temu
rodzic
commit
1eff568a00

+ 3 - 4
src/Compiler-Interpreter.js

@@ -3497,7 +3497,7 @@ $ctx2.sendIdx["pop"]=1;
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)});
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)});
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
 }));
 }));
-receiver=self._peek();
+receiver=self._pop();
 message=self._messageFromSendNode_arguments_(aNode,$recv(args)._reversed());
 message=self._messageFromSendNode_arguments_(aNode,$recv(args)._reversed());
 result=self._sendMessage_to_superSend_(message,receiver,$recv(aNode)._superSend());
 result=self._sendMessage_to_superSend_(message,receiver,$recv(aNode)._superSend());
 $1=$recv($recv(aNode)._isCascadeSendNode())._and_((function(){
 $1=$recv($recv(aNode)._isCascadeSendNode())._and_((function(){
@@ -3510,7 +3510,6 @@ return $recv($recv(aNode)._isLastChild())._not();
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
 }));
 }));
 if(!$core.assert($1)){
 if(!$core.assert($1)){
-self._pop();
 self._push_(result);
 self._push_(result);
 };
 };
 return self;
 return self;
@@ -3520,10 +3519,10 @@ return self;
 },
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["aNode"],
 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: [],
 referencedClasses: [],
 //>>excludeEnd("ide");
 //>>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);
 $globals.ASTInterpreter);
 
 

+ 2 - 2
src/Compiler-Interpreter.st

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

+ 24 - 0
src/Compiler-Tests.js

@@ -991,6 +991,30 @@ messageSends: ["should:return:"]
 }),
 }),
 $globals.CodeGeneratorTest);
 $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.addMethod(
 $core.method({
 $core.method({
 selector: "testInnerTemporalDependentElementsOrdered",
 selector: "testInnerTemporalDependentElementsOrdered",

+ 5 - 0
src/Compiler-Tests.st

@@ -260,6 +260,11 @@ testGlobalVar
 	self should: 'foo ^ NonExistingVar' return: nil
 	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
 testInnerTemporalDependentElementsOrdered
 	self should: 'foo
 	self should: 'foo
 	| x |
 	| x |