Преглед на файлове

More changes to the new compiler toolchain

Nicolas Petton преди 12 години
родител
ревизия
c160297dac
променени са 9 файла, в които са добавени 156 реда и са изтрити 29 реда
  1. 23 1
      js/Compiler-AST.deploy.js
  2. 33 1
      js/Compiler-AST.js
  3. 21 4
      js/Compiler-IR.deploy.js
  4. 31 9
      js/Compiler-IR.js
  5. 4 2
      js/Compiler-Semantic.deploy.js
  6. 8 6
      js/Compiler-Semantic.js
  7. 9 1
      st/Compiler-AST.st
  8. 18 3
      st/Compiler-IR.st
  9. 9 2
      st/Compiler-Semantic.st

+ 23 - 1
js/Compiler-AST.deploy.js

@@ -643,7 +643,7 @@ smalltalk.ReturnNode);
 
 
 
-smalltalk.addClass('SendNode', smalltalk.Node, ['selector', 'arguments', 'receiver'], 'Compiler-AST');
+smalltalk.addClass('SendNode', smalltalk.Node, ['selector', 'arguments', 'receiver', 'superSend'], 'Compiler-AST');
 smalltalk.addMethod(
 "_accept_",
 smalltalk.method({
@@ -756,6 +756,28 @@ return self;}
 }),
 smalltalk.SendNode);
 
