[svn] r6237: nemerle/trunk/ncc: generation/Typer3.n testsuite/negative/base-calls.n testsuite/positive/bas...

nazgul svnadmin at nemerle.org
Sun May 7 13:09:02 CEST 2006


Log:
Support placing ctor calls in the middle of constructor sequence

Author: nazgul
Date: Sun May  7 13:08:22 2006
New Revision: 6237

Added:
   nemerle/trunk/ncc/testsuite/negative/base-calls.n
Modified:
   nemerle/trunk/ncc/generation/Typer3.n
   nemerle/trunk/ncc/testsuite/positive/base-calls.n
   nemerle/trunk/ncc/typing/Typer.n

Modified: nemerle/trunk/ncc/generation/Typer3.n
==============================================================================
--- nemerle/trunk/ncc/generation/Typer3.n	(original)
+++ nemerle/trunk/ncc/generation/Typer3.n	Sun May  7 13:08:22 2006
@@ -990,7 +990,7 @@
         when (need_cast)
           parm.SetType (InternalType.Object); // modify its type
 
-        // Message.Debug ($"handle fp $parm $(parm.Id) $(parm.Type)");
+         //Message.Debug ($"handle fp $parm $(parm.Type)");
         when (parm.InClosure) {
           def expr =
             if (need_cast)
@@ -1022,9 +1022,8 @@
             current_local_fun.body = FunBody.Typed (BuildRevSequence ([]));
             Some (Walk (basecall))
 
-          | FunBody.Typed (body) =>
-            Message.Warning (body.loc, body.ToString ());
-            assert (false)
+          // ctor call is (if not, it's a bug) placed somewhere inside, but this case disallows using 'this' in closures
+          | FunBody.Typed (_) => Some (null) 
 
           | _ => assert (false)
         }
@@ -1053,7 +1052,9 @@
 
       initializers = LoadParameters () + initializers;
 
+      mutable base_call_missing = false;
       match (GetBaseCall ()) {
+        | Some (null) => base_call_missing = true;
         | Some (call) =>
           initializers = call :: initializers;
         | None => {}
@@ -1063,6 +1064,8 @@
       foreach (d in current_local_fun.closure_vars) 
         when (d.InClosure &&
               d.ValKind is LocalValue.Kind.ClosurisedThisPointer) {
+          when (base_call_missing)
+            Message.Error ("closure utilizing 'this' reference is not allowed when base ctor call is not placed at the beginning of current ctor");
           def ini =
             TExpr.Assign (InternalType.Void,
                           LocalRef (d, for_store = true),

Added: nemerle/trunk/ncc/testsuite/negative/base-calls.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/ncc/testsuite/negative/base-calls.n	Sun May  7 13:08:22 2006
@@ -0,0 +1,15 @@
+using Nemerle.IO;
+
+class Closurising {
+  myfun : void -> void;
+  fld : int;
+  
+  public this (_x : int) { // E: closure utilizing 'this' reference is not allowed when base ctor call is not placed at the beginning of current ctor
+    fld = 1;
+    myfun = fun () { print ("fun $fld\n") }
+    myfun ();
+    base ();
+    fld = 7;
+    myfun ();
+  }
+}
\ No newline at end of file

Modified: nemerle/trunk/ncc/testsuite/positive/base-calls.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/positive/base-calls.n	(original)
+++ nemerle/trunk/ncc/testsuite/positive/base-calls.n	Sun May  7 13:08:22 2006
@@ -47,6 +47,38 @@
     def b = B ();
     b.m ();
     b.Prop += 3;
+    def _ = Inherit(1);
+    _ = Closurising (5);
+  }
+}
+
+class Base
+{
+ public this(_ : int) { print("A()\n"); }
+}
+
+class Inherit : Base
+{
+ public this(_ : int)
+ {
+   print("B()\n");
+   base(2);
+ }
+}
+
+class Closurising : Base {
+  myfun : void -> void;
+  fld : int;
+  
+  public this (x : int)  {
+    mutable str = "aaa";
+    fld = 1;
+    myfun = () => print ("fun $x and $str and no fld\n"); // we do not use 'fld', so closure can be created safely
+    myfun ();
+        base (x);
+    str = "bbb";
+    fld = 7;
+    myfun ();    
   }
 }
 
@@ -58,5 +90,10 @@
 A.Prop
 A.Prop set
 B.Prop set
+B()
+A()
+fun 5 and aaa and no fld
+A()
+fun 5 and bbb and no fld
 END-OUTPUT
 */

Modified: nemerle/trunk/ncc/typing/Typer.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer.n	(original)
+++ nemerle/trunk/ncc/typing/Typer.n	Sun May  7 13:08:22 2006
@@ -230,16 +230,19 @@
     {
       when (is_instance_ctor && !m.DeclaringType.IsValueType)
         match (current_fun.body) {
-          | FunBody.Parsed (expr) =>
-            match (expr) {
-              | PT.PExpr.Sequence (<[ base (.. $_) ]> :: _) => ()
-              | PT.PExpr.Sequence (<[ this (.. $_) ]> :: _) => ()
-              | PT.PExpr.Sequence =>
-                Util.locate (expr.loc,
-                  current_fun.body = FunBody.Parsed (<[ { base (); $expr } ]>)
-                )
-              | _ => assert (false)
+          | FunBody.Parsed (Sequence (exprs) as seq) =>
+            def exists_ctor_call (_) {
+              | [] => false 
+              | <[ base (.. $_) ]> :: _ 
+              | <[ this (.. $_) ]> :: _ => true
+              | _ :: xs => exists_ctor_call (xs)
             }
+            if (exists_ctor_call (exprs))
+              ()
+            else
+              Util.locate (seq.loc,
+                current_fun.body = FunBody.Parsed (<[ { ..$(<[ base (); ]> :: exprs) } ]>)
+              )
           | _ => ()
         }
     }
@@ -1675,6 +1678,7 @@
            parms = parms,
            tenv = tenv,
            loc = fn.header.loc);
+
         def parm_types = List.Map (parms, fun (p : Fun_parm) { p.ty });
         def fun_type = ConstructFunctionType (parm_types, header.ret_type);
         def parents = current_fun :: current_fun.GetParents ();



More information about the svn mailing list