瀏覽代碼

js -> eberon transition

Vladislav Folts 10 年之前
父節點
當前提交
f4b328ba0c

二進制
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', 
-               'EberonContextProcedure.ob', 'EberonOperator.ob', 'EberonScope.ob',
+               'EberonContextProcedure.ob', 'EberonContextType.ob', 'EberonOperator.ob', 'EberonScope.ob',
                'OberonContext.ob', 'OberonContextType.ob', 'OberonContextVar.ob',
                'OberonSymbols.ob', 'Lexer.ob', 'Module.ob']
     

+ 9 - 1
src/eberon/EberonContext.ob

@@ -1,5 +1,6 @@
 MODULE EberonContext;
-IMPORT Context;
+IMPORT 
+    Context, Errors;
 TYPE
     IdentdefInfo* = RECORD(Context.IdentdefInfo)
         PROCEDURE IdentdefInfo(id: STRING; exported: BOOLEAN; ro: BOOLEAN);
@@ -19,4 +20,11 @@ PROCEDURE IdentdefInfo.IdentdefInfo(id: STRING; exported: BOOLEAN; ro: BOOLEAN)
       ro(ro);
 END;
 
+PROCEDURE checkOrdinaryExport*(id: IdentdefInfo; hint: STRING);
+BEGIN
+    IF id.isReadOnly() THEN
+        Errors.raise(hint + " cannot be exported as read-only using '-' mark (did you mean '*'?)");
+    END;
+END;
+
 END EberonContext.

+ 41 - 2
src/eberon/EberonContextProcedure.ob

@@ -1,7 +1,7 @@
 MODULE EberonContextProcedure;
 IMPORT
-    Chars, Context, ContextHierarchy, ContextProcedure, 
-    EberonConstructor, EberonContextDesignator, EberonRecord, EberonTypePromotion, EberonTypes,
+    Chars, Context, ContextExpression, ContextHierarchy, ContextProcedure, ContextType, 
+    EberonConstructor, EberonContext, EberonContextDesignator, EberonRecord, EberonTypePromotion, EberonTypes,
     Errors, Expression, LanguageContext, Object, Procedure, Types;
 TYPE
     ProcOrMethodDeclaration* = RECORD(ContextProcedure.Declaration)
@@ -16,6 +16,13 @@ TYPE
     END;
     PProcOrMethodDeclaration = POINTER TO ProcOrMethodDeclaration;
 
+    ProcOrMethodId* = RECORD(ContextHierarchy.Node)
+        PROCEDURE handleIdentdef(id: EberonContext.PIdentdefInfo);
+
+        maybeTypeId: STRING;
+        type: EberonRecord.PRecord;
+    END;
+
     GetConstructorBoundTypeMsg* = RECORD(ContextHierarchy.Message)
     END;
     GetConstructorSuperMsg* = RECORD(ContextHierarchy.Message)
@@ -255,6 +262,38 @@ BEGIN
     RETURN result;
 END;
 