+smalltalk.addMethod(
+"_superSend",
+smalltalk.method({
+selector: "superSend",
+fn: function () {
+var self=this;
+return (($receiver = self['@superSend']) == nil || $receiver == undefined) ? (function(){return false;})() : $receiver;
+return self;}
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_superSend_",
+smalltalk.method({
+selector: "superSend:",
+fn: function (aBoolean) {
+var self=this;
+(self['@superSend']=aBoolean);
+return self;}
+}),
+smalltalk.SendNode);
+
 smalltalk.addMethod(
 "_valueForReceiver_",
 smalltalk.method({

+ 33 - 1
js/Compiler-AST.js

@@ -924,7 +924,7 @@ smalltalk.ReturnNode);
 
 
 
-smalltalk.addClass('SendNode', smalltalk.Node, ['selector', 'arguments', 'receiver'], 'Compiler-AST');
+smalltalk.addClass('SendNode', smalltalk.Node, ['selector', 'arguments', 'receiver', 'superSend'], 'Compiler-AST');
 smalltalk.addMethod(
 "_accept_",
 smalltalk.method({
@@ -1087,6 +1087,38 @@ referencedClasses: []
 }),
 smalltalk.SendNode);
 
+smalltalk.addMethod(
+"_superSend",
+smalltalk.method({
+selector: "superSend",
+category: 'accessing',
+fn: function () {
+var self=this;
+return (($receiver = self['@superSend']) == nil || $receiver == undefined) ? (function(){return false;})() : $receiver;
+return self;},
+args: [],
+source: "superSend\x0a\x09^ superSend ifNil: [ false ]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.SendNode);
+
+smalltalk.addMethod(
+"_superSend_",
+smalltalk.method({
+selector: "superSend:",
+category: 'accessing',
+fn: function (aBoolean) {
+var self=this;
+(self['@superSend']=aBoolean);
+return self;},
+args: ["aBoolean"],
+source: "superSend: aBoolean\x0a\x09superSend := aBoolean",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.SendNode);
+
 smalltalk.addMethod(
 "_valueForReceiver_",
 smalltalk.method({

+ 21 - 4
js/Compiler-IR.deploy.js

@@ -107,7 +107,7 @@ smalltalk.method({
 selector: "visitSendNode:",
 fn: function (aNode) {
 var self=this;
-(function($rec){smalltalk.send($rec, "_selector_", [smalltalk.send(aNode, "_selector", [])]);return smalltalk.send($rec, "_with_", [(function(){smalltalk.send(self, "_visit_", [smalltalk.send(aNode, "_receiver", [])]);return smalltalk.send(smalltalk.send(aNode, "_arguments", []), "_do_", [(function(each){return smalltalk.send(self, "_visit_", [each]);})]);})]);})(smalltalk.send(smalltalk.send(self, "_builder", []), "_send", []));
+(function($rec){smalltalk.send($rec, "_selector_", [smalltalk.send(aNode, "_selector", [])]);smalltalk.send($rec, "_superSend_", [smalltalk.send(aNode, "_superSend", [])]);return smalltalk.send($rec, "_with_", [(function(){smalltalk.send(self, "_visit_", [smalltalk.send(aNode, "_receiver", [])]);return smalltalk.send(smalltalk.send(aNode, "_arguments", []), "_do_", [(function(each){return smalltalk.send(self, "_visit_", [each]);})]);})]);})(smalltalk.send(smalltalk.send(self, "_builder", []), "_send", []));
 return self;}
 }),
 smalltalk.IRASTTranslator);
@@ -470,6 +470,9 @@ smalltalk.IRBuilder);
 
 
 
+smalltalk.addClass('IRInliner', smalltalk.Object, [], 'Compiler-IR');
+
+
 smalltalk.addClass('IRInstruction', smalltalk.Object, ['builder', 'instructions'], 'Compiler-IR');
 smalltalk.addMethod(
 "_accept_",
@@ -1404,6 +1407,21 @@ smalltalk.IRVisitor);
 
 
 
+smalltalk.addClass('IRJSTranslator', smalltalk.IRVisitor, ['stream'], 'Compiler-IR');
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+fn: function () {
+var self=this;
+smalltalk.send(self, "_initialize", [], smalltalk.IRJSTranslator.superclass || nil);
+(self['@stream']=smalltalk.send((smalltalk.JSStream || JSStream), "_new", []));
+return self;}
+}),
+smalltalk.IRJSTranslator);
+
+
+
 smalltalk.addClass('JSStream', smalltalk.Object, ['stream'], 'Compiler-IR');
 smalltalk.addMethod(
 "_contents",
@@ -1498,10 +1516,9 @@ var self=this;
 smalltalk.send(self['@stream'], "_nextPutAll_", ["fn: function("]);
 smalltalk.send(anArray, "_do_separatedBy_", [(function(each){return smalltalk.send(self['@stream'], "_nextPutAll_", [smalltalk.send(each, "_asVariableName", [])]);}), (function(){return smalltalk.send(self['@stream'], "_nextPut_", [","]);})]);
 (function($rec){smalltalk.send($rec, "_nextPutAll_", ["){"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
-smalltalk.send(self, "_nextPutVar_", ["$return"]);
 (function($rec){smalltalk.send($rec, "_nextPutAll_", ["var self=this;"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
 smalltalk.send(aBlock, "_value", []);
-smalltalk.send(self['@stream'], "_nextPutAll_", ["return $return || self;}"]);
+smalltalk.send(self['@stream'], "_nextPutAll_", ["return self;}"]);
 return self;}
 }),
 smalltalk.JSStream);
@@ -1553,7 +1570,7 @@ smalltalk.method({
 selector: "nextPutReturnWith:",
 fn: function (aBlock) {
 var self=this;
-smalltalk.send(self['@stream'], "_nextPutAll_", ["$return="]);
+smalltalk.send(self['@stream'], "_nextPutAll_", ["return "]);
 smalltalk.send(aBlock, "_value", []);
 return self;}
 }),

+ 31 - 9
js/Compiler-IR.js

@@ -154,11 +154,11 @@ selector: "visitSendNode:",
 category: 'visiting',
 fn: function (aNode) {
 var self=this;
-(function($rec){smalltalk.send($rec, "_selector_", [smalltalk.send(aNode, "_selector", [])]);return smalltalk.send($rec, "_with_", [(function(){smalltalk.send(self, "_visit_", [smalltalk.send(aNode, "_receiver", [])]);return smalltalk.send(smalltalk.send(aNode, "_arguments", []), "_do_", [(function(each){return smalltalk.send(self, "_visit_", [each]);})]);})]);})(smalltalk.send(smalltalk.send(self, "_builder", []), "_send", []));
+(function($rec){smalltalk.send($rec, "_selector_", [smalltalk.send(aNode, "_selector", [])]);smalltalk.send($rec, "_superSend_", [smalltalk.send(aNode, "_superSend", [])]);return smalltalk.send($rec, "_with_", [(function(){smalltalk.send(self, "_visit_", [smalltalk.send(aNode, "_receiver", [])]);return smalltalk.send(smalltalk.send(aNode, "_arguments", []), "_do_", [(function(each){return smalltalk.send(self, "_visit_", [each]);})]);})]);})(smalltalk.send(smalltalk.send(self, "_builder", []), "_send", []));
 return self;},
 args: ["aNode"],
-source: "visitSendNode: aNode\x0a\x09self builder send\x0a\x09\x09selector: aNode selector;\x0a\x09\x09with: [\x0a\x09\x09\x09self visit: aNode receiver.\x0a\x09\x09\x09(aNode arguments do: [ :each | self visit: each ]) ]",
-messageSends: ["selector:", "selector", "with:", "visit:", "receiver", "do:", "arguments", "send", "builder"],
+source: "visitSendNode: aNode\x0a\x09self builder send\x0a\x09\x09selector: aNode selector;\x0a\x09\x09superSend: aNode superSend;\x0a\x09\x09with: [\x0a\x09\x09\x09self visit: aNode receiver.\x0a\x09\x09\x09(aNode arguments do: [ :each | self visit: each ]) ]",
+messageSends: ["selector:", "selector", "superSend:", "superSend", "with:", "visit:", "receiver", "do:", "arguments", "send", "builder"],
 referencedClasses: []
 }),
 smalltalk.IRASTTranslator);
@@ -678,6 +678,9 @@ smalltalk.IRBuilder);
 
 
 
+smalltalk.addClass('IRInliner', smalltalk.Object, [], 'Compiler-IR');
+
+
 smalltalk.addClass('IRInstruction', smalltalk.Object, ['builder', 'instructions'], 'Compiler-IR');
 smalltalk.IRInstruction.comment="I am the abstract root class of the IR (intermediate representation) instructions class hierarchy.\x0aThe IR graph is used to emit JavaScript code using a JSStream. "
 smalltalk.addMethod(
@@ -2022,6 +2025,26 @@ smalltalk.IRVisitor);
 
 
 
+smalltalk.addClass('IRJSTranslator', smalltalk.IRVisitor, ['stream'], 'Compiler-IR');
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+category: 'initialization',
+fn: function () {
+var self=this;
+smalltalk.send(self, "_initialize", [], smalltalk.IRJSTranslator.superclass || nil);
+(self['@stream']=smalltalk.send((smalltalk.JSStream || JSStream), "_new", []));
+return self;},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a\x09stream := JSStream new.",
+messageSends: ["initialize", "new"],
+referencedClasses: ["JSStream"]
+}),
+smalltalk.IRJSTranslator);
+
+
+
 smalltalk.addClass('JSStream', smalltalk.Object, ['stream'], 'Compiler-IR');
 smalltalk.addMethod(
 "_contents",
@@ -2152,14 +2175,13 @@ var self=this;
 smalltalk.send(self['@stream'], "_nextPutAll_", ["fn: function("]);
 smalltalk.send(anArray, "_do_separatedBy_", [(function(each){return smalltalk.send(self['@stream'], "_nextPutAll_", [smalltalk.send(each, "_asVariableName", [])]);}), (function(){return smalltalk.send(self['@stream'], "_nextPut_", [","]);})]);
 (function($rec){smalltalk.send($rec, "_nextPutAll_", ["){"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
-smalltalk.send(self, "_nextPutVar_", ["$return"]);
 (function($rec){smalltalk.send($rec, "_nextPutAll_", ["var self=this;"]);return smalltalk.send($rec, "_lf", []);})(self['@stream']);
 smalltalk.send(aBlock, "_value", []);
-smalltalk.send(self['@stream'], "_nextPutAll_", ["return $return || self;}"]);
+smalltalk.send(self['@stream'], "_nextPutAll_", ["return self;}"]);
 return self;},
 args: ["aBlock", "anArray"],
-source: "nextPutFunctionWith: aBlock arguments: anArray\x0a\x09stream nextPutAll: 'fn: function('.\x0a\x09anArray \x0a\x09\x09do: [ :each | stream nextPutAll: each asVariableName ]\x0a\x09\x09separatedBy: [ stream nextPut: ',' ].\x0a\x09stream nextPutAll: '){'; lf.\x0a\x09self nextPutVar: '$return'.\x0a\x09stream nextPutAll: 'var self=this;'; lf.\x0a\x09aBlock value.\x0a\x09stream nextPutAll: 'return $return || self;}'",
-messageSends: ["nextPutAll:", "do:separatedBy:", "asVariableName", "nextPut:", "lf", "nextPutVar:", "value"],
+source: "nextPutFunctionWith: aBlock arguments: anArray\x0a\x09stream nextPutAll: 'fn: function('.\x0a\x09anArray \x0a\x09\x09do: [ :each | stream nextPutAll: each asVariableName ]\x0a\x09\x09separatedBy: [ stream nextPut: ',' ].\x0a\x09stream nextPutAll: '){'; lf.\x0a\x09stream nextPutAll: 'var self=this;'; lf.\x0a\x09aBlock value.\x0a\x09stream nextPutAll: 'return self;}'",
+messageSends: ["nextPutAll:", "do:separatedBy:", "asVariableName", "nextPut:", "lf", "value"],
 referencedClasses: []
 }),
 smalltalk.JSStream);
@@ -2227,11 +2249,11 @@ selector: "nextPutReturnWith:",
 category: 'streaming',
 fn: function (aBlock) {
 var self=this;
-smalltalk.send(self['@stream'], "_nextPutAll_", ["$return="]);
+smalltalk.send(self['@stream'], "_nextPutAll_", ["return "]);
 smalltalk.send(aBlock, "_value", []);
 return self;},
 args: ["aBlock"],
-source: "nextPutReturnWith: aBlock\x0a\x09stream nextPutAll: '$return='.\x0a\x09aBlock value",
+source: "nextPutReturnWith: aBlock\x0a\x09stream nextPutAll: 'return '.\x0a\x09aBlock value",
 messageSends: ["nextPutAll:", "value"],
 referencedClasses: []
 }),

+ 4 - 2
js/Compiler-Semantic.deploy.js

@@ -667,10 +667,11 @@ smalltalk.method({
 selector: "visitAssignmentNode:",
 fn: function (aNode) {
 var self=this;
-((($receiver = smalltalk.send(smalltalk.send(self, "_pseudoVariables", []), "_includes_", [smalltalk.send(smalltalk.send(aNode, "_left", []), "_value", [])])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_errorInvalidAssignment_", [smalltalk.send(aNode, "_left", [])]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_errorInvalidAssignment_", [smalltalk.send(aNode, "_left", [])]);})]));
+smalltalk.send(self, "_visitAssignmentNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
+((($receiver = smalltalk.send(smalltalk.send(self, "_pseudoVariables", []), "_includes_", [smalltalk.send(smalltalk.send(aNode, "_left", []), "_value", [])])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_errorInvalidAssignment_", [smalltalk.send(smalltalk.send(aNode, "_left", []), "_value", [])]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_errorInvalidAssignment_", [smalltalk.send(smalltalk.send(aNode, "_left", []), "_value", [])]);})]));
+((($receiver = smalltalk.send(smalltalk.send(smalltalk.send(aNode, "_left", []), "_binding", []), "_isArgVar", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_errorInvalidAssignment_", [smalltalk.send(smalltalk.send(aNode, "_left", []), "_value", [])]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_errorInvalidAssignment_", [smalltalk.send(smalltalk.send(aNode, "_left", []), "_value", [])]);})]));
 smalltalk.send(smalltalk.send(aNode, "_left", []), "_beAssigned", []);
 smalltalk.send(smalltalk.send(aNode, "_right", []), "_beUsed", []);
