瀏覽代碼

separate scopes logic from type promotion

Vladislav Folts 9 年之前
父節點
當前提交
d277802b77

二進制
bin/compiled.zip


+ 19 - 5
build.py

@@ -203,14 +203,17 @@ def build_html(options):
         with open(build_version_path, 'w') as f:
             f.write(version)
 
-def recompile_with_replace(bin, skip_tests = False):
+def recompile_with_replace(bin, skip_tests = False, out_bin = None):
     recompiled = recompile(bin)
     if not skip_tests:
         run_tests(recompiled)
     
-    print('%s -> %s' % (recompiled, bin))
-    cleanup(bin)
-    os.rename(recompiled, bin)
+    if out_bin is None:
+        out_bin = bin
+
+    print('%s -> %s' % (recompiled, out_bin))
+    cleanup(out_bin)
+    os.rename(recompiled, out_bin)
 
 def pre_commit_check(options):
     bin = os.path.join(root, 'bin')
@@ -231,6 +234,17 @@ class compile_target(object):
     def __init__(self, options):
         compile_using_snapshot(options.file)
 
+class recompile_target(object):
+    name = 'recompile'
+    description = 'recompile all oberon source files using the snapshot'
+
+    @staticmethod
+    def setup_options(parser):
+        pass
+
+    def __init__(self, options):
+        recompile_with_replace(snapshot_root, True, os.path.join(root, 'bin'))
+
 class self_recompile_target(object):
     name = 'self-recompile'
     description = 'compile itself using current sources'
@@ -299,7 +313,7 @@ class snapshot_target(object):
             os.rename(snapshot_root, old_dir)
         os.rename(new_dir, snapshot_root)
 
-targets = [compile_target, self_recompile_target, html_target, tests_target, pre_commit_target, snapshot_target]
+targets = [compile_target, recompile_target, self_recompile_target, html_target, tests_target, pre_commit_target, snapshot_target]
 
 def build(target, options):
     targets[target](options)

+ 1 - 1
src/eberon/EberonContextIf.ob

@@ -10,7 +10,7 @@ TYPE
 
 PROCEDURE Type.Type(parent: ContextHierarchy.PNode)
     | SUPER(parent),
-      scopes(parent);
+      scopes(parent.root());
 END;
 
 PROCEDURE Type.handleLiteral(s: STRING);

+ 1 - 1
src/eberon/EberonContextLoop.ob

@@ -36,7 +36,7 @@ TYPE
 
 PROCEDURE While.While(parent: ContextHierarchy.PNode)
     | SUPER(parent),
-      scopes(parent);
+      scopes(parent.root());
 END;
 
 PROCEDURE While.handleLiteral(s: STRING);

+ 65 - 0
src/eberon/EberonContextTypePromotion.ob

@@ -0,0 +1,65 @@
+MODULE EberonContextTypePromotion;
+IMPORT
+    ContextHierarchy, 
+    EberonContextDesignator, EberonContextProcedure,
+    EberonTypePromotion;
+TYPE
+    Type* = RECORD
+        PROCEDURE handleMessage*(VAR msg: ContextHierarchy.Message): BOOLEAN;
+        PROCEDURE doThen*();
+        PROCEDURE alternate*();
+        PROCEDURE reset*();
+
+        ignorePromotions: BOOLEAN;
+        typePromotion: EberonTypePromotion.PType;
+        typePromotions-: ARRAY * OF EberonTypePromotion.PType;
+    END;
+    PType* = POINTER TO Type;
+
+PROCEDURE Type.handleMessage(VAR msg: ContextHierarchy.Message): BOOLEAN;
+BEGIN
+    result <- FALSE;
+
+    IF SELF.ignorePromotions THEN
+    ELSIF msg IS EberonContextDesignator.TransferPromotedTypesMsg THEN
+        result := TRUE;
+    ELSIF msg IS EberonContextDesignator.PromoteTypeMsg THEN
+        SELF.typePromotion := NEW EberonTypePromotion.ForVariable(msg.info, msg.type, FALSE);
+        SELF.typePromotions.add(SELF.typePromotion);
+        result := TRUE;
+    ELSIF msg IS EberonContextProcedure.BeginTypePromotionOrMsg THEN
+        tp <- NEW EberonTypePromotion.Or(FALSE);
+        SELF.typePromotion := tp;
+        SELF.typePromotions.add(tp);
+        msg.result := tp;
+        result := TRUE;
+    END;
+    RETURN result;
+END;
+
+PROCEDURE Type.doThen();
+BEGIN
+    IF SELF.typePromotion # NIL THEN
+        SELF.typePromotion.and();
+    END;
+    SELF.ignorePromotions := TRUE;
+END;
+
+PROCEDURE Type.alternate();
+BEGIN
+    IF SELF.typePromotion # NIL THEN
+        SELF.typePromotion.reset();
+        SELF.typePromotion.or();
+        SELF.typePromotion := NIL;
+    END;
+    SELF.ignorePromotions := FALSE;
+END;
+
+PROCEDURE Type.reset();
+BEGIN
+    FOR p IN SELF.typePromotions DO
+        p.reset();
+    END;
+END;
+
+END EberonContextTypePromotion.

