提交 d1e59d69 编写于 作者: G Graydon Hoare

Add input coordinate tracking to all major rustc ast nodes.

上级 4168c1dc
......@@ -2,28 +2,39 @@
import util.common.option;
import std.map.hashmap;
import util.common.span;
import util.common.spanned;
import util.common.option;
import util.common.some;
import util.common.none;
type ident = str;
type name = rec(ident ident, vec[ty] types);
type name_ = rec(ident ident, vec[ty] types);
type name = spanned[name_];
type path = vec[name];
type crate_id = int;
type slot_id = int;
type item_id = int;
type crate_num = int;
type slot_num = int;
type item_num = int;
tag referent {
ref_slot(crate_id, slot_id);
ref_item(crate_id, item_id);
tag slot_id {
id_slot(crate_num, slot_num);
}
tag item_id {
id_item(crate_num, slot_num);
}
tag referent {
ref_slot(slot_id);
ref_item(item_id);
}
type crate = rec(_mod module);
type crate = spanned[crate_];
type crate_ = rec(_mod module);
type block = vec[@stmt];
type block = spanned[block_];
type block_ = vec[@stmt];
tag binop {
add;
......@@ -55,19 +66,22 @@
neg;
}
tag stmt {
type stmt = spanned[stmt_];
tag stmt_ {
stmt_decl(@decl);
stmt_ret(option[@expr]);
stmt_log(@expr);
stmt_expr(@expr);
}
tag decl {
decl_local(ident, option[ty]);
decl_item(ident, @item);
type decl = spanned[decl_];
tag decl_ {
decl_local(ident, option[ty], ty);
decl_item(name, @item);
}
tag expr {
type expr = spanned[expr_];
tag expr_ {
expr_vec(vec[@expr]);
expr_tup(vec[@expr]);
expr_rec(vec[tup(ident,@expr)]);
......@@ -83,7 +97,8 @@
expr_block(block);
}
tag lit {
type lit = spanned[lit_];
tag lit_ {
lit_str(str);
lit_char(char);
lit_int(int);
......@@ -92,7 +107,8 @@
lit_bool(bool);
}
tag ty {
type ty = spanned[ty_];
tag ty_ {
ty_nil;
ty_bool;
ty_int;
......@@ -109,7 +125,7 @@
alias;
}
type slot = rec(ty ty, mode mode);
type slot = rec(ty ty, mode mode, option[slot_id] id);
type _fn = rec(vec[rec(slot slot, ident ident)] inputs,
slot output,
......@@ -117,10 +133,11 @@
type _mod = hashmap[ident,item];
tag item {
item_fn(@_fn);
type item = spanned[item_];
tag item_ {
item_fn(@_fn, item_id);
item_mod(@_mod);
item_ty(@ty);
item_ty(@ty, item_id);
}
......
import std._io;
import driver.session;
import util.common;
import util.common.span;
import util.common.new_str_hash;
import util.common.option;
import util.common.some;
......@@ -23,7 +24,7 @@
lexer.reader rdr)
{
fn peek() -> token.token {
log token.to_str(tok);
// log token.to_str(tok);
ret tok;
}
......@@ -66,6 +67,12 @@ fn get_span() -> common.span {
}
}
fn spanned[T](&span lo, &span hi, &T node) -> ast.spanned[T] {
ret rec(node=node, span=rec(filename=lo.filename,
lo=lo.lo,
hi=hi.hi));
}
io fn parse_ident(parser p) -> ast.ident {
alt (p.peek()) {
case (token.IDENT(?i)) { p.bump(); ret i; }
......@@ -77,15 +84,21 @@ fn get_span() -> common.span {
}
io fn parse_ty(parser p) -> ast.ty {
auto lo = p.get_span();
let ast.ty_ t;
alt (p.peek()) {
case (token.INT) { p.bump(); ret ast.ty_int; }
case (token.UINT) { p.bump(); ret ast.ty_int; }
case (token.STR) { p.bump(); ret ast.ty_str; }
case (token.CHAR) { p.bump(); ret ast.ty_char; }
case (token.MACH(?tm)) { p.bump(); ret ast.ty_machine(tm); }
case (token.INT) { p.bump(); t = ast.ty_int; }
case (token.UINT) { p.bump(); t = ast.ty_int; }
case (token.STR) { p.bump(); t = ast.ty_str; }
case (token.CHAR) { p.bump(); t = ast.ty_char; }
case (token.MACH(?tm)) { p.bump(); t = ast.ty_machine(tm); }
case (_) {
p.err("expecting type");
t = ast.ty_nil;
fail;
}
}
p.err("expecting type");
fail;
ret spanned(lo, lo, t);
}
io fn parse_slot(parser p) -> ast.slot {
......@@ -95,15 +108,16 @@ fn get_span() -> common.span {
p.bump();
}
let ast.ty t = parse_ty(p);
ret rec(ty=t, mode=m);
ret rec(ty=t, mode=m, id=none[ast.slot_id]);
}
io fn parse_seq[T](token.token bra,
token.token ket,
option[token.token] sep,
(io fn(parser) -> T) f,
parser p) -> vec[T] {
parser p) -> util.common.spanned[vec[T]] {
let bool first = true;
auto lo = p.get_span();
expect(p, bra);
let vec[T] v = vec();
while (p.peek() != ket) {
......@@ -122,41 +136,52 @@ fn get_span() -> common.span {
let T t = f(p);
v += vec(t);
}
auto hi = p.get_span();
expect(p, ket);
ret v;
ret spanned(lo, hi, v);
}
io fn parse_lit(parser p) -> @ast.lit {
auto lo = p.get_span();
let ast.lit_ lit;
alt (p.peek()) {
case (token.LIT_INT(?i)) {
p.bump();
ret @ast.lit_int(i);
lit = ast.lit_int(i);
}
case (token.LIT_UINT(?u)) {
p.bump();
ret @ast.lit_uint(u);
lit = ast.lit_uint(u);
}
case (token.LIT_CHAR(?c)) {
p.bump();
ret @ast.lit_char(c);
lit = ast.lit_char(c);
}
case (token.LIT_BOOL(?b)) {
p.bump();
ret @ast.lit_bool(b);
lit = ast.lit_bool(b);
}
case (token.LIT_STR(?s)) {
p.bump();
ret @ast.lit_str(s);
lit = ast.lit_str(s);
}
case (_) {
lit = ast.lit_nil;
p.err("expected literal");
fail;
}
}
p.err("expected literal");
fail;
ret @spanned(lo, lo, lit);
}
io fn parse_name(parser p, ast.ident id) -> ast.name {
auto lo = p.get_span();
p.bump();
let vec[ast.ty] tys = vec();
let vec[ast.ty] v = vec();
let util.common.spanned[vec[ast.ty]] tys = rec(node=v, span=lo);
alt (p.peek()) {
case (token.LBRACKET) {
......@@ -169,16 +194,25 @@ fn get_span() -> common.span {
case (_) {
}
}
ret rec(ident=id, types=tys);
ret spanned(lo, tys.span, rec(ident=id, types=tys.node));
}
io fn parse_bottom_expr(parser p) -> @ast.expr {
auto lo = p.get_span();
auto hi = lo;
// FIXME: can only remove this sort of thing when both typestate and
// alt-exhaustive-match checking are co-operating.
let ast.expr_ ex = ast.expr_lit(@spanned(lo, lo, ast.lit_nil));
alt (p.peek()) {
case (token.LPAREN) {
p.bump();
auto e = parse_expr(p);
hi = p.get_span();
expect(p, token.RPAREN);
ret e;
ret @spanned(lo, hi, e.node);
}
case (token.TUP) {
......@@ -188,7 +222,8 @@ fn get_span() -> common.span {
token.RPAREN,
some(token.COMMA),
pf, p);
ret @ast.expr_tup(es);
hi = es.span;
ex = ast.expr_tup(es.node);
}
case (token.VEC) {
......@@ -198,7 +233,8 @@ fn get_span() -> common.span {
token.RPAREN,
some(token.COMMA),
pf, p);
ret @ast.expr_vec(es);
hi = es.span;
ex = ast.expr_vec(es.node);
}
case (token.REC) {
......@@ -216,21 +252,29 @@ fn get_span() -> common.span {
token.RPAREN,
some(token.COMMA),
pf, p);
ret @ast.expr_rec(es);
hi = es.span;
ex = ast.expr_rec(es.node);
}
case (token.IDENT(?i)) {
ret @ast.expr_name(parse_name(p, i), none[ast.referent]);
auto n = parse_name(p, i);
hi = n.span;
ex = ast.expr_name(n, none[ast.referent]);
}
case (_) {
ret @ast.expr_lit(parse_lit(p));
auto lit = parse_lit(p);
hi = lit.span;
ex = ast.expr_lit(lit);
}
}
ret @spanned(lo, hi, ex);
}
io fn parse_path_expr(parser p) -> @ast.expr {
auto lo = p.get_span();
auto e = parse_bottom_expr(p);
auto hi = e.span;
while (true) {
alt (p.peek()) {
case (token.DOT) {
......@@ -238,13 +282,15 @@ fn get_span() -> common.span {
alt (p.peek()) {
case (token.IDENT(?i)) {
hi = p.get_span();
p.bump();
e = @ast.expr_field(e, i);
e = @spanned(lo, hi, ast.expr_field(e, i));
}
case (token.LPAREN) {
auto ix = parse_bottom_expr(p);
e = @ast.expr_index(e, ix);
hi = ix.span;
e = @spanned(lo, hi, ast.expr_index(e, ix));
}
}
}
......@@ -257,33 +303,44 @@ fn get_span() -> common.span {
}
io fn parse_prefix_expr(parser p) -> @ast.expr {
auto lo = p.get_span();
auto hi = lo;
// FIXME: can only remove this sort of thing when both typestate and
// alt-exhaustive-match checking are co-operating.
let ast.expr_ ex = ast.expr_lit(@spanned(lo, lo, ast.lit_nil));
alt (p.peek()) {
case (token.NOT) {
p.bump();
auto e = parse_prefix_expr(p);
ret @ast.expr_unary(ast.not, e);
hi = e.span;
ex = ast.expr_unary(ast.not, e);
}
case (token.TILDE) {
p.bump();
auto e = parse_prefix_expr(p);
ret @ast.expr_unary(ast.bitnot, e);
hi = e.span;
ex = ast.expr_unary(ast.bitnot, e);
}
case (token.BINOP(?b)) {
alt (b) {
case (token.MINUS) {
p.bump();
auto e = parse_prefix_expr(p);
ret @ast.expr_unary(ast.neg, e);
hi = e.span;
ex = ast.expr_unary(ast.neg, e);
}
case (token.STAR) {
p.bump();
auto e = parse_prefix_expr(p);
ret @ast.expr_unary(ast.deref, e);
hi = e.span;
ex = ast.expr_unary(ast.deref, e);
}
case (_) {
......@@ -295,19 +352,23 @@ fn get_span() -> common.span {
case (token.AT) {
p.bump();
auto e = parse_prefix_expr(p);
ret @ast.expr_unary(ast.box, e);
hi = e.span;
ex = ast.expr_unary(ast.box, e);
}
case (_) {
ret parse_path_expr(p);
}
}
ret @spanned(lo, hi, ex);
}
io fn parse_binops(parser p,
(io fn(parser) -> @ast.expr) sub,
vec[tup(token.binop, ast.binop)] ops)
(io fn(parser) -> @ast.expr) sub,
vec[tup(token.binop, ast.binop)] ops)
-> @ast.expr {
auto lo = p.get_span();
auto hi = lo;
auto e = sub(p);
auto more = true;
while (more) {
......@@ -317,7 +378,10 @@ fn get_span() -> common.span {
case (token.BINOP(?op)) {
if (pair._0 == op) {
p.bump();
e = @ast.expr_binary(pair._1, e, sub(p));
auto rhs = sub(p);
hi = rhs.span;
auto exp = ast.expr_binary(pair._1, e, rhs);
e = @spanned(lo, hi, exp);
more = true;
}
}
......@@ -331,6 +395,8 @@ fn get_span() -> common.span {
(io fn(parser) -> @ast.expr) sub,
vec[tup(token.token, ast.binop)] ops)
-> @ast.expr {
auto lo = p.get_span();
auto hi = lo;
auto e = sub(p);
auto more = true;
while (more) {
......@@ -338,7 +404,10 @@ fn get_span() -> common.span {
for (tup(token.token, ast.binop) pair in ops) {
if (pair._0 == p.peek()) {
p.bump();
e = @ast.expr_binary(pair._1, e, sub(p));
auto rhs = sub(p);
hi = rhs.span;
auto exp = ast.expr_binary(pair._1, e, rhs);
e = @spanned(lo, hi, exp);
more = true;
}
}
......@@ -382,13 +451,16 @@ fn get_span() -> common.span {
}
io fn parse_cast_expr(parser p) -> @ast.expr {
auto lo = p.get_span();
auto e = parse_bitor_expr(p);
auto hi = e.span;
while (true) {
alt (p.peek()) {
case (token.AS) {
p.bump();
auto t = parse_ty(p);
e = @ast.expr_cast(e, t);
hi = t.span;
e = @spanned(lo, hi, ast.expr_cast(e, t));
}
case (_) {
......@@ -425,25 +497,33 @@ fn get_span() -> common.span {
}
io fn parse_if_expr(parser p) -> @ast.expr {
auto lo = p.get_span();
auto hi = lo;
expect(p, token.IF);
expect(p, token.LPAREN);
auto cond = parse_expr(p);
expect(p, token.RPAREN);
auto thn = parse_block(p);
let option[ast.block] els = none[ast.block];
hi = thn.span;
alt (p.peek()) {
case (token.ELSE) {
p.bump();
els = some(parse_block(p));
auto eblk = parse_block(p);
els = some(eblk);
hi = eblk.span;
}
}
ret @ast.expr_if(cond, thn, els);
ret @spanned(lo, hi, ast.expr_if(cond, thn, els));
}
io fn parse_expr(parser p) -> @ast.expr {
alt (p.peek()) {
case (token.LBRACE) {
ret @ast.expr_block(parse_block(p));
auto blk = parse_block(p);
ret @spanned(blk.span, blk.span,
ast.expr_block(blk));
}
case (token.IF) {
ret parse_if_expr(p);
......@@ -456,22 +536,27 @@ fn get_span() -> common.span {
}
io fn parse_stmt(parser p) -> @ast.stmt {
auto lo = p.get_span();
alt (p.peek()) {
case (token.LOG) {
p.bump();
auto e = parse_expr(p);
auto hi = p.get_span();
expect(p, token.SEMI);
ret @ast.stmt_log(e);
ret @spanned(lo, hi, ast.stmt_log(e));
}
// Handle the (few) block-expr stmts first.
case (token.IF) {
ret @ast.stmt_expr(parse_expr(p));
auto e = parse_expr(p);
ret @spanned(lo, e.span, ast.stmt_expr(e));
}
case (token.LBRACE) {
ret @ast.stmt_expr(parse_expr(p));
auto e = parse_expr(p);
ret @spanned(lo, e.span, ast.stmt_expr(e));
}
......@@ -479,8 +564,9 @@ fn get_span() -> common.span {
case (_) {
auto e = parse_expr(p);
auto hi = p.get_span();
expect(p, token.SEMI);
ret @ast.stmt_expr(e);
ret @spanned(lo, hi, ast.stmt_expr(e));
}
}
p.err("expected statement");
......@@ -504,10 +590,11 @@ fn get_span() -> common.span {
}
io fn parse_fn(parser p) -> tup(ast.ident, ast.item) {
auto lo = p.get_span();
expect(p, token.FN);
auto id = parse_ident(p);
auto pf = parse_slot_ident_pair;
auto inputs =
let util.common.spanned[vec[rec(ast.slot slot, ast.ident ident)]] inputs =
// FIXME: passing parse_slot_ident_pair as an lval doesn't work at the
// moment.
parse_seq[rec(ast.slot slot, ast.ident ident)]
......@@ -516,24 +603,28 @@ fn get_span() -> common.span {
some(token.COMMA),
pf, p);
auto output;
let ast.slot output;
if (p.peek() == token.RARROW) {
p.bump();
output = rec(ty=parse_ty(p), mode=ast.val);
output = rec(ty=parse_ty(p), mode=ast.val, id=none[ast.slot_id]);
} else {
output = rec(ty=ast.ty_nil, mode=ast.val);
output = rec(ty=spanned(lo, inputs.span, ast.ty_nil),
mode=ast.val, id=none[ast.slot_id]);
}
auto body = parse_block(p);
let ast._fn f = rec(inputs = inputs,
let ast._fn f = rec(inputs = inputs.node,
output = output,
body = body);
ret tup(id, ast.item_fn(@f));
let ast.item i = spanned(lo, body.span,
ast.item_fn(@f, ast.id_item(0,0)));
ret tup(id, i);
}
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);
......@@ -542,8 +633,9 @@ fn get_span() -> common.span {
auto i = parse_item(p);
m.insert(i._0, i._1);
}
auto hi = p.get_span();
expect(p, token.RBRACE);
ret tup(id, ast.item_mod(@m));
ret tup(id, spanned(lo, hi, ast.item_mod(@m)));
}
io fn parse_item(parser p) -> tup(ast.ident, ast.item) {
......@@ -560,12 +652,15 @@ fn get_span() -> common.span {
}
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;
}
ret rec(module=m);
ret spanned(lo, hi, rec(module=m));
}
//
......
......@@ -348,7 +348,7 @@ fn trans_drop_str(@block_ctxt cx, ValueRef v) -> result {
}
fn trans_lit(@block_ctxt cx, &ast.lit lit) -> result {
alt (lit) {
alt (lit.node) {
case (ast.lit_int(?i)) {
ret res(cx, C_int(i));
}
......@@ -545,7 +545,7 @@ fn trans_if(@block_ctxt cx, &ast.expr cond,
}
fn trans_expr(@block_ctxt cx, &ast.expr e) -> result {
alt (e) {
alt (e.node) {
case (ast.expr_lit(?lit)) {
ret trans_lit(cx, *lit);
}
......@@ -578,9 +578,9 @@ fn trans_expr(@block_ctxt cx, &ast.expr e) -> result {
}
fn trans_log(@block_ctxt cx, &ast.expr e) -> result {
alt (e) {
alt (e.node) {
case (ast.expr_lit(?lit)) {
alt (*lit) {
alt (lit.node) {
case (ast.lit_str(_)) {
auto sub = trans_expr(cx, e);
auto v = sub.bcx.build.PtrToInt(sub.val, T_int());
......@@ -607,7 +607,7 @@ fn trans_log(@block_ctxt cx, &ast.expr e) -> result {
fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result {
auto sub = res(cx, C_nil());
alt (s) {
alt (s.node) {
case (ast.stmt_log(?a)) {
sub.bcx = trans_log(cx, *a).bcx;
}
......@@ -688,7 +688,7 @@ fn trans_block_cleanups(@block_ctxt cx) -> @block_ctxt {
fn trans_block(@block_ctxt cx, &ast.block b) -> result {
auto bcx = cx;
for (@ast.stmt s in b) {
for (@ast.stmt s in b.node) {
bcx = trans_stmt(bcx, *s).bcx;
}
......@@ -726,8 +726,8 @@ fn trans_fn(@trans_ctxt cx, &ast._fn f) {
fn trans_item(@trans_ctxt cx, &str name, &ast.item item) {
auto sub_cx = @rec(path=cx.path + "." + name with *cx);
alt (item) {
case (ast.item_fn(?f)) {
alt (item.node) {
case (ast.item_fn(?f, _)) {
trans_fn(sub_cx, *f);
}
case (ast.item_mod(?m)) {
......@@ -872,7 +872,7 @@ fn trans_crate(session.session sess, ast.crate crate) {
names = namegen(0),
path = "_rust");
trans_mod(cx, crate.module);
trans_mod(cx, crate.node.module);
trans_exit_task_glue(cx);
trans_main_fn(cx, crate_constant(cx));
......
......@@ -3,6 +3,7 @@
type pos = rec(uint line, uint col);
type span = rec(str filename, pos lo, pos hi);
type spanned[T] = rec(T node, span span);
// FIXME: import std.util.option and use it here.
// import std.util.option;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册