Skip to content

Commit 4a3edb3

Browse files
committed
Store items and decls in vecs to preserve input order, index externally. Implement block-local name lookup.
1 parent 865bbae commit 4a3edb3

File tree

6 files changed

+232
-137
lines changed

6 files changed

+232
-137
lines changed

src/comp/front/ast.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ type crate = spanned[crate_];
2929
type crate_ = rec(_mod module);
3030

3131
type block = spanned[block_];
32-
type block_ = vec[@stmt];
32+
type block_ = rec(vec[@stmt] stmts,
33+
hashmap[ident,uint] index);
3334

3435
tag binop {
3536
add;
@@ -69,10 +70,16 @@ tag stmt_ {
6970
stmt_expr(@expr);
7071
}
7172

73+
type local = rec(option[@ty] ty,
74+
bool infer,
75+
ident ident,
76+
option[@expr] init,
77+
def_id id);
78+
7279
type decl = spanned[decl_];
7380
tag decl_ {
74-
decl_local(ident, option[@ty], option[@expr]);
75-
decl_item(ident, @item);
81+
decl_local(local);
82+
decl_item(@item);
7683
}
7784

7885
type expr = spanned[expr_];
@@ -125,16 +132,17 @@ tag mode {
125132

126133
type arg = rec(mode mode, @ty ty, ident ident, def_id id);
127134
type _fn = rec(vec[arg] inputs,
128-
ty output,
135+
@ty output,
129136
block body);
130137

131-
type _mod = hashmap[ident,@item];
138+
type _mod = rec(vec[@item] items,
139+
hashmap[ident,uint] index);
132140

133141
type item = spanned[item_];
134142
tag item_ {
135-
item_fn(_fn, def_id);
136-
item_mod(_mod, def_id);
137-
item_ty(@ty, def_id);
143+
item_fn(ident, _fn, def_id);
144+
item_mod(ident, _mod, def_id);
145+
item_ty(ident, @ty, def_id);
138146
}
139147

140148

src/comp/front/parser.rs

Lines changed: 90 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ import std._io;
22
import std.util.option;
33
import std.util.some;
44
import std.util.none;
5+
import std.map.hashmap;
56

67
import driver.session;
78
import util.common;
9+
import util.common.append;
810
import util.common.span;
911
import util.common.new_str_hash;
1012

@@ -610,13 +612,38 @@ io fn parse_let(parser p) -> @ast.decl {
610612

611613
expect(p, token.LET);
612614
auto ty = parse_ty(p);
613-
auto id = parse_ident(p);
615+
auto ident = parse_ident(p);
614616
auto init = parse_initializer(p);
615617

616618
auto hi = p.get_span();
617619
expect(p, token.SEMI);
618620

619-
ret @spanned(lo, hi, ast.decl_local(id, some(ty), init));
621+
let ast.local local = rec(ty = some(ty),
622+
infer = false,
623+
ident = ident,
624+
init = init,
625+
id = p.next_def_id());
626+
627+
ret @spanned(lo, hi, ast.decl_local(local));
628+
}
629+
630+
io fn parse_auto(parser p) -> @ast.decl {
631+
auto lo = p.get_span();
632+
633+
expect(p, token.AUTO);
634+
auto ident = parse_ident(p);
635+
auto init = parse_initializer(p);
636+
637+
auto hi = p.get_span();
638+
expect(p, token.SEMI);
639+
640+
let ast.local local = rec(ty = none[@ast.ty],
641+
infer = true,
642+
ident = ident,
643+
init = init,
644+
id = p.next_def_id());
645+
646+
ret @spanned(lo, hi, ast.decl_local(local));
620647
}
621648

622649
io fn parse_stmt(parser p) -> @ast.stmt {
@@ -632,20 +659,15 @@ io fn parse_stmt(parser p) -> @ast.stmt {
632659
}
633660

634661
case (token.LET) {
635-
auto leht = parse_let(p);
662+
auto decl = parse_let(p);
636663
auto hi = p.get_span();
637-
ret @spanned(lo, hi, ast.stmt_decl(leht));
664+
ret @spanned(lo, hi, ast.stmt_decl(decl));
638665
}
639666

640667
case (token.AUTO) {
641-
p.bump();
642-
auto id = parse_ident(p);
643-
auto init = parse_initializer(p);
668+
auto decl = parse_auto(p);
644669
auto hi = p.get_span();
645-
expect(p, token.SEMI);
646-
647-
auto decl = ast.decl_local(id, none[@ast.ty], init);
648-
ret @spanned(lo, hi, ast.stmt_decl(@spanned(lo, hi, decl)));
670+
ret @spanned(lo, hi, ast.stmt_decl(decl));
649671
}
650672

651673
// Handle the (few) block-expr stmts first.
@@ -677,10 +699,41 @@ io fn parse_stmt(parser p) -> @ast.stmt {
677699
io fn parse_block(parser p) -> ast.block {
678700
auto f = parse_stmt;
679701
// FIXME: passing parse_stmt as an lval doesn't work at the moment.
680-
ret parse_seq[@ast.stmt](token.LBRACE,
681-
token.RBRACE,
682-
none[token.token],
683-
f, p);
702+
auto stmts = parse_seq[@ast.stmt](token.LBRACE,
703+
token.RBRACE,
704+
none[token.token],
705+
f, p);
706+
auto index = new_str_hash[uint]();
707+
auto u = 0u;
708+
for (@ast.stmt s in stmts.node) {
709+
// FIXME: typestate bug requires we do this up top, not
710+
// down below loop. Sigh.
711+
u += 1u;
712+
alt (s.node) {
713+
case (ast.stmt_decl(?d)) {
714+
alt (d.node) {
715+
case (ast.decl_local(?loc)) {
716+
index.insert(loc.ident, u-1u);
717+
}
718+
case (ast.decl_item(?it)) {
719+
alt (it.node) {
720+
case (ast.item_fn(?i, _, _)) {
721+
index.insert(i, u-1u);
722+
}
723+
case (ast.item_mod(?i, _, _)) {
724+
index.insert(i, u-1u);
725+
}
726+
case (ast.item_ty(?i, _, _)) {
727+
index.insert(i, u-1u);
728+
}
729+
}
730+
}
731+
}
732+
}
733+
}
734+
}
735+
let ast.block_ b = rec(stmts=stmts.node, index=index);
736+
ret spanned(stmts.span, stmts.span, b);
684737
}
685738

686739
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) {
697750
some(token.COMMA),
698751
pf, p);
699752

700-
let ast.ty output;
753+
let @ast.ty output;
701754
if (p.peek() == token.RARROW) {
702755
p.bump();
703-
output = *parse_ty(p);
756+
output = parse_ty(p);
704757
} else {
705-
output = spanned(lo, inputs.span, ast.ty_nil);
758+
output = @spanned(lo, inputs.span, ast.ty_nil);
706759
}
707760

708761
auto body = parse_block(p);
@@ -711,24 +764,33 @@ io fn parse_fn(parser p) -> tup(ast.ident, @ast.item) {
711764
output = output,
712765
body = body);
713766

714-
let @ast.item i = @spanned(lo, body.span,
715-
ast.item_fn(f, p.next_def_id()));
716-
ret tup(id, i);
767+
auto item = ast.item_fn(id, f, p.next_def_id());
768+
ret tup(id, @spanned(lo, body.span, item));
717769
}
718770

771+
io fn parse_mod_items(parser p, token.token term) -> ast._mod {
772+
let vec[@ast.item] items = vec();
773+
let hashmap[ast.ident,uint] index = new_str_hash[uint]();
774+
let uint u = 0u;
775+
while (p.peek() != term) {
776+
auto pair = parse_item(p);
777+
append[@ast.item](items, pair._1);
778+
index.insert(pair._0, u);
779+
u += 1u;
780+
}
781+
ret rec(items=items, index=index);
782+
}
783+
719784
io fn parse_mod(parser p) -> tup(ast.ident, @ast.item) {
720785
auto lo = p.get_span();
721786
expect(p, token.MOD);
722787
auto id = parse_ident(p);
723788
expect(p, token.LBRACE);
724-
let ast._mod m = new_str_hash[@ast.item]();
725-
while (p.peek() != token.RBRACE) {
726-
auto i = parse_item(p);
727-
m.insert(i._0, i._1);
728-
}
789+
auto m = parse_mod_items(p, token.RBRACE);
729790
auto hi = p.get_span();
730791
expect(p, token.RBRACE);
731-
ret tup(id, @spanned(lo, hi, ast.item_mod(m, p.next_def_id())));
792+
auto item = ast.item_mod(id, m, p.next_def_id());
793+
ret tup(id, @spanned(lo, hi, item));
732794
}
733795

734796
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) {
747809
io fn parse_crate(parser p) -> @ast.crate {
748810
auto lo = p.get_span();
749811
auto hi = lo;
750-
let ast._mod m = new_str_hash[@ast.item]();
751-
while (p.peek() != token.EOF) {
752-
auto i = parse_item(p);
753-
m.insert(i._0, i._1);
754-
hi = i._1.span;
755-
}
812+
auto m = parse_mod_items(p, token.EOF);
756813
ret @spanned(lo, hi, rec(module=m));
757814
}
758815

0 commit comments

Comments
 (0)