+PROCEDURE ProcOrMethodId.handleIdent(id: STRING);
+BEGIN
+    SELF.maybeTypeId := id;
+END;
+
+PROCEDURE ProcOrMethodId.handleLiteral(s: STRING);
+BEGIN
+    ss <- ContextHierarchy.getSymbolAndScope(SELF.root()^, SELF.maybeTypeId);
+    type <- ContextExpression.unwrapType(ss.symbol().info());
+    IF ~(type IS EberonRecord.PRecord) THEN
+        Errors.raise(
+              "RECORD type expected in method declaration, got '"
+            + type.description() + "'");
+    ELSIF ss.scope() # SELF.root().currentScope() THEN
+        Errors.raise(
+              "method should be defined in the same scope as its bound type '"
+            + SELF.maybeTypeId
+            + "'");
+    ELSE
+        SELF.type := type;
+    END;
+END;
+
+PROCEDURE ProcOrMethodId.handleIdentdef(id: EberonContext.PIdentdefInfo);
+BEGIN
+    IF (SELF.type # NIL) & id.exported() THEN
+        Errors.raise("method implementation cannot be exported: " + id.id());
+    END;
+    EberonContext.checkOrdinaryExport(id^, "procedure");
+    void <- SELF.handleMessage(NEW MethodOrProcMsg(id, SELF.type)^);
+END;
+
 PROCEDURE InitFieldMsg.InitFieldMsg(id: STRING)
     | id(id);
 END;

+ 134 - 0
src/eberon/EberonContextType.ob

@@ -0,0 +1,134 @@
+MODULE EberonContextType;
+IMPORT
+    Chars,
+    Context, ContextHierarchy, ContextProcedure, ContextType, 
+    EberonContext, EberonRecord, EberonTypes,
+    Errors,
+    Object, Procedure, R := Record, ScopeBase, Types;
+TYPE
+    Declaration* = RECORD(ContextType.Declaration)
+    END;
+    PDeclaration = POINTER TO Declaration;
+
+    Record* = RECORD(ContextType.Record)
+        PROCEDURE Record*(parent: PDeclaration);
+    END;
+
+    MethodHeading* = RECORD(ContextType.DeclarationAndIdentHandle)
+        id: EberonContext.PIdentdefInfo;
+        type: Procedure.PType;
+    END;
+
+    MethodDeclMsg = RECORD(ContextHierarchy.Message)
+        PROCEDURE MethodDeclMsg(id: Context.PIdentdefInfo; type: Procedure.PType);
+        
+        id: Context.PIdentdefInfo; 
+        type: Procedure.PType;
+    END;
+
+PROCEDURE Declaration.handleIdentdef(id: Context.PIdentdefInfo);
+BEGIN
+    EberonContext.checkOrdinaryExport(id(EberonContext.PIdentdefInfo)^, "type");
+    SUPER(id);
+END;
+
+PROCEDURE recordTypeFactory(name, cons: STRING; scope: ScopeBase.PType): R.PType;
+    RETURN NEW EberonRecord.Record(name, cons, scope);
+END;
+
+PROCEDURE Record.Record(parent: PDeclaration)
+    | SUPER(parent, recordTypeFactory);
+END;
+
+PROCEDURE Record.handleMessage(VAR msg: ContextHierarchy.Message): Object.PType;
+VAR
+    result: Object.PType;
+BEGIN
+    IF msg IS MethodDeclMsg THEN 
+        methodType <- msg.type;
+        boundType <- SELF.type(EberonRecord.PRecord);
+        id <- msg.id.id();
+        IF boundType.name = id THEN
+            IF msg.id.exported() THEN
+                typeId <- SELF.parent()(PDeclaration).id;
+                IF ~typeId.exported() THEN
+                    Errors.raise("constructor '" + id + "' cannot be exported because record itslef is not exported");
+                END;
+            END;
+            boundType.declareConstructor(methodType, msg.id.exported());
+        ELSE
+            boundType.addMethod(msg.id,
+                                NEW EberonTypes.MethodType(id, methodType, Procedure.makeProcCallGenerator));
+        END;
+    ELSIF msg IS ContextProcedure.EndParametersMsg THEN (* not used *)
+    ELSIF msg IS ContextProcedure.AddArgumentMsg THEN   (* not used *)
+    ELSE
+        result := SUPER(msg);
+    END;
+    RETURN result;
+END;
+
+PROCEDURE Record.doMakeField(field: Context.PIdentdefInfo; type: Types.PStorageType): Types.PField;
+BEGIN
+    RETURN NEW EberonRecord.Field(field, type, SELF.type(EberonRecord.PRecord));
+END;
+
+PROCEDURE Record.doGenerateBaseConstructorCallCode(): STRING;
+VAR
+    result: STRING;
+BEGIN
+    base <- SELF.type.base;
+    IF base # NIL THEN
+        baseConstructor <- EberonRecord.constructor(base^(EberonRecord.Record));
+        IF (baseConstructor = NIL) OR (LEN(baseConstructor.args()) = 0) THEN
+            result := SUPER();
+        ELSE        
+            result := SELF.qualifiedBaseConstructor() + ".apply(this, arguments);" + Chars.ln;
+        END;
+    END;
+    RETURN result;
+END;
+
+PROCEDURE Record.endParse(): BOOLEAN;
+BEGIN
+    result <- TRUE;
+
+    type <- SELF.type(EberonRecord.PRecord);
+    IF type.customConstructor = NIL THEN
+        result := SUPER();
+    ELSE
+        SELF.codeGenerator().write(SELF.generateInheritance());
+        type.setRecordInitializationCode(
+            SELF.doGenerateBaseConstructorCallCode());
+    END;
+
+    RETURN result;
+END;
+
+PROCEDURE MethodHeading.handleIdentdef(id: Context.PIdentdefInfo);
+BEGIN
+    SELF.id := id(EberonContext.PIdentdefInfo);
+    EberonContext.checkOrdinaryExport(SELF.id^, "method");
+END;
+
+PROCEDURE MethodHeading.typeName(): STRING;
+    RETURN "";
+END;
+
+PROCEDURE MethodHeading.setType(type: Types.PStorageType);
+BEGIN
+    SELF.type := type(Procedure.PType);
+END;
+
+PROCEDURE MethodHeading.endParse(): BOOLEAN;
+BEGIN
+    void <- SELF.handleMessage(NEW MethodDeclMsg(SELF.id, SELF.type)^);
+    RETURN TRUE;
+END;
+
+PROCEDURE MethodDeclMsg.MethodDeclMsg(id: Context.PIdentdefInfo; type: Procedure.PType)
+    | id(id),
+      type(type);
+END;
+
+END EberonContextType.

+ 4 - 4
src/eberon/EberonRecord.ob

@@ -16,16 +16,16 @@ TYPE
     MapOfFields = MAP OF Types.PField;
 
     Record* = RECORD(Base.Type)
-        PROCEDURE Record(name: STRING; cons: STRING; scope: ScopeBase.PType);
+        PROCEDURE Record*(name: STRING; cons: STRING; scope: ScopeBase.PType);
 
-        PROCEDURE declareConstructor(type: Procedure.PType; exported: BOOLEAN);
-        PROCEDURE addMethod(methodId: Context.PIdentdefInfo; type: Types.PProcedure);
+        PROCEDURE declareConstructor*(type: Procedure.PType; exported: BOOLEAN);
+        PROCEDURE addMethod*(methodId: Context.PIdentdefInfo; type: Types.PProcedure);
         PROCEDURE defineConstructor*(type: Procedure.PType);
         PROCEDURE defineMethod*(methodId: Context.PIdentdefInfo; type: EberonTypes.PMethodType);
         PROCEDURE requireNewOnly*();
         PROCEDURE setBaseConstructorCallCode(code: STRING);
         PROCEDURE setFieldInitializationCode(field: STRING; code: STRING);
-        PROCEDURE setRecordInitializationCode(baseConstructorCallCode: STRING);
+        PROCEDURE setRecordInitializationCode*(baseConstructorCallCode: STRING);
 
         customConstructor-: Procedure.PType;
         customConstructorExported: BOOLEAN;

+ 3 - 120
src/eberon/eberon_context.js

@@ -20,6 +20,7 @@ var EberonConstructor = require("js/EberonConstructor.js");
 var EberonContext = require("js/EberonContext.js");
 var EberonContextDesignator = require("js/EberonContextDesignator.js");
 var EberonContextProcedure = require("js/EberonContextProcedure.js");
+var EberonContextType = require("js/EberonContextType.js");
 var EberonDynamicArray = require("js/EberonDynamicArray.js");
 var EberonMap = require("js/EberonMap.js");
 var EberonRecord = require("js/EberonRecord.js");
@@ -49,52 +50,6 @@ var ChainedContext = ContextHierarchy.Node;
 ChainedContext.extend = Class.extend;
 ChainedContext.prototype.init = ContextHierarchy.Node;
 
-var ProcOrMethodId = ChainedContext.extend({
-    init: function EberonContext$ProcOrMethodId(parent){
-        ChainedContext.prototype.init.call(this, parent);
-        this.__maybeTypeId = undefined;
-        this.__type = undefined;
-    },
-    handleIdent: function(id){this.__maybeTypeId = id;},
-    handleLiteral: function(s){
-        var ss = ContextHierarchy.getSymbolAndScope(this.root(), this.__maybeTypeId);
-        var type = ContextExpression.unwrapType(ss.symbol().info());
-        if (!(type instanceof Type.Record))
-            throw new Errors.Error(
-                  "RECORD type expected in method declaration, got '"
-                + type.description() + "'");
-        if (ss.scope() != this.root().currentScope())
-            throw new Errors.Error(
-                  "method should be defined in the same scope as its bound type '"
-                + this.__maybeTypeId
-                + "'");
-        this.__type = type;
-    },
-    handleIdentdef: function(id){
-        if (this.__type && id.exported())
-            throw new Errors.Error("method implementation cannot be exported: " + id.id());
-        checkOrdinaryExport(id, "procedure");
-        this.handleMessage(new EberonContextProcedure.MethodOrProcMsg(id, this.__type));
-    }
-});
-
-var MethodHeading = ChainedContext.extend({
-    init: function EberonContext$MethodHeading(parent){
-        ChainedContext.prototype.init.call(this, parent);
-        this.__id = undefined;
-        this.__type = undefined;
-    },
-    handleIdentdef: function(id){
-        checkOrdinaryExport(id, "method");
-        this.__id = id;
-    },
-    typeName: function(){return "";},
-    setType: function(type){this.__type = type;},
-    endParse: function(){
-        this.handleMessage(new EberonContextProcedure.MethodOrProcMsg(this.__id, this.__type));
-    }
-});
-
 var InPlaceStringLiteral = Class.extend.call(EberonContextDesignator.TypeNarrowVariable, {
     init: function(type){
         EberonContextDesignator.TypeNarrowVariable.call(this, type, false, true);
@@ -285,17 +240,12 @@ var AssignmentOrProcedureCall = ChainedContext.extend({
     }
 });
 
-function checkOrdinaryExport(id, hint){
-    if (id.isReadOnly())
-        throw new Errors.Error(hint + " cannot be exported as read-only using '-' mark (did you mean '*'?)");
-}
-
 var ConstDecl = Class.extend.call(ContextConst.Type, {
     init: function EberonContext$ConstDecl(context){
         ContextConst.Type.call(this, context);
     },
     handleIdentdef: function(id){
-        checkOrdinaryExport(id, "constant");
+        EberonContext.checkOrdinaryExport(id, "constant");
         ContextConst.Type.prototype.handleIdentdef.call(this, id);
     }
 });
@@ -305,7 +255,7 @@ var VariableDeclaration = Class.extend.call(ContextVar.Declaration, {
         ContextVar.Declaration.call(this, context);
     },
     handleIdentdef: function(id){
-        checkOrdinaryExport(id, "variable");
+        EberonContext.checkOrdinaryExport(id, "variable");
         ContextVar.Declaration.prototype.handleIdentdef.call(this, id);
     },
     doInitCode: function(){
@@ -316,69 +266,6 @@ var VariableDeclaration = Class.extend.call(ContextVar.Declaration, {
     }
 });
 
-var TypeDeclaration = Class.extend.call(ContextType.Declaration, {
-    init: function EberonContext$TypeDeclaration(context){
-        ContextType.Declaration.call(this, context);
-    },
-    handleIdentdef: function(id){
-        checkOrdinaryExport(id, "type");
-        ContextType.Declaration.prototype.handleIdentdef.call(this, id);
-    }
-});
-
-var RecordDecl = Class.extend.call(ContextType.Record, {
-    init: function EberonContext$RecordDecl(context){
-        ContextType.Record.call(this, context, function(name, cons, scope){return new EberonRecord.Record(name, cons, scope); });
-    },
-    handleMessage: function(msg){
-        if (msg instanceof EberonContextProcedure.MethodOrProcMsg){
-            var methodType = msg.type;
-            var boundType = this.type;
-            var id = msg.id.id();
-            if (Type.typeName(boundType) == id){
-                if (msg.id.exported()){
-                    var typeId = this.parent().id;
-                    if (!typeId.exported())
-                        throw new Errors.Error("constructor '" + id + "' cannot be exported because record itslef is not exported");
-                }
-                boundType.declareConstructor(methodType, msg.id.exported());
-            }
-            else
-                boundType.addMethod(msg.id,
-                                    new EberonTypes.MethodType(id, methodType, Procedure.makeProcCallGenerator));
-            return;
-        }
-
-        if (msg instanceof ContextProcedure.EndParametersMsg) // not used
-            return undefined;
-        if (msg instanceof ContextProcedure.AddArgumentMsg) // not used
-            return undefined;
-        return ContextType.Record.prototype.handleMessage.call(this, msg);
-    },
-    doMakeField: function(field, type){
-        return new EberonRecord.Field(field, type, this.type);
-    },
-    doGenerateBaseConstructorCallCode: function(){
-        var base = this.type.base;
-        if (!base)
-            return "";
-        var baseConstructor = EberonRecord.constructor$(base);
-        if (!baseConstructor || !baseConstructor.args().length)
-            return ContextType.Record.prototype.doGenerateBaseConstructorCallCode.call(this);
-        
-        return this.qualifiedBaseConstructor() + ".apply(this, arguments);\n";
-    },
-    endParse: function(){
-        var type = this.type;
-        if (!type.customConstructor)
-            return ContextType.Record.prototype.endParse.call(this);
-
-        this.codeGenerator().write(this.generateInheritance());
-        type.setRecordInitializationCode(
-            this.doGenerateBaseConstructorCallCode());
-    }
-});
-
 var BaseInit = ChainedContext.extend({
     init: function EberonContext$BaseInit(parent){
         ChainedContext.prototype.init.call(this, parent);
@@ -1008,20 +895,16 @@ exports.FormalParametersProcDecl = FormalParametersProcDecl;
 exports.FormalType = FormalType;
 exports.Identdef = Identdef;
 exports.If = If;
-exports.MethodHeading = MethodHeading;
 exports.ModuleDeclaration = ModuleDeclaration;
 exports.MulOperator = MulOperator;
 exports.AssignmentOrProcedureCall = AssignmentOrProcedureCall;
 exports.Factor = Factor;
 exports.MapDecl = MapDecl;
-exports.ProcOrMethodId = ProcOrMethodId;
-exports.RecordDecl = RecordDecl;
 exports.Repeat = Repeat;
 exports.SimpleExpression = SimpleExpression;
 exports.InPlaceVariableInit = InPlaceVariableInit;
 exports.InPlaceVariableInitFor = InPlaceVariableInitFor;
 exports.OperatorNew = OperatorNew;
 exports.Term = Term;
-exports.TypeDeclaration = TypeDeclaration;
 exports.VariableDeclaration = VariableDeclaration;
 exports.While = While;

+ 5 - 4
src/eberon/eberon_grammar.js

@@ -7,6 +7,7 @@ var ContextType = require("js/ContextType.js");
 var EbContext = require("eberon/eberon_context.js");
 var EberonContextDesignator = require("js/EberonContextDesignator.js");
 var EberonContextProcedure = require("js/EberonContextProcedure.js");
+var EberonContextType = require("js/EberonContextType.js");
 var Grammar = require("grammar.js");
 var EbRtl = require("js/EberonRtl.js");
 var EbRtlCode = require("eberon/eberon_rtl.js");
@@ -36,7 +37,7 @@ function makeStatement(base, statementSequence, ident, expression){
 
 function makeProcedureHeading(ident, identdef, formalParameters){
     return and("PROCEDURE",
-               context(and(optional(and(ident, ".")), identdef), EbContext.ProcOrMethodId),
+               context(and(optional(and(ident, ".")), identdef), EberonContextProcedure.ProcOrMethodId),
                context(optional(formalParameters), EbContext.FormalParametersProcDecl)
                );
 }
@@ -82,7 +83,7 @@ function makeMethodHeading(identdef, formalParameters){
         and("PROCEDURE",
             identdef,
             context(optional(formalParameters), EbContext.FormalParametersProcDecl)),
-        EbContext.MethodHeading);
+        EberonContextType.MethodHeading);
 }
 
 function makeFieldList(identdef, identList, type, formalParameters){
@@ -141,8 +142,8 @@ exports.language = {
         makeReturn,
         { 
             constDeclaration:   EbContext.ConstDecl, 
-            typeDeclaration:    EbContext.TypeDeclaration,
-            recordDecl:         EbContext.RecordDecl,
+            typeDeclaration:    EberonContextType.Declaration,
+            recordDecl:         EberonContextType.Record,
             variableDeclaration: EbContext.VariableDeclaration,
             ArrayDecl:          EbContext.ArrayDecl,
             Factor:             EbContext.Factor,

+ 6 - 6
src/ob/ContextType.ob

@@ -48,7 +48,7 @@ TYPE
     PDeclarationAndIdentHandle* = POINTER TO DeclarationAndIdentHandle;
 
     Declaration* = RECORD(DeclarationAndIdentHandle)
-        id: Context.PIdentdefInfo;
+        id-: Context.PIdentdefInfo;
         symbol: Symbols.PSymbol;
     END;
     PDeclaration* = POINTER TO Declaration;
@@ -60,16 +60,16 @@ TYPE
 
         PROCEDURE addField(field: Context.PIdentdefInfo; type: Types.PStorageType);
         PROCEDURE setBaseType(type: Types.PType);
-        PROCEDURE generateInheritance(): STRING;
-        PROCEDURE qualifiedBaseConstructor(): STRING;
+        PROCEDURE generateInheritance*(): STRING;
+        PROCEDURE qualifiedBaseConstructor*(): STRING;
 
-        PROCEDURE doMakeField(field: Context.PIdentdefInfo; type: Types.PStorageType): Types.PField;
+        PROCEDURE doMakeField*(field: Context.PIdentdefInfo; type: Types.PStorageType): Types.PField;
         PROCEDURE doGenerateConstructor(): STRING;
-        PROCEDURE doGenerateBaseConstructorCallCode(): STRING;
+        PROCEDURE doGenerateBaseConstructorCallCode*(): STRING;
 
         declaration: PDeclaration;
         cons: STRING;
-        type: R.PType;
+        type-: R.PType;
     END;
     PRecord = POINTER TO Record;