Ver código fonte

pass receiver in cascaded messages

making ready for branching sends
Herbert Vojčík 8 anos atrás
pai
commit
a878a63eee
4 arquivos alterados com 38 adições e 52 exclusões
  1. 21 30
      src/Compiler-IR.js
  2. 10 10
      src/Compiler-IR.st
  3. 5 9
      src/Compiler-Interpreter.js
  4. 2 3
      src/Compiler-Interpreter.st

+ 21 - 30
src/Compiler-IR.js

@@ -555,51 +555,42 @@ selector: "visitCascadeNode:",
 protocol: 'visiting',
 protocol: 'visiting',
 fn: function (aNode){
 fn: function (aNode){
 var self=this;
 var self=this;
-var alias,receiver;
 function $VariableNode(){return $globals.VariableNode||(typeof VariableNode=="undefined"?nil:VariableNode)}
 function $VariableNode(){return $globals.VariableNode||(typeof VariableNode=="undefined"?nil:VariableNode)}
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
-var $2,$1,$3,$5,$4;
-$2=$recv(aNode)._receiver();
+var $1,$2,$4,$3;
+$1=$recv(aNode)._nodes();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx["receiver"]=1;
+$ctx1.sendIdx["nodes"]=1;
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
-$1=$recv($2)._isImmutable();
-if($core.assert($1)){
-receiver=$recv(aNode)._receiver();
+$recv($1)._inject_into_($recv(aNode)._receiver(),(function(previous,each){
+var receiver;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx["receiver"]=2;
+return $core.withContext(function($ctx2) {
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
-receiver;
+$2=$recv(previous)._isImmutable();
+if($core.assert($2)){
+receiver=previous;
 } else {
 } else {
-alias=self._alias_($recv(aNode)._receiver());
+var alias;
+alias=self._alias_(previous);
 alias;
 alias;
 receiver=$recv($recv($VariableNode())._new())._binding_($recv(alias)._variable());
 receiver=$recv($recv($VariableNode())._new())._binding_($recv(alias)._variable());
-receiver;
 };
 };
-$3=$recv(aNode)._nodes();
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx["nodes"]=1;
-//>>excludeEnd("ctx");
-$recv($3)._do_((function(each){
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx2) {
-//>>excludeEnd("ctx");
-return $recv(each)._receiver_(receiver);
+receiver;
+$recv(each)._receiver_(receiver);
+return receiver;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,3)});
+}, function($ctx2) {$ctx2.fillBlock({previous:previous,each:each,receiver:receiver},$ctx1,1)});
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
 }));
 }));
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx["do:"]=1;
-//>>excludeEnd("ctx");
-$5=$recv(aNode)._nodes();
+$4=$recv(aNode)._nodes();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["nodes"]=2;
 $ctx1.sendIdx["nodes"]=2;
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
-$4=$recv($5)._allButLast();
-$recv($4)._do_((function(each){
+$3=$recv($4)._allButLast();
+$recv($3)._do_((function(each){
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx2) {
 return $core.withContext(function($ctx2) {
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
@@ -610,15 +601,15 @@ return $recv(self._sequence())._add_(self._visit_(each));
 }));
 }));
 return self._visitOrAlias_($recv($recv(aNode)._nodes())._last());
 return self._visitOrAlias_($recv($recv(aNode)._nodes())._last());
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"visitCascadeNode:",{aNode:aNode,alias:alias,receiver:receiver},$globals.IRASTTranslator)});
+}, function($ctx1) {$ctx1.fill(self,"visitCascadeNode:",{aNode:aNode},$globals.IRASTTranslator)});
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
 },
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["aNode"],
 args: ["aNode"],
-source: "visitCascadeNode: aNode\x0a\x09| alias receiver |\x0a\x0a\x09aNode receiver isImmutable \x0a\x09\x09ifTrue: [ receiver := aNode receiver ]\x0a\x09\x09ifFalse: [\x0a\x09\x09\x09alias := self alias: aNode receiver.\x0a\x09\x09\x09receiver := VariableNode new binding: alias variable ].\x0a\x09\x0a\x09aNode nodes do: [ :each |\x0a\x09\x09\x09each receiver: receiver ].\x0a\x0a\x09aNode nodes allButLast do: [ :each |\x0a\x09\x09self sequence add: (self visit: each) ].\x0a\x0a\x09^ self visitOrAlias: aNode nodes last",
+source: "visitCascadeNode: aNode\x0a\x09aNode nodes inject: aNode receiver into: [ :previous :each |\x0a\x09\x09| receiver |\x0a\x09\x09receiver := previous isImmutable \x0a\x09\x09\x09ifTrue: [ previous ]\x0a\x09\x09\x09ifFalse: [\x0a\x09\x09\x09\x09| alias |\x0a\x09\x09\x09\x09alias := self alias: previous.\x0a\x09\x09\x09\x09VariableNode new binding: alias variable ].\x0a\x09\x09each receiver: receiver.\x0a\x09\x09receiver ].\x0a\x0a\x09aNode nodes allButLast do: [ :each |\x0a\x09\x09self sequence add: (self visit: each) ].\x0a\x0a\x09^ self visitOrAlias: aNode nodes last",
 referencedClasses: ["VariableNode"],
 referencedClasses: ["VariableNode"],
 //>>excludeEnd("ide");
 //>>excludeEnd("ide");
