瀏覽代碼

compiler/parser: only allow simple branch send

branch sends only with single message tail or message cascade
CascadeNode returned back to be subclass only of Node
Herbert Vojčík 10 年之前
父節點
當前提交
79d886744f
共有 4 個文件被更改,包括 345 次插入269 次删除
  1. 85 75
      src/Compiler-AST.js
  2. 31 30
      src/Compiler-AST.st
  3. 220 155
      support/parser.js
  4. 9 9
      support/parser.pegjs

+ 85 - 75
src/Compiler-AST.js

@@ -1455,6 +1455,90 @@ $globals.BlockNode);
 
 
 
+$core.addClass('CascadeNode', $globals.Node, ['receiver'], 'Compiler-AST');
+//>>excludeStart("ide", pragmas.excludeIdeData);
+$globals.CascadeNode.comment="I represent an cascade node.";
+//>>excludeEnd("ide");
+$core.addMethod(
+$core.method({
+selector: "accept:",
+protocol: 'visiting',
+fn: function (aVisitor){
+var self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv(aVisitor)._visitCascadeNode_(self);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"accept:",{aVisitor:aVisitor},$globals.CascadeNode)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aVisitor"],
+source: "accept: aVisitor\x0a\x09^ aVisitor visitCascadeNode: self",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["visitCascadeNode:"]
+}),
+$globals.CascadeNode);
+
+$core.addMethod(
+$core.method({
+selector: "isCascadeNode",
+protocol: 'testing',
+fn: function (){
+var self=this;
+return true;
+
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "isCascadeNode\x0a\x09^ true",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.CascadeNode);
+
+$core.addMethod(
+$core.method({
+selector: "receiver",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return self["@receiver"];
+
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "receiver\x0a\x09^ receiver",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.CascadeNode);
+
+$core.addMethod(
+$core.method({
+selector: "receiver:",
+protocol: 'accessing',
+fn: function (anObject){
+var self=this;
+self["@receiver"]=anObject;
+return self;
+
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["anObject"],
+source: "receiver: anObject\x0a\x09receiver := anObject",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.CascadeNode);
+
+
+
 $core.addClass('DynamicArrayNode', $globals.Node, [], 'Compiler-AST');
 //>>excludeStart("ide", pragmas.excludeIdeData);
 $globals.DynamicArrayNode.comment="I represent an dynamic array node.";
@@ -1923,7 +2007,7 @@ $globals.MethodNode);
 
 $core.addClass('QuasiSendNode', $globals.Node, ['receiver'], 'Compiler-AST');
 //>>excludeStart("ide", pragmas.excludeIdeData);
-$globals.QuasiSendNode.comment="I am a node that has a receiver.\x0a\x0aMy subclasses are `SendNode`, `CascadeNode` and `BranchSendNode`.";
+$globals.QuasiSendNode.comment="I am a node that has a receiver\x0aand with building API `#valueForReceiver:`.\x0a\x0aMy subclasses are `SendNode` and `BranchSendNode`.";
 //>>excludeEnd("ide");
 $core.addMethod(
 $core.method({
@@ -2049,80 +2133,6 @@ $globals.BranchSendNode);
 
 
 
-$core.addClass('CascadeNode', $globals.QuasiSendNode, [], 'Compiler-AST');
-//>>excludeStart("ide", pragmas.excludeIdeData);
-$globals.CascadeNode.comment="I represent an cascade node.";
-//>>excludeEnd("ide");
-$core.addMethod(
-$core.method({
-selector: "accept:",
-protocol: 'visiting',
-fn: function (aVisitor){
-var self=this;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-return $recv(aVisitor)._visitCascadeNode_(self);
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"accept:",{aVisitor:aVisitor},$globals.CascadeNode)});
-//>>excludeEnd("ctx");
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["aVisitor"],
-source: "accept: aVisitor\x0a\x09^ aVisitor visitCascadeNode: self",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: ["visitCascadeNode:"]
-}),
-$globals.CascadeNode);
-
-$core.addMethod(
-$core.method({
-selector: "isCascadeNode",
-protocol: 'testing',
-fn: function (){
-var self=this;
-return true;
-
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: [],
-source: "isCascadeNode\x0a\x09^ true",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: []
-}),
-$globals.CascadeNode);
-
-$core.addMethod(
-$core.method({
-selector: "valueForReceiver:",
-protocol: 'building',
-fn: function (anObject){
-var self=this;
-var nds;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-nds=self._nodes();
-$recv(nds)._at_put_((1),$recv($recv(nds)._first())._valueForReceiver_(anObject));
-self._nodes_(nds);
-return self;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"valueForReceiver:",{anObject:anObject,nds:nds},$globals.CascadeNode)});
-//>>excludeEnd("ctx");
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["anObject"],
-source: "valueForReceiver: anObject\x0a\x09| nds |\x0a\x09nds := self nodes.\x0a\x09nds at: 1 put: (nds first valueForReceiver: anObject).\x0a\x09self nodes: nds.\x0a\x09^ self",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: ["nodes", "at:put:", "valueForReceiver:", "first", "nodes:"]
-}),
-$globals.CascadeNode);
-
-
-
 $core.addClass('SendNode', $globals.QuasiSendNode, ['selector', 'arguments', 'index'], 'Compiler-AST');
 //>>excludeStart("ide", pragmas.excludeIdeData);
 $globals.SendNode.comment="I represent an message send node.";

+ 31 - 30
src/Compiler-AST.st

@@ -311,6 +311,34 @@ accept: aVisitor
 	^ aVisitor visitBlockNode: self
 ! !
 
+Node subclass: #CascadeNode
+	instanceVariableNames: 'receiver'
+	package: 'Compiler-AST'!
+!CascadeNode commentStamp!
+I represent an cascade node.!
+
+!CascadeNode methodsFor: 'accessing'!
+
+receiver
+	^ receiver
+!
+
+receiver: anObject
+	receiver := anObject
+! !
+
+!CascadeNode methodsFor: 'testing'!
+
+isCascadeNode
+	^ true
+! !
+
+!CascadeNode methodsFor: 'visiting'!
+
+accept: aVisitor
+	^ aVisitor visitCascadeNode: self
+! !
+
 Node subclass: #DynamicArrayNode
 	instanceVariableNames: ''
 	package: 'Compiler-AST'!
@@ -440,9 +468,10 @@ Node subclass: #QuasiSendNode
 	instanceVariableNames: 'receiver'
 	package: 'Compiler-AST'!
 !QuasiSendNode commentStamp!
-I am a node that has a receiver.
+I am a node that has a receiver
+and with building API `#valueForReceiver:`.
 
-My subclasses are `SendNode`, `CascadeNode` and `BranchSendNode`.!
+My subclasses are `SendNode` and `BranchSendNode`.!
 
 !QuasiSendNode methodsFor: 'accessing'!
 
@@ -479,34 +508,6 @@ accept: aVisitor
 	^ aVisitor visitBranchSendNode: self
 ! !
 
-QuasiSendNode subclass: #CascadeNode
-	instanceVariableNames: ''
-	package: 'Compiler-AST'!
-!CascadeNode commentStamp!
-I represent an cascade node.!
-
-!CascadeNode methodsFor: 'building'!
-
-valueForReceiver: anObject
-	| nds |
-	nds := self nodes.
-	nds at: 1 put: (nds first valueForReceiver: anObject).
-	self nodes: nds.
-	^ self
-! !
-
-!CascadeNode methodsFor: 'testing'!
-
-isCascadeNode
-	^ true
-! !
-
-!CascadeNode methodsFor: 'visiting'!
-
-accept: aVisitor
-	^ aVisitor visitCascadeNode: self
-! !
-
 QuasiSendNode subclass: #SendNode
 	instanceVariableNames: 'selector arguments index'
 	package: 'Compiler-AST'!

File diff suppressed because it is too large
+ 220 - 155
support/parser.js


+ 9 - 9
support/parser.pegjs

@@ -164,20 +164,20 @@ block          = '[' params:wsBlockParamList? sequence:wsSequenceWs? ']' {
 
 operand        = literal / reference / subexpression
 
-augment = "(" send:(wsBinaryTail / wsKeywordMessage / wsUnaryTail) messages:(ws ";" mess:wsMessage {return mess;})* ws ")" {
-                     if (messages.length) {
-                         messages.unshift(send);
-                         send = $globals.CascadeNode._new()
-                                ._location_(location())
-                                ._source_(text())
-                                ._nodes_(messages);
-					 }
+augment = "(" send:(wsBinaryTail / wsKeywordMessage / wsUnaryTail) ws ")" {
 					 return send._asBranchSendNode()
                             ._location_(location())
                             ._source_(text());
                  }
 
-wsAugmentTail      = ws message:augment tail:wsAugmentTail? {
+augmentCascade = "(" first:wsMessage rest:(ws ";" mess:wsMessage {return mess;})+ ws ")" {
+					 var send = rest.reduce(function (prev, curr) {
+					        return curr._asBranchSendNode()._valueForReceiver_(prev);
+					 }, first._asBranchSendNode());
+					 return send;
+                 }
+
+wsAugmentTail      = ws message:(augment / augmentCascade) tail:wsAugmentTail? {
                      if(tail) {
                          return tail._valueForReceiver_(message);
                      }

Some files were not shown because too many files changed in this diff