Browse Source

Fixed variable assignment

Nicolas Petton 11 years ago
parent
commit
0ab29613a8

+ 22 - 43
js/Compiler-Interpreter.deploy.js

@@ -1,5 +1,5 @@
 smalltalk.addPackage('Compiler-Interpreter', {});
-smalltalk.addClass('AIContext', smalltalk.NodeVisitor, ['outerContext', 'pc', 'locals', 'receiver', 'selector'], 'Compiler-Interpreter');
+smalltalk.addClass('AIContext', smalltalk.NodeVisitor, ['outerContext', 'pc', 'locals', 'selector'], 'Compiler-Interpreter');
 smalltalk.addMethod(
 "_initializeFromMethodContext_",
 smalltalk.method({
@@ -129,7 +129,7 @@ selector: "receiver",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=self["@receiver"];
+$1=_st(self)._localAt_("self");
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"receiver",{}, smalltalk.AIContext)})}
 }),
@@ -141,51 +141,11 @@ smalltalk.method({
 selector: "receiver:",
 fn: function (anObject){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
self["@receiver"]=anObject;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._localAt_put_("self",anObject);
 return self}, function($ctx1) {$ctx1.fill(self,"receiver:",{anObject:anObject}, smalltalk.AIContext)})}
 }),
 smalltalk.AIContext);
 
-smalltalk.addMethod(
-"_selector",
-smalltalk.method({
-selector: "selector",
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=self["@selector"];
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"selector",{}, smalltalk.AIContext)})}
-}),
-smalltalk.AIContext);
-
-smalltalk.addMethod(
-"_selector_",
-smalltalk.method({
-selector: "selector:",
-fn: function (aString){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
self["@selector"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"selector:",{aString:aString}, smalltalk.AIContext)})}
-}),
-smalltalk.AIContext);
-
-
-smalltalk.addMethod(
-"_fromMethodContext_",
-smalltalk.method({
-selector: "fromMethodContext:",
-fn: function (aMethodContext){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
-$2=_st(self)._new();
-_st($2)._initializeFromMethodContext_(aMethodContext);
-$3=_st($2)._yourself();
-$1=$3;
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"fromMethodContext:",{aMethodContext:aMethodContext}, smalltalk.AIContext.klass)})}
-}),
-smalltalk.AIContext.klass);
 
 
 smalltalk.addClass('ASTInterpreter', smalltalk.NodeVisitor, ['currentNode', 'context', 'shouldReturn', 'currentValue'], 'Compiler-Interpreter');
@@ -548,6 +508,25 @@ return self}, function($ctx1) {$ctx1.fill(self,"visitValueNode:",{aNode:aNode},
 }),
 smalltalk.ASTInterpreter);
 
+smalltalk.addMethod(
+"_visitVariableNode_",
+smalltalk.method({
+selector: "visitVariableNode:",
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
+$1=self;
+$3=_st(_st(aNode)._binding())._isInstanceVar();
+if(smalltalk.assert($3)){
+$2=_st(_st(_st(self)._context())._receiver())._instVarAt_(_st(aNode)._value());
+} else {
+$2=_st(_st(self)._context())._localAt_(_st(aNode)._value());
+};
+_st($1)._continue_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"visitVariableNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})}
+}),
+smalltalk.ASTInterpreter);
+
 
 
 smalltalk.addClass('ASTDebugger', smalltalk.ASTInterpreter, ['continuation'], 'Compiler-Interpreter');

+ 31 - 62
js/Compiler-Interpreter.js

@@ -1,5 +1,5 @@
 smalltalk.addPackage('Compiler-Interpreter', {});
-smalltalk.addClass('AIContext', smalltalk.NodeVisitor, ['outerContext', 'pc', 'locals', 'receiver', 'selector'], 'Compiler-Interpreter');
+smalltalk.addClass('AIContext', smalltalk.NodeVisitor, ['outerContext', 'pc', 'locals', 'selector'], 'Compiler-Interpreter');
 smalltalk.addMethod(
 "_initializeFromMethodContext_",
 smalltalk.method({
@@ -170,12 +170,12 @@ category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=self["@receiver"];
+$1=_st(self)._localAt_("self");
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"receiver",{}, smalltalk.AIContext)})},
 args: [],
-source: "receiver\x0a\x09^ receiver",
-messageSends: [],
+source: "receiver\x0a\x09^ self localAt: 'self'",
+messageSends: ["localAt:"],
 referencedClasses: []
 }),
 smalltalk.AIContext);
@@ -187,71 +187,16 @@ selector: "receiver:",
 category: 'accessing',
 fn: function (anObject){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
self["@receiver"]=anObject;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._localAt_put_("self",anObject);
 return self}, function($ctx1) {$ctx1.fill(self,"receiver:",{anObject:anObject}, smalltalk.AIContext)})},
 args: ["anObject"],