-messageSends: ["ifTrue:ifFalse:", "isImmutable", "receiver", "alias:", "binding:", "new", "variable", "do:", "nodes", "receiver:", "allButLast", "add:", "sequence", "visit:", "visitOrAlias:", "last"]
+messageSends: ["inject:into:", "nodes", "receiver", "ifTrue:ifFalse:", "isImmutable", "alias:", "binding:", "new", "variable", "receiver:", "do:", "allButLast", "add:", "sequence", "visit:", "visitOrAlias:", "last"]
 }),
 }),
 $globals.IRASTTranslator);
 $globals.IRASTTranslator);
 
 

+ 10 - 10
src/Compiler-IR.st

@@ -138,16 +138,16 @@ visitBlockSequenceNode: aNode
 !
 !
 
 
 visitCascadeNode: aNode
 visitCascadeNode: aNode
-	| alias receiver |
-
-	aNode receiver isImmutable 
-		ifTrue: [ receiver := aNode receiver ]
-		ifFalse: [
-			alias := self alias: aNode receiver.
-			receiver := VariableNode new binding: alias variable ].
-	
-	aNode nodes do: [ :each |
-			each receiver: receiver ].
+	aNode nodes inject: aNode receiver into: [ :previous :each |
+		| receiver |
+		receiver := previous isImmutable 
+			ifTrue: [ previous ]
+			ifFalse: [
+				| alias |
+				alias := self alias: previous.
+				VariableNode new binding: alias variable ].
+		each receiver: receiver.
+		receiver ].
 
 
 	aNode nodes allButLast do: [ :each |
 	aNode nodes allButLast do: [ :each |
 		self sequence add: (self visit: each) ].
 		self sequence add: (self visit: each) ].

+ 5 - 9
src/Compiler-Interpreter.js

@@ -3200,7 +3200,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._pop();
+receiver=self._peek();
 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(){
@@ -3212,12 +3212,8 @@ return $recv($recv(aNode)._isLastChild())._not();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)});
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)});
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
 }));
 }));
-if($core.assert($1)){
-self._push_(receiver);
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx["push:"]=1;
-//>>excludeEnd("ctx");
-} else {
+if(!$core.assert($1)){
+self._pop();
 self._push_(result);
 self._push_(result);
 };
 };
 return self;
 return self;
@@ -3227,10 +3223,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 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\x09ifTrue: [ self push: receiver ]\x0a\x09\x09ifFalse: [ self push: result ]",
+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 ]",
 referencedClasses: [],
 referencedClasses: [],
 //>>excludeEnd("ide");
 //>>excludeEnd("ide");
-messageSends: ["collect:", "arguments", "pop", "messageFromSendNode:arguments:", "reversed", "sendMessage:to:superSend:", "superSend", "ifTrue:ifFalse:", "and:", "isCascadeSendNode", "not", "isLastChild", "push:"]
+messageSends: ["collect:", "arguments", "pop", "peek", "messageFromSendNode:arguments:", "reversed", "sendMessage:to:superSend:", "superSend", "ifFalse:", "and:", "isCascadeSendNode", "not", "isLastChild", "push:"]
 }),
 }),
 $globals.ASTInterpreter);
 $globals.ASTInterpreter);
 
 

+ 2 - 3
src/Compiler-Interpreter.st

@@ -824,7 +824,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 pop.
+	receiver := self peek.
 	
 	
 	message := self
 	message := self
 		messageFromSendNode: aNode
 		messageFromSendNode: aNode
@@ -834,8 +834,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 ])
-		ifTrue: [ self push: receiver ]
-		ifFalse: [ self push: result ]
+		ifFalse: [ self pop; push: result ]
 !
 !
 
 
 visitSequenceNode: aNode
 visitSequenceNode: aNode