aboutsummaryrefslogtreecommitdiff
path: root/src/comp/front
diff options
context:
space:
mode:
Diffstat (limited to 'src/comp/front')
-rw-r--r--src/comp/front/ast.rs24
-rw-r--r--src/comp/front/parser.rs123
2 files changed, 106 insertions, 41 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index 04c64bea..047bdd06 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -29,7 +29,8 @@ type crate = spanned[crate_];
type crate_ = rec(_mod module);
type block = spanned[block_];
-type block_ = vec[@stmt];
+type block_ = rec(vec[@stmt] stmts,
+ hashmap[ident,uint] index);
tag binop {
add;
@@ -69,10 +70,16 @@ tag stmt_ {
stmt_expr(@expr);
}
+type local = rec(option[@ty] ty,
+ bool infer,
+ ident ident,
+ option[@expr] init,
+ def_id id);
+
type decl = spanned[decl_];
tag decl_ {
- decl_local(ident, option[@ty], option[@expr]);
- decl_item(ident, @item);
+ decl_local(local);
+ decl_item(@item);
}
type expr = spanned[expr_];
@@ -125,16 +132,17 @@ tag mode {
type arg = rec(mode mode, @ty ty, ident ident, def_id id);
type _fn = rec(vec[arg] inputs,
- ty output,
+ @ty output,
block body);
-type _mod = hashmap[ident,@item];
+type _mod = rec(vec[@item] items,
+ hashmap[ident,uint] index);
type item = spanned[item_];
tag item_ {
- item_fn(_fn, def_id);
- item_mod(_mod, def_id);
- item_ty(@ty, def_id);
+ item_fn(ident, _fn, def_id);
+ item_mod(ident, _mod, def_id);
+ item_ty(ident, @ty, def_id);
}
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));
}