Sfoglia il codice sorgente

Fix temporary values scoping (fro WHILE only).
Fix module qualifing for SUPER call.

Vladislav Folts 11 anni fa
parent
commit
2136d88f83

BIN
bin/compiled.zip


+ 1 - 1
build.py

@@ -123,7 +123,7 @@ def run_tests(bin, unit_test=None, code_test=None):
 def recompile(bin):
     print('recompile oberon sources using "%s"...' % bin)
     compiler = os.path.join(root, 'src', 'oc_nodejs.js')
-    sources = ['EberonSymbols.ob', 'EberonCast.ob', 'EberonOperator.ob', 
+    sources = ['EberonSymbols.ob', 'EberonCast.ob', 'EberonOperator.ob', 'EberonScope.ob',
                'OberonSymbols.ob', 'Lexer.ob', 'Module.ob']
     
     result = os.path.join(root, 'bin.recompile')

+ 7 - 8
src/context.js

@@ -1433,20 +1433,19 @@ exports.While = ChainedContext.extend({
         gen.openScope();
         gen.write("if (");
     },
-    handleExpression: handleIfExpression,
-    endParse: function(){
+    handleExpression: function WhileContext$handleExpression(e){
+        handleIfExpression(e);
         var gen = this.codeGenerator();
         gen.write(")");
         gen.openScope();
+    },
+    endParse: function(){
+        var gen = this.codeGenerator();
+        gen.closeScope(" else break;\n");
+        gen.closeScope("");
     }
 });
 
-exports.emitWhileEnd = function(context){
-    var gen = context.codeGenerator();
-    gen.closeScope(" else break;\n");
-    gen.closeScope("");
-};
-
 exports.Repeat = ChainedContext.extend({
     init: function RepeatContext(context){
         ChainedContext.prototype.init.call(this, context);

+ 29 - 0
src/eberon/EberonScope.ob

@@ -0,0 +1,29 @@
+MODULE EberonScope;
+IMPORT Errors, JsMap, Scope, Symbols;
+TYPE
+    Operator = RECORD(Scope.Type)
+        parent: Scope.PType
+    END;
+
+PROCEDURE Operator.addSymbol(s: Symbols.PSymbol; exported: BOOLEAN);
+VAR
+    id: STRING;
+BEGIN
+    id := s.id();
+    IF SELF.parent.findSymbol(id) # NIL THEN
+        Errors.raise("'" + id + "' already declared in procedure scope");
+    END;
+    SUPER(s, exported);
+END Operator.addSymbol;
+
+PROCEDURE makeOperator*(parent: Scope.PType; stdSymbols: JsMap.Type): Scope.PType;
+VAR
+    result: POINTER TO Operator;
+BEGIN
+    NEW(result);
+    Scope.init(result^, stdSymbols);
+    result.parent := parent;
+    RETURN result
+END makeOperator;
+
+END EberonScope.

+ 17 - 2
src/eberon/eberon_context.js

@@ -3,6 +3,7 @@
 var Cast = require("js/Cast.js");
 var Code = require("js/Code.js");
 var Context = require("context.js");
+var EberonScope = require("js/EberonScope.js");
 var EberonString = require("js/EberonString.js");
 var Errors = require("js/Errors.js");
 var op = require("js/Operator.js");
@@ -560,7 +561,8 @@ var ProcOrMethodDecl = Context.ProcDecl.extend({
             symbol: Symbol.makeSymbol(
                 "method",  
                 Type.makeProcedure(new MethodType(id, this.__methodType.procType(), superMethodCallGenerator))),
-            code: Type.typeName(baseType) + ".prototype." + id + ".call"
+            code: this.qualifyScope(Type.recordScope(baseType))
+                + Type.typeName(baseType) + ".prototype." + id + ".call"
         };
     }
 });
@@ -621,6 +623,18 @@ var Expression = Context.Expression.extend({
     }
 });
 
+var While = Context.While.extend({
+    init: function EberonContext$While(context){
+        Context.While.prototype.init.call(this, context);
+        this.__scope = EberonScope.makeOperator(
+            this.parent().currentScope(),
+            this.language().stdSymbols);
+    },
+    currentScope: function EberonContext$While(){
+        return this.__scope;
+    }
+});
+
 exports.AddOperator = AddOperator;
 exports.ConstDecl = ConstDecl;
 exports.Designator = Designator;
@@ -634,4 +648,5 @@ exports.ProcOrMethodDecl = ProcOrMethodDecl;
 exports.RecordDecl = RecordDecl;
 exports.TemplValueInit = TemplValueInit;
 exports.TypeDeclaration = TypeDeclaration;
-exports.VariableDeclaration = VariableDeclaration;
+exports.VariableDeclaration = VariableDeclaration;
+exports.While = While;

+ 2 - 1
src/eberon/eberon_grammar.js

@@ -78,7 +78,8 @@ exports.language = {
             recordDecl:         EbContext.RecordDecl,
             variableDeclaration: EbContext.VariableDeclaration,
             addOperator:        EbContext.AddOperator,
-            expression:         EbContext.Expression
+            expression:         EbContext.Expression,
+            whileContext:       EbContext.While
         },
         Grammar.reservedWords + " SELF SUPER"
         ),

