Browse Source

Reorganize Pragmator and pragma methods.

Herby Vojčík 5 years ago
parent
commit
d152d27526
6 changed files with 338 additions and 338 deletions
  1. 0 262
      src/Compiler-AST.js
  2. 0 75
      src/Compiler-AST.st
  3. 220 1
      src/Compiler-Core.js
  4. 64 0
      src/Compiler-Core.st
  5. 43 0
      src/Compiler-Semantic.js
  6. 11 0
      src/Compiler-Semantic.st

+ 0 - 262
src/Compiler-AST.js

@@ -3150,268 +3150,6 @@ messageSends: ["visitDagNode:"]
 $globals.NodeVisitor);
 
 
-
-$core.addClass("Pragmator", $globals.NodeVisitor, ["methodNode", "sequenceNode"], "Compiler-AST");
-//>>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-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 $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 $self._error_("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\x09self error: 'inlineJS: does not allow smalltalk statements' ].\x0a\x09self sequenceNode addDagChild: (\x0a\x09\x09JSStatementNode new\x0a\x09\x09\x09source: aString;\x0a\x09\x09\x09yourself)",
-referencedClasses: ["JSStatementNode"],
-//>>excludeEnd("ide");
-messageSends: ["ifNotEmpty:", "dagChildren", "sequenceNode", "error:", "addDagChild:", "source:", "new", "yourself"]
-}),
-$globals.EarlyPragmator);
-
-
 $core.addMethod(
 $core.method({
 selector: "ast",

+ 0 - 75
src/Compiler-AST.st

@@ -772,81 +772,6 @@ visitVariableNode: aNode
 	^ self visitDagNode: aNode
 ! !
 
-NodeVisitor subclass: #Pragmator
-	instanceVariableNames: 'methodNode sequenceNode'
-	package: 'Compiler-AST'!
-!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
-	instanceVariableNames: ''
-	package: 'Compiler-AST'!
-
-!EarlyPragmator methodsFor: 'pragmas'!
-
-inlineJS: aString
-	self sequenceNode dagChildren ifNotEmpty: [
-		self error: 'inlineJS: does not allow smalltalk statements' ].
-	self sequenceNode addDagChild: (
-		JSStatementNode new
-			source: aString;
-			yourself)
-! !
-
 !CompiledMethod methodsFor: '*Compiler-AST'!
 
 ast

+ 220 - 1
src/Compiler-Core.js

@@ -1,4 +1,4 @@
-define(["amber/boot", "amber_core/Kernel-Collections", "amber_core/Kernel-Exceptions", "amber_core/Kernel-Objects"], function($boot){"use strict";
+define(["amber/boot", "amber_core/Compiler-AST", "amber_core/Kernel-Collections", "amber_core/Kernel-Exceptions", "amber_core/Kernel-Objects"], function($boot){"use strict";
 if(!("nilAsValue" in $boot))$boot.nilAsValue=$boot.nilAsReceiver;
 var $core=$boot.api,nil=$boot.nilAsValue,$nil=$boot.nilAsReceiver,$recv=$boot.asReceiver,$globals=$boot.globals;
 $core.addPackage("Compiler-Core");
@@ -1271,6 +1271,225 @@ 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",

+ 64 - 0
src/Compiler-Core.st

@@ -330,6 +330,70 @@ evaluate: aString for: anObject
 	^ self new evaluate: aString for: anObject
 ! !
 
+NodeVisitor subclass: #Pragmator
+	instanceVariableNames: '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
+	instanceVariableNames: ''
+	package: 'Compiler-Core'!
+
 !String methodsFor: '*Compiler-Core'!
 
 asVariableName

+ 43 - 0
src/Compiler-Semantic.js

@@ -2879,4 +2879,47 @@ 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 $self._error_("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\x09self error: 'inlineJS: does not allow smalltalk statements' ].\x0a\x09self sequenceNode addDagChild: (\x0a\x09\x09JSStatementNode new\x0a\x09\x09\x09source: aString;\x0a\x09\x09\x09yourself)",
+referencedClasses: ["JSStatementNode"],
+//>>excludeEnd("ide");
+messageSends: ["ifNotEmpty:", "dagChildren", "sequenceNode", "error:", "addDagChild:", "source:", "new", "yourself"]
+}),
+$globals.EarlyPragmator);
+
 });

+ 11 - 0
src/Compiler-Semantic.st

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