-smalltalk.send(self, "_visitAssignmentNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
 return self;}
 }),
 smalltalk.SemanticAnalyzer);
@@ -750,6 +751,7 @@ smalltalk.method({
 selector: "visitSendNode:",
 fn: function (aNode) {
 var self=this;
+((($receiver = smalltalk.send(smalltalk.send(smalltalk.send(aNode, "_receiver", []), "_value", []), "__eq", ["super"])).klass === smalltalk.Boolean) ? ($receiver ? (function(){smalltalk.send(aNode, "_superSend_", [true]);return smalltalk.send(smalltalk.send(aNode, "_receiver", []), "_value_", ["self"]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){smalltalk.send(aNode, "_superSend_", [true]);return smalltalk.send(smalltalk.send(aNode, "_receiver", []), "_value_", ["self"]);})]));
 smalltalk.send(smalltalk.send(self, "_messageSends", []), "_add_", [smalltalk.send(aNode, "_selector", [])]);
 (($receiver = smalltalk.send(aNode, "_receiver", [])) != nil && $receiver != undefined) ? (function(){return smalltalk.send(smalltalk.send(aNode, "_receiver", []), "_beUsed", []);})() : nil;
 smalltalk.send(smalltalk.send(aNode, "_arguments", []), "_do_", [(function(each){return smalltalk.send(each, "_beUsed", []);})]);

+ 8 - 6
js/Compiler-Semantic.js

@@ -963,14 +963,15 @@ selector: "visitAssignmentNode:",
 category: 'visiting',
 fn: function (aNode) {
 var self=this;
-((($receiver = smalltalk.send(smalltalk.send(self, "_pseudoVariables", []), "_includes_", [smalltalk.send(smalltalk.send(aNode, "_left", []), "_value", [])])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_errorInvalidAssignment_", [smalltalk.send(aNode, "_left", [])]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_errorInvalidAssignment_", [smalltalk.send(aNode, "_left", [])]);})]));
+smalltalk.send(self, "_visitAssignmentNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
+((($receiver = smalltalk.send(smalltalk.send(self, "_pseudoVariables", []), "_includes_", [smalltalk.send(smalltalk.send(aNode, "_left", []), "_value", [])])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_errorInvalidAssignment_", [smalltalk.send(smalltalk.send(aNode, "_left", []), "_value", [])]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_errorInvalidAssignment_", [smalltalk.send(smalltalk.send(aNode, "_left", []), "_value", [])]);})]));
+((($receiver = smalltalk.send(smalltalk.send(smalltalk.send(aNode, "_left", []), "_binding", []), "_isArgVar", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_errorInvalidAssignment_", [smalltalk.send(smalltalk.send(aNode, "_left", []), "_value", [])]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_errorInvalidAssignment_", [smalltalk.send(smalltalk.send(aNode, "_left", []), "_value", [])]);})]));
 smalltalk.send(smalltalk.send(aNode, "_left", []), "_beAssigned", []);
 smalltalk.send(smalltalk.send(aNode, "_right", []), "_beUsed", []);
