diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index a6cbf1ce793..830856e0c6f 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -130,6 +130,7 @@ tag ty_ { ty_box(@ty); ty_vec(@ty); ty_tup(vec[tup(bool /* mutability */, @ty)]); + ty_fn(vec[rec(mode mode, @ty ty)], @ty); // TODO: effect ty_path(path, option.t[def]); } diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 6eb334ca81f..7ce5703f628 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -108,6 +108,45 @@ impure fn parse_possibly_mutable_ty(parser p) -> tup(bool, @ast.ty) { ret tup(mut, parse_ty(p)); } +impure fn parse_ty_fn(parser p) -> ast.ty_ { + impure fn parse_fn_input_ty(parser p) -> rec(ast.mode mode, @ast.ty ty) { + auto mode; + if (p.peek() == token.BINOP(token.AND)) { + p.bump(); + mode = ast.alias; + } else { + mode = ast.val; + } + + auto t = parse_ty(p); + + alt (p.peek()) { + case (token.IDENT(_)) { p.bump(); /* ignore the param name */ } + case (_) { /* no param name present */ } + } + + ret rec(mode=mode, ty=t); + } + + auto lo = p.get_span(); + + expect(p, token.FN); + + auto f = parse_fn_input_ty; // FIXME: trans_const_lval bug + auto inputs = parse_seq[rec(ast.mode mode, @ast.ty ty)](token.LPAREN, + token.RPAREN, some(token.COMMA), f, p); + + let @ast.ty output; + if (p.peek() == token.RARROW) { + p.bump(); + output = parse_ty(p); + } else { + output = @spanned(lo, inputs.span, ast.ty_nil); + } + + ret ast.ty_fn(inputs.node, output); +} + impure fn parse_ty(parser p) -> @ast.ty { auto lo = p.get_span(); let ast.ty_ t; @@ -135,6 +174,10 @@ impure fn parse_ty(parser p) -> @ast.ty { t = ast.ty_tup(elems.node); } + case (token.FN) { + t = parse_ty_fn(p); + } + case (_) { p.err("expecting type"); t = ast.ty_nil; diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs index 48363437b37..51b9595a020 100644 --- a/src/comp/middle/fold.rs +++ b/src/comp/middle/fold.rs @@ -46,8 +46,12 @@ type ast_fold[ENV] = (fn(&ENV e, &span sp, vec[tup(bool, @ty)] elts) -> @ty) fold_ty_tup, + (fn(&ENV e, &span sp, + vec[rec(ast.mode mode, @ty ty)] inputs, + @ty output) -> @ty) fold_ty_fn, + (fn(&ENV e, &span sp, ast.path p, - &option.t[def] d) -> @ty) fold_ty_path, + &option.t[def] d) -> @ty) fold_ty_path, // Expr folds. (fn(&ENV e, &span sp, @@ -226,6 +230,10 @@ fn fold_ty[ENV](&ENV env, ast_fold[ENV] fld, @ty t) -> @ty { } ret fld.fold_ty_path(env_, t.span, path, ref_opt); } + + case (ast.ty_fn(?inputs, ?output)) { + ret fld.fold_ty_fn(env_, t.span, inputs, output); + } } } @@ -567,6 +575,12 @@ fn identity_fold_ty_tup[ENV](&ENV env, &span sp, vec[tup(bool,@ty)] elts) ret @respan(sp, ast.ty_tup(elts)); } +fn identity_fold_ty_fn[ENV](&ENV env, &span sp, + vec[rec(ast.mode mode, @ty ty)] inputs, + @ty output) -> @ty { + ret @respan(sp, ast.ty_fn(inputs, output)); +} + fn identity_fold_ty_path[ENV](&ENV env, &span sp, ast.path p, &option.t[def] d) -> @ty { ret @respan(sp, ast.ty_path(p, d)); @@ -785,6 +799,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] { fold_ty_box = bind identity_fold_ty_box[ENV](_,_,_), fold_ty_vec = bind identity_fold_ty_vec[ENV](_,_,_), fold_ty_tup = bind identity_fold_ty_tup[ENV](_,_,_), + fold_ty_fn = bind identity_fold_ty_fn[ENV](_,_,_,_), fold_ty_path = bind identity_fold_ty_path[ENV](_,_,_,_), fold_expr_vec = bind identity_fold_expr_vec[ENV](_,_,_,_),