Vladislav Folts преди 10 години
родител
ревизия
e5b7dbccb1
променени са 5 файла, в които са добавени 95 реда и са изтрити 120 реда
  1. BIN
      bin/compiled.zip
  2. 2 2
      src/context.js
  3. 79 101
      src/eberon/EberonRecord.ob
  4. 1 1
      src/eberon/eberon_context.js
  5. 13 16
      src/ob/Types.ob

BIN
bin/compiled.zip


+ 2 - 2
src/context.js

@@ -1715,7 +1715,7 @@ function isTypeRecursive(type, base){
     if (type instanceof Type.Record){
         if (isTypeRecursive(Type.recordBase(type), base))
             return true;
-        var fields = Type.recordOwnFields(type);
+        var fields = type.fields;
         for(var fieldName in fields){
             if (isTypeRecursive(fields[fieldName].type(), base))
                 return true;
@@ -1786,7 +1786,7 @@ exports.RecordDecl = ChainedContext.extend({
     },
     __generateFieldsInitializationCode: function(){
         var result = "";
-        var ownFields = Type.recordOwnFields(this.__type);
+        var ownFields = this.__type.fields;
         for(var f in ownFields){
             var fieldType = ownFields[f].type();
             result += "this." + Type.mangleField(f, fieldType) + " = " + fieldType.initializer(this) + ";\n";

+ 79 - 101
src/eberon/EberonRecord.ob

@@ -1,11 +1,18 @@
 MODULE EberonRecord;
 IMPORT 
-    Cast, Context, EberonContext, EberonTypes, Errors, JS, JsMap, Object, Scope, ScopeBase, Stream, String, Types;
+    Cast, Context, EberonContext, EberonTypes, Errors, JS, Object, Scope, ScopeBase, Stream, String, Types;
 CONST
     instantiateForVar* = 0;    
     instantiateForNew* = 1;    
     instantiateForCopy* = 2;    
 TYPE
+    MethodIds = RECORD
+        ids: ARRAY * OF STRING;
+    END;
+    PMethodIds = POINTER TO MethodIds;
+    MapOfMethodIds = MAP OF PMethodIds;
+    MapOfFields = MAP OF Types.PField;
+
     Record* = RECORD(Types.Record)
         PROCEDURE Record(name: STRING; cons: STRING; scope: ScopeBase.PType);
 
@@ -23,16 +30,16 @@ TYPE
         customConstructorDefined: BOOLEAN;
         customInitedfields-: ARRAY * OF STRING;
         finalized: BOOLEAN;
-        declaredMethods: JsMap.Type;
+        declaredMethods: MapOfFields;
         definedMethods: ARRAY * OF STRING;
         abstractMethods: ARRAY * OF STRING;
         instantiated: BOOLEAN;
         createByNewOnly: BOOLEAN;
         declaredAsVariable: BOOLEAN;
-        lazyDefinitions: JsMap.Type;
+        lazyDefinitions: MapOfMethodIds;
         nonExportedMethods: ARRAY * OF STRING;
         baseConstructorCallCode-: STRING;
-        fieldsInit: JsMap.Strings;
+        fieldsInit: MAP OF STRING;
         fieldsInitOrder: ARRAY * OF STRING;
         lastFieldInit: INTEGER;
     END;
@@ -48,27 +55,6 @@ TYPE
     END;
     PRecordFieldAsMethod = POINTER TO RecordFieldAsMethod;
 
-    MethodIds = RECORD(Object.Type)
-        ids: ARRAY * OF STRING;
-    END;
-    PMethodIds = POINTER TO MethodIds;
-
-    EnsureMethodDefinitionsClosure = RECORD(Object.Type)
-        record: PRecord;
-        result: ARRAY * OF STRING;
-    END;
-
-    RequireMethodDefinitionClosure = RECORD(Object.Type)
-        record: PRecord;
-        base: PRecord;
-    END;
-
-    GenFieldInitCodeClosure = RECORD(Object.Type)
-        cx: Context.PType;
-        record: PRecord;
-        code: STRING;
-    END;
-
 PROCEDURE assertNotReadOnly*(isReadObly: BOOLEAN; method: STRING; class: STRING);
 BEGIN
     IF isReadObly THEN
@@ -93,49 +79,51 @@ END;
 
 PROCEDURE findMethodDeclaration(r: PRecord; id: STRING): Types.PField;
 VAR
-    result: Object.PType;
+    result: Types.PField;
 BEGIN
     type <- r;
-    WHILE (type # NIL) & ~JsMap.find(type.declaredMethods, id, result) DO
-        type := type.base(PRecord);
+    WHILE (type # NIL) & (result = NIL) DO
+        IF id IN type.declaredMethods THEN
+            result := type.declaredMethods[id];
+        ELSE
+            type := type.base(PRecord);
+        END;
     END;
-    RETURN result(Types.PField);
+    RETURN result;
 END;
 
-PROCEDURE ensureMethodDefinitionsForEach(key: STRING; value: Object.PType; VAR closure: Object.Type);
-    PROCEDURE do(ids: ARRAY OF STRING; VAR closure: EnsureMethodDefinitionsClosure);
-    VAR
-        report: ARRAY * OF STRING;
-    BEGIN
-        FOR i <- 0 TO LEN(ids) - 1 DO
-            m <- ids[i];
-            IF ~hasMethodDefinition(closure.record, m) THEN
-                report.add(m);
-            END;
+PROCEDURE ensureMethodDefinitionsForEach(key: STRING; ids: ARRAY OF STRING; r: PRecord; VAR result: ARRAY * OF STRING);
+VAR
+    report: ARRAY * OF STRING;
+BEGIN
+    FOR i <- 0 TO LEN(ids) - 1 DO
+        m <- ids[i];
+        IF ~hasMethodDefinition(r, m) THEN
+            report.add(m);
         END;
+    END;
 
-        IF LEN(report) # 0 THEN
-            closure.result.add(key + ": " + String.join(report, ", "));
-        END;
+    IF LEN(report) # 0 THEN
+        result.add(key + ": " + String.join(report, ", "));
     END;
-BEGIN
-    do(value(PMethodIds).ids, closure(EnsureMethodDefinitionsClosure));
 END;
 
-PROCEDURE ensureMethodDefinitions(r: PRecord; reasons: JsMap.Type);
+PROCEDURE ensureMethodDefinitions(r: PRecord; reasons: MapOfMethodIds);
 VAR
-    closure: EnsureMethodDefinitionsClosure;
+    result: ARRAY * OF STRING;
 BEGIN
-    closure.record := r;
-    JsMap.forEach(reasons, ensureMethodDefinitionsForEach, closure);
-    IF LEN(closure.result) # 0 THEN
-        Errors.raise(String.join(closure.result, "; "));
+    FOREACH v, k IN reasons DO
+        ensureMethodDefinitionsForEach(k, v.ids, r, result);
+    END;
+    IF LEN(result) # 0 THEN
+        Errors.raise(String.join(result, "; "));
     END;
 END;
 
 PROCEDURE requireMethodDefinition*(r: PRecord; id: STRING; reason: STRING);
 VAR
     existingIds: Object.PType;
+    reasons: MapOfMethodIds;
 
     PROCEDURE makeIds(): PMethodIds;
     BEGIN
@@ -157,43 +145,35 @@ BEGIN
     END;
 
     IF r.finalized THEN
-        reasons <- JsMap.make();
-        JsMap.put(reasons, reason, makeIds());
+        reasons[reason] := makeIds();
         ensureMethodDefinitions(r, reasons);
     ELSE
-        IF ~JsMap.find(r.lazyDefinitions, reason, existingIds) THEN
-            JsMap.put(r.lazyDefinitions, reason, makeIds());
+        IF ~(reason IN r.lazyDefinitions) THEN
+            r.lazyDefinitions[reason] := makeIds();
         ELSE
-            addIfNotThere(existingIds(PMethodIds).ids);
+            addIfNotThere(r.lazyDefinitions[reason].ids);
         END;
     END;
 END;
 
-PROCEDURE requireMethodDefinitionForEach(key: STRING; value: Object.PType; VAR closure: Object.Type);
-    PROCEDURE do(closure: RequireMethodDefinitionClosure);
+PROCEDURE ensureNonAbstract(r: PRecord);
+    PROCEDURE require(declaredMethods: MapOfFields; base: PRecord);
     BEGIN
-        IF ~hasMethodDefinition(closure.record, key) THEN
-            requireMethodDefinition(closure.base, key, cannotInstantiateErrMsg(closure.record^));
+        FOREACH v, k IN declaredMethods DO
+            IF ~hasMethodDefinition(r, k) THEN
+                requireMethodDefinition(base, k, cannotInstantiateErrMsg(r^));
+            END;
         END;
     END;
-BEGIN
-    do(closure(RequireMethodDefinitionClosure));
-END;
-
-PROCEDURE ensureNonAbstract(r: PRecord);
-VAR
-    closure: RequireMethodDefinitionClosure;
 BEGIN
     IF LEN(r.abstractMethods) # 0 THEN
         Errors.raise(cannotInstantiateErrMsg(r^) + ": " + String.join(r.abstractMethods, ", "));
     END;
 
     baseType <- r.base(PRecord);
-    closure.record := r;
     WHILE baseType # NIL DO
         IF ~baseType.finalized THEN
-            closure.base := baseType;
-            JsMap.forEach(baseType.declaredMethods, requireMethodDefinitionForEach, closure);
+            require(baseType.declaredMethods, baseType)
         END;
         baseType := baseType.base(PRecord);
     END;
@@ -328,7 +308,7 @@ BEGIN
         Errors.raise(msg);
     END;
 
-    JsMap.put(SELF.declaredMethods, id, NEW RecordFieldAsMethod(methodId, type));
+    SELF.declaredMethods[id] := NEW RecordFieldAsMethod(methodId, type);
     IF ~methodId.exported() THEN
         SELF.nonExportedMethods.add(id);
     END;
@@ -383,7 +363,7 @@ BEGIN
     ELSE
         SELF.lastFieldInit := index;
     END;
-    JsMap.putString(SELF.fieldsInit, field, code);
+    SELF.fieldsInit[field] := code;
 END;
 
 PROCEDURE Record.setRecordInitializationCode(baseConstructorCallCode: STRING);
@@ -421,10 +401,22 @@ BEGIN
 END;
 
 PROCEDURE collectAbstractMethods(VAR r: Record);
+TYPE
+    Strings = ARRAY * OF STRING;
 VAR
-    methods: ARRAY * OF STRING;
+    methods: Strings;
+
+    PROCEDURE keys(m: MapOfFields): Strings;
+    VAR
+        result: Strings;
+    BEGIN
+        FOREACH v, k IN m DO
+            result.add(k);
+        END;
+        RETURN result;
+    END;
 BEGIN
-    selfMethods <- JsMap.keys(r.declaredMethods);
+    selfMethods <- keys(r.declaredMethods);
     baseType <- r.base(PRecord);
     IF baseType # NIL THEN
         JS.do("methods = baseType.abstractMethods.concat(selfMethods);");
@@ -446,7 +438,7 @@ VAR
 BEGIN
     FOR i <- 0 TO LEN(r.customInitedfields) - 1 DO
         f <- r.customInitedfields[i];
-        IF ~JsMap.hasString(r.fieldsInit, f) THEN
+        IF ~(f IN r.fieldsInit) THEN
             fieldsWereNotInited.add(f);
         END;
     END;
@@ -477,7 +469,7 @@ BEGIN
     ensureMethodDefinitions(SELF(POINTER), SELF.lazyDefinitions);
 
     FOR i <- 0 TO LEN(SELF.nonExportedMethods) - 1 DO
-        JsMap.erase(SELF.declaredMethods, SELF.nonExportedMethods[i]);
+        SELF.declaredMethods.remove(SELF.nonExportedMethods[i]);
     END;
     SELF.nonExportedMethods.clear();
 
@@ -497,39 +489,25 @@ END;
 
 PROCEDURE Record.Record(name: STRING; cons: STRING; scope: ScopeBase.PType)
     | SUPER(name, cons, scope),
-      declaredMethods(JsMap.make()),
-      lazyDefinitions(JsMap.make()),
-      fieldsInit(JsMap.makeStrings()),
       lastFieldInit(-1);
 END;
 
-PROCEDURE genFieldInitCode(key: STRING; value: Object.PType; VAR closure: Object.Type);
-    PROCEDURE do(f: Types.PField; VAR closure: GenFieldInitCodeClosure);
-    VAR
-        code: STRING;
-        result: STRING;
-    BEGIN
+PROCEDURE fieldsInitializationCode*(r: PRecord; cx: Context.PType): STRING;
+VAR
+    code: STRING;
+    result: STRING;
+BEGIN
+    FOREACH f, key IN r.fields DO
         type <- f.type()(Types.PStorageType);
-        IF JsMap.findString(closure.record.fieldsInit, key, code) THEN
-            result := code;
+        IF key IN r.fieldsInit THEN
+            code := r.fieldsInit[key];
         ELSE
-            result := "this." + Types.mangleField(key, type) 
-                    + " = " + type.initializer(closure.cx^);
+            code := "this." + Types.mangleField(key, type) 
+                    + " = " + type.initializer(cx^);
         END;
-        closure.code := closure.code + result + ";" + Stream.kCR;
+        result := result + code + ";" + Stream.kCR;
     END;
-BEGIN
-    do(value(Types.PField), closure(GenFieldInitCodeClosure));
-END;
-
-PROCEDURE fieldsInitializationCode*(r: PRecord; cx: Context.PType): STRING;
-VAR
-    closure: GenFieldInitCodeClosure;
-BEGIN
-    closure.cx := cx;
-    closure.record := r;
-    JsMap.forEach(Types.recordOwnFields(r^), genFieldInitCode, closure);
-    RETURN closure.code;
+    RETURN result;
 END;
 
 PROCEDURE RecordField.RecordField(identdef: Context.PIdentdefInfo; type: Types.PType; record: PRecord)

+ 1 - 1
src/eberon/eberon_context.js

@@ -759,7 +759,7 @@ var ProcOrMethodDecl = Context.ProcDecl.extend({
         };
     },
     __handleFieldInit: function(id){
-        var fields = Type.recordOwnFields(this.__boundType);
+        var fields = this.__boundType.fields;
         if (!fields.hasOwnProperty(id))
             throw new Errors.Error("'" + id + "' is not record '" + Type.typeName(this.__boundType) + "' own field");
         

+ 13 - 16
src/ob/Types.ob

@@ -199,10 +199,10 @@ TYPE
         PROCEDURE codeForNew*(cx: Context.Type): STRING;
         PROCEDURE finalize*();
 
-        fields: JsMap.Type;
-        base-:  PRecord;
-        cons-:  STRING;
-        scope-: ScopeBase.PType;
+        fields-: MAP OF PField;
+        base-:   PRecord;
+        cons-:   STRING;
+        scope-:  ScopeBase.PType;
         notExported: ARRAY * OF STRING
     END;
     
@@ -256,14 +256,13 @@ END;
 PROCEDURE Record.finalize();
 BEGIN
     FOR i <- 0 TO LEN(SELF.notExported) - 1 DO
-        JsMap.erase(SELF.fields, SELF.notExported[i])
+        SELF.fields.remove(SELF.notExported[i])
     END;
     SELF.notExported.clear();
 END Record.finalize;
 
 PROCEDURE Record.Record(name: STRING; cons: STRING; scope: ScopeBase.PType)
     | SUPER(name),
-      fields(JsMap.make()),
       cons(cons),
       scope(scope);
 BEGIN
@@ -453,13 +452,13 @@ END;
 
 PROCEDURE Record.addField(f: PField);
 BEGIN
-    IF JsMap.has(SELF.fields, f.id()) THEN
+    IF f.id() IN SELF.fields THEN
         Errors.raise("duplicated field: '" + f.id() + "'");
     END;
     IF (SELF.base # NIL) & (SELF.base.findSymbol(f.id()) # NIL) THEN
         Errors.raise("base record already has field: '" + f.id() + "'");
     END;
-    JsMap.put(SELF.fields, f.id(), f);
+    SELF.fields[f.id()] := f;
     IF ~f.exported() THEN
         SELF.notExported.add(f.id());
     END;
@@ -467,13 +466,15 @@ END Record.addField;
 
 PROCEDURE Record.findSymbol(id: STRING): PField;
 VAR
-    result: Object.PType;
+    result: PField;
 BEGIN
-    IF ~JsMap.find(SELF.fields, id, result) & (SELF.base # NIL) THEN
+    IF id IN SELF.fields THEN
+        result := SELF.fields[id];
+    ELSIF SELF.base # NIL THEN
         result := SELF.base.findSymbol(id);
     END;
-    RETURN result(PField)
-END Record.findSymbol;
+    RETURN result;
+END;
 
 PROCEDURE existingField(r: Record; id: STRING; d: NamedType): PField;
 BEGIN
@@ -506,10 +507,6 @@ PROCEDURE recordConstructor*(r: Record): STRING;
     RETURN r.cons
 END recordConstructor;
 
-PROCEDURE recordOwnFields*(r: Record): JsMap.Type;
-    RETURN r.fields
-END recordOwnFields;
-
 PROCEDURE pointerBase*(p: Pointer): PRecord;
 VAR
     result: PType;