[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