aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/ast.rs1
-rw-r--r--src/comp/front/parser.rs43
-rw-r--r--src/comp/middle/fold.rs17
3 files changed, 60 insertions, 1 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index a6cbf1ce..830856e0 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 6eb334ca..7ce5703f 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 48363437..51b9595a 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](_,_,_,_),