rustc: Implement function types
This commit is contained in:
parent
91b1885ba2
commit
35eb088ae3
@ -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]);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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](_,_,_,_),
|
||||
|
Loading…
x
Reference in New Issue
Block a user