浏览代码

js -> eberon transition

Vladislav Folts 10 年之前
父节点
当前提交
9448c0517f

二进制
bin/compiled.zip


+ 1 - 1
build.py

@@ -130,7 +130,7 @@ def recompile(bin):
     sources = ['ContextAssignment.ob', 'ContextCase.ob', 'ContextConst.ob', 
                'ContextIdentdef.ob', 'ContextLoop.ob', 'ContextModule.ob', 'ContextProcedure.ob', 
                'ContextVar.ob', 'EberonSymbols.ob', 'EberonCast.ob', 
-               'EberonConstructor.ob', 'EberonOperator.ob', 'EberonScope.ob',
+               'EberonContextDesignator.ob', 'EberonOperator.ob', 'EberonScope.ob',
                'EberonTypePromotion.ob',
                'OberonContext.ob', 'OberonContextType.ob', 'OberonContextVar.ob',
                'OberonSymbols.ob', 'Lexer.ob', 'Module.ob']

+ 386 - 0
src/eberon/EberonContextDesignator.ob

@@ -0,0 +1,386 @@
+MODULE EberonContextDesignator;
+IMPORT
+    ContextDesignator, ContextHierarchy, ContextProcedure,
+    EberonConstructor, EberonMap, EberonRtl, EberonString, EberonTypePromotion,
+    Errors, Expression, Object, Procedure, Record, TypeId, Types, Variable;
+TYPE
+    Type* = RECORD(ContextDesignator.Type)
+        procCall: Procedure.PCallGenerator;
+    END;
+    PType = POINTER TO Type;
+
+    MapElementVariable = RECORD(Types.Variable)
+        PROCEDURE MapElementVariable(type: Types.PStorageType; readOnly: BOOLEAN; code: STRING);
+
+        elementType: Types.PStorageType; 
+        readOnly: BOOLEAN; 
+        code: STRING;
+    END;
+
+    ResultVariable* = RECORD(Types.Variable)
+        PROCEDURE ResultVariable(e: Expression.PType);
+
+        expression: Expression.PType;
+    END;
+
+    TypeNarrowVariableBase* = RECORD(Types.Variable)
+    END;
+
+    TypeNarrowVariable* = RECORD(TypeNarrowVariableBase)
+        PROCEDURE TypeNarrowVariable(type: Types.PStorageType; isRef, isReadOnly: BOOLEAN; code: STRING);
+
+        PROCEDURE setType(type: Types.PStorageType);
+
+        mType: Types.PStorageType;
+        isRef: BOOLEAN;
+        readOnly: BOOLEAN;
+        code: STRING;
+    END;
+    PTypeNarrowVariable = POINTER TO TypeNarrowVariable;
+
+    DereferencedTypeNarrowVariable = RECORD(TypeNarrowVariableBase)
+        PROCEDURE DereferencedTypeNarrowVariable(var: PTypeNarrowVariable);
+
+        PROCEDURE setType(type: Types.PStorageType);
+
+        var: PTypeNarrowVariable;
+    END;
+
+    SelfAsPointer = RECORD(Types.Id)
+    END;
+
+    OperatorNewMsg* = RECORD(ContextHierarchy.Message)
+        PROCEDURE OperatorNewMsg(e: Expression.PType);
+
+        expression: Expression.PType;
+    END;
+
+    PromoteTypeMsg* = RECORD(ContextHierarchy.Message)
+        PROCEDURE PromoteTypeMsg(info: Types.PId; type: Types.PType);
+
+        info: Types.PId;
+        type: Types.PType;
+    END;
+
+    TransferPromotedTypesMsg* = RECORD(ContextHierarchy.Message)
+        PROCEDURE TransferPromotedTypesMsg(p: EberonTypePromotion.PCombined); 
+
+        promotion: EberonTypePromotion.PCombined;
+    END;
+
+    GetMethodSelfMsg* = RECORD(ContextHierarchy.Message)
+    END;
+
+    GetSelfAsPointerMsg* = RECORD(ContextHierarchy.Message)
+    END;
+
+    GetMethodSuperMsg* = RECORD(ContextHierarchy.Message)
+    END;
+
+    SuperMethodInfo* = RECORD(Object.Type)
+        PROCEDURE SuperMethodInfo(info: Types.PProcedureId; code: STRING);
+
+        info: Types.PProcedureId;
+        code: STRING;
+    END;
+    PSuperMethodInfo = POINTER TO SuperMethodInfo;
+
+VAR
+    getMethodSelfMsg: GetMethodSelfMsg;
+    getSelfAsPointerMsg: GetSelfAsPointerMsg;
+    getMethodSuperMsg: GetMethodSuperMsg;
+
+PROCEDURE checkMapKeyType*(type: Types.PType);
+BEGIN
+    IF (type # EberonString.string) & (~Types.isString(type)) THEN
+        Errors.raise("invalid MAP key type: STRING or string literal or ARRAY OF CHAR expected, got '" 
+                    + type.description() + "'");            
+    END;
+END;
+
+PROCEDURE Type.doCheckIndexType(type: Types.PType);
+BEGIN
+    IF SELF.currentType IS EberonMap.PType THEN
+        checkMapKeyType(type);
+    ELSE
+        SUPER(type);
+    END;
+END;
+
+PROCEDURE Type.doIndexSequence(info: Types.PId; code, indexCode: STRING): ContextDesignator.PIndex;
+VAR
+    result: ContextDesignator.PIndex;
+BEGIN
+    currentType <- SELF.currentType;
+    IF currentType = EberonString.string THEN
+        result := NEW ContextDesignator.Index(
+            0, 
+            Types.basic.ch, 
+            EberonString.makeElementVariable(),
+            ContextDesignator.stringIndexCode(SELF),
+            "",
+            "");
+    ELSIF currentType IS EberonMap.PType THEN
+        indexType <- currentType.valueType;
+        rtl <- SELF.root().language().rtl(EberonRtl.PType);
+        rval <- rtl.getMappedValue(code, indexCode);
+        lval <- code + "[" + indexCode + "]";
+        var <- NEW MapElementVariable(indexType, info(Types.PVariable).isReadOnly(), rval);
+        result := NEW ContextDesignator.Index(0, indexType, var, rval, lval, "");
+    ELSE
+        result := SUPER(info, code, indexCode);
+    END;
+    RETURN result;
+END;
+
+PROCEDURE Type.doMakeDerefVar(info: Types.PId): Types.PVariable;
+VAR
+    result: Types.PVariable;
+BEGIN
+    IF info IS PTypeNarrowVariable THEN
+        result := NEW DereferencedTypeNarrowVariable(info);
+    ELSE
+        result := SUPER(info);
+    END;
+    RETURN result;
+END;
+
+PROCEDURE beginCall(d: PType);
+BEGIN
+    type <- d.currentType;
+    info <- d.info;
+    IF (info IS TypeId.PType) & (type IS Types.PRecord) THEN
+        cx <- ContextHierarchy.makeLanguageContext(d);
+        d.procCall := EberonConstructor.makeConstructorCall(info, cx, FALSE);
+        ContextDesignator.discardCode(d^);
+    ELSE
+        d.procCall := ContextProcedure.makeCall(d, type, info);
+    END;
+END;
+
+PROCEDURE endCall(VAR d: Type);
+BEGIN
+    e <- d.procCall.end();
+    ContextDesignator.advance(d, e.type(), NEW ResultVariable(e), e.code(), "", FALSE);
+    d.procCall := NIL;
+END;
+
+PROCEDURE breakTypePromotion*(VAR msg: ContextHierarchy.Message): BOOLEAN;
+BEGIN
+    result <- FALSE;
+    IF msg IS TransferPromotedTypesMsg THEN
+        msg.promotion.clear();
+        result := TRUE;
+    ELSIF msg IS PromoteTypeMsg THEN
+        result := TRUE;
+    END;
+    RETURN result;
+END;
+
+PROCEDURE Type.handleMessage(VAR msg: ContextHierarchy.Message): Object.PType;
+VAR
+    result: Object.PType;
+BEGIN
+    IF msg IS ContextDesignator.BeginCallMsg THEN
+        beginCall(SELF(POINTER));
+    ELSIF msg IS ContextDesignator.EndCallMsg THEN
+        endCall(SELF);
+    ELSIF msg IS OperatorNewMsg THEN
+        e <- msg.expression;
+        ContextDesignator.advance(SELF, e.type(), NEW ResultVariable(e), e.code(), "", FALSE);
+    ELSIF ~breakTypePromotion(msg) THEN (* no type promotion after calling functions *)
+        result := SUPER(msg);
+    END;    
+
+    RETURN result;
+END;
+
+PROCEDURE Type.handleExpression(e: Expression.PType);
+BEGIN
+    IF SELF.procCall # NIL THEN
+        SELF.procCall.handleArgument(e);
+    ELSE
+        SUPER(e);
+    END;
+END;
+
+PROCEDURE Type.handleLiteral(s: STRING);
+BEGIN
+    IF s = "SELF" THEN
+        type <- SELF.handleMessage(getMethodSelfMsg)(Types.PStorageType);
+        info <- NEW Variable.DeclaredVariable("this", type);
+        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);
+    ELSIF s = "SUPER" THEN
+        ms <- SELF.handleMessage(getMethodSuperMsg)(PSuperMethodInfo);
+        ContextDesignator.advance(SELF, ms.info.type, ms.info, ms.code, "", FALSE);
+    ELSE
+        SUPER(s);
+    END;
+END;
+
+PROCEDURE MapElementVariable.MapElementVariable(type: Types.PStorageType; readOnly: BOOLEAN; code: STRING)
+    | elementType(type),
+      readOnly(readOnly),
+      code(code);
+END;
+
+PROCEDURE MapElementVariable.type(): Types.PStorageType;
+    RETURN SELF.elementType;
+END;
+
+PROCEDURE MapElementVariable.isReference(): BOOLEAN;
+    RETURN FALSE;
+END;
+
+PROCEDURE MapElementVariable.isReadOnly(): BOOLEAN;
+    RETURN SELF.readOnly;
+END;
+
+PROCEDURE MapElementVariable.referenceCode(): STRING;
+BEGIN
+    IF SELF.elementType.isScalar() THEN
+        Errors.raise("cannot reference map element of type '" 
+                     + SELF.elementType.description() + "'");
+    END;
+    RETURN SELF.code;        
+END;
+
+PROCEDURE MapElementVariable.idType(): STRING;
+VAR
+    result: STRING;
+BEGIN
+    result := "MAP's element";
+    IF SELF.readOnly THEN
+        result := "read-only " + result;
+    END;
+    RETURN result;
+END;
+
+PROCEDURE ResultVariable.ResultVariable(e: Expression.PType)
+    | expression(e);
+END;
+
+PROCEDURE ResultVariable.type(): Types.PStorageType;
+    RETURN SELF.expression.type()(Types.PStorageType);
+END;
+
+PROCEDURE ResultVariable.isReference(): BOOLEAN;
+    RETURN FALSE;
+END;
+
+PROCEDURE ResultVariable.referenceCode(): STRING;
+BEGIN
+    RETURN "";        
+END;
+
+PROCEDURE ResultVariable.isReadOnly(): BOOLEAN;
+    RETURN TRUE;
+END;
+
+PROCEDURE ResultVariable.idType(): STRING;
+VAR
+    result: STRING;
+BEGIN
+    IF SELF.expression.type() # NIL THEN
+        result := "result";
+    ELSE
+        result := "statement";
+    END;
+    RETURN "procedure call " + result;
+END;
+
+PROCEDURE TypeNarrowVariable.TypeNarrowVariable(type: Types.PStorageType; isRef, isReadOnly: BOOLEAN; code: STRING)
+    | mType(type),
+      isRef(isRef),
+      readOnly(isReadOnly),
+      code(code);
+END;
+
+PROCEDURE TypeNarrowVariable.type(): Types.PStorageType;
+    RETURN SELF.mType;
+END;
+
+PROCEDURE TypeNarrowVariable.setType(type: Types.PStorageType);
+BEGIN
+    SELF.mType := type;
+END;
+
+PROCEDURE TypeNarrowVariable.isReference(): BOOLEAN;
+    RETURN SELF.isRef;
+END;
+
+PROCEDURE TypeNarrowVariable.isReadOnly(): BOOLEAN;
+    RETURN SELF.readOnly;
+END;
+
+PROCEDURE TypeNarrowVariable.referenceCode(): STRING;
+BEGIN
+    RETURN SELF.code;        
+END;
+
+PROCEDURE TypeNarrowVariable.idType(): STRING;
+VAR
+    result: STRING;
+BEGIN
+    IF SELF.readOnly THEN
+        result := "non-VAR formal parameter";
+    ELSE
+        result := SUPER();
+    END;
+    RETURN result;
+END;
+
+PROCEDURE DereferencedTypeNarrowVariable.DereferencedTypeNarrowVariable(var: PTypeNarrowVariable)
+    | var(var);
+END;
+
+PROCEDURE DereferencedTypeNarrowVariable.type(): Types.PStorageType;
+    RETURN SELF.var.type();
+END;
+
+PROCEDURE DereferencedTypeNarrowVariable.setType(type: Types.PStorageType);
+BEGIN
+    SELF.var.setType(type);
+END;
+
+PROCEDURE DereferencedTypeNarrowVariable.isReference(): BOOLEAN;
+    RETURN TRUE;
+END;
+
+PROCEDURE DereferencedTypeNarrowVariable.isReadOnly(): BOOLEAN;
+    RETURN FALSE;
+END;
+
+PROCEDURE DereferencedTypeNarrowVariable.referenceCode(): STRING;
+BEGIN
+    RETURN SELF.var.code;        
+END;
+
+PROCEDURE SelfAsPointer.idType(): STRING;
+    RETURN "SELF(POINTER)";
+END;
+
+PROCEDURE OperatorNewMsg.OperatorNewMsg(e: Expression.PType)
+    | expression(e);
+END;
+
+PROCEDURE PromoteTypeMsg.PromoteTypeMsg(info: Types.PId; type: Types.PType)
+    | info(info),
+      type(type);
+END;
+
+PROCEDURE TransferPromotedTypesMsg.TransferPromotedTypesMsg(p: EberonTypePromotion.PCombined)
+    | promotion(p); 
+END;
+
+PROCEDURE SuperMethodInfo.SuperMethodInfo(info: Types.PProcedureId; code: STRING)
+    | info(info),
+      code(code);
+END;
+
+END EberonContextDesignator.

