Vladislav Folts 11 лет назад
Родитель
Сommit
6cc46c6c83
3 измененных файлов с 41 добавлено и 17 удалено
  1. BIN
      bin/compiled.zip
  2. 25 13
      src/eberon/eberon_context.js
  3. 16 4
      test/test_unit_eberon.js

BIN
bin/compiled.zip


+ 25 - 13
src/eberon/eberon_context.js

@@ -777,24 +777,30 @@ var Term = Context.Term.extend({
 var SimpleExpression = Context.SimpleExpression.extend({
     init: function EberonContext$SimpleExpression(context){
         Context.SimpleExpression.prototype.init.call(this, context);
-        this.__typePromotionInverted = false;
+        this.__typePromotion = new TypePromotionHandler();
+        this.__orTypePromotion = this.__typePromotion;
     },
     handleLogicalOr: function(){
-        if (!this.__typePromotionInverted){
-            this.handleMessage(resetTypePromotionMsg);
-            this.handleMessage(invertTypePromotionMsg);
-            this.__typePromotionInverted = true;
-        }
+        this.__orTypePromotion.reset();
+        this.__orTypePromotion.invert();
+        if (this.__orTypePromotion != this.__typePromotion)
+            this.__typePromotion.transferFrom(this.__orTypePromotion);
+        this.__orTypePromotion = new TypePromotionHandler();
     },
     handleMessage: function(msg){
-        if (this.__typePromotionInverted 
-            && resetTypePromotionMadeInSeparateStatement(msg))
+        if (this.__orTypePromotion.handleMessage(msg))
             return;
         return Context.SimpleExpression.prototype.handleMessage.call(this, msg);
     },
     endParse: function(){
-        if (this.__typePromotionInverted)
-            this.handleMessage(invertTypePromotionMsg);
+        if (this.__orTypePromotion != this.__typePromotion){
+
+            //this.__orTypePromotion.reset();
+            this.__orTypePromotion.invert();
+            this.__typePromotion.transferFrom(this.__orTypePromotion);
+            this.__typePromotion.invert();
+        }
+        this.__typePromotion.transferTo(this.parent());
         Context.SimpleExpression.prototype.endParse.call(this);
     }
 });
@@ -839,9 +845,7 @@ var TypePromotionHandler = Class.extend({
             return true;
         }
         if (msg instanceof TransferPromotedTypesMsg){
-            //log("transfer, " + this.__id);
-            Array.prototype.push.apply(this.__promotedTypes, msg.types);
-            Array.prototype.push.apply(this.__invertPromotedTypes, msg.invertTypes);
+            this.__transferFrom(msg.types, msg.invertTypes);
             return true;
         }
         switch (msg){
@@ -880,6 +884,14 @@ var TypePromotionHandler = Class.extend({
     transferTo: function(context){
         if (this.__promotedTypes.length || this.__invertPromotedTypes.length)
             context.handleMessage(new TransferPromotedTypesMsg(this.__promotedTypes, this.__invertPromotedTypes));
+    },
+    transferFrom: function(other){
+        this.__transferFrom(other.__promotedTypes, this.__invertPromotedTypes);
+    },
+    __transferFrom: function(promotedTypes, invertPromotedTypes){
+        //log("transfer, " + this.__id);
+        Array.prototype.push.apply(this.__promotedTypes, promotedTypes);
+        Array.prototype.push.apply(this.__invertPromotedTypes, invertPromotedTypes);
     }
 });
 

+ 16 - 4
test/test_unit_eberon.js

@@ -453,7 +453,8 @@ exports.suite = {
              "((b IS PDerived) = FALSE) & b.flag",
              "b IS PDerived); ASSERT(b.flag",
              "((b IS PDerived) OR (b IS PDerived)) & b.flag",
-             "(b IS PDerived) OR (b IS PDerived) OR b.flag"
+             "(b IS PDerived) OR (b IS PDerived) OR b.flag",
+             "(bVar OR (b IS PDerived)) & b.flag"
              )
         ),
     "invert type promotion in expression": testWithContext(
@@ -467,7 +468,11 @@ exports.suite = {
              "~(b IS PDerived) OR bVar OR b.flag",
              "~(b IS PDerived) OR (bVar = b.flag)",
              "~(~(b IS PDerived) OR bVar) & b.flag",
-             "~(~(b IS PDerived) OR b.flag) & b.flag"
+             "~(~(b IS PDerived) OR b.flag) & b.flag",
+             "~(b IS PDerived) OR ~(b2 IS PDerived) OR b2.flag",
+             "~(b IS PDerived) OR b.flag OR ~(b2 IS PDerived) OR b2.flag",
+             "~((b IS PDerived) & b.flag) OR b.flag OR ~(b2 IS PDerived) OR b2.flag",
+             "~((b IS PDerived) & b.flag) OR b.flag OR ~((b2 IS PDerived) & b.flag & b2.flag) OR b2.flag"
              ),
         temporaryValues.failExpressions(
              "(~(b IS PDerived) OR bVar) & b.flag",
@@ -507,6 +512,9 @@ exports.suite = {
             "IF ~(b IS PDerived) THEN ELSIF bVar THEN ELSE END; b.flag := FALSE",
             "IF bVar THEN ELSIF b IS PDerived THEN ELSE END; b.flag := FALSE",
             "IF b IS PDerived THEN ELSE b.flag := FALSE; END",
+            "IF bVar OR (b IS PDerived) THEN b.flag := FALSE; END;",
+            "IF bVar OR (b IS PDerived) THEN ELSE b.flag := FALSE; END;",
+            "IF bVar OR ~(b IS PDerived) THEN b.flag := FALSE; END;",
             "IF b IS PDerived THEN ELSIF TRUE THEN b.flag := FALSE; END"
              )
         ),
@@ -518,12 +526,16 @@ exports.suite = {
             "IF ~(b IS PDerived) THEN ELSIF ~(b2 IS PDerived) THEN b.flag := FALSE; ELSE b.flag := FALSE; b2.flag := FALSE; END;",
             "IF ~(b IS PDerived) OR bVar THEN ELSE b.flag := FALSE; END;",
             "IF ~(b IS PDerived) OR b.flag THEN ELSE b.flag := FALSE; END;",
+            "IF ~(b IS PDerived) OR (b2 IS PDerived) THEN ELSE b.flag := FALSE; END;",
+            "IF ~(b IS PDerived) OR ~(b2 IS PDerived) THEN ELSE b2.flag := FALSE; END;",
             "IF ~(b IS PDerived) THEN bVar := b IS PDerived; ELSE b.flag := FALSE; END;",
-            "IF ~(b IS PDerived) THEN ASSERT((b IS PDerived) & b.flag); ELSE b.flag := FALSE; END;"
+            "IF ~(b IS PDerived) THEN ASSERT((b IS PDerived) & b.flag); ELSE b.flag := FALSE; END;",
+            "IF bVar OR ~(b IS PDerived) THEN ELSE b.flag := FALSE; END;"
             ),
         temporaryValues.failStatements(
             "IF ~(b IS PDerived) & bVar THEN ELSE b.flag := FALSE; END; END p;",
-            "IF ~(b IS PDerived) THEN ELSIF ~(b2 IS PDerived) THEN b2.flag := FALSE; END;"
+            "IF ~(b IS PDerived) THEN ELSIF ~(b2 IS PDerived) THEN b2.flag := FALSE; END;",
+            "IF bVar OR (b IS PDerived) THEN ELSE b.flag := FALSE; END;"
             )
         ),
     "type promotion in WHILE": testWithContext(