[svn] r7694: nemerle/trunk: macros/core.n ncc/testsuite/positive/basic-macros.n

nazgul svnadmin at nemerle.org
Sat Jun 2 21:07:45 CEST 2007


Log:
Add extended version of using macro, which allows specifying catch at the same time

Author: nazgul
Date: Sat Jun  2 21:07:43 2007
New Revision: 7694

Modified:
   nemerle/trunk/macros/core.n
   nemerle/trunk/ncc/testsuite/positive/basic-macros.n

Modified: nemerle/trunk/macros/core.n
==============================================================================
--- nemerle/trunk/macros/core.n	(original)
+++ nemerle/trunk/macros/core.n	Sat Jun  2 21:07:43 2007
@@ -255,6 +255,37 @@
   macro @using (body, params args : array [expr])
   syntax ("using", "(", args, ")", body) 
   {
+    def (preexps, postexps) = UsingMacroGenerator.ProcessUsingArgs (args);
+    UsingMacroGenerator.OutputExpression (preexps, postexps, body, null);
+  }
+
+  macro using_catch (body, catch_block, params args : array [expr])
+  syntax ("using", "(", args, ")", body, "catch", catch_block) 
+  {
+    def (preexps, postexps) = UsingMacroGenerator.ProcessUsingArgs (args);
+    def cases = UsingMacroGenerator.ConvertMatchToCatchCases (catch_block);
+    UsingMacroGenerator.OutputExpression (preexps, postexps, body, cases);
+  }
+
+  module UsingMacroGenerator
+  {
+    public ConvertMatchToCatchCases (_ : Parsetree.PExpr) : list [Parsetree.TryCase]
+    {
+      | <[ match ($_) { ..$cases } ]> => cases.Map (c =>
+        match (c) {
+          | <[ case: $(x : name) is $exc => $exp ]> =>
+            Parsetree.TryCase.Catch (Parsetree.Splicable.Name (x), exc, exp)
+          | <[ case: $(x : name) => $exp ]> =>
+            Parsetree.TryCase.Catch (Parsetree.Splicable.Name (x), <[ System.Exception ]>, exp)
+          | _ => 
+            Message.Error ("expected simple catch pattern: '| x is Exception => body'");
+            null
+        })
+      | _ => null
+    }
+  
+    public ProcessUsingArgs (args : array [Parsetree.PExpr]) : list [Parsetree.PExpr] * list [Parsetree.PExpr]
+    {
     def len = args.Length;
     def store_exprs (i, preexprs, postexprs) {
       if (i < len) {
@@ -276,12 +307,22 @@
       else
         (preexprs, postexprs)
     };
+      store_exprs (0, [], []);
+    }
 
-    def (preexps, postexps) = store_exprs (0, [], []);
-    List.FoldLeft2 (preexps, postexps, <[ $body ]>, fun (pre, post, acc) {
+    public OutputExpression (preexps : list[Parsetree.PExpr], postexps : list [Parsetree.PExpr], 
+                             body : Parsetree.PExpr, catch_cases : list [Parsetree.TryCase]) : Parsetree.PExpr
+    {
+      def body = if (catch_cases == null) body
+        else <[
+          try { $body }
+          catch { ..$catch_cases }
+        ]>;
+      List.FoldLeft2 (preexps, postexps, body, fun (pre, post, acc) {
       <[ $pre; try { $acc } finally { $post } ]>
     });
   }
+  }
 
   // disposes given value, if it is reference type then check nullness before disposing
   macro maybe_valuetype_dispose (val)

Modified: nemerle/trunk/ncc/testsuite/positive/basic-macros.n
==============================================================================
--- nemerle/trunk/ncc/testsuite/positive/basic-macros.n	(original)
+++ nemerle/trunk/ncc/testsuite/positive/basic-macros.n	Sat Jun  2 21:07:43 2007
@@ -167,6 +167,13 @@
     };
     using(def x = Disposable()) {};
 
+    using (y = Disposer("with catch")) {
+      throw System.Exception ("a")
+    }
+    catch {
+      | e is System.Exception => System.Console.WriteLine ("catch " + e.Message)
+    }
+
     def y = Disposable();
     using(y) {};
   }
@@ -385,6 +392,9 @@
 I'm being disposed of - two
 I'm being disposed of - one
 Disposing.
+I'm being created - with catch
+catch a
+I'm being disposed of - with catch
 Disposing.
 ----- Test for -----
 for 0



More information about the svn mailing list