Explorar el Código

js -> eberon transition

Vladislav Folts hace 10 años
padre
commit
e384606afc
Se han modificado 5 ficheros con 101 adiciones y 62 borrados
  1. BIN
      bin/compiled.zip
  2. 1 1
      build.py
  3. 98 0
      src/eberon/EberonContextLoop.ob
  4. 0 60
      src/eberon/eberon_context.js
  5. 2 1
      src/eberon/eberon_grammar.js

BIN
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', 
-               'EberonContextExpression.ob', 'EberonContextIdentdef.ob', 'EberonContextInPlace.ob', 'EberonContextType.ob', 'EberonOperatorScopes.ob',
+               'EberonContextExpression.ob', 'EberonContextIdentdef.ob', 'EberonContextInPlace.ob', 'EberonContextLoop.ob', 'EberonContextType.ob', 'EberonOperatorScopes.ob',
                'OberonContext.ob', 'OberonContextType.ob', 'OberonContextVar.ob',
                'OberonSymbols.ob', 'Lexer.ob', 'Module.ob']
     

+ 98 - 0
src/eberon/EberonContextLoop.ob

@@ -0,0 +1,98 @@
+MODULE EberonContextLoop;
+IMPORT
+    Chars, CodeGenerator, 
+    ContextLoop, ContextExpression, ContextHierarchy,
+    Errors, Expression,
+    EberonContextDesignator, 
+    EberonMap, EberonScope, EberonString,
+    Scope, Symbols, Types, Variable;
+TYPE
+    ForEachVariable = RECORD(Variable.TypedVariable)
+    END;
+
+    ForEach* = RECORD(ContextExpression.ExpressionHandler)
+        PROCEDURE ForEach(parent: ContextHierarchy.PNode);
+
+        keyId, valueId: STRING;
+        code: CodeGenerator.PIGenerator;
+        scopeWasCreated: BOOLEAN;
+    END;
+
+PROCEDURE ForEachVariable.idType(): STRING;
+    RETURN "FOR variable";
+END;
+
+PROCEDURE ForEachVariable.referenceCode(): STRING;
+    RETURN "";
+END;
+
+PROCEDURE ForEachVariable.isReference(): BOOLEAN;
+    RETURN FALSE;
+END;
+
+PROCEDURE ForEachVariable.isReadOnly(): BOOLEAN;
+    RETURN TRUE;
+END;
+
+PROCEDURE ForEach.ForEach(parent: ContextHierarchy.PNode)
+    | SUPER(parent),
+      code(CodeGenerator.nullGenerator);
+END;
+
+PROCEDURE ForEach.handleIdent(id: STRING);
+BEGIN
+    IF LEN(SELF.keyId) = 0 THEN
+        SELF.keyId := id;
+    ELSE
+        SELF.valueId := id;
+    END;
+END;
+
+PROCEDURE ForEach.codeGenerator(): CodeGenerator.PIGenerator;
+    RETURN SELF.code;
+END;
+
+PROCEDURE makeVariable(id: STRING; type: Types.PStorageType; scope: Scope.PType);
+BEGIN
+    v <- NEW ForEachVariable(type);
+    s <- NEW Symbols.Symbol(id, v);
+    scope.addSymbol(s, FALSE);
+END;
+
+PROCEDURE ForEach.handleExpression(e: Expression.PType);
+BEGIN
+    type <- e.type();
+    IF ~(type IS EberonMap.PType) THEN
+        Errors.raise("expression of type MAP is expected in FOR, got '" 
+                     + type.description() + "'");
+    ELSE
+        root <- SELF.root();
+        scope <- EberonScope.makeOperator(
+            root.currentScope(),
+            root.language().stdSymbols);
+        root.pushScope(scope);
+        SELF.scopeWasCreated := TRUE;
+
+        code <- SELF.parent().codeGenerator();
+        mapVar <- root.currentScope().generateTempVar("map");
+        code.write("var " + mapVar + " = " + e.code() + ";" + Chars.ln);
+        code.write("for(var " + SELF.keyId + " in " + mapVar + ")");
+        code.openScope();
+        code.write("var " + SELF.valueId + " = " + mapVar + "[" + SELF.keyId + "];" + Chars.ln);
+        SELF.code := code;
+
+        makeVariable(SELF.keyId, EberonString.string, scope);
+        makeVariable(SELF.valueId, type.valueType, scope);
+    END;
+END;
+
+PROCEDURE ForEach.endParse(): BOOLEAN;
+BEGIN
+    SELF.code.closeScope("");
+    IF SELF.scopeWasCreated THEN
+        SELF.root().popScope();
+    END;
+    RETURN TRUE;
+END;
+
+END EberonContextLoop.