+ 3 - 3
src/eberon/EberonMap.ob

@@ -6,9 +6,9 @@ CONST
     clearMethodName = "clear";
 TYPE
     Type* = RECORD(Types.StorageType)
-        PROCEDURE Type*(type: Types.PType);
+        PROCEDURE Type*(type: Types.PStorageType);
 
-        valueType*: Types.PType;
+        valueType*: Types.PStorageType;
     END;
     PType* = POINTER TO Type;
 
@@ -48,7 +48,7 @@ PROCEDURE Type.description(): STRING;
     RETURN "MAP OF " + SELF.valueType.description();
 END;
 
-PROCEDURE Type.Type(valueType: Types.PType)
+PROCEDURE Type.Type(valueType: Types.PStorageType)
     | valueType(valueType);
 END;
 

+ 2 - 1
src/eberon/EberonRtl.ob

@@ -2,7 +2,8 @@ MODULE EberonRtl;
 IMPORT OberonRtl;
 TYPE
     Type* = RECORD(OberonRtl.Type)
-        clearMap*: PROCEDURE(s: STRING): STRING;
+        PROCEDURE clearMap*(s: STRING): STRING;
+        PROCEDURE getMappedValue*(code, indexCode: STRING): STRING;
     END;
     PType* = POINTER TO Type;
 

