Jelajahi Sumber

js -> eberon transition
fix bug after type promotion for dereferenced pointer

Vladislav Folts 10 tahun lalu
induk
melakukan
fbde0ffd0c

TEMPAT SAMPAH
bin/compiled.zip


+ 15 - 18
src/eberon/EberonContextDesignator.ob

@@ -23,14 +23,9 @@ TYPE
         expression: Expression.PType;
     END;
 
-    TypeNarrowVariableBase* = RECORD(Types.Variable)
-    END;
-
-    TypeNarrowVariable* = RECORD(TypeNarrowVariableBase)
+    TypeNarrowVariable* = RECORD(EberonTypePromotion.Variable)
         PROCEDURE TypeNarrowVariable*(type: Types.PStorageType; isRef, isReadOnly: BOOLEAN; code: STRING);
 
-        PROCEDURE setType(type: Types.PStorageType);
-
         mType: Types.PStorageType;
         isRef: BOOLEAN;
         readOnly: BOOLEAN;
@@ -38,11 +33,9 @@ TYPE
     END;
     PTypeNarrowVariable = POINTER TO TypeNarrowVariable;
 
-    DereferencedTypeNarrowVariable = RECORD(TypeNarrowVariableBase)
+    DereferencedTypeNarrowVariable = RECORD(EberonTypePromotion.Variable)
         PROCEDURE DereferencedTypeNarrowVariable(var: PTypeNarrowVariable);
 
-        PROCEDURE setType(type: Types.PStorageType);
-
         var: PTypeNarrowVariable;
     END;
 
@@ -56,14 +49,14 @@ TYPE
     END;
 
     PromoteTypeMsg* = RECORD(ContextHierarchy.Message)
-        PROCEDURE PromoteTypeMsg(info: EberonTypePromotion.PVariable; type: Types.PType);
+        PROCEDURE PromoteTypeMsg*(info: EberonTypePromotion.PVariable; type: Types.PStorageType);
 
         info-: EberonTypePromotion.PVariable;
-        type-: Types.PType;
+        type-: Types.PStorageType;
     END;
 
     TransferPromotedTypesMsg* = RECORD(ContextHierarchy.Message)
-        PROCEDURE TransferPromotedTypesMsg(p: EberonTypePromotion.PCombined); 
+        PROCEDURE TransferPromotedTypesMsg*(p: EberonTypePromotion.PCombined); 
 
         promotion: EberonTypePromotion.PCombined;
     END;
@@ -177,6 +170,12 @@ BEGIN
     RETURN result;
 END;
 
+PROCEDURE makePointer(type: Types.PStorageType): Record.PPointer;
+BEGIN
+    typeId <- NEW TypeId.Type(type);
+    RETURN NEW Record.Pointer("", typeId);
+END;
+
 PROCEDURE Type.handleMessage(VAR msg: ContextHierarchy.Message): Object.PType;
 VAR
     result: Object.PType;
@@ -212,9 +211,7 @@ BEGIN
         ContextDesignator.advance(SELF, type, info, "this", "", FALSE);
     ELSIF s = "POINTER" THEN
         type <- SELF.handleMessage(getSelfAsPointerMsg)(Types.PStorageType);
-        typeId <- NEW TypeId.Type(type);
-        pointerType <- NEW Record.Pointer("", typeId);
-        ContextDesignator.advance(SELF, pointerType, NEW SelfAsPointer(), "", "", FALSE);
+        ContextDesignator.advance(SELF, makePointer(type), NEW SelfAsPointer(), "", "", FALSE);
     ELSIF s = "SUPER" THEN
         ms <- SELF.handleMessage(getMethodSuperMsg)(PSuperMethodInfo);
         ContextDesignator.advance(SELF, ms.info.type, ms.info, ms.code, "", FALSE);