-source: "receiver: anObject\x0a\x09receiver := anObject",
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.AIContext);
-
-smalltalk.addMethod(
-"_selector",
-smalltalk.method({
-selector: "selector",
-category: 'accessing',
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=self["@selector"];
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"selector",{}, smalltalk.AIContext)})},
-args: [],
-source: "selector\x0a\x09^ selector",
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.AIContext);
-
-smalltalk.addMethod(
-"_selector_",
-smalltalk.method({
-selector: "selector:",
-category: 'accessing',
-fn: function (aString){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
self["@selector"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"selector:",{aString:aString}, smalltalk.AIContext)})},
-args: ["aString"],
-source: "selector: aString\x0a\x09selector := aString",
-messageSends: [],
+source: "receiver: anObject\x0a\x09self localAt: 'self' put: anObject",
+messageSends: ["localAt:put:"],
 referencedClasses: []
 }),
 smalltalk.AIContext);
 
 
-smalltalk.addMethod(
-"_fromMethodContext_",
-smalltalk.method({
-selector: "fromMethodContext:",
-category: 'instance creation',
-fn: function (aMethodContext){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
-$2=_st(self)._new();
-_st($2)._initializeFromMethodContext_(aMethodContext);
-$3=_st($2)._yourself();
-$1=$3;
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"fromMethodContext:",{aMethodContext:aMethodContext}, smalltalk.AIContext.klass)})},
-args: ["aMethodContext"],
-source: "fromMethodContext: aMethodContext\x0a\x09^ self new \x0a    \x09initializeFromMethodContext: aMethodContext;\x0a        yourself",
-messageSends: ["initializeFromMethodContext:", "new", "yourself"],
-referencedClasses: []
-}),
-smalltalk.AIContext.klass);
-
 
 smalltalk.addClass('ASTInterpreter', smalltalk.NodeVisitor, ['currentNode', 'context', 'shouldReturn', 'currentValue'], 'Compiler-Interpreter');
 smalltalk.addMethod(
@@ -728,6 +673,30 @@ referencedClasses: []
 }),
 smalltalk.ASTInterpreter);
 
+smalltalk.addMethod(
+"_visitVariableNode_",
+smalltalk.method({
+selector: "visitVariableNode:",
+category: 'visiting',
+fn: function (aNode){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
+$1=self;
+$3=_st(_st(aNode)._binding())._isInstanceVar();
+if(smalltalk.assert($3)){
+$2=_st(_st(_st(self)._context())._receiver())._instVarAt_(_st(aNode)._value());
+} else {
+$2=_st(_st(self)._context())._localAt_(_st(aNode)._value());
+};
+_st($1)._continue_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"visitVariableNode:",{aNode:aNode}, smalltalk.ASTInterpreter)})},
+args: ["aNode"],
+source: "visitVariableNode: aNode\x0a    self continue: (aNode binding isInstanceVar\x0a\x09\x09ifTrue: [ self context receiver instVarAt: aNode value ]\x0a\x09\x09ifFalse: [ self context localAt: aNode value ])",
+messageSends: ["continue:", "ifTrue:ifFalse:", "instVarAt:", "value", "receiver", "context", "localAt:", "isInstanceVar", "binding"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreter);
+
 
 
 smalltalk.addClass('ASTDebugger', smalltalk.ASTInterpreter, ['continuation'], 'Compiler-Interpreter');

+ 22 - 0
js/Compiler-Tests.deploy.js

@@ -171,6 +171,17 @@ return self}, function($ctx1) {$ctx1.fill(self,"testInlinedJSStatement",{}, smal
 }),
 smalltalk.ASTInterpreterTest);
 
+smalltalk.addMethod(
+"_testInstVarAccess",
+smalltalk.method({
+selector: "testInstVarAccess",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_equals_(_st(self)._interpret_receiver_withArguments_("foo ^ x",_st((2)).__at((3)),smalltalk.HashedCollection._fromPairs_([])),(2));
+return self}, function($ctx1) {$ctx1.fill(self,"testInstVarAccess",{}, smalltalk.ASTInterpreterTest)})}
+}),
+smalltalk.ASTInterpreterTest);
+
 smalltalk.addMethod(
 "_testInstVarAssignment",
 smalltalk.method({
@@ -193,6 +204,17 @@ return self}, function($ctx1) {$ctx1.fill(self,"testNonlocalReturn",{}, smalltal
 }),
 smalltalk.ASTInterpreterTest);
 
+smalltalk.addMethod(
+"_testReceiver",
+smalltalk.method({
+selector: "testReceiver",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_equals_(_st(self)._interpret_receiver_withArguments_("foo ^ self",_st((2)).__at((3)),smalltalk.HashedCollection._fromPairs_([])),_st((2)).__at((3)));
+return self}, function($ctx1) {$ctx1.fill(self,"testReceiver",{}, smalltalk.ASTInterpreterTest)})}
+}),
+smalltalk.ASTInterpreterTest);
+
 smalltalk.addMethod(
 "_testTempAssignment",
 smalltalk.method({

+ 32 - 0
js/Compiler-Tests.js

@@ -236,6 +236,22 @@ referencedClasses: []
 }),
 smalltalk.ASTInterpreterTest);
 