-smalltalk.send(self, "_visitAssignmentNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
 return self;},
 args: ["aNode"],
-source: "visitAssignmentNode: aNode\x0a\x09(self pseudoVariables includes: aNode left value) ifTrue: [\x0a\x09\x09self errorInvalidAssignment: aNode left ].\x0a\x09aNode left beAssigned.\x0a\x09aNode right beUsed.\x0a\x09super visitAssignmentNode: aNode",
-messageSends: ["ifTrue:", "includes:", "pseudoVariables", "value", "left", "errorInvalidAssignment:", "beAssigned", "beUsed", "right", "visitAssignmentNode:"],
+source: "visitAssignmentNode: aNode\x0a\x09super visitAssignmentNode: aNode.\x0a\x09(self pseudoVariables includes: aNode left value) ifTrue: [\x0a\x09\x09self errorInvalidAssignment: aNode left value ].\x0a\x09aNode left binding isArgVar ifTrue: [\x0a\x09\x09self errorInvalidAssignment: aNode left value ].\x0a\x09aNode left beAssigned.\x0a\x09aNode right beUsed.",
+messageSends: ["visitAssignmentNode:", "ifTrue:", "includes:", "pseudoVariables", "value", "left", "errorInvalidAssignment:", "isArgVar", "binding", "beAssigned", "beUsed", "right"],
 referencedClasses: []
 }),
 smalltalk.SemanticAnalyzer);
