Browse Source

Compiler: ExpressionNode, group expression nodes.

Herby Vojčík 4 years ago
parent
commit
fe2304fa41
4 changed files with 645 additions and 519 deletions
  1. 379 265
      lang/src/Compiler-AST.js
  2. 199 189
      lang/src/Compiler-AST.st
  3. 53 53
      lang/src/Compiler-IR.js
  4. 14 12
      lang/src/Compiler-IR.st

File diff suppressed because it is too large
+ 379 - 265
lang/src/Compiler-AST.js


+ 199 - 189
lang/src/Compiler-AST.st

@@ -1,6 +1,6 @@
 Smalltalk createPackage: 'Compiler-AST'!
 DagParentNode subclass: #ASTNode
-	slots: {#parent. #position. #source. #shouldBeAliased}
+	slots: {#parent. #position. #source}
 	package: 'Compiler-AST'!
 !ASTNode commentStamp!
 I am the abstract root class of the abstract syntax tree.
@@ -60,14 +60,6 @@ positionStart
 	^ self position
 !
 
-shouldBeAliased
-	^ shouldBeAliased ifNil: [ false ]
-!
-
-shouldBeAliased: aBoolean
-	shouldBeAliased := aBoolean
-!
-
 size
 	^ self source size
 !
@@ -80,19 +72,6 @@ source: aString
 	source := aString
 ! !
 
-!ASTNode methodsFor: 'building'!
-
-withTail: aCollection
-	^ aCollection inject: self into: [
-		:receiver :send | SendNode new
-			position: send position;
-			source: send source;
-			receiver: receiver;
-			selector: send selector;
-			arguments: send arguments;
-			yourself ]
-! !
-
 !ASTNode methodsFor: 'testing'!
 
 inPosition: aPoint
@@ -100,10 +79,6 @@ inPosition: aPoint
 		self positionEnd >= aPoint ])
 !
 
-isImmutable
-	^ false
-!
-
 isNavigationNode
 	"Answer true if the node can be navigated to"
 	
@@ -112,13 +87,48 @@ isNavigationNode
 
 isReturnNode
 	^ false
