Procházet zdrojové kódy

Block context creation refactoring

Nicolas Petton před 11 roky
rodič
revize
a6450fdd41

+ 34 - 18
js/Compiler-Interpreter.deploy.js

@@ -687,28 +687,22 @@ smalltalk.addMethod(
 "_interpretBlockNode_continue_",
 smalltalk.method({
 selector: "interpretBlockNode:continue:",
-fn: function (aNode, aBlock) {
+fn: function (aNode,aBlock){
 var self=this;
-function $AIContext(){return smalltalk.AIContext||(typeof AIContext=="undefined"?nil:AIContext)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3,$4;
+var $1,$2;
 _st(self)._continue_value_(aBlock,(function(){
-var blockResult;
 return smalltalk.withContext(function($ctx2) {
-$1=_st($AIContext())._new();
-_st($1)._outerContext_(_st(self)._context());
-$2=_st($1)._yourself();
-_st(self)._context_($2);
-$3=self;
-_st($3)._interpret_(_st(_st(aNode)._nodes())._first());
-$4=_st($3)._result();
-blockResult=$4;
-blockResult;
-_st(self)._context_(_st(_st(self)._context())._outerContext());
-return blockResult;
-}, function($ctx2) {$ctx2.fillBlock({blockResult:blockResult},$ctx1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"interpretBlockNode:continue:",{aNode:aNode,aBlock:aBlock},smalltalk.ASTInterpreter)});},
-messageSends: ["continue:value:", "context:", "outerContext:", "context", "new", "yourself", "interpret:", "first", "nodes", "result", "outerContext"]}),
+return _st(self)._withBlockContext_((function(){
+return smalltalk.withContext(function($ctx3) {
+$1=self;
+_st($1)._interpret_(_st(_st(aNode)._nodes())._first());
+$2=_st($1)._result();
+return $2;
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"interpretBlockNode:continue:",{aNode:aNode,aBlock:aBlock},smalltalk.ASTInterpreter)})},
+messageSends: ["continue:value:", "withBlockContext:", "interpret:", "first", "nodes", "result"]}),
 smalltalk.ASTInterpreter);
 
 smalltalk.addMethod(
@@ -977,6 +971,28 @@ return $1;
 messageSends: ["ifNil:"]}),
 smalltalk.ASTInterpreter);
 
+smalltalk.addMethod(
+"_withBlockContext_",
+smalltalk.method({
+selector: "withBlockContext:",
+fn: function (aBlock){
+var self=this;
+var blockResult;
+function $AIContext(){return smalltalk.AIContext||(typeof AIContext=="undefined"?nil:AIContext)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3;
+$1=_st($AIContext())._new();
+_st($1)._outerContext_(_st(self)._context());
+$2=_st($1)._yourself();
+_st(self)._context_($2);
+blockResult=_st(aBlock)._value();
+_st(self)._context_(_st(_st(self)._context())._outerContext());
+$3=blockResult;
+return $3;
+}, function($ctx1) {$ctx1.fill(self,"withBlockContext:",{aBlock:aBlock,blockResult:blockResult},smalltalk.ASTInterpreter)})},
+messageSends: ["context:", "outerContext:", "context", "new", "yourself", "value", "outerContext"]}),
+smalltalk.ASTInterpreter);
+
 
 
 smalltalk.addClass('ASTSteppingInterpreter', smalltalk.ASTInterpreter, ['continuation', 'nextNode'], 'Compiler-Interpreter');

+ 41 - 20
js/Compiler-Interpreter.js

@@ -901,31 +901,25 @@ smalltalk.addMethod(
 smalltalk.method({
 selector: "interpretBlockNode:continue:",
 category: 'interpreting',
-fn: function (aNode, aBlock) {
+fn: function (aNode,aBlock){
 var self=this;
-function $AIContext(){return smalltalk.AIContext||(typeof AIContext=="undefined"?nil:AIContext)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3,$4;
+var $1,$2;
 _st(self)._continue_value_(aBlock,(function(){
-var blockResult;
 return smalltalk.withContext(function($ctx2) {
-$1=_st($AIContext())._new();
-_st($1)._outerContext_(_st(self)._context());
-$2=_st($1)._yourself();
-_st(self)._context_($2);
-$3=self;
-_st($3)._interpret_(_st(_st(aNode)._nodes())._first());
-$4=_st($3)._result();
-blockResult=$4;
-blockResult;
-_st(self)._context_(_st(_st(self)._context())._outerContext());
-return blockResult;
-}, function($ctx2) {$ctx2.fillBlock({blockResult:blockResult},$ctx1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"interpretBlockNode:continue:",{aNode:aNode,aBlock:aBlock},smalltalk.ASTInterpreter)});},
+return _st(self)._withBlockContext_((function(){
+return smalltalk.withContext(function($ctx3) {
+$1=self;
+_st($1)._interpret_(_st(_st(aNode)._nodes())._first());
+$2=_st($1)._result();
+return $2;
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"interpretBlockNode:continue:",{aNode:aNode,aBlock:aBlock},smalltalk.ASTInterpreter)})},
 args: ["aNode", "aBlock"],
-source: "interpretBlockNode: aNode continue: aBlock\x0a\x09self\x0a\x09\x09continue: aBlock\x0a\x09\x09value: [ \x0a\x09\x09\x09| blockResult |\x0a\x09\x09\x09\x0a\x09\x09\x09self context: (AIContext new\x0a\x09\x09\x09\x09outerContext: self context;\x0a\x09\x09\x09\x09yourself).\x0a\x09\x09\x09\x0a\x09\x09\x09blockResult := self interpret: aNode nodes first; result.\x0a\x09\x09\x09\x0a\x09\x09\x09self context: self context outerContext.\x0a\x09\x09\x09blockResult ]",
-messageSends: ["continue:value:", "context:", "outerContext:", "context", "new", "yourself", "interpret:", "first", "nodes", "result", "outerContext"],
-referencedClasses: ["AIContext"]
+source: "interpretBlockNode: aNode continue: aBlock\x0a\x09self\x0a\x09\x09continue: aBlock\x0a\x09\x09value: [ \x0a\x09\x09\x09self withBlockContext: [ \x0a\x09\x09\x09\x09self interpret: aNode nodes first; result ] ]",
+messageSends: ["continue:value:", "withBlockContext:", "interpret:", "first", "nodes", "result"],
+referencedClasses: []
 }),
 smalltalk.ASTInterpreter);
 
@@ -1275,6 +1269,33 @@ referencedClasses: []
 }),
 smalltalk.ASTInterpreter);
 
+smalltalk.addMethod(
+"_withBlockContext_",
+smalltalk.method({
+selector: "withBlockContext:",
+category: 'private',
+fn: function (aBlock){
+var self=this;
+var blockResult;
+function $AIContext(){return smalltalk.AIContext||(typeof AIContext=="undefined"?nil:AIContext)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3;
+$1=_st($AIContext())._new();
+_st($1)._outerContext_(_st(self)._context());
+$2=_st($1)._yourself();
+_st(self)._context_($2);
+blockResult=_st(aBlock)._value();
+_st(self)._context_(_st(_st(self)._context())._outerContext());
+$3=blockResult;
+return $3;
+}, function($ctx1) {$ctx1.fill(self,"withBlockContext:",{aBlock:aBlock,blockResult:blockResult},smalltalk.ASTInterpreter)})},
+args: ["aBlock"],
+source: "withBlockContext: aBlock\x0a\x09\x22Evaluate aBlock with a BlockContext:\x0a\x09- a context is pushed before aBlock evaluation.\x0a\x09- the context is poped after aBlock evaluation\x0a\x09- the result of aBlock evaluation is answered\x22\x0a\x09\x0a\x09| blockResult |\x0a\x09\x09\x09\x0a\x09self context: (AIContext new\x0a\x09\x09outerContext: self context;\x0a\x09\x09yourself).\x0a\x09\x0a\x09blockResult := aBlock value.\x0a\x09\x0a\x09self context: self context outerContext.\x0a\x09^ blockResult",
+messageSends: ["context:", "outerContext:", "context", "new", "yourself", "value", "outerContext"],
+referencedClasses: ["AIContext"]
+}),
+smalltalk.ASTInterpreter);
+
 
 
 smalltalk.addClass('ASTSteppingInterpreter', smalltalk.ASTInterpreter, ['continuation', 'nextNode'], 'Compiler-Interpreter');

+ 20 - 10
st/Compiler-Interpreter.st

@@ -264,16 +264,8 @@ interpretBlockNode: aNode continue: aBlock
 	self
 		continue: aBlock
 		value: [ 
-			| blockResult |
-			
-			self context: (AIContext new
-				outerContext: self context;
-				yourself).
-			
-			blockResult := self interpret: aNode nodes first; result.
-			
-			self context: self context outerContext.
-			blockResult ]
+			self withBlockContext: [ 
+				self interpret: aNode nodes first; result ] ]
 !
 
 interpretBlockSequenceNode: aNode continue: aBlock
@@ -426,6 +418,24 @@ messageFromSendNode: aSendNode arguments: aCollection do: aBlock
 			selector: aSendNode selector;
 			arguments: aCollection;
 			yourself)
+!
+
+withBlockContext: aBlock
+	"Evaluate aBlock with a BlockContext:
+	- a context is pushed before aBlock evaluation.
+	- the context is poped after aBlock evaluation
+	- the result of aBlock evaluation is answered"
+	
+	| blockResult |
+			
+	self context: (AIContext new
+		outerContext: self context;
+		yourself).
+	
+	blockResult := aBlock value.
+	
+	self context: self context outerContext.
+	^ blockResult
 ! !
 
 !ASTInterpreter methodsFor: 'testing'!