@@ -1076,14 +1077,15 @@ selector: "visitSendNode:",
 category: 'visiting',
 fn: function (aNode) {
 var self=this;
+((($receiver = smalltalk.send(smalltalk.send(smalltalk.send(aNode, "_receiver", []), "_value", []), "__eq", ["super"])).klass === smalltalk.Boolean) ? ($receiver ? (function(){smalltalk.send(aNode, "_superSend_", [true]);return smalltalk.send(smalltalk.send(aNode, "_receiver", []), "_value_", ["self"]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){smalltalk.send(aNode, "_superSend_", [true]);return smalltalk.send(smalltalk.send(aNode, "_receiver", []), "_value_", ["self"]);})]));
 smalltalk.send(smalltalk.send(self, "_messageSends", []), "_add_", [smalltalk.send(aNode, "_selector", [])]);
 (($receiver = smalltalk.send(aNode, "_receiver", [])) != nil && $receiver != undefined) ? (function(){return smalltalk.send(smalltalk.send(aNode, "_receiver", []), "_beUsed", []);})() : nil;
 smalltalk.send(smalltalk.send(aNode, "_arguments", []), "_do_", [(function(each){return smalltalk.send(each, "_beUsed", []);})]);
 smalltalk.send(self, "_visitSendNode_", [aNode], smalltalk.SemanticAnalyzer.superclass || nil);
 return self;},
 args: ["aNode"],