+! !
+
+ASTNode subclass: #ExpressionNode
+	slots: {#shouldBeAliased}
+	package: 'Compiler-AST'!
+!ExpressionNode commentStamp!
+I am the abstract root class for expression nodes.!
+
+!ExpressionNode methodsFor: 'accessing'!
+
+shouldBeAliased
+	^ shouldBeAliased ifNil: [ false ]
+!
+
+shouldBeAliased: aBoolean
+	shouldBeAliased := aBoolean
+! !
+
+!ExpressionNode methodsFor: 'building'!
+
+withTail: aCollection
+	^ aCollection inject: self into: [
+		:receiver :send | SendNode new
+			position: send position;
+			source: send source;
+			receiver: receiver;
+			selector: send selector;
+			arguments: send arguments;
+			yourself ]
+! !
+
+!ExpressionNode methodsFor: 'testing'!
+
+isImmutable
+	^ false
 !
 
 isSuper
 	^ false
 ! !
 
-ASTNode subclass: #AssignmentNode
+ExpressionNode subclass: #AssignmentNode
 	slots: {#left. #right}
 	package: 'Compiler-AST'!
 !AssignmentNode commentStamp!
@@ -152,7 +162,7 @@ acceptDagVisitor: aVisitor
 	^ aVisitor visitAssignmentNode: self
 ! !
 
-ASTNode subclass: #BlockNode
+ExpressionNode subclass: #BlockNode
 	slots: {#parameters. #scope. #sequenceNode}
 	package: 'Compiler-AST'!
 !BlockNode commentStamp!
@@ -194,7 +204,7 @@ acceptDagVisitor: aVisitor
 	^ aVisitor visitBlockNode: self
 ! !
 
-ASTNode subclass: #CascadeNode
+ExpressionNode subclass: #CascadeNode
 	slots: {#receiver}
 	package: 'Compiler-AST'!
 !CascadeNode commentStamp!
@@ -216,7 +226,7 @@ acceptDagVisitor: aVisitor
 	^ aVisitor visitCascadeNode: self
 ! !
 
-ASTNode subclass: #DynamicArrayNode
+ExpressionNode subclass: #DynamicArrayNode
 	slots: {}
 	package: 'Compiler-AST'!
 !DynamicArrayNode commentStamp!
@@ -228,7 +238,7 @@ acceptDagVisitor: aVisitor
 	^ aVisitor visitDynamicArrayNode: self
 ! !
 
-ASTNode subclass: #DynamicDictionaryNode
+ExpressionNode subclass: #DynamicDictionaryNode
 	slots: {}
 	package: 'Compiler-AST'!
 !DynamicDictionaryNode commentStamp!
@@ -240,6 +250,160 @@ acceptDagVisitor: aVisitor
 	^ aVisitor visitDynamicDictionaryNode: self
 ! !
 
+ExpressionNode subclass: #SendNode
+	slots: {#selector. #arguments. #receiver. #index. #isSideEffect}
+	package: 'Compiler-AST'!
+!SendNode commentStamp!
+I represent an message send node.!
+
+!SendNode methodsFor: 'accessing'!
+
+arguments
+	^ arguments ifNil: [ arguments := #() ]
+!
+
+arguments: aCollection
+	arguments := aCollection
+!
+
+beSideEffect
+	isSideEffect := true
+!
+
+dagChildren
+	self receiver ifNil: [ ^ self arguments copy ].
+	
+	^ self arguments copyWithFirst: self receiver
+!
+
+index
+	^ index
+!
+
+index: anInteger
+	index := anInteger
+!
+
+isSideEffect
+	^ isSideEffect ifNil: [ false ]
+!
+
+navigationLink
+	^ self selector
+!
+
+receiver
+	^ receiver
+!
+
+receiver: aNode
+	receiver := aNode
+!
+
+selector
+	^ selector
+!
+
+selector: aString
+	selector := aString
+!
+
+superSend
+	^ self receiver ifNil: [ false ] ifNotNil: [ :recv | recv isSuper ]
+! !
+
+!SendNode methodsFor: 'testing'!
+
+isNavigationNode
+	^ true
+! !
+
+!SendNode methodsFor: 'visiting'!
+
+acceptDagVisitor: aVisitor
+	^ aVisitor visitSendNode: self
+! !
+
+ExpressionNode subclass: #ValueNode
+	slots: {#value}
+	package: 'Compiler-AST'!
+!ValueNode commentStamp!
+I represent a value node.!
+
+!ValueNode methodsFor: 'accessing'!
+
+value
+	^ value
+!
+
+value: anObject
+	value := anObject
+! !
+
+!ValueNode methodsFor: 'testing'!
+
+isImmutable
+	^ self value isImmutable
+! !
+
+!ValueNode methodsFor: 'visiting'!
+
+acceptDagVisitor: aVisitor
+	^ aVisitor visitValueNode: self
+! !
+
+ValueNode subclass: #VariableNode
+	slots: {#assigned. #binding}
+	package: 'Compiler-AST'!
+!VariableNode commentStamp!
+I represent an variable node.!
+
+!VariableNode methodsFor: 'accessing'!
+
+alias
+	^ self binding alias
+!
+
+assigned
+	^ assigned ifNil: [ false ]
+!
+
+assigned: aBoolean
+	assigned := aBoolean
+!
+
+binding
+	^ binding
+!
+
+binding: aScopeVar
+	binding := aScopeVar
+!
+
+navigationLink
+	^ self value
+! !
+
+!VariableNode methodsFor: 'testing'!
+
+isImmutable
+	^ self binding isImmutable
+!
+
+isNavigationNode
+	^ true
+!
+
+isSuper
+	^ self binding isSuper
+! !
+
+!VariableNode methodsFor: 'visiting'!
+
+acceptDagVisitor: aVisitor
+	^ aVisitor visitVariableNode: self
+! !
+
 ASTNode subclass: #JSStatementNode
 	slots: {}
 	package: 'Compiler-AST'!
@@ -380,80 +544,6 @@ acceptDagVisitor: aVisitor
 	^ aVisitor visitReturnNode: self
 ! !
 
-ASTNode subclass: #SendNode
-	slots: {#selector. #arguments. #receiver. #index. #isSideEffect}
-	package: 'Compiler-AST'!
-!SendNode commentStamp!
-I represent an message send node.!
-
-!SendNode methodsFor: 'accessing'!
-
-arguments
-	^ arguments ifNil: [ arguments := #() ]
-!
-
-arguments: aCollection
-	arguments := aCollection
-!
-
-beSideEffect
-	isSideEffect := true
-!
-
-dagChildren
-	self receiver ifNil: [ ^ self arguments copy ].
-	
-	^ self arguments copyWithFirst: self receiver
-!
-
-index
-	^ index
-!
-
-index: anInteger
-	index := anInteger
-!
-
-isSideEffect
-	^ isSideEffect ifNil: [ false ]
-!
-
-navigationLink
-	^ self selector
-!
-
-receiver
-	^ receiver
-!
-
-receiver: aNode
-	receiver := aNode
-!
-
-selector
-	^ selector
-!
-
-selector: aString
-	selector := aString
-!
-
-superSend
-	^ self receiver ifNil: [ false ] ifNotNil: [ :recv | recv isSuper ]
-! !
-
-!SendNode methodsFor: 'testing'!
-
-isNavigationNode
-	^ true
-! !
-
-!SendNode methodsFor: 'visiting'!
-
-acceptDagVisitor: aVisitor
-	^ aVisitor visitSendNode: self
-! !
-
 ASTNode subclass: #SequenceNode
 	slots: {#temps}
 	package: 'Compiler-AST'!
@@ -488,86 +578,6 @@ acceptDagVisitor: aVisitor
 	^ aVisitor visitBlockSequenceNode: self
 ! !
 
-ASTNode subclass: #ValueNode
-	slots: {#value}
-	package: 'Compiler-AST'!
-!ValueNode commentStamp!
-I represent a value node.!
-
-!ValueNode methodsFor: 'accessing'!
-
-value
-	^ value
-!
-
-value: anObject
-	value := anObject
-! !
-
-!ValueNode methodsFor: 'testing'!
-
-isImmutable
-	^ self value isImmutable
-! !
-
-!ValueNode methodsFor: 'visiting'!
-
-acceptDagVisitor: aVisitor
-	^ aVisitor visitValueNode: self
-! !
-
-ValueNode subclass: #VariableNode
-	slots: {#assigned. #binding}
-	package: 'Compiler-AST'!
-!VariableNode commentStamp!
-I represent an variable node.!
-
-!VariableNode methodsFor: 'accessing'!
-
-alias
-	^ self binding alias
-!
-
-assigned
-	^ assigned ifNil: [ false ]
-!
-
-assigned: aBoolean
-	assigned := aBoolean
-!
-
-binding
-	^ binding
-!
-
-binding: aScopeVar
-	binding := aScopeVar
-!
-
-navigationLink
-	^ self value
-! !
-
-!VariableNode methodsFor: 'testing'!
-
-isImmutable
-	^ self binding isImmutable
-!
-
-isNavigationNode
-	^ true
-!
-
-isSuper
-	^ self binding isSuper
-! !
-
-!VariableNode methodsFor: 'visiting'!
-
-acceptDagVisitor: aVisitor
-	^ aVisitor visitVariableNode: self
-! !
-
 Object subclass: #AstPragmator
 	slots: {#methodNode}
 	package: 'Compiler-AST'!
@@ -704,14 +714,14 @@ visitVariableNode: aNode
 	^ self visitDagNode: aNode
 ! !
 
-AssignmentNode setTraitComposition: {TDerivedDagChildren} asTraitComposition!
-BlockNode setTraitComposition: {TSingleDagChild} asTraitComposition!
 JSStatementNode setTraitComposition: {TDagSink} asTraitComposition!
 MethodNode setTraitComposition: {TSingleDagChild} asTraitComposition!
 ReturnNode setTraitComposition: {TSingleDagChild} asTraitComposition!
-SendNode setTraitComposition: {TDerivedDagChildren} asTraitComposition!
-ValueNode setTraitComposition: {TDagSink} asTraitComposition!
 AstPragmator setTraitComposition: {TPragmator} asTraitComposition!
+ValueNode setTraitComposition: {TDagSink} asTraitComposition!
+SendNode setTraitComposition: {TDerivedDagChildren} asTraitComposition!
+BlockNode setTraitComposition: {TSingleDagChild} asTraitComposition!
+AssignmentNode setTraitComposition: {TDerivedDagChildren} asTraitComposition!
 ! !
 
 !CompiledMethod methodsFor: '*Compiler-AST'!

+ 53 - 53
lang/src/Compiler-IR.js

@@ -45,22 +45,22 @@ $core.method({
 selector: "alias:",
 protocol: "visiting",
 //>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["aNode"],
-source: "alias: aNode\x0a\x09| variable |\x0a\x0a\x09aNode isImmutable ifTrue: [ ^ self visit: aNode ].\x0a\x0a\x09variable := IRVariable new\x0a\x09\x09variable: (AliasVar new name: '$', self nextAlias);\x0a\x09\x09yourself.\x0a\x0a\x09self addToSequence: (IRAssignment new\x0a\x09\x09add: variable;\x0a\x09\x09add: (self visit: aNode);\x0a\x09\x09yourself).\x0a\x0a\x09self method internalVariables add: variable.\x0a\x0a\x09^ variable",
+args: ["anExpressionNode"],
+source: "alias: anExpressionNode\x0a\x09| variable |\x0a\x0a\x09anExpressionNode isImmutable ifTrue: [ ^ self visit: anExpressionNode ].\x0a\x0a\x09variable := IRVariable new\x0a\x09\x09variable: (AliasVar new name: '$', self nextAlias);\x0a\x09\x09yourself.\x0a\x0a\x09self addToSequence: (IRAssignment new\x0a\x09\x09add: variable;\x0a\x09\x09add: (self visit: anExpressionNode);\x0a\x09\x09yourself).\x0a\x0a\x09self method internalVariables add: variable.\x0a\x0a\x09^ variable",
 referencedClasses: ["IRVariable", "AliasVar", "IRAssignment"],
 //>>excludeEnd("ide");
 pragmas: [],
 messageSends: ["ifTrue:", "isImmutable", "visit:", "variable:", "new", "name:", ",", "nextAlias", "yourself", "addToSequence:", "add:", "internalVariables", "method"]
-}, function ($methodClass){ return function (aNode){
+}, function ($methodClass){ return function (anExpressionNode){
 var self=this,$self=this;
 var variable;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
 var $1,$2,$4,$3;
-$1=$recv(aNode)._isImmutable();
+$1=$recv(anExpressionNode)._isImmutable();
 if($core.assert($1)){
-return [$self._visit_(aNode)
+return [$self._visit_(anExpressionNode)
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 ,$ctx1.sendIdx["visit:"]=1
 //>>excludeEnd("ctx");
@@ -87,7 +87,7 @@ $4=$recv($globals.IRAssignment)._new();
 ,$ctx1.sendIdx["add:"]=1
 //>>excludeEnd("ctx");
 ][0];
-[$recv($4)._add_($self._visit_(aNode))
+[$recv($4)._add_($self._visit_(anExpressionNode))
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 ,$ctx1.sendIdx["add:"]=2
 //>>excludeEnd("ctx");
@@ -97,7 +97,7 @@ $self._addToSequence_($3);
 $recv($recv($self._method())._internalVariables())._add_(variable);
 return variable;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"alias:",{aNode:aNode,variable:variable})});
+}, function($ctx1) {$ctx1.fill(self,"alias:",{anExpressionNode:anExpressionNode,variable:variable})});
 //>>excludeEnd("ctx");
 }; }),
 $globals.IRASTTranslator);
@@ -899,26 +899,26 @@ $core.method({
 selector: "visitOrAlias:",
 protocol: "visiting",
 //>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["aNode"],
-source: "visitOrAlias: aNode\x0a\x09^ aNode shouldBeAliased\x0a\x09\x09ifTrue: [ self alias: aNode ]\x0a\x09\x09ifFalse: [ self visit: aNode ]",
+args: ["anExpressionNode"],
+source: "visitOrAlias: anExpressionNode\x0a\x09^ anExpressionNode shouldBeAliased\x0a\x09\x09ifTrue: [ self alias: anExpressionNode ]\x0a\x09\x09ifFalse: [ self visit: anExpressionNode ]",
 referencedClasses: [],
 //>>excludeEnd("ide");
 pragmas: [],
 messageSends: ["ifTrue:ifFalse:", "shouldBeAliased", "alias:", "visit:"]
-}, function ($methodClass){ return function (aNode){
+}, function ($methodClass){ return function (anExpressionNode){
 var self=this,$self=this;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
 var $1;
-$1=$recv(aNode)._shouldBeAliased();
+$1=$recv(anExpressionNode)._shouldBeAliased();
 if($core.assert($1)){
-return $self._alias_(aNode);
+return $self._alias_(anExpressionNode);
 } else {
-return $self._visit_(aNode);
+return $self._visit_(anExpressionNode);
 }
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"visitOrAlias:",{aNode:aNode})});
+}, function($ctx1) {$ctx1.fill(self,"visitOrAlias:",{anExpressionNode:anExpressionNode})});
 //>>excludeEnd("ctx");
 }; }),
 $globals.IRASTTranslator);
@@ -5865,45 +5865,6 @@ return $recv(each)._requiresSmalltalkContext();
 }; }),
 $globals.ASTNode);
 
-$core.addMethod(
-$core.method({
-selector: "subtreeNeedsAliasing",
-protocol: "*Compiler-IR",
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: [],
-source: "subtreeNeedsAliasing\x0a\x09^ self shouldBeAliased or: [\x0a\x09\x09self dagChildren anySatisfy: [ :each | each subtreeNeedsAliasing ] ]",
-referencedClasses: [],
-//>>excludeEnd("ide");
-pragmas: [],
-messageSends: ["or:", "shouldBeAliased", "anySatisfy:", "dagChildren", "subtreeNeedsAliasing"]
-}, function ($methodClass){ return function (){
-var self=this,$self=this;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-return $recv($self._shouldBeAliased())._or_((function(){
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx2) {
-//>>excludeEnd("ctx");
-return $recv($self._dagChildren())._anySatisfy_((function(each){
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx3) {
-//>>excludeEnd("ctx");
-return $recv(each)._subtreeNeedsAliasing();
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx2,2)});
-//>>excludeEnd("ctx");
-}));
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)});
-//>>excludeEnd("ctx");
-}));
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"subtreeNeedsAliasing",{})});
-//>>excludeEnd("ctx");
-}; }),
-$globals.ASTNode);
-
 $core.addMethod(
 $core.method({
 selector: "subtreeNeedsAliasing",
@@ -5963,6 +5924,45 @@ return true;
 }; }),
 $globals.CascadeNode);
 