@@ -340,12 +337,12 @@ PROCEDURE DereferencedTypeNarrowVariable.DereferencedTypeNarrowVariable(var: PTy
 END;
 
 PROCEDURE DereferencedTypeNarrowVariable.type(): Types.PStorageType;
-    RETURN SELF.var.type();
+    RETURN Record.pointerBase(SELF.var.type()(Record.PPointer)^);
 END;
 
 PROCEDURE DereferencedTypeNarrowVariable.setType(type: Types.PStorageType);
 BEGIN
-    SELF.var.setType(type);
+    SELF.var.setType(makePointer(type));
 END;
 
 PROCEDURE DereferencedTypeNarrowVariable.isReference(): BOOLEAN;
@@ -369,7 +366,7 @@ PROCEDURE OperatorNewMsg.OperatorNewMsg(e: Expression.PType)
     | expression(e);
 END;
 
-PROCEDURE PromoteTypeMsg.PromoteTypeMsg(info: EberonTypePromotion.PVariable; type: Types.PType)
+PROCEDURE PromoteTypeMsg.PromoteTypeMsg(info: EberonTypePromotion.PVariable; type: Types.PStorageType)
     | info(info),
       type(type);
 END;

+ 282 - 4
src/eberon/EberonContextExpression.ob

@@ -1,9 +1,32 @@
 MODULE EberonContextExpression;
 IMPORT
-    ContextExpression, ContextHierarchy, 
-    EberonContextDesignator, EberonContextProcedure, EberonTypePromotion, 
-    Object;
+    Context, ContextExpression, ContextHierarchy, 
+    EberonContextDesignator, EberonContextProcedure, 
+    EberonMap, EberonOperator, EberonString, EberonTypePromotion, 
+    Expression, LanguageContext,
+    JS,
+    Object, Types;
 TYPE
+    ExpressionNode* = RECORD(ContextExpression.ExpressionNode)
+        PROCEDURE ExpressionNode(parent: ContextExpression.PExpressionHandler);
+
+        PROCEDURE handleTypePromotion(promotion: EberonTypePromotion.PCombined);
+
+        currentTypePromotion: EberonTypePromotion.PCombined;
+    END;
+    PExpressionNode = POINTER TO ExpressionNode;
+
+    SimpleExpression* = RECORD(ContextExpression.SimpleExpression)
+        PROCEDURE SimpleExpression(parent: PExpressionNode);
+
+        PROCEDURE handleLogicalOr();
+
+        parentExppression: PExpressionNode;
+        typePromotion: EberonTypePromotion.PCombined;
+        currentPromotion: EberonTypePromotion.PMaybe;
+        orHandled: BOOLEAN;
+    END;
+
     Term* = RECORD(ContextExpression.Term)
         PROCEDURE getCurrentPromotion(): EberonTypePromotion.PMaybe;
         PROCEDURE handleLogicalAnd();
@@ -16,7 +39,16 @@ TYPE
     Factor* = RECORD(ContextExpression.Factor)
     END;
 
-    BeginTypePromotionAndMsg* = RECORD(ContextHierarchy.Message)
+    AddOperator* = RECORD(ContextExpression.AddOperator)
+    END;
+
+    MulOperator* = RECORD(ContextExpression.MulOperator)
+    END;
+
+    RelationOps = RECORD(ContextExpression.RelationOps)
+    END;
+
+    BeginTypePromotionAndMsg = RECORD(ContextHierarchy.Message)
         result: EberonTypePromotion.PCombined;
     END;
 
@@ -24,6 +56,112 @@ TYPE
         result: EberonTypePromotion.PMaybe;
     END;
 
+VAR
+    relationOps: POINTER TO RelationOps;
+
+PROCEDURE ExpressionNode.ExpressionNode(parent: ContextExpression.PExpressionHandler)
+    | SUPER(parent, relationOps);
+END;
+
+PROCEDURE ExpressionNode.handleMessage(VAR msg: ContextHierarchy.Message): Object.PType;
+VAR
+    result: Object.PType;
+BEGIN
+    IF msg IS EberonContextDesignator.TransferPromotedTypesMsg THEN
+    ELSE
+        result := SUPER(msg);
+    END;
+    RETURN result;
+END;
+
+PROCEDURE ExpressionNode.handleTypePromotion(promotion: EberonTypePromotion.PCombined);
+BEGIN
+    SELF.currentTypePromotion := promotion;
+END;
+
+PROCEDURE ExpressionNode.handleLiteral(s: STRING);
+BEGIN
+    IF SELF.currentTypePromotion # NIL THEN
+        SELF.currentTypePromotion.clear();
+    END;
+    SUPER(s);
+END;
+
+PROCEDURE ExpressionNode.doRelationOperation(left, right: Expression.PType; relation: STRING): ContextExpression.BinaryOperatorCx;
+VAR
+    result: ContextExpression.BinaryOperatorCx;
+BEGIN
+    IF (relation = "IN") & (right.type() IS EberonMap.PType) THEN
+        EberonContextDesignator.checkMapKeyType(left.type());
+        result := EberonOperator.inMap;            
+    ELSE
+        result := SUPER(left, right, relation);
+    END;
+    RETURN result;
+END;
+
+PROCEDURE ExpressionNode.endParse(): BOOLEAN;
+BEGIN
+    IF SELF.currentTypePromotion # NIL THEN
+        void <- SELF.parent().handleMessage(
+            NEW EberonContextDesignator.TransferPromotedTypesMsg(SELF.currentTypePromotion)^);
+    END;
+    RETURN SUPER();
+END;
+
+PROCEDURE SimpleExpression.SimpleExpression(parent: PExpressionNode)
+    | SUPER(parent),
+      parentExppression(parent);
+END;
+
+PROCEDURE SimpleExpression.handleLogicalOr();
+BEGIN
+    IF SELF.typePromotion # NIL THEN
+        SELF.currentPromotion := SELF.typePromotion.next();
+    ELSE
+        SELF.orHandled := TRUE;
+    END;
+END;
+
+PROCEDURE getCurrentPromotion(VAR e: SimpleExpression): EberonTypePromotion.PMaybe;
+BEGIN
+    IF e.currentPromotion = NIL THEN
+        msg <- NEW EberonContextProcedure.BeginTypePromotionOrMsg();
+        void <- e.parent().handleMessage(msg^);
+        e.typePromotion := msg.result;
+        IF e.typePromotion # NIL THEN
+            IF e.orHandled THEN
+                unused <- e.typePromotion.next();
+            END;
+            e.currentPromotion := e.typePromotion.next();
+        END;
+    END;
+    RETURN e.currentPromotion;
+END;
+
+PROCEDURE SimpleExpression.handleMessage(VAR msg: ContextHierarchy.Message): Object.PType;
+VAR
+    result: Object.PType;
+BEGIN
+    IF msg IS BeginTypePromotionAndMsg THEN
+        p <- getCurrentPromotion(SELF);
+        IF p # NIL THEN
+            msg.result := p.makeAnd();
+        END;
+    ELSE
+        result := SUPER(msg);
+    END;
+    RETURN result;
+END;
+
+PROCEDURE SimpleExpression.endParse(): BOOLEAN;
+BEGIN
+    IF SELF.typePromotion # NIL THEN
+        SELF.parentExppression.handleTypePromotion(SELF.typePromotion);
+    END;
+    RETURN SUPER();
+END;
+
 PROCEDURE Term.handleMessage(VAR msg: ContextHierarchy.Message): Object.PType;
 VAR
     result: Object.PType;
@@ -84,4 +222,144 @@ BEGIN
     END;
 END;
 
+PROCEDURE AddOperator.doMatchPlusOperator(type: Types.PType): ContextExpression.BinaryOperator;
+VAR
+    result: ContextExpression.BinaryOperator;
+BEGIN
+    IF (type = EberonString.string) OR (type IS Types.PString) THEN
+        result := EberonOperator.addStr;
+    ELSE
+        result := SUPER(type);
+    END;
+    RETURN result;
+END;
+
+PROCEDURE AddOperator.doExpectPlusOperator(): STRING;
+    RETURN "numeric type or SET or STRING";
+END;
+
+PROCEDURE AddOperator.endParse(): BOOLEAN;
+BEGIN
+    SELF.parent()^(SimpleExpression).handleLogicalOr();
+    RETURN TRUE;
+END;
+
+PROCEDURE MulOperator.endParse(): BOOLEAN;
+BEGIN
+    SELF.parent()^(Term).handleLogicalAnd();
+    RETURN TRUE;
+END;
+
+PROCEDURE RelationOps.eq(type: Types.PType): ContextExpression.BinaryOperatorCx;
+VAR
+    result: ContextExpression.BinaryOperatorCx;
+BEGIN
+    IF type = EberonString.string THEN
+        result := EberonOperator.equalStr;
+    ELSE
+        result := SUPER(type);
+    END;
+    RETURN result;
+END;
+
+PROCEDURE RelationOps.notEq(type: Types.PType): ContextExpression.BinaryOperatorCx;
+VAR
+    result: ContextExpression.BinaryOperatorCx;
+BEGIN
+    IF type = EberonString.string THEN
+        result := EberonOperator.notEqualStr;
+    ELSE
+        result := SUPER(type);
+    END;
+    RETURN result;
+END;
+
+PROCEDURE RelationOps.less(type: Types.PType): ContextExpression.BinaryOperatorCx;
+VAR
+    result: ContextExpression.BinaryOperatorCx;
+BEGIN
+    IF type = EberonString.string THEN
+        result := EberonOperator.lessStr;
+    ELSE
+        result := SUPER(type);
+    END;
+    RETURN result;
+END;
+
+PROCEDURE RelationOps.greater(type: Types.PType): ContextExpression.BinaryOperatorCx;
+VAR
+    result: ContextExpression.BinaryOperatorCx;
+BEGIN
+    IF type = EberonString.string THEN
+        result := EberonOperator.greaterStr;
+    ELSE
+        result := SUPER(type);
+    END;
+    RETURN result;
+END;
+
+PROCEDURE RelationOps.lessEq(type: Types.PType): ContextExpression.BinaryOperatorCx;
+VAR
+    result: ContextExpression.BinaryOperatorCx;
+BEGIN
+    IF type = EberonString.string THEN
+        result := EberonOperator.lessEqualStr;
+    ELSE
+        result := SUPER(type);
+    END;
+    RETURN result;
+END;
+
+PROCEDURE RelationOps.greaterEq(type: Types.PType): ContextExpression.BinaryOperatorCx;
+VAR
+    result: ContextExpression.BinaryOperatorCx;
+BEGIN
+    IF type = EberonString.string THEN
+        result := EberonOperator.greaterEqualStr;
+    ELSE
+        result := SUPER(type);
+    END;
+    RETURN result;
+END;
+
+PROCEDURE RelationOps.is(cx: ContextHierarchy.Node): ContextExpression.BinaryOperatorCx;
+VAR
+    impl: ContextExpression.BinaryOperatorCx;
+    r: ContextExpression.BinaryOperatorCx;
+
+    PROCEDURE is(left, right: Expression.PType; lcx: LanguageContext.PType): Expression.PType;
+    BEGIN
+        d <- left.designator();
+        IF d # NIL THEN
+            v <- d.info();
+            IF v IS EberonTypePromotion.PVariable THEN
+                void <- cx.handleMessage(
+                    NEW EberonContextDesignator.PromoteTypeMsg(
+                        v, 
+                        ContextExpression.unwrapType(right.designator().info()))^);
+            END;
+        END;
+        RETURN impl(left, right, lcx);
+    END;
+BEGIN
+    impl := SUPER(cx);
+    JS.do("r = is"); (*allow closure*)
+    RETURN r;
+END;
+
+PROCEDURE RelationOps.coalesceType(leftType, rightType: Types.PType): Types.PType;
+VAR
+    result: Types.PType;
+BEGIN
+    IF     (((leftType = EberonString.string) & (rightType IS Types.PString))
+        OR ((rightType = EberonString.string) & (leftType IS Types.PString))) THEN
+        result := EberonString.string;
+    ELSE
+        result := SUPER(leftType, rightType);
+    END;
+    RETURN result;
+END;
+
+BEGIN
+    NEW(relationOps);
 END EberonContextExpression.

+ 7 - 7
src/eberon/EberonOperator.ob

@@ -45,31 +45,31 @@ PROCEDURE addStr*(left, right: Expression.PType): Expression.PType;
     RETURN Operator.binaryWithCode(left, right, opAddStr, " + ", CodePrecedence.addSub)
 END addStr;
 
-PROCEDURE equalStr*(left, right: Expression.PType): Expression.PType;
+PROCEDURE equalStr*(left, right: Expression.PType; cx: LanguageContext.PType): Expression.PType;
     RETURN Operator.equal(left, right, opEqualStr, Operator.equalCode)
 END equalStr;
 
-PROCEDURE notEqualStr*(left, right: Expression.PType): Expression.PType;
+PROCEDURE notEqualStr*(left, right: Expression.PType; cx: LanguageContext.PType): Expression.PType;
     RETURN Operator.equal(left, right, opNotEqualStr, Operator.notEqualCode)
 END notEqualStr;
 
-PROCEDURE lessStr*(left, right: Expression.PType): Expression.PType;
+PROCEDURE lessStr*(left, right: Expression.PType; cx: LanguageContext.PType): Expression.PType;
     RETURN Operator.relational(left, right, opLessStr, " < ")
 END lessStr;
 
-PROCEDURE greaterStr*(left, right: Expression.PType): Expression.PType;
+PROCEDURE greaterStr*(left, right: Expression.PType; cx: LanguageContext.PType): Expression.PType;
     RETURN Operator.relational(left, right, opGreaterStr, " > ")
 END greaterStr;
 
-PROCEDURE lessEqualStr*(left, right: Expression.PType): Expression.PType;
+PROCEDURE lessEqualStr*(left, right: Expression.PType; cx: LanguageContext.PType): Expression.PType;
     RETURN Operator.relational(left, right, opLessEqualStr, " <= ")
 END lessEqualStr;
 
-PROCEDURE greaterEqualStr*(left, right: Expression.PType): Expression.PType;
+PROCEDURE greaterEqualStr*(left, right: Expression.PType; cx: LanguageContext.PType): Expression.PType;
     RETURN Operator.relational(left, right, opGraterEqualStr, " >= ")
 END greaterEqualStr;
 
-PROCEDURE inMap*(left, right: Expression.PType; rtl: OberonRtl.PType): Expression.PType;
+PROCEDURE inMap*(left, right: Expression.PType; cx: LanguageContext.PType): Expression.PType;
     RETURN Expression.makeSimple("Object.prototype.hasOwnProperty.call(" + right.code() + ", " + left.code() + ")",
                                  Types.basic.bool);
 END;

+ 8 - 9
src/eberon/EberonTypePromotion.ob

@@ -2,9 +2,8 @@ MODULE EberonTypePromotion;
 IMPORT
     Types;
 TYPE
-    Variable = RECORD
-        PROCEDURE type(): Types.PType;
-        PROCEDURE setType(type: Types.PType);
+    Variable* = RECORD(Types.Variable)
+        PROCEDURE setType*(type: Types.PStorageType);
     END;
     PVariable* = POINTER TO Variable;
 
@@ -16,12 +15,12 @@ TYPE
     PType = POINTER TO Type;
 
     ForVariable* = RECORD(Type)
-        PROCEDURE ForVariable(v: PVariable; type: Types.PType; inverted: BOOLEAN);
+        PROCEDURE ForVariable(v: PVariable; type: Types.PStorageType; inverted: BOOLEAN);
 
         PROCEDURE invert();
 
         v: PVariable;
-        type, originalType: Types.PType;
+        type, originalType: Types.PStorageType;
         inverted: BOOLEAN;
     END;
 
@@ -53,16 +52,16 @@ TYPE
     Maybe = RECORD
         PROCEDURE Maybe(handler: PCombined);
 
-        PROCEDURE promote*(v: PVariable; type: Types.PType);
+        PROCEDURE promote*(v: PVariable; type: Types.PStorageType);
         PROCEDURE invert*();
         PROCEDURE makeOr*(): PCombined;
-        PROCEDURE makeAnd(): PCombined;
+        PROCEDURE makeAnd*(): PCombined;
 
         inverted: BOOLEAN;
         handler: PCombined;
     END;
 
-PROCEDURE ForVariable.ForVariable(v: PVariable; type: Types.PType; inverted: BOOLEAN)
+PROCEDURE ForVariable.ForVariable(v: PVariable; type: Types.PStorageType; inverted: BOOLEAN)
     | v(v),
       type(type),
       originalType(v.type()),
@@ -104,7 +103,7 @@ BEGIN
     handler.current := p;
 END;
 
-PROCEDURE Maybe.promote(v: PVariable; type: Types.PType);
+PROCEDURE Maybe.promote(v: PVariable; type: Types.PStorageType);
 BEGIN
     handlePromotion(SELF.handler^, NEW ForVariable(v, type, SELF.inverted));
 END;

+ 0 - 160
src/eberon/eberon_context.js

@@ -315,162 +315,6 @@ var BaseInit = ChainedContext.extend({
     }
 });
 