+ 3 - 3
src/eberon/EberonTypePromotion.ob

@@ -28,10 +28,10 @@ TYPE
     Operation = PROCEDURE(p: Type);
     PMaybe = POINTER TO Maybe;
 
-    Combined = RECORD(Type)
+    Combined* = RECORD(Type)
         PROCEDURE Combined(op, invertedOp: Operation; inverted: BOOLEAN);
 
-        PROCEDURE clear();
+        PROCEDURE clear*();
         PROCEDURE next(): PMaybe;
 
         op, invertedOp: Operation;
@@ -40,7 +40,7 @@ TYPE
         current: PType;
         count: INTEGER;
     END;
-    PCombined = POINTER TO Combined;
+    PCombined* = POINTER TO Combined;
 
     And* = RECORD(Combined)
         PROCEDURE And(inverted: BOOLEAN);

+ 31 - 258
src/eberon/eberon_context.js

@@ -16,8 +16,9 @@ var ContextHierarchy = require("js/ContextHierarchy.js");
 var ContextProcedure = require("js/ContextProcedure.js");
 var ContextType = require("js/ContextType.js");
 var ContextVar = require("js/ContextVar.js");
-var EberonConstructor= require("js/EberonConstructor.js");
-var EberonContext= require("js/EberonContext.js");
+var EberonConstructor = require("js/EberonConstructor.js");
+var EberonContext = require("js/EberonContext.js");
+var EberonContextDesignator = require("js/EberonContextDesignator.js");
 var EberonDynamicArray = require("js/EberonDynamicArray.js");
 var EberonMap = require("js/EberonMap.js");
 var EberonRecord = require("js/EberonRecord.js");
