Pārlūkot izejas kodu

do not spread "logical not" logic between term/factor

Vladislav Folts 10 gadi atpakaļ
vecāks
revīzija
beed56bc82
4 mainītis faili ar 35 papildinājumiem un 29 dzēšanām
  1. BIN
      bin/compiled.zip
  2. 17 18
      src/context.js
  3. 17 10
      src/eberon/eberon_context.js
  4. 1 1
      test/expected/logical.js

BIN
bin/compiled.zip


+ 17 - 18
src/context.js

@@ -1058,7 +1058,6 @@ 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;
     },
@@ -1066,15 +1065,7 @@ exports.Term = ChainedContext.extend({
         return this.__expression ? this.__expression.type()
                                  : this.attributes.designator.type();
     },
-    handleLogicalNot: function(){
-        this.__logicalNot = !this.__logicalNot;
-        this.parent().setType(basicTypes.bool);
-    },
     handleOperator: function(o){this.__operator = o;},
-    handleConst: function(type, value, code){
-        this.handleExpression(Code.makeExpression(
-            code, type, undefined, value));
-    },
     handleFactor: function(e){
         this.handleExpression(e);
     },
@@ -1092,10 +1083,6 @@ exports.Term = ChainedContext.extend({
     },
     handleExpression: function(e){
         promoteExpressionType(this, this.__expression, e);
-        if (this.__logicalNot){
-            e = op.not(e);
-            this.__logicalNot = false;
-        }
         if (this.__operator)
             e = this.__expression ? this.__operator(this.__expression, e)
                                   : this.__operator(e);
@@ -1106,6 +1093,8 @@ exports.Term = ChainedContext.extend({
 exports.Factor = ChainedContext.extend({
     init: function FactorContext(context){
         ChainedContext.prototype.init.call(this, context);
+        this.__logicalNot = false;
+        this.__factor = undefined;
     },
     type: function(){return this.parent().type();},
     handleLiteral: function(s){
@@ -1116,18 +1105,28 @@ exports.Factor = ChainedContext.extend({
         else if (s == "FALSE")
             this.handleConst(basicTypes.bool, Code.makeIntConst(0), "false");
         else if (s == "~")
-            this.parent().handleLogicalNot();
+            this.handleLogicalNot();
     },
     handleConst: function(type, value, code){
-        this.parent().handleConst(type, value, code);
+        this.__factor = Code.makeExpression(
+            code, type, undefined, value);
     },
     handleFactor: function(e){
-        this.parent().handleFactor(e);
+        this.__factor = e;
     },
     handleExpression: function(e){
-        this.parent().handleExpression(e);
+        this.__factor = e;
+    },
+    handleLogicalNot: function(){
+        this.__logicalNot = true;
     },
-    handleLogicalNot: function(){this.parent().handleLogicalNot();}
+    endParse: function(){
+        if (this.__logicalNot){
+            checkTypeMatch(this.__factor.type(), basicTypes.bool);
+            this.__factor = op.not(this.__factor);
+        }
+        this.parent().handleFactor(this.__factor);
+    }
 });
 
 function designatorAsExpression(d){

+ 17 - 10
src/eberon/eberon_context.js

@@ -809,7 +809,20 @@ var ProcOrMethodDecl = Context.ProcDecl.extend({
     }
 });
 
-var Factor = Context.Factor;
+var Factor = Context.Factor.extend({
+    init: function EberonContext$Factor(context){
+        Context.Factor.prototype.init.call(this, context);
+    },
+    handleLogicalNot: function(){
+        Context.Factor.prototype.handleLogicalNot.call(this);
+        var p = this.getCurrentPromotion();
+        if (p)
+            p.invert();
+    },
+    getCurrentPromotion: function(){
+        return this.parent().getCurrentPromotion();
+    }
+});
 
 var AddOperator = Context.AddOperator.extend({
     init: function EberonContext$AddOperator(context){
@@ -916,13 +929,13 @@ var Term = Context.Term.extend({
     handleMessage: function(msg){
         if (msg instanceof PromoteTypeMsg) {
             var promoted = msg.info;
-            var p = this.__getCurrentPromotion();
+            var p = this.getCurrentPromotion();
             if (p)
                 p.promote(promoted, msg.type);
             return;
         }
         if (msg instanceof BeginTypePromotionOrMsg){
-            var cp = this.__getCurrentPromotion();
+            var cp = this.getCurrentPromotion();
             if (cp)
                 msg.result = cp.makeOr();
             return;
@@ -935,13 +948,7 @@ var Term = Context.Term.extend({
         else
             this.__andHandled = true;
     },
-    handleLogicalNot: function(){
-        Context.Term.prototype.handleLogicalNot.call(this);
-        var p = this.__getCurrentPromotion();
-        if (p)
-            p.invert();
-    },
-    __getCurrentPromotion: function(){
+    getCurrentPromotion: function(){
         if (!this.__currentPromotion){
             var msg = new BeginTypePromotionAndMsg();
             this.parent().handleMessage(msg);

+ 1 - 1
test/expected/logical.js

@@ -6,7 +6,7 @@ b1 = b1 && b2;
 b1 = !b2;
 b1 = b1 && b2 || !b1;
 b1 = b2 && !b1;
-b1 = b2 || b1;
+b1 = b2 || !!b1;
 b1 = b2 || !!(b1 && b2);
 b1 = !b1 && !b2;
 }();