Browse Source

factor out 'setDesignator'

Vladislav Folts 10 years ago
parent
commit
f99da833c3
4 changed files with 79 additions and 64 deletions
  1. BIN
      bin/compiled.zip
  2. 41 23
      src/context.js
  3. 10 10
      src/eberon/eberon_context.js
  4. 28 31
      src/oberon/oberon_context.js

BIN
bin/compiled.zip


+ 41 - 23
src/context.js

@@ -130,7 +130,10 @@ function checkTypeCast(fromInfo, fromType, toType, msg){
 }
 
 var ChainedContext = Class.extend({
-    init: function ChainedContext(parent){this.__parent = parent;},
+    init: function ChainedContext(parent){
+        this.__parent = parent;
+        this.attributes = parent.attributes;
+    },
     parent: function(){return this.__parent;},
     handleMessage: function(msg){return this.__parent.handleMessage(msg);},
     language: function(){return this.__parent.language();},
@@ -140,9 +143,8 @@ var ChainedContext = Class.extend({
     pushScope: function(scope){this.__parent.pushScope(scope);},
     popScope: function(){this.__parent.popScope();},
     setType: function(type){this.__parent.setType(type);},
-    setDesignator: function(d){this.__parent.setDesignator(d);},
     handleExpression: function(e){this.__parent.handleExpression(e);},
-    handleLiteral: function(s){this.__parent.handleLiteral(s);},
+    handleLiteral: function(s){},
     handleConst: function(type, value, code){this.__parent.handleConst(type, value, code);},
     genTypeName: function(){return this.__parent.genTypeName();},
     qualifyScope: function(scope){return this.__parent.qualifyScope(scope);}
@@ -470,8 +472,8 @@ exports.Designator = ChainedContext.extend({
     },
     endParse: function(){
         var code = this.__code;
-        this.parent().setDesignator(
-            new Code.Designator(code, this.__lval ? this.__lval : code, this.__currentType, this.__info, this.__scope));
+        this.parent().attributes.designator =
+            new Code.Designator(code, this.__lval ? this.__lval : code, this.__currentType, this.__info, this.__scope);
     }
 });
 
@@ -1070,27 +1072,14 @@ exports.MulOperator = ChainedContext.extend({
 exports.Term = ChainedContext.extend({
     init: function TermContext(context){
         ChainedContext.prototype.init.call(this, context);
+        this.attributes = {};
         this.__logicalNot = false;
         this.__operator = undefined;
         this.__expression = undefined;
     },
-    type: function(){return this.__expression.type();},
-    setDesignator: function(d){
-        var info = d.info();
-        if (info instanceof Type.ProcedureId){
-            var proc = Type.procedureType(info);
-            if (proc instanceof Procedure.Std)
-                throw new Errors.Error(proc.description() + " cannot be referenced");
-            var scope = d.scope();
-            if (scope instanceof Scope.Procedure)
-                throw new Errors.Error("local procedure '" + d.code() + "' cannot be referenced");
-        }
-
-        var value;
-        if (info instanceof Type.Const)
-            value = Type.constValue(info);
-        this.handleExpression(
-            Code.makeExpression(d.code(), d.type(), d, value));
+    type: function(){
+        return this.__expression ? this.__expression.type()
+                                 : this.attributes.designator.type();
     },
     handleLogicalNot: function(){
         this.__logicalNot = !this.__logicalNot;
@@ -1104,7 +1093,18 @@ exports.Term = ChainedContext.extend({
     handleFactor: function(e){
         this.handleExpression(e);
     },
-    endParse: function(){this.parent().handleTerm(this.__expression);},
+    endParse: function(){
+        var e = this.__expression;
+        if (!e){
+            var d = this.attributes.designator;
+            var value;
+            var info = d.info();
+            if (info instanceof Type.Const)
+                value = Type.constValue(info);
+            e = Code.makeExpression(d.code(), d.type(), d, value);
+        }
+        this.parent().handleTerm(e);
+    },
     handleExpression: function(e){
         promoteExpressionType(this, this.__expression, e);
         if (this.__logicalNot){
@@ -1138,6 +1138,23 @@ exports.Factor = ChainedContext.extend({
     handleLogicalNot: function(){this.parent().handleLogicalNot();}
 });
 
+function designatorAsExpression(d){
+    var info = d.info();
+    if (info instanceof Type.ProcedureId){
+        var proc = Type.procedureType(info);
+        if (proc instanceof Procedure.Std)
+            throw new Errors.Error(proc.description() + " cannot be referenced");
+        var scope = d.scope();
+        if (scope instanceof Scope.Procedure)
+            throw new Errors.Error("local procedure '" + d.code() + "' cannot be referenced");
+    }
+
+    var value;
+    if (info instanceof Type.Const)
+        value = Type.constValue(info);
+    return Code.makeExpression(d.code(), d.type(), d, value);
+}
+
 exports.Set = ChainedContext.extend({
     init: function SetContext(context){
         ChainedContext.prototype.init.call(this, context);
@@ -2018,6 +2035,7 @@ exports.assertProcStatementResult = assertProcStatementResult;
 exports.beginCallMsg = beginCallMsg;
 exports.endCallMsg = endCallMsg;
 exports.Chained = ChainedContext;
+exports.designatorAsExpression = designatorAsExpression;
 exports.endParametersMsg = endParametersMsg;
 exports.getSymbolAndScope = getSymbolAndScope;
 exports.getQIdSymbolAndScope = getQIdSymbolAndScope;

+ 10 - 10
src/eberon/eberon_context.js

@@ -432,33 +432,33 @@ var ExpressionProcedureCall = Context.Chained.extend({
     init: function EberonContext$init(context){
         Context.Chained.prototype.init.call(this, context);
     },
-    setDesignator: function(d){
-        var info = d.info();
+    endParse: function(){
         var parent = this.parent();
+        var d = this.attributes.designator;
+        var info = d.info();
+        var e;
         if (info instanceof ResultVariable){
-            var e = info.expression();
-            parent.handleExpression(new Code.Expression(d.code(), d.type(), undefined, e.constValue(), e.maxPrecedence()));
+            e = info.expression();
+            e = new Code.Expression(d.code(), d.type(), undefined, e.constValue(), e.maxPrecedence());
         }
         else
-            parent.setDesignator(d);
+            e = Context.designatorAsExpression(d);
+        parent.handleExpression(e);
     }
 });
 
 var AssignmentOrProcedureCall = Context.Chained.extend({
     init: function EberonContext$init(context){
         Context.Chained.prototype.init.call(this, context);
-        this.__left = undefined;
+        this.attributes = {};
         this.__right = undefined;
     },
-    setDesignator: function(d){
-        this.__left = d;
-    },
     handleExpression: function(e){
         this.__right = e;
     },
     codeGenerator: function(){return CodeGenerator.nullGenerator();},
     endParse: function(){
-        var d = this.__left;
+        var d = this.attributes.designator;
         var type = d.type();
         var code;
         if (this.__right){

+ 28 - 31
src/oberon/oberon_context.js

@@ -27,16 +27,21 @@ var VariableDeclaration = Context.VariableDeclaration.extend({
 var ProcedureCall = Context.Chained.extend({
     init: function ProcedureCallContext(context){
         Context.Chained.prototype.init.call(this, context);
+        this.attributes = {};
         this.__type = undefined;
         this.__id = undefined;
         this.__procCall = undefined;
         this.__code = CodeGenerator.makeSimpleGenerator();
     },
-    setDesignator: function(d){
-        this.__type = d.type();
-        this.__id = d.code();
-        this.__procCall = Context.makeProcCall(this, this.__type, d.info());
-        this.__callExpression = undefined;
+    procCall: function(){
+        if (!this.__procCall){
+            var d = this.attributes.designator;
+            this.__type = d.type();
+            this.__id = d.code();
+            this.__procCall = Context.makeProcCall(this, this.__type, d.info());
+            this.__callExpression = undefined;
+        }
+        return this.__procCall;
     },
     codeGenerator: function(){return this.__code;},
     type: function(){return this.__type;},
@@ -45,11 +50,15 @@ var ProcedureCall = Context.Chained.extend({
             return undefined;
         return Context.Chained.prototype.handleMessage.call(this, msg);
     },
-    handleExpression: function(e){this.__procCall.handleArgument(e);},
-    callExpression: function(){return this.__callExpression;},
-    endParse: function(){
-        var e = this.__procCall.end();
-        this.__callExpression = new Code.Expression(this.__id + e.code(), e.type(), undefined, e.constValue(), e.maxPrecedence());
+    handleExpression: function(e){
+        this.procCall().handleArgument(e);
+    },
+    callExpression: function(){
+        if (!this.__callExpression){
+            var e = this.procCall().end();
+            this.__callExpression = new Code.Expression(this.__id + e.code(), e.type(), undefined, e.constValue(), e.maxPrecedence());
+        }
+        return this.__callExpression;
     }
 });
 
@@ -58,7 +67,6 @@ var StatementProcedureCall = ProcedureCall.extend({
         ProcedureCall.prototype.init.call(this, context);
     },
     endParse: function(){
-        ProcedureCall.prototype.endParse.call(this);
         var e = this.callExpression();
         Context.assertProcStatementResult(e.type());
         this.parent().codeGenerator().write(e.code());
@@ -68,44 +76,33 @@ var StatementProcedureCall = ProcedureCall.extend({
 var ExpressionProcedureCall = ProcedureCall.extend({
     init: function ExpressionProcedureCall(context){
         ProcedureCall.prototype.init.call(this, context);
-        this.__designator = undefined;
         this.__hasActualParameters = false;
     },
-    setDesignator: function(d){
-        this.__designator = d;
-    },
     handleMessage: function(msg){
         if (msg == Context.beginCallMsg){
-            ProcedureCall.prototype.setDesignator.call(this, this.__designator);
             this.__hasActualParameters = true;
-            return undefined;
+            return;
         }
         return ProcedureCall.prototype.handleMessage.call(this, msg);
     },
     endParse: function(){
-        var parent = this.parent();
-        if (this.__hasActualParameters){
-            ProcedureCall.prototype.endParse.call(this);
-            parent.handleFactor(this.callExpression());
-        }
-        else{
-            var d = this.__designator;
-            parent.setDesignator(d);
-        }
+        var e = this.__hasActualParameters 
+              ? this.callExpression()
+              : Context.designatorAsExpression(this.attributes.designator); 
+        this.parent().handleFactor(e);
     }
 });
 
 var Assignment = Context.Chained.extend({
     init: function AssignmentContext(context){
         Context.Chained.prototype.init.call(this, context);
-        this.__left = undefined;
+        this.attributes = {};
     },
     codeGenerator: function(){return CodeGenerator.nullGenerator();},
-    setDesignator: function(d){
-        this.__left = Code.makeExpression(d.code(), d.type(), d);
-    },
     handleExpression: function(e){
-        this.parent().codeGenerator().write(op.assign(this.__left, e, this.language()));
+        var d = this.attributes.designator;
+        var left = Code.makeExpression(d.code(), d.type(), d);
+        this.parent().codeGenerator().write(op.assign(left, e, this.language()));
     }
 });