Browse Source

Move pragmas to MethodNode.

Herby Vojčík 5 years ago
parent
commit
18bf800931

+ 4 - 4
lang/base/parser.js

@@ -294,10 +294,9 @@ define(["./boot"], function($boot) {
         	},
         peg$c101 = function(expressions) {return expressions || [];},
         peg$c102 = function(aPragmas, temps, zPragmas, statements) {
-        	return newNode($globals.SequenceNode)
+        	return [newNode($globals.SequenceNode)
         		._temps_(temps || [])
-        		._pragmas_((aPragmas || []).concat(zPragmas || []))
-        		._dagChildren_(statements || []);
+        		._dagChildren_(statements || []), (aPragmas || []).concat(zPragmas || [])];
         },
         peg$c103 = function(temps, statements) {
         	return newNode($globals.BlockSequenceNode)
@@ -346,7 +345,8 @@ define(["./boot"], function($boot) {
         		return newNode($globals.MethodNode)
         			._selector_(pattern[0])
         			._arguments_(pattern[1])
-        			._dagChildren_([sequence]);
+        			._pragmas_(sequence[1])
+        			._dagChildren_([sequence[0]]);
         	},
         peg$c121 = function(receiver, tail) { return tail.length > 0 && tail[tail.length-1]._selector() === '->' },
         peg$c122 = function(receiver, tail) {

+ 4 - 4
lang/base/parser.pegjs

@@ -179,10 +179,9 @@ wsStatements =
 	expressions:wsExpressions? {return expressions || [];}
 
 wsSequenceWs = aPragmas:wsPragmas? ws temps:temps? zPragmas:wsPragmas? statements:wsStatements? maybeDotsWs {
-	return newNode($globals.SequenceNode)
+	return [newNode($globals.SequenceNode)
 		._temps_(temps || [])
-		._pragmas_((aPragmas || []).concat(zPragmas || []))
-		._dagChildren_(statements || []);
+		._dagChildren_(statements || []), (aPragmas || []).concat(zPragmas || [])];
 }
 
 wsBlockSequenceWs = ws temps:temps? statements:wsStatements? maybeDotsWs {
@@ -252,7 +251,8 @@ method =
 		return newNode($globals.MethodNode)
 			._selector_(pattern[0])
 			._arguments_(pattern[1])
-			._dagChildren_([sequence]);
+			._pragmas_(sequence[1])
+			._dagChildren_([sequence[0]]);
 	}
 
 associationSend =

+ 246 - 74
lang/src/Compiler-AST.js

@@ -1240,7 +1240,7 @@ $globals.JSStatementNode);
 
 
 
-$core.addClass("MethodNode", $globals.ASTNode, ["selector", "arguments", "source", "scope", "classReferences", "sendIndexes"], "Compiler-AST");
+$core.addClass("MethodNode", $globals.ASTNode, ["selector", "arguments", "source", "pragmas", "scope", "classReferences", "sendIndexes"], "Compiler-AST");
 //>>excludeStart("ide", pragmas.excludeIdeData);
 $globals.MethodNode.comment="I represent an method node.\x0a\x0aA method node must be the root and only method node of a valid AST.";
 //>>excludeEnd("ide");
@@ -1393,6 +1393,54 @@ messageSends: []
 }),
 $globals.MethodNode);
 
