[svn] r6016: nemerle/trunk/ncc: parsing/MainParser.n parsing/ParseTree.n testsuite/positive/patterns-in-pa...

malekith svnadmin at nemerle.org
Sun Dec 18 15:28:54 CET 2005


Log:
Add kinda hackish support for tuple-matching directly in function parameters. Resolves #518.

Author: malekith
Date: Sun Dec 18 15:28:53 2005
New Revision: 6016

Added:
   nemerle/trunk/ncc/testsuite/positive/patterns-in-parms.n
Modified:
   nemerle/trunk/ncc/parsing/MainParser.n
   nemerle/trunk/ncc/parsing/ParseTree.n

Modified: nemerle/trunk/ncc/parsing/MainParser.n
==============================================================================
--- nemerle/trunk/ncc/parsing/MainParser.n	(original)
+++ nemerle/trunk/ncc/parsing/MainParser.n	Sun Dec 18 15:28:53 2005
@@ -1275,11 +1275,11 @@
      *  Parse plain functional header (with optional '[..]' generic parameters
      *                                 and '(..)' fun parameters)
      */
-    parse_fun_header (mutable name : Splicable) : Fun_header
+    parse_fun_header (mutable name : Splicable, allow_patterns = false) : Fun_header
     {
       when (name == null) name = get_splicable_id ();
       def tyvars = parse_tyvars ();      
-      def parms = parse_parameters ();
+      def parms = parse_parameters (allow_patterns);
       def ret_type = parse_return_type (true);
       def typarms = parse_where_constraints (tyvars);
 
@@ -1291,26 +1291,42 @@
     }
    
 
+    parse_parameter () : Fun_parm
+    {
+      parse_parameter (false)
+    }
+
     /** Parse function parameter definition from given LooseGroup */
-    parse_parameter () : Fun_parm {
+    parse_parameter (allow_patterns : bool) : Fun_parm {
       mutable customs_token = get_customs ();
       def mods = Modifiers (get_modifiers (), []);
       take_attributes_out (ref customs_token, System.AttributeTargets.Parameter, true, mods);      
 
       parse_top_extensions (mods, MacroTargets.Parameter);
       
+      mutable pattern = null;
+     
+      def id =
       match (peek_token ()) {
         | Token.Keyword ("params") =>
           shift ();
           mods.custom_attrs = <[ System.ParamArrayAttribute ]> :: mods.custom_attrs;
-        | _ => ()
-      };
-      def id = get_splicable_id ();
+            get_splicable_id ()
+            
+          | Token.RoundGroup as tok when allow_patterns =>
+            pattern = parse_expr ();
+            Splicable.Name (tok.Location, Macros.NewSymbol ("pat"));
+            
+          | _ =>
+            get_splicable_id ()
+        }
+        
       def t =
         match (peek_token ()) {
           | Token.Operator (":") => shift (); parse_expr (TokenStoppers.Equal)
           | _ => PExpr.Wildcard (id.Location)
-        };
+        }
+
       match (peek_token ()) {
         | Token.Operator ("=") => 
           shift ();
@@ -1318,12 +1334,14 @@
           mods.custom_attrs = <[ System.ComponentModel.DefaultValueAttribute ($e)
                               ]> :: mods.custom_attrs;
         | _ => ()
-      };
-      Fun_parm (loc = id.loc, name = id, ty = t, modifiers = mods)
+      }
+      
+      Fun_parm (loc = id.loc, name = id, ty = t,
+                modifiers = mods, pattern_hack = pattern)
     }
 
     /// parameters of (a:foo,b,c) or [a,b:foo,c] kind