+ 0 - 60
src/eberon/eberon_context.js

@@ -52,13 +52,6 @@ var ChainedContext = ContextHierarchy.Node;
 ChainedContext.extend = Class.extend;
 ChainedContext.prototype.init = ContextHierarchy.Node;
 
-var ForEachVariable = Class.extend.call(EberonContextDesignator.TypeNarrowVariable, {
-    init: function(type){
-        EberonContextDesignator.TypeNarrowVariable.call(this, type, false, true);
-    },
-    idType: function(){return "FOR variable";}
-});
-
 function makeContextCall(context, call){
     return call(ContextHierarchy.makeLanguageContext(context));
     }
@@ -305,58 +298,6 @@ var MapDecl = ChainedContext.extend({
     }
 });
 
-var ForEach = ChainedContext.extend({
-    init: function EberonContext$MapDecl(context){
-        ChainedContext.prototype.init.call(this, context);
-        this.__valueId = undefined;
-        this.__keyId = undefined;
-        this.__scopeWasCreated = false;
-        this.__codeGenerator = CodeGenerator.nullGenerator();
-    },
-    handleIdent: function(id){
-        if (!this.__keyId)
-                this.__keyId = id;
-            else
-                this.__valueId = id;
-    },
-    codeGenerator: function(){return this.__codeGenerator;},
-    handleExpression: function(e){
-        var type = e.type();
-        if (!(type instanceof EberonMap.Type))
-            throw new Errors.Error("expression of type MAP is expected in FOR, got '" 
-                                 + type.description() + "'");
-
-        var root = this.root();
-        var scope = EberonScope.makeOperator(
-            root.currentScope(),
-            root.language().stdSymbols);
-        root.pushScope(scope);
-        this.__scopeWasCreated = true;
-
-        var code = this.parent().codeGenerator();
-        var mapVar = root.currentScope().generateTempVar("map");
-        code.write("var " + mapVar + " = " + e.code() + ";\n");
-        code.write("for(var " + this.__keyId + " in " + mapVar + ")");
-        code.openScope();
-        code.write("var " + this.__valueId + " = " + mapVar + "[" + this.__keyId + "];\n");
-        this.__codeGenerator = code;
-
-        this.__makeVariable(this.__keyId, EberonString.string(), scope);
-        this.__makeVariable(this.__valueId, type.valueType, scope);
-    },
-    endParse: function(){
-        this.__codeGenerator.closeScope("");
-        if (this.__scopeWasCreated)
-            this.root().popScope();
-    },
-    __makeVariable: function(id, type, scope){
-        var v = new ForEachVariable(type);
-        var s = new Symbol.Symbol(id, v);
-        scope.addSymbol(s);
-        return s;
-    }
-});
-
 function assertArgumentIsNotNonVarDynamicArray(msg){
     if (msg instanceof ContextProcedure.AddArgumentMsg){
         var arg = msg.arg;
@@ -443,7 +384,6 @@ exports.CaseLabel = CaseLabel;
 exports.ConstDecl = ConstDecl;
 exports.ExpressionProcedureCall = ExpressionProcedureCall;
 exports.For = For;
-exports.ForEach = ForEach;
 exports.FormalParameters = FormalParameters;
 exports.FormalParametersProcDecl = FormalParametersProcDecl;
 exports.FormalType = FormalType;

+ 2 - 1
src/eberon/eberon_grammar.js

@@ -9,6 +9,7 @@ var EberonContextDesignator = require("js/EberonContextDesignator.js");
 var EberonContextExpression = require("js/EberonContextExpression.js");
 var EberonContextIdentdef = require("js/EberonContextIdentdef.js");
 var EberonContextInPlace = require("js/EberonContextInPlace.js");
+var EberonContextLoop = require("js/EberonContextLoop.js");
 var EberonContextProcedure = require("js/EberonContextProcedure.js");
 var EberonContextType = require("js/EberonContextType.js");
 var Grammar = require("grammar.js");
@@ -33,7 +34,7 @@ function makeStrucType(base, type){
 function makeStatement(base, statementSequence, ident, expression){
     return or(context(and("FOR", ident, ",", ident, "IN", expression, "DO", 
                           statementSequence, required("END", "END expected (FOR)")), 
-                      EbContext.ForEach),
+                      EberonContextLoop.ForEach),
               base
               );
 }