+$core.addMethod(
+$core.method({
+selector: "pragmas",
+protocol: "accessing",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1,$receiver;
+$1=$self.pragmas;
+if(($receiver = $1) == null || $receiver.a$nil){
+return [];
+} else {
+return $1;
+}
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"pragmas",{},$globals.MethodNode)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "pragmas\x0a\x09^ pragmas ifNil: [ #() ]",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["ifNil:"]
+}),
+$globals.MethodNode);
+
+$core.addMethod(
+$core.method({
+selector: "pragmas:",
+protocol: "accessing",
+fn: function (aCollection){
+var self=this,$self=this;
+$self.pragmas=aCollection;
+return self;
+
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aCollection"],
+source: "pragmas: aCollection\x0a\x09pragmas := aCollection",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.MethodNode);
+
 $core.addMethod(
 $core.method({
 selector: "scope",
@@ -2080,7 +2128,7 @@ $globals.SendNode);
 
 
 
-$core.addClass("SequenceNode", $globals.ASTNode, ["temps", "pragmas", "scope"], "Compiler-AST");
+$core.addClass("SequenceNode", $globals.ASTNode, ["temps", "scope"], "Compiler-AST");
 //>>excludeStart("ide", pragmas.excludeIdeData);
 $globals.SequenceNode.comment="I represent an sequence node. A sequence represent a set of instructions inside the same scope (the method scope or a block scope).";
 //>>excludeEnd("ide");
@@ -2125,54 +2173,6 @@ messageSends: []
 }),
 $globals.SequenceNode);
 
-$core.addMethod(
-$core.method({
-selector: "pragmas",
-protocol: "accessing",
-fn: function (){
-var self=this,$self=this;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-var $1,$receiver;
-$1=$self.pragmas;
-if(($receiver = $1) == null || $receiver.a$nil){
-return [];
-} else {
-return $1;
-}
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"pragmas",{},$globals.SequenceNode)});
-//>>excludeEnd("ctx");
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: [],
-source: "pragmas\x0a\x09^ pragmas ifNil: [ #() ]",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: ["ifNil:"]
-}),
-$globals.SequenceNode);
-
-$core.addMethod(
-$core.method({
-selector: "pragmas:",
-protocol: "accessing",
-fn: function (aCollection){
-var self=this,$self=this;
-$self.pragmas=aCollection;
-return self;
-
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["aCollection"],
-source: "pragmas: aCollection\x0a\x09pragmas := aCollection",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: []
-}),
-$globals.SequenceNode);
-
 $core.addMethod(
 $core.method({
 selector: "scope",
@@ -2305,30 +2305,6 @@ messageSends: []
 }),
 $globals.BlockSequenceNode);
 
-$core.addMethod(
-$core.method({
-selector: "pragmas:",
-protocol: "visiting",
-fn: function (aCollection){
-var self=this,$self=this;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-$self._shouldNotImplement();
-return self;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"pragmas:",{aCollection:aCollection},$globals.BlockSequenceNode)});
-//>>excludeEnd("ctx");
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["aCollection"],
-source: "pragmas: aCollection\x0a\x09self shouldNotImplement",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: ["shouldNotImplement"]
-}),
-$globals.BlockSequenceNode);
-
 
 
 $core.addClass("ValueNode", $globals.ASTNode, ["value"], "Compiler-AST");
@@ -3108,6 +3084,202 @@ messageSends: ["visitDagNode:"]
 $globals.NodeVisitor);
 
 