+smalltalk.addMethod(
+"_testInstVarAccess",
+smalltalk.method({
+selector: "testInstVarAccess",
+category: 'tests',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_equals_(_st(self)._interpret_receiver_withArguments_("foo ^ x",_st((2)).__at((3)),smalltalk.HashedCollection._fromPairs_([])),(2));
+return self}, function($ctx1) {$ctx1.fill(self,"testInstVarAccess",{}, smalltalk.ASTInterpreterTest)})},
+args: [],
+source: "testInstVarAccess\x0a\x09self \x0a    \x09assert: (self \x0a    \x09\x09interpret: 'foo ^ x'\x0a        \x09receiver: 2@3\x0a        \x09withArguments: #{})\x0a        equals: 2",
+messageSends: ["assert:equals:", "interpret:receiver:withArguments:", "@"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreterTest);
+
 smalltalk.addMethod(
 "_testInstVarAssignment",
 smalltalk.method({
@@ -268,6 +284,22 @@ referencedClasses: []
 }),
 smalltalk.ASTInterpreterTest);
 
+smalltalk.addMethod(
+"_testReceiver",
+smalltalk.method({
+selector: "testReceiver",
+category: 'tests',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._assert_equals_(_st(self)._interpret_receiver_withArguments_("foo ^ self",_st((2)).__at((3)),smalltalk.HashedCollection._fromPairs_([])),_st((2)).__at((3)));
+return self}, function($ctx1) {$ctx1.fill(self,"testReceiver",{}, smalltalk.ASTInterpreterTest)})},
+args: [],
+source: "testReceiver\x0a\x09self \x0a    \x09assert: (self \x0a    \x09\x09interpret: 'foo ^ self'\x0a        \x09receiver: 2@3\x0a        \x09withArguments: #{})\x0a        equals: 2@3",
+messageSends: ["assert:equals:", "interpret:receiver:withArguments:", "@"],
+referencedClasses: []
+}),
+smalltalk.ASTInterpreterTest);
+
 smalltalk.addMethod(
 "_testTempAssignment",
 smalltalk.method({

+ 9 - 19
st/Compiler-Interpreter.st

@@ -1,6 +1,6 @@
 Smalltalk current createPackage: 'Compiler-Interpreter' properties: #{}!
 NodeVisitor subclass: #AIContext
-	instanceVariableNames: 'outerContext pc locals receiver selector'
+	instanceVariableNames: 'outerContext pc locals selector'
 	package: 'Compiler-Interpreter'!
 
 !AIContext methodsFor: 'accessing'!
@@ -44,27 +44,11 @@ pc: anInteger
 !
 
 receiver
-	^ receiver
+	^ self localAt: 'self'
 !
 
 receiver: anObject
-	receiver := anObject
-!
-
-selector
-	^ selector
-!
-
-selector: aString
-	selector := aString
-! !
-
-!AIContext class methodsFor: 'instance creation'!
-
-fromMethodContext: aMethodContext
-	^ self new 
-    	initializeFromMethodContext: aMethodContext;
-        yourself
+	self localAt: 'self' put: anObject
 ! !
 
 NodeVisitor subclass: #ASTInterpreter
@@ -239,6 +223,12 @@ visitSequenceNode: aNode
 
 visitValueNode: aNode
 	self continue: aNode value
+!
+
+visitVariableNode: aNode
+    self continue: (aNode binding isInstanceVar
+		ifTrue: [ self context receiver instVarAt: aNode value ]
+		ifFalse: [ self context localAt: aNode value ])
 ! !
 
 ASTInterpreter subclass: #ASTDebugger

+ 18 - 0
st/Compiler-Tests.st

@@ -86,6 +86,15 @@ testInlinedJSStatement
 		equals: 5
 !
 
+testInstVarAccess
+	self 
+    	assert: (self 
+    		interpret: 'foo ^ x'
+        	receiver: 2@3
+        	withArguments: #{})
+        equals: 2
+!
+
 testInstVarAssignment
 	self 
     	assert: (self 
@@ -99,6 +108,15 @@ testNonlocalReturn
 	self assert: (self interpret: 'foo true ifTrue: [ ^ 1 ]. ^2') equals: 1
 !
 
+testReceiver
+	self 
+    	assert: (self 
+    		interpret: 'foo ^ self'
+        	receiver: 2@3
+        	withArguments: #{})
+        equals: 2@3
+!
+
 testTempAssignment
 	self assert: (self interpret: 'foo | a | a := 2. ^ a') equals: 2
 ! !