@@ -104,87 +105,16 @@ var MethodHeading = ChainedContext.extend({
     }
 });
 
-function getMethodSelf(){}
-function getSelfAsPointerMsg(){}
-function getMethodSuper(){}
-
-var ResultVariable = Class.extend.call(Type.Variable, {
-    init: function(e){
-        this.__e = e;
-    },
-    expression: function(){return this.__e;},
-    type: function(){return this.__e.type();},
-    isReadOnly: function(){return true;},
-    idType: function(){return "procedure call " + (this.type() ? "result" : "statement");}
-});
-
-var TypeNarrowVariableBase = Class.extend.call(Type.Variable, {
-    init: function TypeNarrowVariableBase(){
-    }    
-});
-
-var TypeNarrowVariable = TypeNarrowVariableBase.extend({
-    init: function TypeNarrowVariable(type, isRef, isReadOnly, code){
-        this.__type = type;
-        this.__isRef = isRef;
-        this.__isReadOnly = isReadOnly;
-        this.__code = code;
-    },
-    type: function(){
-        return this.__type;
-    },
-    isReference: function(){
-        return this.__isRef;
-    },
-    code: function(){
-        return this.__code;
-    },
-    referenceCode: function(){
-        return this.__code;
-    },
-    isReadOnly: function(){
-        return this.__isReadOnly;
-    },
-    idType: function(){
-        return this.__isReadOnly ? "non-VAR formal parameter"
-                                 : TypeNarrowVariableBase.prototype.idType.call(this);
-    },
-    setType: function(type){
-        this.__type = type;
-    }
-});
-
-var DereferencedTypeNarrowVariable = TypeNarrowVariableBase.extend({
-    init: function DereferencedTypeNarrowVariable(v){
-        this.__v = v;
-    },
-    type: function(){
-        return this.__v.type();
-    },
-    isReference: function(){
-        return true;
-    },
-    isReadOnly: function(){
-        return false;
-    },
-    setType: function(type){
-        this.__v.setType(type);
-    },
-    referenceCode: function(){
-        return this.__v.code();
-    }
-});
-
-var InPlaceStringLiteral = TypeNarrowVariable.extend({
+var InPlaceStringLiteral = Class.extend.call(EberonContextDesignator.TypeNarrowVariable, {
     init: function(type){
-        TypeNarrowVariable.prototype.init.call(this, type, false, true);
+        EberonContextDesignator.TypeNarrowVariable.call(this, type, false, true);
     },
     idType: function(){return "string literal";}
 });
 
-var ForEachVariable = TypeNarrowVariable.extend({
+var ForEachVariable = Class.extend.call(EberonContextDesignator.TypeNarrowVariable, {
     init: function(type){
-        TypeNarrowVariable.prototype.init.call(this, type, false, true);
+        EberonContextDesignator.TypeNarrowVariable.call(this, type, false, true);
     },
     idType: function(){return "FOR variable";}
 });
@@ -208,144 +138,6 @@ function makeContextCall(context, call){
     return call(ContextHierarchy.makeLanguageContext(context));
     }
 
-function OperatorNewMsg(e){
-    this.expression = e;
-}
-
-function checkMapKeyType(type){
-    if (type != EberonString.string() && !Type.isString(type))
-        throw new Errors.Error("invalid MAP key type: STRING or string literal or ARRAY OF CHAR expected, got '" + type.description() + "'");            
-}
-
-var MapElementVariable = Class.extend.call(Type.Variable, {
-    init: function(type, readOnly, code){
-        this.__type = type;
-        this.__isReadOnly = readOnly;
-        this.__code = code;
-    },
-    type: function(){return this.__type;},
-    isReadOnly: function(){return this.__isReadOnly;},
-    isReference: function(){return false;},
-    referenceCode: function(){
-        if (this.__type.isScalar())
-            throw new Errors.Error("cannot reference map element of type '" 
-                                 + this.__type.description() + "'");
-        return this.__code;        
-    },
-    idType: function(){
-        return (this.__isReadOnly ? "read-only " : "") + "MAP's element";
-    }
-});
-
-var SelfAsPointer = Class.extend.call(Type.Id, {
-    init: function(){
-    },
-    idType: function(){
-        return "SELF(POINTER)";
-    }
-});
-
-var Designator = Class.extend.call(ContextDesignator.Type, {
-    init: function EberonContext$Designator(parent){
-        ContextDesignator.Type.call(this, parent);
-        this.__procCall = undefined;
-    },
-    doCheckIndexType: function(type){
-        if (this.currentType instanceof EberonMap.Type){
-            checkMapKeyType(type);
-            return;
-        }
-        return ContextDesignator.Type.prototype.doCheckIndexType.call(this, type);
-    },
-    doIndexSequence: function(info, code, indexCode){
-        var currentType = this.currentType;
-        if (currentType == EberonString.string())
-            return { length: undefined, 
-                     type: Type.basic().ch,
-                     info: EberonString.makeElementVariable(),
-                     code: this.stringIndexCode(),
-                     lval: ""
-                   };
-
-        if (currentType instanceof EberonMap.Type){
-            var indexType = currentType.valueType;
-            var rval = this.root().language().rtl.getMappedValue(code, indexCode);
-            return { length: undefined, 
-                     type: indexType,
-                     info: new MapElementVariable(indexType, info.isReadOnly(), rval),
-                     code: rval,
-                     lval: code + "[" + indexCode + "]"
-                   };
-        }
-        
-        return ContextDesignator.Type.prototype.doIndexSequence.call(this, info, code, indexCode);
-    },
-    doMakeDerefVar: function(info){
-        if (info instanceof TypeNarrowVariable)
-            return new DereferencedTypeNarrowVariable(info);
-        return ContextDesignator.Type.prototype.doMakeDerefVar.call(this, info);
-    },
-    handleMessage: function(msg){
-        if (msg instanceof ContextDesignator.BeginCallMsg)
-            return this.__beginCall();
-        if (msg instanceof ContextDesignator.EndCallMsg)
-            return this.__endCall();
-        if (msg instanceof OperatorNewMsg){
-            var e = msg.expression;
-            this.advance(e.type(), new ResultVariable(e), e.code(), "");
-            return;
-        }
-
-        // no type promotion after calling functions
-        if (breakTypePromotion(msg))
-            return;
-        
-        return ContextDesignator.Type.prototype.handleMessage.call(this, msg);
-    },
-    handleExpression: function(e){
-        if (this.__procCall)
-            this.__procCall.handleArgument(e);
-        else
-            ContextDesignator.Type.prototype.handleExpression.call(this, e);
-    },
-    handleLiteral: function(s){
-        if (s == "SELF"){
-            var type = this.handleMessage(getMethodSelf);
-            var info = new Variable.DeclaredVariable("this", type);
-            this.advance(type, info, "this", "");
-        } 
-        else if (s == "POINTER"){
-            var typeId = new TypeId.Type(this.handleMessage(getSelfAsPointerMsg));
-            var pointerType = new Record.Pointer("", typeId);
-            this.advance(pointerType, new SelfAsPointer(), "", "");
-        }
-        else if (s == "SUPER"){
-            var ms = this.handleMessage(getMethodSuper);
-            this.advance(ms.info.type, ms.info, ms.code, "");
-        }
-        else 
-            ContextDesignator.Type.prototype.handleLiteral.call(this, s);
-    },
-    __beginCall: function(){
-        var type = this.currentType;
-        var info = this.info;
-        if (info instanceof TypeId.Type && type instanceof Type.Record){
-            this.__procCall = makeContextCall(
-                this, 
-                function(cx){ return EberonConstructor.makeConstructorCall(info, cx, false); }
-                );
-            this.discardCode();
-        }
-        else
-            this.__procCall = ContextProcedure.makeCall(this, type, this.info);
-    },
-    __endCall: function(){
-        var e = this.__procCall.end();
-        this.advance(e.type(), new ResultVariable(e), e.code(), "");
-        this.__procCall = undefined;
-    }
-});
-
 var OperatorNew = ChainedContext.extend({
     init: function EberonContext$OperatorNew(parent){
         ChainedContext.prototype.init.call(this, parent);
@@ -383,7 +175,7 @@ var OperatorNew = ChainedContext.extend({
         return ChainedContext.prototype.handleMessage.call(this, msg);
     },
     endParse: function(){
-        this.handleMessage(new OperatorNewMsg(this.__call.end()));
+        this.handleMessage(new EberonContextDesignator.OperatorNewMsg(this.__call.end()));
     }
 });
 
@@ -407,7 +199,7 @@ var InPlaceVariableInit = ChainedContext.extend({
         if (!isString && !(type instanceof Type.StorageType))
             throw new Errors.Error("cannot use " + type.description() + " to initialize variable");
         var v = isString ? new InPlaceStringLiteral(type) 
-                         : new TypeNarrowVariable(type, false, false, this.__id);
+                         : new EberonContextDesignator.TypeNarrowVariable(type, false, false, this.__id);
         this._symbol = new Symbol.Symbol(this.__id, v);
         if (type instanceof Type.Record){
             EberonRecord.ensureCanBeInstantiated(this, type, EberonRecord.instantiateForCopy);
@@ -460,8 +252,8 @@ var ExpressionProcedureCall = ChainedContext.extend({
         var d = this.attributes.designator;
         var info = d.info();
         var e;
-        if (info instanceof ResultVariable){
-            e = info.expression();
+        if (info instanceof EberonContextDesignator.ResultVariable){
+            e = info.expression;
             e = new Expression.Type(d.code(), d.type(), undefined, e.constValue(), e.maxPrecedence());
         }
         else
@@ -488,7 +280,7 @@ var AssignmentOrProcedureCall = ChainedContext.extend({
             var left = Expression.make(d.code(), type, d);
             code = op.assign(left, this.__right, ContextHierarchy.makeLanguageContext(this));
         }
-        else if (!(d.info() instanceof ResultVariable)){
+        else if (!(d.info() instanceof EberonContextDesignator.ResultVariable)){
             var procCall = ContextProcedure.makeCall(this, type, d.info());
             var result = procCall.end();
             Module.assertProcStatementResult(result.type());
@@ -597,17 +389,8 @@ var RecordDecl = Class.extend.call(ContextType.Record, {
     }
 });
 
-function breakTypePromotion(msg){
-    if (msg instanceof TransferPromotedTypesMsg){
-        msg.promotion.clear();
-        return true;
-    }
-    if (msg instanceof PromoteTypeMsg)
-        return true;
-}
-
 function handleTypePromotionMadeInSeparateStatement(msg){
-    if (breakTypePromotion(msg))
+    if (EberonContextDesignator.breakTypePromotion(msg))
         return true;
     if (msg instanceof BeginTypePromotionOrMsg){
         msg.result = new TypePromotion.Or();
@@ -683,12 +466,12 @@ var ProcOrMethodDecl = Class.extend.call(ContextProcedure.Declaration, {
         this.__initedFields = [];
     },
     handleMessage: function(msg){
-        if (msg == getMethodSelf){
+        if (msg instanceof EberonContextDesignator.GetMethodSelfMsg){
             if (!this.__boundType)
                 throw new Errors.Error("SELF can be used only in methods");
             return this.__boundType;
         }
-        if (msg == getSelfAsPointerMsg){
+        if (msg instanceof EberonContextDesignator.GetSelfAsPointerMsg){
             this.__boundType.requireNewOnly();
             return this.__boundType;
         }
@@ -701,7 +484,7 @@ var ProcOrMethodDecl = Class.extend.call(ContextProcedure.Declaration, {
             return this.__handleSuperCall();
         }
 
-        if (msg == getMethodSuper){
+        if (msg instanceof EberonContextDesignator.GetMethodSuperMsg){
             if (this.__isConstructor)
                 throw new Errors.Error("cannot call base constructor from procedure body (use '| SUPER' to pass parameters to base constructor)");
             return this.__handleSuperCall();
@@ -749,10 +532,10 @@ var ProcOrMethodDecl = Class.extend.call(ContextProcedure.Declaration, {
     },
     doMakeArgumentVariable: function(arg, name){
         if (!arg.isVar)
-            return new TypeNarrowVariable(arg.type, false, true, name);
+            return new EberonContextDesignator.TypeNarrowVariable(arg.type, false, true, name);
 
         if (arg.type instanceof Type.Record)
-            return new TypeNarrowVariable(arg.type, true, false, name);
+            return new EberonContextDesignator.TypeNarrowVariable(arg.type, true, false, name);
 
         return ContextProcedure.Declaration.prototype.doMakeArgumentVariable.call(this, arg, name);
     },
@@ -814,12 +597,12 @@ var ProcOrMethodDecl = Class.extend.call(ContextProcedure.Declaration, {
         if (!this.__isConstructor)
             EberonRecord.requireMethodDefinition(baseType, id, "cannot use abstract method(s) in SUPER calls");
         
-        return {
-            info: this.__isConstructor ? undefined
-                                       : new Type.ProcedureId(new EberonTypes.MethodType(id, this.__methodType.procType(), superMethodCallGenerator)),
-            code: this.qualifyScope(baseType.scope)
+        return new EberonContextDesignator.SuperMethodInfo(
+            this.__isConstructor ? undefined
+                                 : new Type.ProcedureId(new EberonTypes.MethodType(id, this.__methodType.procType(), superMethodCallGenerator)),
+            this.qualifyScope(baseType.scope)
                 + Type.typeName(baseType) + ".prototype." + id + ".call"
-        };
+            );
     },
     __handleFieldInit: function(id){
         var fields = this.__boundType.fields;
@@ -876,15 +659,6 @@ var MulOperator = Class.extend.call(ContextExpression.MulOperator, {
     }
 });
 
-function PromoteTypeMsg(info, type){
-    this.info = info;
-    this.type = type;
-}
-
-function TransferPromotedTypesMsg(promotion){
-    this.promotion = promotion;
-}
-
 var RelationOps = Class.extend.call(ContextExpression.RelationOps, {
     init: function EberonContext$RelationOps(){
         ContextExpression.RelationOps.call(this);
@@ -925,8 +699,8 @@ var RelationOps = Class.extend.call(ContextExpression.RelationOps, {
             var d = left.designator();
             if (d){
                 var v = d.info();
-                if (v instanceof TypeNarrowVariableBase)
-                    context.handleMessage(new PromoteTypeMsg(v, ContextExpression.unwrapType(right.designator().info())));
+                if (v instanceof EberonContextDesignator.TypeNarrowVariableBase)
+                    context.handleMessage(new EberonContextDesignator.PromoteTypeMsg(v, ContextExpression.unwrapType(right.designator().info())));
             }
             return impl(left, right);
         };
@@ -955,7 +729,7 @@ var Term = Class.extend.call(ContextExpression.Term, {
         this.__andHandled = false;
     },
     handleMessage: function(msg){
-        if (msg instanceof PromoteTypeMsg) {
+        if (msg instanceof EberonContextDesignator.PromoteTypeMsg) {
             var promoted = msg.info;
             var p = this.getCurrentPromotion();
             if (p)
@@ -1042,7 +816,7 @@ var ExpressionContext = Class.extend.call(ContextExpression.ExpressionNode, {
         this.__currentTypePromotion = undefined;
     },
     handleMessage: function(msg){
-        if (msg instanceof TransferPromotedTypesMsg)
+        if (msg instanceof EberonContextDesignator.TransferPromotedTypesMsg)
             return;
         return ContextExpression.ExpressionNode.prototype.handleMessage.call(this, msg);
     },
@@ -1057,12 +831,12 @@ var ExpressionContext = Class.extend.call(ContextExpression.ExpressionNode, {
     },
     endParse: function(){
         if (this.__currentTypePromotion)
-            this.parent().handleMessage(new TransferPromotedTypesMsg(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){
-            checkMapKeyType(left.type());
+            EberonContextDesignator.checkMapKeyType(left.type());
             return eOp.inMap;            
         }
         return ContextExpression.ExpressionNode.prototype.doRelationOperation.call(this, left, right, relation);
@@ -1082,9 +856,9 @@ var OperatorScopes = Class.extend({
     handleMessage: function(msg){
         if (this.__ignorePromotions)
             return false;
-        if (msg instanceof TransferPromotedTypesMsg)
+        if (msg instanceof EberonContextDesignator.TransferPromotedTypesMsg)
             return true;
-        if (msg instanceof PromoteTypeMsg){
+        if (msg instanceof EberonContextDesignator.PromoteTypeMsg){
             this.__typePromotion = new TypePromotion.ForVariable(msg.info, msg.type);
             this.__typePromotions.push(this.__typePromotion);
             return true;
@@ -1422,7 +1196,6 @@ exports.ArrayDimensions = ArrayDimensions;
 exports.BaseInit = BaseInit;
 exports.CaseLabel = CaseLabel;
 exports.ConstDecl = ConstDecl;
-exports.Designator = Designator;
 exports.Expression = ExpressionContext;
 exports.ExpressionProcedureCall = ExpressionProcedureCall;
 exports.For = For;

+ 2 - 1
src/eberon/eberon_grammar.js

@@ -5,6 +5,7 @@ var EbArray = require("js/EberonArray.js");
 var CodeGenerator = require("js/CodeGenerator.js");
 var ContextType = require("js/ContextType.js");
 var EbContext = require("eberon/eberon_context.js");
+var EberonContextDesignator = require("js/EberonContextDesignator.js");
 var Grammar = require("grammar.js");
 var EbRtl = require("js/EberonRtl.js");
 var EbRtlCode = require("eberon/eberon_rtl.js");
@@ -59,7 +60,7 @@ function makeDesignator(ident, qualident, selector, actualParameters){
     var operatorNew = and("NEW", context(and(qualident, actualParameters), EbContext.OperatorNew));
     var designator = context(
         and(or(self, "SUPER", operatorNew, qualident), 
-            repeat(or(selector, actualParameters))), EbContext.Designator);
+            repeat(or(selector, actualParameters))), EberonContextDesignator.Type);
     return { 
         factor: context(designator, EbContext.ExpressionProcedureCall),
         assignmentOrProcedureCall: function(assignment, expression){

+ 28 - 31
src/ob/ContextDesignator.ob

@@ -4,15 +4,15 @@ IMPORT
     Designator, Errors, Expression,
     Record, ScopeBase, String, TypeId, Types, Variable;
 TYPE
-    Index = RECORD
-        PROCEDURE Index(length: INTEGER; type: Types.PType; info: Types.PId; code, lval, asProperty: STRING);
+    Index* = RECORD
+        PROCEDURE Index*(length: INTEGER; type: Types.PType; info: Types.PId; code, lval, asProperty: STRING);
 
         length: INTEGER;
         type: Types.PType;
         info: Types.PId;
         code, lval, asProperty: STRING;
     END;
-    PIndex = POINTER TO Index;
+    PIndex* = POINTER TO Index;
 
     QIdentHandler* = RECORD(ContextHierarchy.Node)
         PROCEDURE handleQIdent*(q: ContextHierarchy.QIdent);
@@ -20,16 +20,13 @@ TYPE
     PQIdentHandler* = POINTER TO QIdentHandler;
 
     Type* = RECORD(QIdentHandler)
-        PROCEDURE handleExpression(e: Expression.PType);
+        PROCEDURE handleExpression*(e: Expression.PType);
         PROCEDURE handleTypeCast(type: Types.PType);
 
-        PROCEDURE advance(type: Types.PType; info: Types.PId; code, lval: STRING; replace: BOOLEAN);
-        PROCEDURE doCheckIndexType(type: Types.PType);
+        PROCEDURE doCheckIndexType*(type: Types.PType);
         PROCEDURE doCheckIndexValue(index: PIndex; const: ConstValue.PType);
-        PROCEDURE doIndexSequence(info: Types.PId; code, indexCode: STRING): PIndex;
-        PROCEDURE stringIndexCode(): STRING;
-        PROCEDURE discardCode();
-        PROCEDURE doMakeDerefVar(info: Types.PId): Types.PVariable;
+        PROCEDURE doIndexSequence*(info: Types.PId; code, indexCode: STRING): PIndex;
+        PROCEDURE doMakeDerefVar*(info: Types.PId): Types.PVariable;
 
         scope: ScopeBase.PType;
         currentType-: Types.PType;
@@ -133,12 +130,28 @@ BEGIN
     designator.lval := "";
 END;
 
+PROCEDURE stringIndexCode*(d: Type): STRING;
+    RETURN d.derefCode + ".charCodeAt(" + Expression.deref(d.indexExpression).code() + ")";
+END;
+
+PROCEDURE advance*(VAR d: Type; type: Types.PType; info: Types.PId; code, lval: STRING; replace: BOOLEAN);
+BEGIN
+    d.currentType := type;
+    d.info := info;
+    IF replace THEN
+        d.code := code;
+    ELSE
+        d.code := d.code + code;
+    END;
+    d.lval := lval;
+END;
+
 PROCEDURE Type.handleLiteral(s: STRING);
 BEGIN
     IF (s = "]") OR (s = ",") THEN
         index <- handleIndexExpression(SELF);
         SELF.propCode := index.asProperty;
-        SELF.advance(index.type, index.info, SELF.code + index.code, index.lval, FALSE);
+        advance(SELF, index.type, index.info, SELF.code + index.code, index.lval, FALSE);
     END;
     IF (s = "[") OR (s = ",") THEN
         SELF.derefCode := SELF.code;
@@ -170,23 +183,11 @@ BEGIN
         fieldCode <- field.designatorCode(SELF.code, SELF);
         SELF.derefCode := fieldCode.derefCode;
         SELF.propCode := fieldCode.propCode;
-        SELF.advance(currentType, field.asVar(SELF.code, isReadOnly, SELF), fieldCode.code, "", TRUE);
+        advance(SELF, currentType, field.asVar(SELF.code, isReadOnly, SELF), fieldCode.code, "", TRUE);
         SELF.scope := NIL;
     END;
 END;
 
-PROCEDURE Type.advance(type: Types.PType; info: Types.PId; code, lval: STRING; replace: BOOLEAN);
-BEGIN
-    SELF.currentType := type;
-    SELF.info := info;
-    IF replace THEN
-        SELF.code := code;
-    ELSE
-        SELF.code := SELF.code + code;
-    END;
-    SELF.lval := lval;
-END;
-
 PROCEDURE Type.doCheckIndexType(type: Types.PType);
 BEGIN
     IF ~Types.isInt(type) THEN
@@ -239,7 +240,7 @@ BEGIN
     wholeCode <- code + "[" + indexCode + "]";
     IF indexType = Types.basic.ch THEN
         lval := wholeCode;
-        wholeCode := SELF.stringIndexCode();
+        wholeCode := stringIndexCode(SELF);
     END;
 
     readOnly <- (info IS Types.PConst) 
@@ -248,13 +249,9 @@ BEGIN
     RETURN NEW Index(length, indexType, v, wholeCode, lval, indexCode);
 END;
 
-PROCEDURE Type.stringIndexCode(): STRING;
-    RETURN SELF.derefCode + ".charCodeAt(" + Expression.deref(SELF.indexExpression).code() + ")";
-END;
-
-PROCEDURE Type.discardCode();
+PROCEDURE discardCode*(VAR d: Type);
 BEGIN
-    SELF.code := "";
+    d.code := "";
 END;
 
 PROCEDURE Type.doMakeDerefVar(info: Types.PId): Types.PVariable;

+ 1 - 1
src/ob/Types.ob

@@ -284,7 +284,7 @@ BEGIN
     Errors.raise("selector '." + id + "' cannot be applied to '" + obj + "'");
 END;
 
-PROCEDURE StorageType.denote(id: STRING; isReadObly: BOOLEAN): PField;
+PROCEDURE StorageType.denote(id: STRING; isReadOnly: BOOLEAN): PField;
 BEGIN
     raiseUnexpectedSelector(id, SELF.description());
     RETURN NIL