-source: "visitSendNode: aNode\x0a\x09self messageSends add: aNode selector.\x0a\x09aNode receiver ifNotNil: [\x0a\x09\x09aNode receiver beUsed ].\x0a\x09aNode arguments do: [ :each |\x0a\x09\x09each beUsed ].\x0a\x09super visitSendNode: aNode",
-messageSends: ["add:", "messageSends", "selector", "ifNotNil:", "receiver", "beUsed", "do:", "arguments", "visitSendNode:"],
+source: "visitSendNode: aNode\x0a\x0a\x09aNode receiver value = 'super' ifTrue: [\x0a\x09\x09aNode superSend: true.\x0a\x09\x09aNode receiver value: 'self'].\x0a\x0a\x09self messageSends add: aNode selector.\x0a\x09aNode receiver ifNotNil: [\x0a\x09\x09aNode receiver beUsed ].\x0a\x09aNode arguments do: [ :each |\x0a\x09\x09each beUsed ].\x0a\x09super visitSendNode: aNode",
+messageSends: ["ifTrue:", "=", "value", "receiver", "superSend:", "value:", "add:", "messageSends", "selector", "ifNotNil:", "beUsed", "do:", "arguments", "visitSendNode:"],
 referencedClasses: []
 }),
 smalltalk.SemanticAnalyzer);

