Browse Source

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 8 years ago
parent
commit
79d886744f
4 changed files with 345 additions and 269 deletions
  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