-    parse_parameters () : list [Fun_parm] {
+    parse_parameters (allow_patterns = false) : list [Fun_parm] {
       def group = get_token ();
       match (group) {
         | Token.RoundGroup (null) | Token.SquareGroup (null) => []
@@ -1336,7 +1354,7 @@
               [Fun_parm (e.loc, Splicable.Name (mkname ("")), PExpr.Void (e.loc), 
                          Modifiers (NemerleAttributes.None, [e]))]
                          
-            | _ => pop_stream (); TokenMap (group, parse_parameter);
+            | _ => pop_stream (); TokenMap (group, fun () { parse_parameter (allow_patterns) });
           }
         | _ => Error (group, "expecting function parameters"); []
       }
@@ -1358,6 +1376,7 @@
     parse_block (tok : Token.BracesGroup, parms : list [Fun_parm]) : PExpr
     {
       def loc = tok.Location;
+      mutable res =
       match (tok.Child) {
         | null => PExpr.Sequence (loc, [])
 
@@ -1390,6 +1409,17 @@
         | groups => 
           PExpr.Sequence (loc, parse_expr_sequence (groups));
       }
+        
+      foreach (p in parms)
+        when (p.pattern_hack != null) {
+          res = <[
+            def $(p.pattern_hack) = $(p.name.GetName () : name); 
+            $res 
+          ]>;
+          p.pattern_hack = null;
+        }
+
+      res
     }
 
     /// parse {...} or $body - usually it is a body of method
@@ -1850,7 +1880,7 @@
 
           | Token.Keyword ("fun") =>
             def tyvars = parse_tyvars ();      
-            def parms = parse_parameters ();
+            def parms = parse_parameters (allow_patterns = true);
             def ret_type = parse_return_type (true);
             def typarms = parse_where_constraints (tyvars);
 
@@ -1973,7 +2003,7 @@
               PExpr.Define (loc + expr.loc, pat, expr)
             };
             def parse_funs (acc, idopt) {
-              def h = parse_fun_header (idopt);
+              def h = parse_fun_header (idopt, allow_patterns = true);
               def fd = Function_decl (h, parse_block (h.parms));
               if (flag_sibling_keyword ("and")) {
                 def id = get_splicable_id ();

Modified: nemerle/trunk/ncc/parsing/ParseTree.n
==============================================================================
--- nemerle/trunk/ncc/parsing/ParseTree.n	(original)
+++ nemerle/trunk/ncc/parsing/ParseTree.n	Sun Dec 18 15:28:53 2005
@@ -329,16 +329,21 @@
   {
     public mutable ty : PExpr;
     
+    // when parse_header() sees a pattern as a function parameters,
+    // it generates a dummy name and puts the pattern in this field
+    internal mutable pattern_hack : PExpr;
+    
     public this (name : Splicable, ty : PExpr, modifiers : Modifiers) 
     {
       base (Location.Default, name, modifiers);
       this.ty = ty;
     }
     public this (loc : Location, name : Splicable, ty : PExpr,
-                 modifiers : Modifiers) 
+                 modifiers : Modifiers, pattern_hack : PExpr = null) 
     {
       base (loc, name, modifiers);      
       this.ty = ty;
+      this.pattern_hack = pattern_hack;
     }
 
     public this (from : PExpr) 

Added: nemerle/trunk/ncc/testsuite/positive/patterns-in-parms.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/ncc/testsuite/positive/patterns-in-parms.n	Sun Dec 18 15:28:53 2005
@@ -0,0 +1,19 @@
+def fn (k, (x, y)) { (k + x, k * y) }
+System.Console.WriteLine ([1,2,3,4].FoldLeft ((0, 1), fn));
+System.Console.WriteLine ([1,2,3,4].FoldLeft ((0, 1), fun (k, (x, y)) { (k + x, k * y) }));
+
+def f2 ((a,b),(c,d,e)) {
+  System.Console.WriteLine (a+b);
+  System.Console.WriteLine (c+d+e);
+}
+
+f2 ((1,2),(3,4,5));
+
+/*
+BEGIN-OUTPUT
+(10, 24)
+(10, 24)
+3
+12
+END-OUTPUT
+*/



More information about the svn mailing list