+ 5 - 4
src/grammar.js

@@ -135,10 +135,11 @@ var caseStatement = and("CASE", context(and(expression
                       , "OF", caseParser, repeat(and("|", caseParser)), "END")
                       , Context.Case));
 
-var whileStatement = and("WHILE", context(expression, Context.While), "DO", statementSequence
-                       , repeat(and("ELSIF", context(expression, Context.ElseIf), "DO", statementSequence))
-                       , emit("END", Context.emitWhileEnd)
-                       );
+var whileStatement = and("WHILE", 
+                         context(and(expression, "DO", statementSequence, 
+                                     repeat(and("ELSIF", context(expression, Context.ElseIf), "DO", statementSequence)),
+                                     "END"),
+                                 contexts.whileContext));
 var repeatStatement = and("REPEAT", context(statementSequence, Context.Repeat)
                         , "UNTIL", context(expression, Context.Until));
 

+ 5 - 5
src/ob/Scope.ob

@@ -9,9 +9,9 @@ IMPORT
     Symbols, 
     Types;
 TYPE
-    Type = RECORD(ScopeBase.Type)
-        PROCEDURE addSymbol(s: Symbols.PSymbol; exported: BOOLEAN);
-        PROCEDURE findSymbol(id: STRING): Symbols.PSymbol;
+    Type* = RECORD(ScopeBase.Type)
+        PROCEDURE addSymbol*(s: Symbols.PSymbol; exported: BOOLEAN);
+        PROCEDURE findSymbol*(id: STRING): Symbols.PSymbol;
         PROCEDURE close();
 
         stdSymbols: JsMap.Type;
@@ -19,7 +19,7 @@ TYPE
         unresolved: JsArray.Strings;
         finalizers: JsArray.Type
     END;
-    PType = POINTER TO Type;
+    PType* = POINTER TO Type;
 
     Procedure* = RECORD(Type)
     END;
@@ -76,7 +76,7 @@ BEGIN
     RETURN result
 END makeStdSymbols;
 
-PROCEDURE init(VAR scope: Type; stdSymbols: JsMap.Type);
+PROCEDURE init*(VAR scope: Type; stdSymbols: JsMap.Type);
 BEGIN
     scope.stdSymbols := stdSymbols;
     scope.symbols := JsMap.make();

+ 2 - 1
src/oberon/oberon_grammar.js

@@ -65,7 +65,8 @@ exports.language = {
             recordDecl:         ObContext.RecordDecl,
             variableDeclaration: ObContext.VariableDeclaration,
             addOperator:        Context.AddOperator,
-            expression:         Context.Expression
+            expression:         Context.Expression,
+            whileContext:       Context.While
         },
         Grammar.reservedWords
         ),

+ 37 - 0
test/expected/eberon/modules.js

@@ -0,0 +1,37 @@
+var RTL$ = {
+    extend: function extend(methods){
+        function Type(){
+            for(var m in methods)
+                this[m] = methods[m];
+        }
+        Type.prototype = this.prototype;
+
+        var result = methods.init;
+        result.prototype = new Type(); // inherit this.prototype
+        result.prototype.constructor = result; // to see constructor name in diagnostic
+        
+        result.extend = extend;
+        return result;
+    }
+};
+var m1 = function (){
+var Base = RTL$.extend({
+	init: function Base(){
+	}
+});
+Base.prototype.p = function(){
+}
+return {
+	Base: Base
+}
+}();
+var m2 = function (m1){
+var T = m1.Base.extend({
+	init: function T(){
+		m1.Base.prototype.init.call(this);
+	}
+});
+T.prototype.p = function(){
+	m1.Base.prototype.p.call(this);
+}
+}(m1);

+ 24 - 0
test/input/eberon/modules.ob

@@ -0,0 +1,24 @@
+MODULE m1;
+TYPE
+	Base* = RECORD 
+        PROCEDURE p*()
+    END;
+
+PROCEDURE Base.p();
+END Base.p;
+
+END m1.
+
+MODULE m2;
+IMPORT m1;
+
+TYPE
+	T = RECORD(m1.Base)
+    END;
+
+PROCEDURE T.p();
+BEGIN
+    SUPER();
+END T.p;
+
+END m2.

+ 2 - 1
test/test_unit_eberon.js

@@ -367,7 +367,8 @@ exports.suite = {
              ),
         fail(["PROCEDURE p(); BEGIN v <- 0; v <-0; END p;", "'v' already declared"],
              ["PROCEDURE p(); VAR v: INTEGER; BEGIN v <- 0; END p;", "'v' already declared"],
-             ["PROCEDURE p(); BEGIN v <- 0; WHILE FALSE DO v <- 0; END; END p;", "'v' already declared"]
+             ["PROCEDURE p(); BEGIN v <- 0; WHILE FALSE DO v <- 0; END; END p;", 
+              "'v' already declared in procedure scope"]
             )
         ),
     "read-only": testWithContext(