+ 26 - 49
src/eberon/EberonOperatorScopes.ob

@@ -1,85 +1,62 @@
 MODULE EberonOperatorScopes;
 IMPORT
-    ContextHierarchy, 
-    EberonContextDesignator, EberonContextProcedure, EberonScope,
-    EberonTypePromotion,
-    Scope;
+    ContextHierarchy, EberonContextTypePromotion, EberonScope, Scope;
 TYPE
+    PRoot = POINTER TO ContextHierarchy.Root;
+
     Type* = RECORD
-        PROCEDURE Type*(cx: ContextHierarchy.PNode);
+        PROCEDURE Type*(cx: PRoot);
 
         PROCEDURE handleMessage*(VAR msg: ContextHierarchy.Message): BOOLEAN;
         PROCEDURE doThen*();
         PROCEDURE alternate*();
         PROCEDURE reset*();
 
-        context: ContextHierarchy.PNode;
+        root: PRoot;
+        typePromotion: EberonContextTypePromotion.Type;
         scope: Scope.PType;
-        ignorePromotions: BOOLEAN;
-        typePromotion: EberonTypePromotion.PType;
-        typePromotions: ARRAY * OF EberonTypePromotion.PType;
     END;
+    PType* = POINTER TO Type;
 
-PROCEDURE Type.Type(cx: ContextHierarchy.PNode)
-    | context(cx);
+PROCEDURE newScope(root: PRoot): Scope.PType;
 BEGIN
-    SELF.alternate();
-END;
+    scope <- EberonScope.makeOperator(
+        root.currentScope(),
+        root.language().stdSymbols);
+    root.pushScope(scope);
+    RETURN scope;
+END;    
 
-PROCEDURE Type.handleMessage(VAR msg: ContextHierarchy.Message): BOOLEAN;
+PROCEDURE Type.Type(root: PRoot)
+    | root(root),
+      scope(newScope(root));
 BEGIN
-    result <- FALSE;
+END;
 
-    IF SELF.ignorePromotions THEN
-    ELSIF msg IS EberonContextDesignator.TransferPromotedTypesMsg THEN
-        result := TRUE;
-    ELSIF msg IS EberonContextDesignator.PromoteTypeMsg THEN
-        SELF.typePromotion := NEW EberonTypePromotion.ForVariable(msg.info, msg.type, FALSE);
-        SELF.typePromotions.add(SELF.typePromotion);
-        result := TRUE;
-    ELSIF msg IS EberonContextProcedure.BeginTypePromotionOrMsg THEN
-        tp <- NEW EberonTypePromotion.Or(FALSE);
-        SELF.typePromotion := tp;
-        SELF.typePromotions.add(tp);
-        msg.result := tp;
-        result := TRUE;
-    END;
-    RETURN result;
+PROCEDURE Type.handleMessage(VAR msg: ContextHierarchy.Message): BOOLEAN;
+    RETURN SELF.typePromotion.handleMessage(msg);
 END;
 
 PROCEDURE Type.doThen();
 BEGIN
-    IF SELF.typePromotion # NIL THEN
-        SELF.typePromotion.and();
-    END;
-    SELF.ignorePromotions := TRUE;
+    SELF.typePromotion.doThen();
 END;
 
 PROCEDURE Type.alternate();
 BEGIN
-    root <- SELF.context.root();
+    root <- SELF.root;
     IF SELF.scope # NIL THEN
         root.popScope();
     END;
-    SELF.scope := EberonScope.makeOperator(
-        root.currentScope(),
-        root.language().stdSymbols);
-    root.pushScope(SELF.scope);
+    SELF.scope := newScope(root);
 
-    IF SELF.typePromotion # NIL THEN
-        SELF.typePromotion.reset();
-        SELF.typePromotion.or();
-        SELF.typePromotion := NIL;
-    END;
-    SELF.ignorePromotions := FALSE;
+    SELF.typePromotion.alternate();
 END;
 
 PROCEDURE Type.reset();
 BEGIN
-    SELF.context.root().popScope();
-    FOR p IN SELF.typePromotions DO
-        p.reset();
-    END;
+    SELF.root.popScope();
+    SELF.typePromotion.reset();
 END;
 
 END EberonOperatorScopes.

+ 6 - 0
test/test_unit_eberon.js

@@ -738,6 +738,12 @@ exports.suite = {
             "bVar := (b IS PDerived) & bVar; ASSERT(b.flag)"
             )
         ),
+    "type promotion in ternary operator": testWithContext(
+        temporaryValues.context,
+        temporaryValues.passExpressions(
+            //"b IS PDerived ? b.flag : FALSE"
+            )
+        ),
     "type promotion in IF": testWithContext(
         temporaryValues.context,
         temporaryValues.passStatements(