aboutsummaryrefslogtreecommitdiff
path: root/src/comp/front/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/comp/front/parser.rs')
-rw-r--r--src/comp/front/parser.rs123
1 files changed, 90 insertions, 33 deletions
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index 1d07299b..4aa71743 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -2,9 +2,11 @@ import std._io;
import std.util.option;
import std.util.some;
import std.util.none;
+import std.map.hashmap;
import driver.session;
import util.common;
+import util.common.append;
import util.common.span;
import util.common.new_str_hash;
@@ -610,13 +612,38 @@ io fn parse_let(parser p) -> @ast.decl {
expect(p, token.LET);
auto ty = parse_ty(p);
- auto id = parse_ident(p);
+ auto ident = parse_ident(p);
auto init = parse_initializer(p);
auto hi = p.get_span();
expect(p, token.SEMI);
- ret @spanned(lo, hi, ast.decl_local(id, some(ty), init));
+ let ast.local local = rec(ty = some(ty),
+ infer = false,
+ ident = ident,
+ init = init,
+ id = p.next_def_id());
+
+ ret @spanned(lo, hi, ast.decl_local(local));
+}
+
+io fn parse_auto(parser p) -> @ast.decl {
+ auto lo = p.get_span();
+
+ expect(p, token.AUTO);
+ auto ident = parse_ident(p);
+ auto init = parse_initializer(p);
+
+ auto hi = p.get_span();
+ expect(p, token.SEMI);
+
+ let ast.local local = rec(ty = none[@ast.ty],
+ infer = true,
+ ident = ident,
+ init = init,
+ id = p.next_def_id());
+
+ ret @spanned(lo, hi, ast.decl_local(local));
}
io fn parse_stmt(parser p) -> @ast.stmt {
@@ -632,20 +659,15 @@ io fn parse_stmt(parser p) -> @ast.stmt {
}
case (token.LET) {
- auto leht = parse_let(p);
+ auto decl = parse_let(p);
auto hi = p.get_span();
- ret @spanned(lo, hi, ast.stmt_decl(leht));
+ ret @spanned(lo, hi, ast.stmt_decl(decl));
}
case (token.AUTO) {
- p.bump();
- auto id = parse_ident(p);
- auto init = parse_initializer(p);
+ auto decl = parse_auto(p);
auto hi = p.get_span();
- expect(p, token.SEMI);
-
- auto decl = ast.decl_local(id, none[@ast.ty], init);
- ret @spanned(lo, hi, ast.stmt_decl(@spanned(lo, hi, decl)));
+ ret @spanned(lo, hi, ast.stmt_decl(decl));
}
// Handle the (few) block-expr stmts first.
@@ -677,10 +699,41 @@ io fn parse_stmt(parser p) -> @ast.stmt {
io fn parse_block(parser p) -> ast.block {
auto f = parse_stmt;
// FIXME: passing parse_stmt as an lval doesn't work at the moment.
- ret parse_seq[@ast.stmt](token.LBRACE,
- token.RBRACE,
- none[token.token],
- f, p);
+ auto stmts = parse_seq[@ast.stmt](token.LBRACE,
+ token.RBRACE,
+ none[token.token],
+ f, p);
+ auto index = new_str_hash[uint]();
+ auto u = 0u;
+ for (@ast.stmt s in stmts.node) {
+ // FIXME: typestate bug requires we do this up top, not
+ // down below loop. Sigh.
+ u += 1u;
+ alt (s.node) {
+ case (ast.stmt_decl(?d)) {
+ alt (d.node) {
+ case (ast.decl_local(?loc)) {
+ index.insert(loc.ident, u-1u);
+ }
+ case (ast.decl_item(?it)) {
+ alt (it.node) {
+ case (ast.item_fn(?i, _, _)) {
+ index.insert(i, u-1u);
+ }
+ case (ast.item_mod(?i, _, _)) {
+ index.insert(i, u-1u);
+ }
+ case (ast.item_ty(?i, _, _)) {
+ index.insert(i, u-1u);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ let ast.block_ b = rec(stmts=stmts.node, index=index);
+ ret spanned(stmts.span, stmts.span, b);
}
io fn parse_fn(parser p) -> tup(ast.ident, @ast.item) {
@@ -697,12 +750,12 @@ io fn parse_fn(parser p) -> tup(ast.ident, @ast.item) {
some(token.COMMA),
pf, p);
- let ast.ty output;
+ let @ast.ty output;
if (p.peek() == token.RARROW) {
p.bump();
- output = *parse_ty(p);
+ output = parse_ty(p);
} else {
- output = spanned(lo, inputs.span, ast.ty_nil);
+ output = @spanned(lo, inputs.span, ast.ty_nil);
}
auto body = parse_block(p);
@@ -711,24 +764,33 @@ io fn parse_fn(parser p) -> tup(ast.ident, @ast.item) {
output = output,
body = body);
- let @ast.item i = @spanned(lo, body.span,
- ast.item_fn(f, p.next_def_id()));
- ret tup(id, i);
+ auto item = ast.item_fn(id, f, p.next_def_id());
+ ret tup(id, @spanned(lo, body.span, item));
}
+io fn parse_mod_items(parser p, token.token term) -> ast._mod {
+ let vec[@ast.item] items = vec();
+ let hashmap[ast.ident,uint] index = new_str_hash[uint]();
+ let uint u = 0u;
+ while (p.peek() != term) {
+ auto pair = parse_item(p);
+ append[@ast.item](items, pair._1);
+ index.insert(pair._0, u);
+ u += 1u;
+ }
+ ret rec(items=items, index=index);
+ }
+
io fn parse_mod(parser p) -> tup(ast.ident, @ast.item) {
auto lo = p.get_span();
expect(p, token.MOD);
auto id = parse_ident(p);
expect(p, token.LBRACE);
- let ast._mod m = new_str_hash[@ast.item]();
- while (p.peek() != token.RBRACE) {
- auto i = parse_item(p);
- m.insert(i._0, i._1);
- }
+ auto m = parse_mod_items(p, token.RBRACE);
auto hi = p.get_span();
expect(p, token.RBRACE);
- ret tup(id, @spanned(lo, hi, ast.item_mod(m, p.next_def_id())));
+ auto item = ast.item_mod(id, m, p.next_def_id());
+ ret tup(id, @spanned(lo, hi, item));
}
io fn parse_item(parser p) -> tup(ast.ident, @ast.item) {
@@ -747,12 +809,7 @@ io fn parse_item(parser p) -> tup(ast.ident, @ast.item) {
io fn parse_crate(parser p) -> @ast.crate {
auto lo = p.get_span();
auto hi = lo;
- let ast._mod m = new_str_hash[@ast.item]();
- while (p.peek() != token.EOF) {
- auto i = parse_item(p);
- m.insert(i._0, i._1);
- hi = i._1.span;
- }
+ auto m = parse_mod_items(p, token.EOF);
ret @spanned(lo, hi, rec(module=m));
}