-var AddOperator = Class.extend.call(ContextExpression.AddOperator, {
-    init: function EberonContext$AddOperator(context){
-        ContextExpression.AddOperator.call(this, context);
-    },
-    doMatchPlusOperator: function(type){
-        if (type == EberonString.string() || type instanceof Type.String)
-            return eOp.addStr;
-        return ContextExpression.AddOperator.prototype.doMatchPlusOperator.call(this, type);
-    },
-    doExpectPlusOperator: function(){return "numeric type or SET or STRING";},
-    endParse: function(){
-        this.parent().handleLogicalOr();
-    }
-});
-
-var MulOperator = Class.extend.call(ContextExpression.MulOperator, {
-    init: function EberonContext$MulOperator(context){
-        ContextExpression.MulOperator.call(this, context);
-    },
-    endParse: function(s){
-        this.parent().handleLogicalAnd();
-    }
-});
-
-var RelationOps = Class.extend.call(ContextExpression.RelationOps, {
-    init: function EberonContext$RelationOps(){
-        ContextExpression.RelationOps.call(this);
-    },
-    eq: function(type){
-        return type == EberonString.string() 
-            ? eOp.equalStr
-            : ContextExpression.RelationOps.prototype.eq.call(this, type);
-    },
-    notEq: function(type){
-        return type == EberonString.string() 
-            ? eOp.notEqualStr
-            : ContextExpression.RelationOps.prototype.notEq.call(this, type);
-    },
-    less: function(type){
-        return type == EberonString.string() 
-            ? eOp.lessStr
-            : ContextExpression.RelationOps.prototype.less.call(this, type);
-    },
-    greater: function(type){
-        return type == EberonString.string() 
-            ? eOp.greaterStr
-            : ContextExpression.RelationOps.prototype.greater.call(this, type);
-    },
-    lessEq: function(type){
-        return type == EberonString.string() 
-            ? eOp.lessEqualStr
-            : ContextExpression.RelationOps.prototype.lessEq.call(this, type);
-    },
-    greaterEq: function(type){
-        return type == EberonString.string() 
-            ? eOp.greaterEqualStr
-            : ContextExpression.RelationOps.prototype.greaterEq.call(this, type);
-    },
-    is: function(context){
-        var impl = ContextExpression.RelationOps.prototype.is.call(this, context);
-        return function(left, right){
-            var d = left.designator();
-            if (d){
-                var v = d.info();
-                if (v instanceof EberonContextDesignator.TypeNarrowVariableBase)
-                    context.handleMessage(new EberonContextDesignator.PromoteTypeMsg(v, ContextExpression.unwrapType(right.designator().info())));
-            }
-            return impl(left, right);
-        };
-    },
-    coalesceType: function(leftType, rightType){
-        if ((leftType == EberonString.string() && rightType instanceof Type.String)
-            || (rightType == EberonString.string() && leftType instanceof Type.String))
-            return EberonString.string();
-        return ContextExpression.RelationOps.prototype.coalesceType.call(this, leftType, rightType);
-    }
-});
-
-var SimpleExpression = Class.extend.call(ContextExpression.SimpleExpression, {
-    init: function EberonContext$SimpleExpression(context){
-        ContextExpression.SimpleExpression.call(this, context);
-        this.__typePromotion = undefined;
-        this.__currentTypePromotion = undefined;
-        this.__orHandled = false;
-    },
-    handleLogicalOr: function(){
-        if (this.__typePromotion)
-            this.__currentPromotion = this.__typePromotion.next();
-        else
-            this.__orHandled = true;
-    },
-    handleMessage: function(msg){
-        if (msg instanceof EberonContextExpression.BeginTypePromotionAndMsg){
-            var p = this.__getCurrentPromotion();
-            if (p)
-                msg.result = p.makeAnd();
-            return;
-        }
-        return ContextExpression.SimpleExpression.prototype.handleMessage.call(this, msg);
-    },
-    endParse: function(){
-        if (this.__typePromotion)
-            this.parent().handleTypePromotion(this.__typePromotion);
-        ContextExpression.SimpleExpression.prototype.endParse.call(this);
-    },
-    __getCurrentPromotion: function(){
-        if (!this.__currentPromotion){
-            var msg = new EberonContextProcedure.BeginTypePromotionOrMsg();
-            this.parent().handleMessage(msg);
-            this.__typePromotion = msg.result;
-            if (this.__typePromotion){
-                if (this.__orHandled)
-                    this.__typePromotion.next();
-                this.__currentPromotion = this.__typePromotion.next();
-            }
-        }
-        return this.__currentPromotion;
-    }
-});
-
-var relationOps = new RelationOps();
-
-var ExpressionContext = Class.extend.call(ContextExpression.ExpressionNode, {
-    init: function EberonContext$Expression(context){
-        ContextExpression.ExpressionNode.call(this, context, relationOps);
-        this.__typePromotion = undefined;
-        this.__currentTypePromotion = undefined;
-    },
-    handleMessage: function(msg){
-        if (msg instanceof EberonContextDesignator.TransferPromotedTypesMsg)
-            return;
-        return ContextExpression.ExpressionNode.prototype.handleMessage.call(this, msg);
-    },
-    handleTypePromotion: function(t){
-        this.__currentTypePromotion = t;
-    },
-    handleLiteral: function(s){
-        if (this.__currentTypePromotion){
-            this.__currentTypePromotion.clear();
-        }
-        ContextExpression.ExpressionNode.prototype.handleLiteral.call(this, s);
-    },
-    endParse: function(){
-        if (this.__currentTypePromotion)
-            this.parent().handleMessage(new EberonContextDesignator.TransferPromotedTypesMsg(this.__currentTypePromotion));
-        return ContextExpression.ExpressionNode.prototype.endParse.call(this);
-    },
-    doRelationOperation: function(left, right, relation){
-        if (relation == "IN" && right.type() instanceof EberonMap.Type){
-            EberonContextDesignator.checkMapKeyType(left.type());
-            return eOp.inMap;            
-        }
-        return ContextExpression.ExpressionNode.prototype.doRelationOperation.call(this, left, right, relation);
-    }
-});
-
 var OperatorScopes = Class.extend({
     init: function EberonContext$OperatorScopes(context){
         this.__context = context;
@@ -818,13 +662,11 @@ var ModuleDeclaration = Class.extend.call(ContextModule.Declaration, {
     }
 });
 
-exports.AddOperator = AddOperator;
 exports.ArrayDecl = ArrayDecl;
 exports.ArrayDimensions = ArrayDimensions;
 exports.BaseInit = BaseInit;
 exports.CaseLabel = CaseLabel;
 exports.ConstDecl = ConstDecl;
-exports.Expression = ExpressionContext;
 exports.ExpressionProcedureCall = ExpressionProcedureCall;
 exports.For = For;
 exports.ForEach = ForEach;
@@ -834,11 +676,9 @@ exports.FormalType = FormalType;
 exports.Identdef = Identdef;
 exports.If = If;
 exports.ModuleDeclaration = ModuleDeclaration;
-exports.MulOperator = MulOperator;
 exports.AssignmentOrProcedureCall = AssignmentOrProcedureCall;
 exports.MapDecl = MapDecl;
 exports.Repeat = Repeat;
-exports.SimpleExpression = SimpleExpression;
 exports.InPlaceVariableInit = InPlaceVariableInit;
 exports.InPlaceVariableInitFor = InPlaceVariableInitFor;
 exports.OperatorNew = OperatorNew;

+ 4 - 4
src/eberon/eberon_grammar.js

@@ -151,10 +151,10 @@ exports.language = {
             FormalParameters:   EbContext.FormalParameters,
             FormalType:         EbContext.FormalType,
             Term:               EberonContextExpression.Term,
-            AddOperator:        EbContext.AddOperator,
-            MulOperator:        EbContext.MulOperator,
-            SimpleExpression:   EbContext.SimpleExpression, 
-            Expression:         EbContext.Expression,
+            AddOperator:        EberonContextExpression.AddOperator,
+            MulOperator:        EberonContextExpression.MulOperator,
+            SimpleExpression:   EberonContextExpression.SimpleExpression, 
+            Expression:         EberonContextExpression.ExpressionNode,
             For:                EbContext.For,
             While:              EbContext.While,
             If:                 EbContext.If,

+ 16 - 16
src/ob/ContextExpression.ob

@@ -9,31 +9,31 @@ TYPE
     END;
     PExpressionHandler* = POINTER TO ExpressionHandler;
 
-    BinaryOperator = PROCEDURE(l, r: Expression.PType): Expression.PType;
-    BinaryOperatorCx = PROCEDURE(l, r: Expression.PType; cx: LanguageContext.PType): Expression.PType;
+    BinaryOperator* = PROCEDURE(l, r: Expression.PType): Expression.PType;
+    BinaryOperatorCx* = PROCEDURE(l, r: Expression.PType; cx: LanguageContext.PType): Expression.PType;
 
     RelationOps* = RECORD
-        PROCEDURE eq(type: Types.PType): BinaryOperatorCx;
-        PROCEDURE notEq(type: Types.PType): BinaryOperatorCx;
-        PROCEDURE less(type: Types.PType): BinaryOperatorCx;
-        PROCEDURE greater(type: Types.PType): BinaryOperatorCx;
-        PROCEDURE lessEq(type: Types.PType): BinaryOperatorCx;
-        PROCEDURE greaterEq(type: Types.PType): BinaryOperatorCx;
-        PROCEDURE is(cx: Context.Type): BinaryOperatorCx;
+        PROCEDURE eq*(type: Types.PType): BinaryOperatorCx;
+        PROCEDURE notEq*(type: Types.PType): BinaryOperatorCx;
+        PROCEDURE less*(type: Types.PType): BinaryOperatorCx;
+        PROCEDURE greater*(type: Types.PType): BinaryOperatorCx;
+        PROCEDURE lessEq*(type: Types.PType): BinaryOperatorCx;
+        PROCEDURE greaterEq*(type: Types.PType): BinaryOperatorCx;
+        PROCEDURE is*(cx: ContextHierarchy.Node): BinaryOperatorCx;
 
         PROCEDURE eqExpect(): STRING;
         PROCEDURE strongRelExpect(): STRING;
         PROCEDURE relExpect(): STRING;
 
-        PROCEDURE coalesceType(leftType, rightType: Types.PType): Types.PType;
+        PROCEDURE coalesceType*(leftType, rightType: Types.PType): Types.PType;
     END;
     PRelationOps = POINTER TO RelationOps;
 
     ExpressionNode* = RECORD(ContextHierarchy.Node)
-        PROCEDURE ExpressionNode(parent: PExpressionHandler; ops: PRelationOps);
+        PROCEDURE ExpressionNode*(parent: PExpressionHandler; ops: PRelationOps);
 
         PROCEDURE handleSimpleExpression(e: Expression.PType);
-        PROCEDURE doRelationOperation(left, right: Expression.PType; relation: STRING): BinaryOperatorCx;
+        PROCEDURE doRelationOperation*(left, right: Expression.PType; relation: STRING): BinaryOperatorCx;
 
         expressionHandler: PExpressionHandler;
         relOps: PRelationOps;
@@ -43,7 +43,7 @@ TYPE
     PExpressionNode = POINTER TO ExpressionNode;
 
     SimpleExpression* = RECORD(ContextHierarchy.Node)
-        PROCEDURE SimpleExpression(parent: PExpressionNode);
+        PROCEDURE SimpleExpression*(parent: PExpressionNode);
 
         PROCEDURE handleTerm(e: Expression.PType);
         PROCEDURE type(): Types.PType;
@@ -80,8 +80,8 @@ TYPE
     END;
 
     AddOperator* = RECORD(ContextHierarchy.Node)
-        PROCEDURE doMatchPlusOperator(type: Types.PType): BinaryOperator;
-        PROCEDURE doExpectPlusOperator(): STRING;
+        PROCEDURE doMatchPlusOperator*(type: Types.PType): BinaryOperator;
+        PROCEDURE doExpectPlusOperator*(): STRING;
     END;
 
     Const = RECORD(ContextHierarchy.Node)
@@ -431,7 +431,7 @@ BEGIN
     RETURN result;
 END;
 
-PROCEDURE RelationOps.is(cx: Context.Type): BinaryOperatorCx;
+PROCEDURE RelationOps.is(cx: ContextHierarchy.Node): BinaryOperatorCx;
 VAR
     r: BinaryOperatorCx;
 

+ 6 - 2
test/test_unit_eberon.js

@@ -35,7 +35,9 @@ var temporaryValues = {
         + "PDerived = POINTER TO Derived;"
         + "PDerived2 = POINTER TO Derived2;"
         + "VAR pBase: POINTER TO Base; bVar: BOOLEAN;"
-        + "PROCEDURE proc(b: BOOLEAN): BOOLEAN; RETURN b END proc;"),
+        + "PROCEDURE proc(b: BOOLEAN): BOOLEAN; RETURN b END proc;"
+        + "PROCEDURE passPDerived(p: PDerived): BOOLEAN; RETURN TRUE END;"
+        ),
     __expression: function(e){
         return "PROCEDURE p(); BEGIN b <- pBase; b2 <- pBase; ASSERT(" + e + "); END p;";
     },
@@ -853,7 +855,9 @@ exports.suite = {
     "type promotion after dereferencing": testWithContext(
         temporaryValues.context,
         temporaryValues.passExpressions(
-            "(b^ IS Derived) & b.flag")
+            "(b^ IS Derived) & b.flag",
+            "(b^ IS Derived) & passPDerived(b)"
+            )
         ),
     "IS expression after type promotion": testWithContext(
         temporaryValues.context,