+$core.addMethod(
+$core.method({
+selector: "subtreeNeedsAliasing",
+protocol: "*Compiler-IR",
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "subtreeNeedsAliasing\x0a\x09^ self shouldBeAliased or: [\x0a\x09\x09self dagChildren anySatisfy: [ :each | each subtreeNeedsAliasing ] ]",
+referencedClasses: [],
+//>>excludeEnd("ide");
+pragmas: [],
+messageSends: ["or:", "shouldBeAliased", "anySatisfy:", "dagChildren", "subtreeNeedsAliasing"]
+}, function ($methodClass){ return function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv($self._shouldBeAliased())._or_((function(){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv($self._dagChildren())._anySatisfy_((function(each){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx3) {
+//>>excludeEnd("ctx");
+return $recv(each)._subtreeNeedsAliasing();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx2,2)});
+//>>excludeEnd("ctx");
+}));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"subtreeNeedsAliasing",{})});
+//>>excludeEnd("ctx");
+}; }),
+$globals.ExpressionNode);
+
 $core.addMethod(
 $core.method({
 selector: "requiresSmalltalkContext",

+ 14 - 12
lang/src/Compiler-IR.st

@@ -63,10 +63,10 @@ addToSequence: anInstruction
 	^ anInstruction
 !
 
-alias: aNode
+alias: anExpressionNode
 	| variable |
 
-	aNode isImmutable ifTrue: [ ^ self visit: aNode ].
+	anExpressionNode isImmutable ifTrue: [ ^ self visit: anExpressionNode ].
 
 	variable := IRVariable new
 		variable: (AliasVar new name: '$', self nextAlias);
@@ -74,7 +74,7 @@ alias: aNode
 
 	self addToSequence: (IRAssignment new
 		add: variable;
-		add: (self visit: aNode);
+		add: (self visit: anExpressionNode);
 		yourself).
 
 	self method internalVariables add: variable.
@@ -212,10 +212,10 @@ visitMethodNode: aNode
 	^ self method
 !
 
-visitOrAlias: aNode
-	^ aNode shouldBeAliased
-		ifTrue: [ self alias: aNode ]
-		ifFalse: [ self visit: aNode ]
+visitOrAlias: anExpressionNode
+	^ anExpressionNode shouldBeAliased
+		ifTrue: [ self alias: anExpressionNode ]
+		ifFalse: [ self visit: anExpressionNode ]
 !
 
 visitReturnNode: aNode
@@ -1334,11 +1334,6 @@ requiresSmalltalkContext
 	See `IRJSTranslator` and `JSStream` for context creation"
 	
 	^ self dagChildren anySatisfy: [ :each | each requiresSmalltalkContext ]
-!
-
-subtreeNeedsAliasing
-	^ self shouldBeAliased or: [
-		self dagChildren anySatisfy: [ :each | each subtreeNeedsAliasing ] ]
 ! !
 
 !AssignmentNode methodsFor: '*Compiler-IR'!
@@ -1359,6 +1354,13 @@ subtreeNeedsAliasing
 	^ true
 ! !
 
+!ExpressionNode methodsFor: '*Compiler-IR'!
+
+subtreeNeedsAliasing
+	^ self shouldBeAliased or: [
+		self dagChildren anySatisfy: [ :each | each subtreeNeedsAliasing ] ]
+! !
+
 !JSStatementNode methodsFor: '*Compiler-IR'!
 
 requiresSmalltalkContext

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