+ 9 - 1
st/Compiler-AST.st

@@ -307,7 +307,7 @@ accept: aVisitor
 ! !
 
 Node subclass: #SendNode
-	instanceVariableNames: 'selector arguments receiver'
+	instanceVariableNames: 'selector arguments receiver superSend'
 	package: 'Compiler-AST'!
 
 !SendNode methodsFor: 'accessing'!
@@ -354,6 +354,14 @@ selector: aString
 	selector := aString
 !
 
+superSend
+	^ superSend ifNil: [ false ]
+!
+
+superSend: aBoolean
+	superSend := aBoolean
+!
+
 valueForReceiver: anObject
 	^SendNode new
 	    receiver: (self receiver 

+ 18 - 3
st/Compiler-IR.st

@@ -70,6 +70,7 @@ visitReturnNode: aNode
 visitSendNode: aNode
 	self builder send
 		selector: aNode selector;
+		superSend: aNode superSend;
 		with: [
 			self visit: aNode receiver.
 			(aNode arguments do: [ :each | self visit: each ]) ]
@@ -257,6 +258,10 @@ initialize
 	root := method := IRMethod on: self
 ! !
 
+Object subclass: #IRInliner
+	instanceVariableNames: ''
+	package: 'Compiler-IR'!
+
 Object subclass: #IRInstruction
 	instanceVariableNames: 'builder instructions'
 	package: 'Compiler-IR'!
@@ -779,6 +784,17 @@ visitIRVerbatim: anIRVerbatim
 	self visitIRInstruction: anIRVerbatim
 ! !
 
+IRVisitor subclass: #IRJSTranslator
+	instanceVariableNames: 'stream'
+	package: 'Compiler-IR'!
+
+!IRJSTranslator methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	stream := JSStream new.
+! !
+
 Object subclass: #JSStream
 	instanceVariableNames: 'stream'
 	package: 'Compiler-IR'!
@@ -832,10 +848,9 @@ nextPutFunctionWith: aBlock arguments: anArray
 		do: [ :each | stream nextPutAll: each asVariableName ]
 		separatedBy: [ stream nextPut: ',' ].
 	stream nextPutAll: '){'; lf.
-	self nextPutVar: '$return'.
 	stream nextPutAll: 'var self=this;'; lf.
 	aBlock value.
-	stream nextPutAll: 'return $return || self;}'
+	stream nextPutAll: 'return self;}'
 !
 
 nextPutMethodDeclaration: aMethod with: aBlock
@@ -874,7 +889,7 @@ nextPutNonLocalReturnWith: aBlock
 !
 
 nextPutReturnWith: aBlock
-	stream nextPutAll: '$return='.
+	stream nextPutAll: 'return '.
 	aBlock value
 !
 

+ 9 - 2
st/Compiler-Semantic.st

@@ -368,11 +368,13 @@ allowUnknownVariables
 !SemanticAnalyzer methodsFor: 'visiting'!
 
 visitAssignmentNode: aNode
+	super visitAssignmentNode: aNode.
 	(self pseudoVariables includes: aNode left value) ifTrue: [
-		self errorInvalidAssignment: aNode left ].
+		self errorInvalidAssignment: aNode left value ].
+	aNode left binding isArgVar ifTrue: [
+		self errorInvalidAssignment: aNode left value ].
 	aNode left beAssigned.
 	aNode right beUsed.
-	super visitAssignmentNode: aNode
 !
 
 visitBlockNode: aNode
@@ -425,6 +427,11 @@ visitReturnNode: aNode
 !
 
 visitSendNode: aNode
+
+	aNode receiver value = 'super' ifTrue: [
+		aNode superSend: true.
+		aNode receiver value: 'self'].
+
 	self messageSends add: aNode selector.
 	aNode receiver ifNotNil: [
 		aNode receiver beUsed ].