+
+$core.addClass("AstPragmator", $globals.NodeVisitor, ["methodNode"], "Compiler-AST");
+//>>excludeStart("ide", pragmas.excludeIdeData);
+$globals.AstPragmator.comment="I am abstract superclass for pragma-processing transformer.\x0a\x0aMy subclasses should implement messages for each pragma\x0athey process. Pragma processing checks if a message is known\x0ato a class but not to its superclass. IOW, each and only those\x0apragmas are processed which are defined as methods in the subclass.\x0a\x0aThese messages can access sequence node in which\x0aa pragma occurred and its containing method node\x0aas `self sequenceNode` and `self methodNode`.\x0a\x0aSee `EarlyPragmator` for an example.";
+//>>excludeEnd("ide");
+$core.addMethod(
+$core.method({
+selector: "canProcessPragma:",
+protocol: "pragma processing",
+fn: function (aMessage){
+var self=this,$self=this;
+var selector;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+selector=$recv(aMessage)._selector();
+return $recv($self._respondsTo_(selector))._and_((function(){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv($recv($recv($self._class())._superclass())._canUnderstand_(selector))._not();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"canProcessPragma:",{aMessage:aMessage,selector:selector},$globals.AstPragmator)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aMessage"],
+source: "canProcessPragma: aMessage\x0a\x09| selector |\x0a\x09selector := aMessage selector.\x0a\x09^ (self respondsTo: selector) and: [\x0a\x09\x09(self class superclass canUnderstand: selector) not]",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["selector", "and:", "respondsTo:", "not", "canUnderstand:", "superclass", "class"]
+}),
+$globals.AstPragmator);
+
+$core.addMethod(
+$core.method({
+selector: "methodNode",
+protocol: "accessing",
+fn: function (){
+var self=this,$self=this;
+return $self.methodNode;
+
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "methodNode\x0a\x09^ methodNode",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.AstPragmator);
+
+$core.addMethod(
+$core.method({
+selector: "methodNode:",
+protocol: "accessing",
+fn: function (anObject){
+var self=this,$self=this;
+$self.methodNode=anObject;
+return self;
+
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["anObject"],
+source: "methodNode: anObject\x0a\x09methodNode := anObject",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: []
+}),
+$globals.AstPragmator);
+
+$core.addMethod(
+$core.method({
+selector: "processPragma:",
+protocol: "pragma processing",
+fn: function (aMessage){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1;
+$1=$self._canProcessPragma_(aMessage);
+if($core.assert($1)){
+return $recv(aMessage)._sendTo_(self);
+}
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"processPragma:",{aMessage:aMessage},$globals.AstPragmator)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aMessage"],
+source: "processPragma: aMessage\x0a\x09(self canProcessPragma: aMessage) ifTrue: [\x0a\x09\x09^ aMessage sendTo: self ]",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["ifTrue:", "canProcessPragma:", "sendTo:"]
+}),
+$globals.AstPragmator);
+
+$core.addMethod(
+$core.method({
+selector: "visitMethodNode:",
+protocol: "pragma processing",
+fn: function (aNode){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1;
+$self._methodNode_(aNode);
+$recv($recv(aNode)._pragmas())._do_((function(each){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $self._processPragma_(each);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+$1=(
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.supercall = true,
+//>>excludeEnd("ctx");
+($globals.AstPragmator.superclass||$boot.nilAsClass).fn.prototype._visitMethodNode_.apply($self, [aNode]));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.supercall = false;
+//>>excludeEnd("ctx");;
+return $1;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"visitMethodNode:",{aNode:aNode},$globals.AstPragmator)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aNode"],
+source: "visitMethodNode: aNode\x0a\x09self methodNode: aNode.\x0a\x09aNode pragmas do: [ :each | self processPragma: each ].\x0a\x09^ super visitMethodNode: aNode",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["methodNode:", "do:", "pragmas", "processPragma:", "visitMethodNode:"]
+}),
+$globals.AstPragmator);
+
+
+
+$core.addClass("AstEarlyPragmator", $globals.AstPragmator, [], "Compiler-AST");
+$core.addMethod(
+$core.method({
+selector: "inlineJS:",
+protocol: "pragmas",
+fn: function (aString){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $3,$2,$1,$4,$6,$5;
+$3=$self._methodNode();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["methodNode"]=1;
+//>>excludeEnd("ctx");
+$2=$recv($3)._sequenceNode();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["sequenceNode"]=1;
+//>>excludeEnd("ctx");
+$1=$recv($2)._dagChildren();
+$recv($1)._ifNotEmpty_((function(){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv($globals.CompilerError)._signal_("There must be no other code or code generator pragma than a lone inlineJS:");
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+$4=$recv($self._methodNode())._sequenceNode();
+$6=$recv($globals.JSStatementNode)._new();
+$recv($6)._source_(aString);
+$5=$recv($6)._yourself();
+$recv($4)._addDagChild_($5);
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"inlineJS:",{aString:aString},$globals.AstEarlyPragmator)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aString"],
+source: "inlineJS: aString\x0a\x09self methodNode sequenceNode dagChildren ifNotEmpty: [\x0a\x09\x09CompilerError signal: 'There must be no other code or code generator pragma than a lone inlineJS:' ].\x0a\x09self methodNode sequenceNode addDagChild: (\x0a\x09\x09JSStatementNode new\x0a\x09\x09\x09source: aString;\x0a\x09\x09\x09yourself)",
+referencedClasses: ["CompilerError", "JSStatementNode"],
+//>>excludeEnd("ide");
+messageSends: ["ifNotEmpty:", "dagChildren", "sequenceNode", "methodNode", "signal:", "addDagChild:", "source:", "new", "yourself"]
+}),
+$globals.AstEarlyPragmator);
+
+
 $core.addMethod(
 $core.method({
 selector: "ast",

+ 72 - 14
lang/src/Compiler-AST.st

@@ -321,7 +321,7 @@ acceptDagVisitor: aVisitor
 ! !
 
 ASTNode subclass: #MethodNode
-	slots: {#selector. #arguments. #source. #scope. #classReferences. #sendIndexes}
+	slots: {#selector. #arguments. #source. #pragmas. #scope. #classReferences. #sendIndexes}
 	package: 'Compiler-AST'!
 !MethodNode commentStamp!
 I represent an method node.
@@ -354,6 +354,14 @@ method
 	^ self
 !
 
+pragmas
+	^ pragmas ifNil: [ #() ]
+!
+
+pragmas: aCollection
+	pragmas := aCollection
+!
+
 scope
 	^ scope
 !
@@ -516,21 +524,13 @@ acceptDagVisitor: aVisitor
 ! !
 
 ASTNode subclass: #SequenceNode
-	slots: {#temps. #pragmas. #scope}
+	slots: {#temps. #scope}
 	package: 'Compiler-AST'!
 !SequenceNode commentStamp!
 I represent an sequence node. A sequence represent a set of instructions inside the same scope (the method scope or a block scope).!
 
 !SequenceNode methodsFor: 'accessing'!
 
-pragmas
-	^ pragmas ifNil: [ #() ]
-!
-
-pragmas: aCollection
-	pragmas := aCollection
-!
-
 scope
 	^ scope
 !
@@ -575,10 +575,6 @@ isBlockSequenceNode
 
 acceptDagVisitor: aVisitor
 	^ aVisitor visitBlockSequenceNode: self
-!
-
-pragmas: aCollection
-	self shouldNotImplement
 ! !
 
 ASTNode subclass: #ValueNode
@@ -764,6 +760,68 @@ visitVariableNode: aNode
 	^ self visitDagNode: aNode
 ! !
 
+NodeVisitor subclass: #AstPragmator
+	slots: {#methodNode}
+	package: 'Compiler-AST'!
+!AstPragmator commentStamp!
+I am abstract superclass for pragma-processing transformer.
+
+My subclasses should implement messages for each pragma
+they process. Pragma processing checks if a message is known
+to a class but not to its superclass. IOW, each and only those
+pragmas are processed which are defined as methods in the subclass.
+
+These messages can access sequence node in which
+a pragma occurred and its containing method node
+as `self sequenceNode` and `self methodNode`.
+
+See `EarlyPragmator` for an example.!
+
+!AstPragmator methodsFor: 'accessing'!
+
+methodNode
+	^ methodNode
+!
+
+methodNode: anObject
+	methodNode := anObject
+! !
+
+!AstPragmator methodsFor: 'pragma processing'!
+
+canProcessPragma: aMessage
+	| selector |
+	selector := aMessage selector.
+	^ (self respondsTo: selector) and: [
+		(self class superclass canUnderstand: selector) not]
+!
+
+processPragma: aMessage
+	(self canProcessPragma: aMessage) ifTrue: [
+		^ aMessage sendTo: self ]
+!
+
+visitMethodNode: aNode
+	self methodNode: aNode.
+	aNode pragmas do: [ :each | self processPragma: each ].
+	^ super visitMethodNode: aNode
+! !
+
+AstPragmator subclass: #AstEarlyPragmator
+	slots: {}
+	package: 'Compiler-AST'!
+
+!AstEarlyPragmator methodsFor: 'pragmas'!
+
+inlineJS: aString
+	self methodNode sequenceNode dagChildren ifNotEmpty: [
+		CompilerError signal: 'There must be no other code or code generator pragma than a lone inlineJS:' ].
+	self methodNode sequenceNode addDagChild: (
+		JSStatementNode new
+			source: aString;
+			yourself)
+! !
+
 !CompiledMethod methodsFor: '*Compiler-AST'!
 
 ast

+ 28 - 227
lang/src/Compiler-Core.js

@@ -1,4 +1,4 @@
-define(["amber/boot", "require", "amber/core/Compiler-AST", "amber/core/Kernel-Collections", "amber/core/Kernel-Objects"], function($boot,requirejs){"use strict";
+define(["amber/boot", "require", "amber/core/Kernel-Collections", "amber/core/Kernel-Objects"], function($boot,requirejs){"use strict";
 var $core=$boot.api,nil=$boot.nilAsValue,$nil=$boot.nilAsReceiver,$recv=$boot.asReceiver,$globals=$boot.globals;
 var $pkg = $core.addPackage("Compiler-Core");
 $pkg.innerEval = function (expr) { return eval(expr); };
@@ -247,6 +247,29 @@ $core.addClass("CodeGenerator", $globals.AbstractCodeGenerator, ["transformersDi
 //>>excludeStart("ide", pragmas.excludeIdeData);
 $globals.CodeGenerator.comment="I am a basic code generator. I generate a valid JavaScript output, but no not perform any inlining.\x0aSee `InliningCodeGenerator` for an optimized JavaScript code generation.";
 //>>excludeEnd("ide");
+$core.addMethod(
+$core.method({
+selector: "earlyAstPragmator",
+protocol: "compiling",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+return $recv($globals.AstEarlyPragmator)._new();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"earlyAstPragmator",{},$globals.CodeGenerator)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "earlyAstPragmator\x0a\x09^ AstEarlyPragmator new",
+referencedClasses: ["AstEarlyPragmator"],
+//>>excludeEnd("ide");
+messageSends: ["new"]
+}),
+$globals.CodeGenerator);
+
 $core.addMethod(
 $core.method({
 selector: "irTranslator",
@@ -330,10 +353,7 @@ var $1,$2,$receiver;
 $1=$self.transformersDictionary;
 if(($receiver = $1) == null || $receiver.a$nil){
 $2=$recv($globals.Dictionary)._new();
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx["new"]=1;
-//>>excludeEnd("ctx");
-$recv($2)._at_put_("1000-earlyPragmas",$recv($globals.EarlyPragmator)._new());
+$recv($2)._at_put_("1000-earlyPragmas",$self._earlyAstPragmator());
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["at:put:"]=1;
 //>>excludeEnd("ctx");
@@ -357,10 +377,10 @@ return $1;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: [],
-source: "transformersDictionary\x0a\x09^ transformersDictionary ifNil: [ transformersDictionary := Dictionary new\x0a\x09\x09at: '1000-earlyPragmas' put: EarlyPragmator new;\x0a\x09\x09at: '2000-semantic' put: self semanticAnalyzer;\x0a\x09\x09at: '5000-astToIr' put: self translator;\x0a\x09\x09at: '8000-irToJs' put: self irTranslator;\x0a\x09\x09yourself ]",
-referencedClasses: ["Dictionary", "EarlyPragmator"],
+source: "transformersDictionary\x0a\x09^ transformersDictionary ifNil: [ transformersDictionary := Dictionary new\x0a\x09\x09at: '1000-earlyPragmas' put: self earlyAstPragmator;\x0a\x09\x09at: '2000-semantic' put: self semanticAnalyzer;\x0a\x09\x09at: '5000-astToIr' put: self translator;\x0a\x09\x09at: '8000-irToJs' put: self irTranslator;\x0a\x09\x09yourself ]",
+referencedClasses: ["Dictionary"],
 //>>excludeEnd("ide");
-messageSends: ["ifNil:", "at:put:", "new", "semanticAnalyzer", "translator", "irTranslator", "yourself"]
+messageSends: ["ifNil:", "at:put:", "new", "earlyAstPragmator", "semanticAnalyzer", "translator", "irTranslator", "yourself"]
 }),
 $globals.CodeGenerator);
 
@@ -1264,225 +1284,6 @@ messageSends: ["evaluate:for:", "new"]
 }),
 $globals.Evaluator.a$cls);
 
-
-$core.addClass("Pragmator", $globals.NodeVisitor, ["methodNode", "sequenceNode"], "Compiler-Core");
-//>>excludeStart("ide", pragmas.excludeIdeData);
-$globals.Pragmator.comment="I am abstract superclass for pragma-processing transformer.\x0a\x0aMy subclasses should implement messages for each pragma\x0athey process. Pragma processing checks if a message is known\x0ato a class but not to its superclass. IOW, each and only those\x0apragmas are processed which are defined as methods in the subclass.\x0a\x0aThese messages can access sequence node in which\x0aa pragma occurred and its containing method node\x0aas `self sequenceNode` and `self methodNode`.\x0a\x0aSee `EarlyPragmator` for an example.";
-//>>excludeEnd("ide");
-$core.addMethod(
-$core.method({
-selector: "canProcessPragma:",
-protocol: "pragma processing",
-fn: function (aMessage){
-var self=this,$self=this;
-var selector;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-selector=$recv(aMessage)._selector();
-return $recv($self._respondsTo_(selector))._and_((function(){
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx2) {
-//>>excludeEnd("ctx");
-return $recv($recv($recv($self._class())._superclass())._canUnderstand_(selector))._not();
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)});
-//>>excludeEnd("ctx");
-}));
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"canProcessPragma:",{aMessage:aMessage,selector:selector},$globals.Pragmator)});
-//>>excludeEnd("ctx");
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["aMessage"],
-source: "canProcessPragma: aMessage\x0a\x09| selector |\x0a\x09selector := aMessage selector.\x0a\x09^ (self respondsTo: selector) and: [\x0a\x09\x09(self class superclass canUnderstand: selector) not]",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: ["selector", "and:", "respondsTo:", "not", "canUnderstand:", "superclass", "class"]
-}),
-$globals.Pragmator);
-
-$core.addMethod(
-$core.method({
-selector: "methodNode",
-protocol: "accessing",
-fn: function (){
-var self=this,$self=this;
-return $self.methodNode;
-
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: [],
-source: "methodNode\x0a\x09^ methodNode",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: []
-}),
-$globals.Pragmator);
-
-$core.addMethod(
-$core.method({
-selector: "methodNode:",
-protocol: "accessing",
-fn: function (anObject){
-var self=this,$self=this;
-$self.methodNode=anObject;
-return self;
-
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["anObject"],
-source: "methodNode: anObject\x0a\x09methodNode := anObject",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: []
-}),
-$globals.Pragmator);
-
-$core.addMethod(
-$core.method({
-selector: "processPragma:",
-protocol: "pragma processing",
-fn: function (aMessage){
-var self=this,$self=this;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-var $1;
-$1=$self._canProcessPragma_(aMessage);
-if($core.assert($1)){
-return $recv(aMessage)._sendTo_(self);
-}
-return self;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"processPragma:",{aMessage:aMessage},$globals.Pragmator)});
-//>>excludeEnd("ctx");
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["aMessage"],
-source: "processPragma: aMessage\x0a\x09(self canProcessPragma: aMessage) ifTrue: [\x0a\x09\x09^ aMessage sendTo: self ]",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: ["ifTrue:", "canProcessPragma:", "sendTo:"]
-}),
-$globals.Pragmator);
-
-$core.addMethod(
-$core.method({
-selector: "sequenceNode",
-protocol: "accessing",
-fn: function (){
-var self=this,$self=this;
-return $self.sequenceNode;
-
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: [],
-source: "sequenceNode\x0a\x09^ sequenceNode",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: []
-}),
-$globals.Pragmator);
-
-$core.addMethod(
-$core.method({
-selector: "sequenceNode:",
-protocol: "accessing",
-fn: function (anObject){
-var self=this,$self=this;
-$self.sequenceNode=anObject;
-return self;
-
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["anObject"],
-source: "sequenceNode: anObject\x0a\x09sequenceNode := anObject",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: []
-}),
-$globals.Pragmator);
-
-$core.addMethod(
-$core.method({
-selector: "visitMethodNode:",
-protocol: "pragma processing",
-fn: function (aNode){
-var self=this,$self=this;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-var $1;
-$self._methodNode_(aNode);
-$1=(
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.supercall = true,
-//>>excludeEnd("ctx");
-($globals.Pragmator.superclass||$boot.nilAsClass).fn.prototype._visitMethodNode_.apply($self, [aNode]));
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.supercall = false;
-//>>excludeEnd("ctx");;
-return $1;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"visitMethodNode:",{aNode:aNode},$globals.Pragmator)});
-//>>excludeEnd("ctx");
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["aNode"],
-source: "visitMethodNode: aNode\x0a\x09self methodNode: aNode.\x0a\x09^ super visitMethodNode: aNode",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: ["methodNode:", "visitMethodNode:"]
-}),
-$globals.Pragmator);
-
-$core.addMethod(
-$core.method({
-selector: "visitSequenceNode:",
-protocol: "pragma processing",
-fn: function (aNode){
-var self=this,$self=this;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-var $1;
-$self._sequenceNode_(aNode);
-$recv($recv(aNode)._pragmas())._do_((function(each){
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx2) {
-//>>excludeEnd("ctx");
-return $self._processPragma_(each);
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)});
-//>>excludeEnd("ctx");
-}));
-$1=(
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.supercall = true,
-//>>excludeEnd("ctx");
-($globals.Pragmator.superclass||$boot.nilAsClass).fn.prototype._visitSequenceNode_.apply($self, [aNode]));
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.supercall = false;
-//>>excludeEnd("ctx");;
-return $1;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"visitSequenceNode:",{aNode:aNode},$globals.Pragmator)});
-//>>excludeEnd("ctx");
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["aNode"],
-source: "visitSequenceNode: aNode\x0a\x09self sequenceNode: aNode.\x0a\x09aNode pragmas do: [ :each | self processPragma: each ].\x0a\x09^ super visitSequenceNode: aNode",
-referencedClasses: [],
-//>>excludeEnd("ide");
-messageSends: ["sequenceNode:", "do:", "pragmas", "processPragma:", "visitSequenceNode:"]
-}),
-$globals.Pragmator);
-
-
-
-$core.addClass("EarlyPragmator", $globals.Pragmator, [], "Compiler-Core");
-
 $core.addMethod(
 $core.method({
 selector: "asVariableName",

+ 5 - 65
lang/src/Compiler-Core.st

@@ -62,6 +62,10 @@ See `InliningCodeGenerator` for an optimized JavaScript code generation.!
 
 !CodeGenerator methodsFor: 'compiling'!
 
+earlyAstPragmator
+	^ AstEarlyPragmator new
+!
+
 irTranslator
 	^ self irTranslatorClass new
 		currentClass: self currentClass;
@@ -80,7 +84,7 @@ semanticAnalyzer
 
 transformersDictionary
 	^ transformersDictionary ifNil: [ transformersDictionary := Dictionary new
-		at: '1000-earlyPragmas' put: EarlyPragmator new;
+		at: '1000-earlyPragmas' put: self earlyAstPragmator;
 		at: '2000-semantic' put: self semanticAnalyzer;
 		at: '5000-astToIr' put: self translator;
 		at: '8000-irToJs' put: self irTranslator;
@@ -324,70 +328,6 @@ evaluate: aString for: anObject
 	^ self new evaluate: aString for: anObject
 ! !
 
-NodeVisitor subclass: #Pragmator
-	slots: {#methodNode. #sequenceNode}
-	package: 'Compiler-Core'!
-!Pragmator commentStamp!
-I am abstract superclass for pragma-processing transformer.
-
-My subclasses should implement messages for each pragma
-they process. Pragma processing checks if a message is known
-to a class but not to its superclass. IOW, each and only those
-pragmas are processed which are defined as methods in the subclass.
-
-These messages can access sequence node in which
-a pragma occurred and its containing method node
-as `self sequenceNode` and `self methodNode`.
-
-See `EarlyPragmator` for an example.!
-
-!Pragmator methodsFor: 'accessing'!
-
-methodNode
-	^ methodNode
-!
-
-methodNode: anObject
-	methodNode := anObject
-!
-
-sequenceNode
-	^ sequenceNode
-!
-
-sequenceNode: anObject
-	sequenceNode := anObject
-! !
-
-!Pragmator methodsFor: 'pragma processing'!
-
-canProcessPragma: aMessage
-	| selector |
-	selector := aMessage selector.
-	^ (self respondsTo: selector) and: [
-		(self class superclass canUnderstand: selector) not]
-!
-
-processPragma: aMessage
-	(self canProcessPragma: aMessage) ifTrue: [
-		^ aMessage sendTo: self ]
-!
-
-visitMethodNode: aNode
-	self methodNode: aNode.
-	^ super visitMethodNode: aNode
-!
-
-visitSequenceNode: aNode
-	self sequenceNode: aNode.
-	aNode pragmas do: [ :each | self processPragma: each ].
-	^ super visitSequenceNode: aNode
-! !
-
-Pragmator subclass: #EarlyPragmator
-	slots: {}
-	package: 'Compiler-Core'!
-
 !String methodsFor: '*Compiler-Core'!
 
 asVariableName

+ 1 - 44
lang/src/Compiler-Semantic.js

@@ -1,4 +1,4 @@
-define(["amber/boot", "require", "amber/core/Compiler-AST", "amber/core/Compiler-Core", "amber/core/Kernel-Objects"], function($boot,requirejs){"use strict";
+define(["amber/boot", "require", "amber/core/Compiler-AST", "amber/core/Kernel-Objects"], function($boot,requirejs){"use strict";
 var $core=$boot.api,nil=$boot.nilAsValue,$nil=$boot.nilAsReceiver,$recv=$boot.asReceiver,$globals=$boot.globals;
 var $pkg = $core.addPackage("Compiler-Semantic");
 $pkg.innerEval = function (expr) { return eval(expr); };
@@ -2834,47 +2834,4 @@ messageSends: []
 $globals.UnknownVariableError);
 
 
-$core.addMethod(
-$core.method({
-selector: "inlineJS:",
-protocol: "*Compiler-Semantic",
-fn: function (aString){
-var self=this,$self=this;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx1) {
-//>>excludeEnd("ctx");
-var $2,$1,$3,$5,$4;
-$2=$self._sequenceNode();
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx["sequenceNode"]=1;
-//>>excludeEnd("ctx");
-$1=$recv($2)._dagChildren();
-$recv($1)._ifNotEmpty_((function(){
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx2) {
-//>>excludeEnd("ctx");
-return $recv($globals.CompilerError)._signal_("inlineJS: does not allow smalltalk statements");
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)});
-//>>excludeEnd("ctx");
-}));
-$3=$self._sequenceNode();
-$5=$recv($globals.JSStatementNode)._new();
-$recv($5)._source_(aString);
-$4=$recv($5)._yourself();
-$recv($3)._addDagChild_($4);
-return self;
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"inlineJS:",{aString:aString},$globals.EarlyPragmator)});
-//>>excludeEnd("ctx");
-},
-//>>excludeStart("ide", pragmas.excludeIdeData);
-args: ["aString"],
-source: "inlineJS: aString\x0a\x09self sequenceNode dagChildren ifNotEmpty: [\x0a\x09\x09CompilerError signal: 'inlineJS: does not allow smalltalk statements' ].\x0a\x09self sequenceNode addDagChild: (\x0a\x09\x09JSStatementNode new\x0a\x09\x09\x09source: aString;\x0a\x09\x09\x09yourself)",
-referencedClasses: ["CompilerError", "JSStatementNode"],
-//>>excludeEnd("ide");
-messageSends: ["ifNotEmpty:", "dagChildren", "sequenceNode", "signal:", "addDagChild:", "source:", "new", "yourself"]
-}),
-$globals.EarlyPragmator);
-
 });

+ 0 - 11
lang/src/Compiler-Semantic.st

@@ -714,14 +714,3 @@ variableName: aString
 	variableName := aString
 ! !
 
-!EarlyPragmator methodsFor: '*Compiler-Semantic'!
-
-inlineJS: aString
-	self sequenceNode dagChildren ifNotEmpty: [
-		CompilerError signal: 'inlineJS: does not allow smalltalk statements' ].
-	self sequenceNode addDagChild: (
-		JSStatementNode new
-			source: aString;
-			yourself)
-! !
-