2010-08-18 15:41:13 -07:00
|
|
|
import std._io;
|
2010-11-03 17:10:37 -07:00
|
|
|
import std.option;
|
|
|
|
import std.option.some;
|
|
|
|
import std.option.none;
|
2010-11-05 10:41:23 -07:00
|
|
|
import std.map.hashmap;
|
2010-10-15 22:09:09 -07:00
|
|
|
|
2010-09-01 13:24:14 -07:00
|
|
|
import driver.session;
|
|
|
|
import util.common;
|
2010-10-18 18:19:16 -07:00
|
|
|
import util.common.append;
|
2010-10-05 18:21:44 -07:00
|
|
|
import util.common.span;
|
2010-09-21 16:22:32 -07:00
|
|
|
import util.common.new_str_hash;
|
2010-08-18 15:41:13 -07:00
|
|
|
|
|
|
|
state type parser =
|
|
|
|
state obj {
|
2010-09-29 17:22:07 -07:00
|
|
|
fn peek() -> token.token;
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn bump();
|
|
|
|
impure fn err(str s);
|
2010-09-01 13:24:14 -07:00
|
|
|
fn get_session() -> session.session;
|
|
|
|
fn get_span() -> common.span;
|
2010-10-18 16:15:25 -07:00
|
|
|
fn next_def_id() -> ast.def_id;
|
2010-08-18 15:41:13 -07:00
|
|
|
};
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn new_parser(session.session sess,
|
2010-10-18 16:15:25 -07:00
|
|
|
ast.crate_num crate, str path) -> parser {
|
2010-09-01 13:24:14 -07:00
|
|
|
state obj stdio_parser(session.session sess,
|
|
|
|
mutable token.token tok,
|
|
|
|
mutable common.pos lo,
|
|
|
|
mutable common.pos hi,
|
2010-10-18 16:15:25 -07:00
|
|
|
mutable ast.def_num def,
|
|
|
|
ast.crate_num crate,
|
2010-08-27 12:36:57 -07:00
|
|
|
lexer.reader rdr)
|
2010-08-18 15:41:13 -07:00
|
|
|
{
|
2010-09-29 17:22:07 -07:00
|
|
|
fn peek() -> token.token {
|
2010-10-05 18:21:44 -07:00
|
|
|
// log token.to_str(tok);
|
2010-08-18 15:41:13 -07:00
|
|
|
ret tok;
|
|
|
|
}
|
2010-09-01 13:24:14 -07:00
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn bump() {
|
2010-08-18 15:41:13 -07:00
|
|
|
tok = lexer.next_token(rdr);
|
2010-09-01 13:24:14 -07:00
|
|
|
lo = rdr.get_mark_pos();
|
|
|
|
hi = rdr.get_curr_pos();
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn err(str m) {
|
2010-09-01 13:24:14 -07:00
|
|
|
auto span = rec(filename = rdr.get_filename(),
|
|
|
|
lo = lo, hi = hi);
|
|
|
|
sess.span_err(span, m);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_session() -> session.session {
|
|
|
|
ret sess;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_span() -> common.span {
|
|
|
|
ret rec(filename = rdr.get_filename(),
|
|
|
|
lo = lo, hi = hi);
|
2010-08-18 15:41:13 -07:00
|
|
|
}
|
2010-10-18 16:15:25 -07:00
|
|
|
|
|
|
|
fn next_def_id() -> ast.def_id {
|
|
|
|
def += 1;
|
|
|
|
ret tup(crate, def);
|
|
|
|
}
|
2010-08-18 15:41:13 -07:00
|
|
|
}
|
2010-08-27 12:36:57 -07:00
|
|
|
auto srdr = _io.new_stdio_reader(path);
|
|
|
|
auto rdr = lexer.new_reader(srdr, path);
|
2010-09-01 13:24:14 -07:00
|
|
|
auto npos = rdr.get_curr_pos();
|
2010-10-18 16:15:25 -07:00
|
|
|
ret stdio_parser(sess, lexer.next_token(rdr),
|
|
|
|
npos, npos, 0, crate, rdr);
|
2010-09-01 13:24:14 -07:00
|
|
|
}
|
|
|
|
|
2010-12-09 17:11:52 -08:00
|
|
|
impure fn unexpected(parser p, token.token t) {
|
|
|
|
let str s = "unexpected token: ";
|
|
|
|
s += token.to_str(t);
|
|
|
|
p.err(s);
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn expect(parser p, token.token t) {
|
2010-09-21 11:47:10 -07:00
|
|
|
if (p.peek() == t) {
|
2010-09-01 13:24:14 -07:00
|
|
|
p.bump();
|
|
|
|
} else {
|
|
|
|
let str s = "expecting ";
|
|
|
|
s += token.to_str(t);
|
|
|
|
s += ", found ";
|
2010-09-21 16:22:32 -07:00
|
|
|
s += token.to_str(p.peek());
|
2010-09-01 13:24:14 -07:00
|
|
|
p.err(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-05 18:21:44 -07:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_ident(parser p) -> ast.ident {
|
2010-09-01 13:24:14 -07:00
|
|
|
alt (p.peek()) {
|
2010-09-21 16:22:32 -07:00
|
|
|
case (token.IDENT(?i)) { p.bump(); ret i; }
|
2010-09-01 13:24:14 -07:00
|
|
|
case (_) {
|
|
|
|
p.err("expecting ident");
|
|
|
|
fail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-14 17:42:12 -08:00
|
|
|
impure fn parse_ty_fn(parser p, ast.span lo) -> ast.ty_ {
|
2010-11-05 15:23:03 -07:00
|
|
|
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();
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2010-11-19 16:34:47 -08:00
|
|
|
|
2010-12-14 17:42:12 -08:00
|
|
|
impure fn parse_ty_obj(parser p, &mutable ast.span hi) -> ast.ty_ {
|
|
|
|
expect(p, token.OBJ);
|
|
|
|
impure fn parse_method_sig(parser p) -> ast.ty_method {
|
|
|
|
auto flo = p.get_span();
|
|
|
|
expect(p, token.FN);
|
|
|
|
auto ident = parse_ident(p);
|
|
|
|
auto f = parse_ty_fn(p, flo);
|
|
|
|
expect(p, token.SEMI);
|
|
|
|
alt (f) {
|
|
|
|
case (ast.ty_fn(?inputs, ?output)) {
|
|
|
|
ret rec(ident=ident, inputs=inputs, output=output);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fail;
|
|
|
|
}
|
|
|
|
auto f = parse_method_sig;
|
|
|
|
auto meths =
|
|
|
|
parse_seq[ast.ty_method](token.LBRACE,
|
|
|
|
token.RBRACE,
|
|
|
|
none[token.token],
|
|
|
|
f, p);
|
|
|
|
hi = meths.span;
|
|
|
|
ret ast.ty_obj(meths.node);
|
|
|
|
}
|
|
|
|
|
2010-12-14 15:32:13 -08:00
|
|
|
impure fn parse_ty_field(parser p) -> ast.ty_field {
|
|
|
|
auto ty = parse_ty(p);
|
|
|
|
auto id = parse_ident(p);
|
|
|
|
ret rec(ident=id, ty=ty);
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_ty(parser p) -> @ast.ty {
|
2010-10-05 18:21:44 -07:00
|
|
|
auto lo = p.get_span();
|
2010-11-19 16:34:47 -08:00
|
|
|
auto hi = lo;
|
2010-10-05 18:21:44 -07:00
|
|
|
let ast.ty_ t;
|
2010-09-21 16:22:32 -07:00
|
|
|
alt (p.peek()) {
|
2010-12-08 15:04:57 -08:00
|
|
|
case (token.BOOL) { p.bump(); t = ast.ty_bool; }
|
2010-10-05 18:21:44 -07:00
|
|
|
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); }
|
2010-10-12 14:15:12 -07:00
|
|
|
|
2010-11-19 16:34:47 -08:00
|
|
|
case (token.LPAREN) {
|
|
|
|
p.bump();
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.RPAREN) {
|
|
|
|
hi = p.get_span();
|
|
|
|
p.bump();
|
|
|
|
t = ast.ty_nil;
|
|
|
|
}
|
|
|
|
case (_) {
|
|
|
|
t = parse_ty(p).node;
|
|
|
|
hi = p.get_span();
|
|
|
|
expect(p, token.RPAREN);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-29 12:29:57 -08:00
|
|
|
case (token.AT) {
|
|
|
|
p.bump();
|
|
|
|
auto t0 = parse_ty(p);
|
|
|
|
hi = t0.span;
|
|
|
|
t = ast.ty_box(t0);
|
|
|
|
}
|
2010-10-12 14:54:49 -07:00
|
|
|
|
2010-10-13 10:55:20 -07:00
|
|
|
case (token.VEC) {
|
|
|
|
p.bump();
|
|
|
|
expect(p, token.LBRACKET);
|
|
|
|
t = ast.ty_vec(parse_ty(p));
|
2010-11-19 16:34:47 -08:00
|
|
|
hi = p.get_span();
|
2010-10-13 10:55:20 -07:00
|
|
|
expect(p, token.RBRACKET);
|
|
|
|
}
|
|
|
|
|
2010-10-12 14:15:12 -07:00
|
|
|
case (token.TUP) {
|
|
|
|
p.bump();
|
2010-11-29 15:29:55 -08:00
|
|
|
auto f = parse_ty; // FIXME: trans_const_lval bug
|
|
|
|
auto elems = parse_seq[@ast.ty] (token.LPAREN,
|
|
|
|
token.RPAREN,
|
|
|
|
some(token.COMMA), f, p);
|
2010-12-14 17:42:12 -08:00
|
|
|
hi = elems.span;
|
2010-10-12 14:15:12 -07:00
|
|
|
t = ast.ty_tup(elems.node);
|
|
|
|
}
|
|
|
|
|
2010-11-29 15:42:09 -08:00
|
|
|
case (token.REC) {
|
|
|
|
p.bump();
|
2010-12-14 15:32:13 -08:00
|
|
|
auto f = parse_ty_field; // FIXME: trans_const_lval bug
|
2010-11-29 15:42:09 -08:00
|
|
|
auto elems =
|
2010-11-30 16:31:43 -08:00
|
|
|
parse_seq[ast.ty_field](token.LPAREN,
|
|
|
|
token.RPAREN,
|
|
|
|
some(token.COMMA),
|
|
|
|
f, p);
|
2010-12-14 17:42:12 -08:00
|
|
|
hi = elems.span;
|
2010-11-29 15:42:09 -08:00
|
|
|
t = ast.ty_rec(elems.node);
|
|
|
|
}
|
|
|
|
|
2010-11-29 12:29:57 -08:00
|
|
|
case (token.MUTABLE) {
|
|
|
|
p.bump();
|
|
|
|
auto t0 = parse_ty(p);
|
2010-12-14 17:42:12 -08:00
|
|
|
hi = t0.span;
|
2010-11-29 12:29:57 -08:00
|
|
|
t = ast.ty_mutable(t0);
|
|
|
|
}
|
|
|
|
|
2010-11-05 15:23:03 -07:00
|
|
|
case (token.FN) {
|
2010-12-14 17:42:12 -08:00
|
|
|
auto flo = p.get_span();
|
|
|
|
p.bump();
|
|
|
|
t = parse_ty_fn(p, flo);
|
2010-11-19 16:34:47 -08:00
|
|
|
alt (t) {
|
|
|
|
case (ast.ty_fn(_, ?out)) {
|
|
|
|
hi = out.span;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-14 17:42:12 -08:00
|
|
|
case (token.OBJ) {
|
|
|
|
t = parse_ty_obj(p, hi);
|
|
|
|
}
|
|
|
|
|
2010-11-19 16:34:47 -08:00
|
|
|
case (token.IDENT(_)) {
|
|
|
|
let ast.path pth = vec();
|
|
|
|
let bool more = true;
|
|
|
|
while (more) {
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.IDENT(?i)) {
|
|
|
|
auto n = parse_name(p, i);
|
|
|
|
hi = n.span;
|
2010-11-22 13:21:54 -08:00
|
|
|
pth += n;
|
2010-11-19 16:34:47 -08:00
|
|
|
if (p.peek() == token.DOT) {
|
|
|
|
p.bump();
|
|
|
|
} else {
|
|
|
|
more = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case (_) {
|
|
|
|
more = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
t = ast.ty_path(pth, none[ast.def]);
|
2010-11-05 15:23:03 -07:00
|
|
|
}
|
|
|
|
|
2010-10-05 18:21:44 -07:00
|
|
|
case (_) {
|
|
|
|
p.err("expecting type");
|
|
|
|
t = ast.ty_nil;
|
|
|
|
fail;
|
|
|
|
}
|
2010-09-21 16:22:32 -07:00
|
|
|
}
|
2010-11-19 16:34:47 -08:00
|
|
|
ret @spanned(lo, hi, t);
|
2010-09-21 16:22:32 -07:00
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_arg(parser p) -> ast.arg {
|
2010-09-21 16:22:32 -07:00
|
|
|
let ast.mode m = ast.val;
|
|
|
|
if (p.peek() == token.BINOP(token.AND)) {
|
|
|
|
m = ast.alias;
|
|
|
|
p.bump();
|
|
|
|
}
|
2010-10-06 15:41:14 -07:00
|
|
|
let @ast.ty t = parse_ty(p);
|
2010-10-18 16:15:25 -07:00
|
|
|
let ast.ident i = parse_ident(p);
|
|
|
|
ret rec(mode=m, ty=t, ident=i, id=p.next_def_id());
|
2010-09-21 16:22:32 -07:00
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_seq[T](token.token bra,
|
2010-09-21 16:22:32 -07:00
|
|
|
token.token ket,
|
2010-11-03 17:10:37 -07:00
|
|
|
option.t[token.token] sep,
|
2010-11-02 11:11:58 -07:00
|
|
|
(impure fn(parser) -> T) f,
|
2010-10-05 18:21:44 -07:00
|
|
|
parser p) -> util.common.spanned[vec[T]] {
|
2010-09-21 16:22:32 -07:00
|
|
|
let bool first = true;
|
2010-10-05 18:21:44 -07:00
|
|
|
auto lo = p.get_span();
|
2010-09-21 16:22:32 -07:00
|
|
|
expect(p, bra);
|
|
|
|
let vec[T] v = vec();
|
2010-11-19 14:59:58 -08:00
|
|
|
while (p.peek() != ket) {
|
2010-09-21 16:22:32 -07:00
|
|
|
alt(sep) {
|
|
|
|
case (some[token.token](?t)) {
|
|
|
|
if (first) {
|
|
|
|
first = false;
|
|
|
|
} else {
|
|
|
|
expect(p, t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case (_) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// FIXME: v += f(p) doesn't work at the moment.
|
|
|
|
let T t = f(p);
|
|
|
|
v += vec(t);
|
|
|
|
}
|
2010-10-05 18:21:44 -07:00
|
|
|
auto hi = p.get_span();
|
2010-09-21 16:22:32 -07:00
|
|
|
expect(p, ket);
|
2010-10-05 18:21:44 -07:00
|
|
|
ret spanned(lo, hi, v);
|
2010-09-21 16:22:32 -07:00
|
|
|
}
|
|
|
|
|
2010-11-03 17:10:37 -07:00
|
|
|
impure fn parse_lit(parser p) -> option.t[ast.lit] {
|
2010-10-05 18:21:44 -07:00
|
|
|
auto lo = p.get_span();
|
|
|
|
let ast.lit_ lit;
|
2010-09-01 13:24:14 -07:00
|
|
|
alt (p.peek()) {
|
2010-09-21 16:22:32 -07:00
|
|
|
case (token.LIT_INT(?i)) {
|
|
|
|
p.bump();
|
2010-10-05 18:21:44 -07:00
|
|
|
lit = ast.lit_int(i);
|
2010-09-21 16:22:32 -07:00
|
|
|
}
|
|
|
|
case (token.LIT_UINT(?u)) {
|
2010-09-01 13:24:14 -07:00
|
|
|
p.bump();
|
2010-10-05 18:21:44 -07:00
|
|
|
lit = ast.lit_uint(u);
|
2010-09-21 16:22:32 -07:00
|
|
|
}
|
2010-11-22 17:41:26 -08:00
|
|
|
case (token.LIT_MACH_INT(?tm, ?i)) {
|
|
|
|
p.bump();
|
|
|
|
lit = ast.lit_mach_int(tm, i);
|
|
|
|
}
|
2010-09-21 16:22:32 -07:00
|
|
|
case (token.LIT_CHAR(?c)) {
|
|
|
|
p.bump();
|
2010-10-05 18:21:44 -07:00
|
|
|
lit = ast.lit_char(c);
|
2010-09-21 16:22:32 -07:00
|
|
|
}
|
|
|
|
case (token.LIT_BOOL(?b)) {
|
|
|
|
p.bump();
|
2010-10-05 18:21:44 -07:00
|
|
|
lit = ast.lit_bool(b);
|
2010-09-01 13:24:14 -07:00
|
|
|
}
|
2010-09-28 12:23:40 -07:00
|
|
|
case (token.LIT_STR(?s)) {
|
|
|
|
p.bump();
|
2010-10-05 18:21:44 -07:00
|
|
|
lit = ast.lit_str(s);
|
|
|
|
}
|
|
|
|
case (_) {
|
2010-10-11 17:21:36 -07:00
|
|
|
lit = ast.lit_nil; // FIXME: typestate bug requires this
|
|
|
|
ret none[ast.lit];
|
2010-09-28 12:23:40 -07:00
|
|
|
}
|
2010-09-01 13:24:14 -07:00
|
|
|
}
|
2010-10-11 17:21:36 -07:00
|
|
|
ret some(spanned(lo, lo, lit));
|
2010-08-18 15:41:13 -07:00
|
|
|
}
|
2010-08-12 10:29:23 -07:00
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_name(parser p, ast.ident id) -> ast.name {
|
2010-10-05 18:21:44 -07:00
|
|
|
|
|
|
|
auto lo = p.get_span();
|
|
|
|
|
2010-10-04 17:25:52 -07:00
|
|
|
p.bump();
|
2010-09-27 18:25:02 -07:00
|
|
|
|
2010-10-06 15:41:14 -07:00
|
|
|
let vec[@ast.ty] v = vec();
|
|
|
|
let util.common.spanned[vec[@ast.ty]] tys = rec(node=v, span=lo);
|
2010-10-04 17:25:52 -07:00
|
|
|
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.LBRACKET) {
|
|
|
|
auto pf = parse_ty;
|
2010-10-06 15:41:14 -07:00
|
|
|
tys = parse_seq[@ast.ty](token.LBRACKET,
|
|
|
|
token.RBRACKET,
|
|
|
|
some(token.COMMA),
|
|
|
|
pf, p);
|
2010-10-04 17:25:52 -07:00
|
|
|
}
|
|
|
|
case (_) {
|
|
|
|
}
|
|
|
|
}
|
2010-10-05 18:21:44 -07:00
|
|
|
ret spanned(lo, tys.span, rec(ident=id, types=tys.node));
|
2010-10-04 17:25:52 -07:00
|
|
|
}
|
2010-09-27 18:25:02 -07:00
|
|
|
|
2010-11-30 16:31:43 -08:00
|
|
|
impure fn parse_mutabliity(parser p) -> ast.mutability {
|
2010-10-12 16:30:44 -07:00
|
|
|
if (p.peek() == token.MUTABLE) {
|
|
|
|
p.bump();
|
2010-11-30 16:31:43 -08:00
|
|
|
ret ast.mut;
|
2010-10-12 16:30:44 -07:00
|
|
|
}
|
2010-11-30 16:31:43 -08:00
|
|
|
ret ast.imm;
|
2010-10-12 16:30:44 -07:00
|
|
|
}
|
|
|
|
|
2010-12-14 15:32:13 -08:00
|
|
|
impure fn parse_field(parser p) -> ast.field {
|
|
|
|
auto m = parse_mutabliity(p);
|
|
|
|
auto i = parse_ident(p);
|
|
|
|
expect(p, token.EQ);
|
|
|
|
auto e = parse_expr(p);
|
|
|
|
ret rec(mut=m, ident=i, expr=e);
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_bottom_expr(parser p) -> @ast.expr {
|
2010-10-05 18:21:44 -07:00
|
|
|
|
|
|
|
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.
|
2010-10-19 13:28:43 -07:00
|
|
|
auto lit = @spanned(lo, lo, ast.lit_nil);
|
2010-11-03 15:53:53 -07:00
|
|
|
let ast.expr_ ex = ast.expr_lit(lit, ast.ann_none);
|
2010-10-05 18:21:44 -07:00
|
|
|
|
2010-09-27 18:25:02 -07:00
|
|
|
alt (p.peek()) {
|
2010-10-18 16:15:25 -07:00
|
|
|
|
|
|
|
case (token.IDENT(?i)) {
|
|
|
|
auto n = parse_name(p, i);
|
|
|
|
hi = n.span;
|
2010-11-03 15:53:53 -07:00
|
|
|
ex = ast.expr_name(n, none[ast.def], ast.ann_none);
|
2010-10-18 16:15:25 -07:00
|
|
|
}
|
|
|
|
|
2010-09-27 18:25:02 -07:00
|
|
|
case (token.LPAREN) {
|
|
|
|
p.bump();
|
2010-11-19 16:34:47 -08:00
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.RPAREN) {
|
|
|
|
hi = p.get_span();
|
|
|
|
p.bump();
|
|
|
|
auto lit = @spanned(lo, hi, ast.lit_nil);
|
|
|
|
ret @spanned(lo, hi,
|
|
|
|
ast.expr_lit(lit, ast.ann_none));
|
|
|
|
}
|
2010-12-01 17:08:46 -08:00
|
|
|
case (_) { /* fall through */ }
|
2010-11-19 16:34:47 -08:00
|
|
|
}
|
2010-09-27 18:25:02 -07:00
|
|
|
auto e = parse_expr(p);
|
2010-10-05 18:21:44 -07:00
|
|
|
hi = p.get_span();
|
2010-09-27 18:25:02 -07:00
|
|
|
expect(p, token.RPAREN);
|
2010-10-05 18:21:44 -07:00
|
|
|
ret @spanned(lo, hi, e.node);
|
2010-09-27 18:25:02 -07:00
|
|
|
}
|
|
|
|
|
2010-09-28 10:30:34 -07:00
|
|
|
case (token.TUP) {
|
|
|
|
p.bump();
|
2010-11-30 16:31:43 -08:00
|
|
|
impure fn parse_elt(parser p) -> ast.elt {
|
|
|
|
auto m = parse_mutabliity(p);
|
|
|
|
auto e = parse_expr(p);
|
|
|
|
ret rec(mut=m, expr=e);
|
|
|
|
}
|
|
|
|
auto pf = parse_elt;
|
2010-11-29 14:18:26 -08:00
|
|
|
auto es =
|
2010-11-30 16:31:43 -08:00
|
|
|
parse_seq[ast.elt](token.LPAREN,
|
|
|
|
token.RPAREN,
|
|
|
|
some(token.COMMA),
|
|
|
|
pf, p);
|
2010-10-05 18:21:44 -07:00
|
|
|
hi = es.span;
|
2010-11-03 15:53:53 -07:00
|
|
|
ex = ast.expr_tup(es.node, ast.ann_none);
|
2010-09-28 10:30:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
case (token.VEC) {
|
|
|
|
p.bump();
|
|
|
|
auto pf = parse_expr;
|
|
|
|
auto es = parse_seq[@ast.expr](token.LPAREN,
|
|
|
|
token.RPAREN,
|
|
|
|
some(token.COMMA),
|
|
|
|
pf, p);
|
2010-10-05 18:21:44 -07:00
|
|
|
hi = es.span;
|
2010-11-03 15:53:53 -07:00
|
|
|
ex = ast.expr_vec(es.node, ast.ann_none);
|
2010-09-28 10:30:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
case (token.REC) {
|
|
|
|
p.bump();
|
2010-11-30 16:31:43 -08:00
|
|
|
auto pf = parse_field;
|
|
|
|
auto fs =
|
|
|
|
parse_seq[ast.field](token.LPAREN,
|
|
|
|
token.RPAREN,
|
|
|
|
some(token.COMMA),
|
|
|
|
pf, p);
|
|
|
|
hi = fs.span;
|
|
|
|
ex = ast.expr_rec(fs.node, ast.ann_none);
|
2010-09-28 10:30:34 -07:00
|
|
|
}
|
|
|
|
|
2010-09-27 18:25:02 -07:00
|
|
|
case (_) {
|
2010-10-14 17:42:06 -07:00
|
|
|
alt (parse_lit(p)) {
|
|
|
|
case (some[ast.lit](?lit)) {
|
|
|
|
hi = lit.span;
|
2010-11-03 15:53:53 -07:00
|
|
|
ex = ast.expr_lit(@lit, ast.ann_none);
|
2010-10-11 17:21:36 -07:00
|
|
|
}
|
2010-10-14 17:42:06 -07:00
|
|
|
case (none[ast.lit]) {
|
|
|
|
p.err("expecting expression");
|
2010-10-11 17:21:36 -07:00
|
|
|
}
|
|
|
|
}
|
2010-09-27 18:25:02 -07:00
|
|
|
}
|
|
|
|
}
|
2010-10-14 17:42:06 -07:00
|
|
|
|
2010-10-18 11:31:31 -07:00
|
|
|
ret @spanned(lo, hi, ex);
|
2010-09-27 18:25:02 -07:00
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_path_expr(parser p) -> @ast.expr {
|
2010-10-05 18:21:44 -07:00
|
|
|
auto lo = p.get_span();
|
2010-09-28 10:30:34 -07:00
|
|
|
auto e = parse_bottom_expr(p);
|
2010-10-05 18:21:44 -07:00
|
|
|
auto hi = e.span;
|
2010-09-28 10:30:34 -07:00
|
|
|
while (true) {
|
|
|
|
alt (p.peek()) {
|
2010-12-14 16:59:13 -08:00
|
|
|
|
|
|
|
case (token.LPAREN) {
|
|
|
|
// Call expr.
|
|
|
|
auto pf = parse_expr;
|
|
|
|
auto es = parse_seq[@ast.expr](token.LPAREN,
|
|
|
|
token.RPAREN,
|
|
|
|
some(token.COMMA),
|
|
|
|
pf, p);
|
|
|
|
hi = es.span;
|
|
|
|
auto e_ = ast.expr_call(e, es.node, ast.ann_none);
|
|
|
|
e = @spanned(lo, hi, e_);
|
|
|
|
}
|
|
|
|
|
2010-09-28 10:30:34 -07:00
|
|
|
case (token.DOT) {
|
|
|
|
p.bump();
|
|
|
|
alt (p.peek()) {
|
|
|
|
|
|
|
|
case (token.IDENT(?i)) {
|
2010-10-05 18:21:44 -07:00
|
|
|
hi = p.get_span();
|
2010-09-28 10:30:34 -07:00
|
|
|
p.bump();
|
2010-11-03 15:53:53 -07:00
|
|
|
auto e_ = ast.expr_field(e, i, ast.ann_none);
|
2010-10-19 13:28:43 -07:00
|
|
|
e = @spanned(lo, hi, e_);
|
2010-09-28 10:30:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
case (token.LPAREN) {
|
2010-11-19 16:34:47 -08:00
|
|
|
p.bump();
|
2010-12-09 17:34:44 -08:00
|
|
|
auto ix = parse_expr(p);
|
2010-10-05 18:21:44 -07:00
|
|
|
hi = ix.span;
|
2010-12-09 17:12:08 -08:00
|
|
|
expect(p, token.RPAREN);
|
2010-11-03 15:53:53 -07:00
|
|
|
auto e_ = ast.expr_index(e, ix, ast.ann_none);
|
2010-10-19 13:28:43 -07:00
|
|
|
e = @spanned(lo, hi, e_);
|
2010-09-28 10:30:34 -07:00
|
|
|
}
|
2010-12-09 17:12:08 -08:00
|
|
|
|
|
|
|
case (?t) {
|
|
|
|
unexpected(p, t);
|
|
|
|
}
|
2010-09-28 10:30:34 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
case (_) {
|
|
|
|
ret e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret e;
|
|
|
|
}
|
2010-09-27 18:25:02 -07:00
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_prefix_expr(parser p) -> @ast.expr {
|
2010-10-05 18:21:44 -07:00
|
|
|
|
|
|
|
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.
|
2010-10-19 13:28:43 -07:00
|
|
|
auto lit = @spanned(lo, lo, ast.lit_nil);
|
2010-11-03 15:53:53 -07:00
|
|
|
let ast.expr_ ex = ast.expr_lit(lit, ast.ann_none);
|
2010-10-05 18:21:44 -07:00
|
|
|
|
2010-09-27 18:25:02 -07:00
|
|
|
alt (p.peek()) {
|
|
|
|
|
|
|
|
case (token.NOT) {
|
2010-09-28 14:01:21 -07:00
|
|
|
p.bump();
|
2010-09-28 10:30:34 -07:00
|
|
|
auto e = parse_prefix_expr(p);
|
2010-10-05 18:21:44 -07:00
|
|
|
hi = e.span;
|
2010-11-03 15:53:53 -07:00
|
|
|
ex = ast.expr_unary(ast.not, e, ast.ann_none);
|
2010-09-27 18:25:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
case (token.TILDE) {
|
2010-09-28 14:01:21 -07:00
|
|
|
p.bump();
|
2010-09-28 10:30:34 -07:00
|
|
|
auto e = parse_prefix_expr(p);
|
2010-10-05 18:21:44 -07:00
|
|
|
hi = e.span;
|
2010-11-03 15:53:53 -07:00
|
|
|
ex = ast.expr_unary(ast.bitnot, e, ast.ann_none);
|
2010-09-27 18:25:02 -07:00
|
|
|
}
|
|
|
|
|
2010-09-28 10:30:34 -07:00
|
|
|
case (token.BINOP(?b)) {
|
|
|
|
alt (b) {
|
|
|
|
case (token.MINUS) {
|
2010-09-28 14:01:21 -07:00
|
|
|
p.bump();
|
2010-09-28 10:30:34 -07:00
|
|
|
auto e = parse_prefix_expr(p);
|
2010-10-05 18:21:44 -07:00
|
|
|
hi = e.span;
|
2010-11-03 15:53:53 -07:00
|
|
|
ex = ast.expr_unary(ast.neg, e, ast.ann_none);
|
2010-09-28 10:30:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
case (token.STAR) {
|
2010-09-28 14:01:21 -07:00
|
|
|
p.bump();
|
2010-09-28 10:30:34 -07:00
|
|
|
auto e = parse_prefix_expr(p);
|
2010-10-05 18:21:44 -07:00
|
|
|
hi = e.span;
|
2010-11-03 15:53:53 -07:00
|
|
|
ex = ast.expr_unary(ast.deref, e, ast.ann_none);
|
2010-09-28 10:30:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
case (_) {
|
|
|
|
ret parse_path_expr(p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
case (token.AT) {
|
|
|
|
p.bump();
|
|
|
|
auto e = parse_prefix_expr(p);
|
2010-10-05 18:21:44 -07:00
|
|
|
hi = e.span;
|
2010-11-03 15:53:53 -07:00
|
|
|
ex = ast.expr_unary(ast.box, e, ast.ann_none);
|
2010-09-28 10:30:34 -07:00
|
|
|
}
|
|
|
|
|
2010-09-27 18:25:02 -07:00
|
|
|
case (_) {
|
2010-09-28 10:30:34 -07:00
|
|
|
ret parse_path_expr(p);
|
|
|
|
}
|
|
|
|
}
|
2010-10-05 18:21:44 -07:00
|
|
|
ret @spanned(lo, hi, ex);
|
2010-09-28 10:30:34 -07:00
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_binops(parser p,
|
|
|
|
(impure fn(parser) -> @ast.expr) sub,
|
2010-10-05 18:21:44 -07:00
|
|
|
vec[tup(token.binop, ast.binop)] ops)
|
2010-09-28 10:30:34 -07:00
|
|
|
-> @ast.expr {
|
2010-10-05 18:21:44 -07:00
|
|
|
auto lo = p.get_span();
|
|
|
|
auto hi = lo;
|
2010-09-28 10:30:34 -07:00
|
|
|
auto e = sub(p);
|
|
|
|
auto more = true;
|
|
|
|
while (more) {
|
|
|
|
more = false;
|
2010-09-28 14:01:21 -07:00
|
|
|
for (tup(token.binop, ast.binop) pair in ops) {
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.BINOP(?op)) {
|
2010-09-28 10:30:34 -07:00
|
|
|
if (pair._0 == op) {
|
2010-09-28 14:01:21 -07:00
|
|
|
p.bump();
|
2010-10-05 18:21:44 -07:00
|
|
|
auto rhs = sub(p);
|
|
|
|
hi = rhs.span;
|
2010-10-19 13:28:43 -07:00
|
|
|
auto exp = ast.expr_binary(pair._1, e, rhs,
|
2010-11-03 15:53:53 -07:00
|
|
|
ast.ann_none);
|
2010-10-05 18:21:44 -07:00
|
|
|
e = @spanned(lo, hi, exp);
|
2010-09-28 10:30:34 -07:00
|
|
|
more = true;
|
|
|
|
}
|
|
|
|
}
|
2010-12-01 17:08:46 -08:00
|
|
|
case (_) { /* fall through */ }
|
2010-09-28 10:30:34 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret e;
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_binary_exprs(parser p,
|
|
|
|
(impure fn(parser) -> @ast.expr) sub,
|
2010-09-28 10:30:34 -07:00
|
|
|
vec[tup(token.token, ast.binop)] ops)
|
|
|
|
-> @ast.expr {
|
2010-10-05 18:21:44 -07:00
|
|
|
auto lo = p.get_span();
|
|
|
|
auto hi = lo;
|
2010-09-28 10:30:34 -07:00
|
|
|
auto e = sub(p);
|
|
|
|
auto more = true;
|
|
|
|
while (more) {
|
|
|
|
more = false;
|
|
|
|
for (tup(token.token, ast.binop) pair in ops) {
|
2010-09-28 14:01:21 -07:00
|
|
|
if (pair._0 == p.peek()) {
|
|
|
|
p.bump();
|
2010-10-05 18:21:44 -07:00
|
|
|
auto rhs = sub(p);
|
|
|
|
hi = rhs.span;
|
2010-11-03 15:53:53 -07:00
|
|
|
auto exp = ast.expr_binary(pair._1, e, rhs, ast.ann_none);
|
2010-10-05 18:21:44 -07:00
|
|
|
e = @spanned(lo, hi, exp);
|
2010-09-28 10:30:34 -07:00
|
|
|
more = true;
|
|
|
|
}
|
2010-09-27 18:25:02 -07:00
|
|
|
}
|
|
|
|
}
|
2010-09-28 10:30:34 -07:00
|
|
|
ret e;
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_factor_expr(parser p) -> @ast.expr {
|
2010-09-28 10:30:34 -07:00
|
|
|
auto sub = parse_prefix_expr;
|
|
|
|
ret parse_binops(p, sub, vec(tup(token.STAR, ast.mul),
|
|
|
|
tup(token.SLASH, ast.div),
|
|
|
|
tup(token.PERCENT, ast.rem)));
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_term_expr(parser p) -> @ast.expr {
|
2010-09-28 10:30:34 -07:00
|
|
|
auto sub = parse_factor_expr;
|
|
|
|
ret parse_binops(p, sub, vec(tup(token.PLUS, ast.add),
|
|
|
|
tup(token.MINUS, ast.sub)));
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_shift_expr(parser p) -> @ast.expr {
|
2010-09-28 10:30:34 -07:00
|
|
|
auto sub = parse_term_expr;
|
|
|
|
ret parse_binops(p, sub, vec(tup(token.LSL, ast.lsl),
|
|
|
|
tup(token.LSR, ast.lsr),
|
|
|
|
tup(token.ASR, ast.asr)));
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_bitand_expr(parser p) -> @ast.expr {
|
2010-09-28 10:30:34 -07:00
|
|
|
auto sub = parse_shift_expr;
|
|
|
|
ret parse_binops(p, sub, vec(tup(token.AND, ast.bitand)));
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_bitxor_expr(parser p) -> @ast.expr {
|
2010-09-28 10:30:34 -07:00
|
|
|
auto sub = parse_bitand_expr;
|
|
|
|
ret parse_binops(p, sub, vec(tup(token.CARET, ast.bitxor)));
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_bitor_expr(parser p) -> @ast.expr {
|
2010-09-28 10:30:34 -07:00
|
|
|
auto sub = parse_bitxor_expr;
|
|
|
|
ret parse_binops(p, sub, vec(tup(token.OR, ast.bitor)));
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_cast_expr(parser p) -> @ast.expr {
|
2010-10-05 18:21:44 -07:00
|
|
|
auto lo = p.get_span();
|
2010-09-28 10:30:34 -07:00
|
|
|
auto e = parse_bitor_expr(p);
|
2010-10-05 18:21:44 -07:00
|
|
|
auto hi = e.span;
|
2010-09-28 10:30:34 -07:00
|
|
|
while (true) {
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.AS) {
|
|
|
|
p.bump();
|
|
|
|
auto t = parse_ty(p);
|
2010-10-05 18:21:44 -07:00
|
|
|
hi = t.span;
|
2010-11-03 15:53:53 -07:00
|
|
|
e = @spanned(lo, hi, ast.expr_cast(e, t, ast.ann_none));
|
2010-09-28 10:30:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
case (_) {
|
|
|
|
ret e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret e;
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_relational_expr(parser p) -> @ast.expr {
|
2010-09-28 10:30:34 -07:00
|
|
|
auto sub = parse_cast_expr;
|
|
|
|
ret parse_binary_exprs(p, sub, vec(tup(token.LT, ast.lt),
|
|
|
|
tup(token.LE, ast.le),
|
|
|
|
tup(token.GE, ast.ge),
|
|
|
|
tup(token.GT, ast.gt)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_equality_expr(parser p) -> @ast.expr {
|
2010-09-28 10:30:34 -07:00
|
|
|
auto sub = parse_relational_expr;
|
|
|
|
ret parse_binary_exprs(p, sub, vec(tup(token.EQEQ, ast.eq),
|
|
|
|
tup(token.NE, ast.ne)));
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_and_expr(parser p) -> @ast.expr {
|
2010-09-28 10:30:34 -07:00
|
|
|
auto sub = parse_equality_expr;
|
|
|
|
ret parse_binary_exprs(p, sub, vec(tup(token.ANDAND, ast.and)));
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_or_expr(parser p) -> @ast.expr {
|
2010-09-28 10:30:34 -07:00
|
|
|
auto sub = parse_and_expr;
|
|
|
|
ret parse_binary_exprs(p, sub, vec(tup(token.OROR, ast.or)));
|
2010-09-27 18:25:02 -07:00
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_assign_expr(parser p) -> @ast.expr {
|
2010-10-19 16:33:11 -07:00
|
|
|
auto lo = p.get_span();
|
|
|
|
auto lhs = parse_or_expr(p);
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.EQ) {
|
|
|
|
p.bump();
|
|
|
|
auto rhs = parse_expr(p);
|
|
|
|
ret @spanned(lo, rhs.span,
|
2010-11-03 15:53:53 -07:00
|
|
|
ast.expr_assign(lhs, rhs, ast.ann_none));
|
2010-10-19 16:33:11 -07:00
|
|
|
}
|
2010-12-08 14:50:47 -08:00
|
|
|
case (token.BINOPEQ(?op)) {
|
|
|
|
p.bump();
|
|
|
|
auto rhs = parse_expr(p);
|
|
|
|
auto aop = ast.add;
|
|
|
|
alt (op) {
|
|
|
|
case (token.PLUS) { aop = ast.add; }
|
|
|
|
case (token.MINUS) { aop = ast.sub; }
|
|
|
|
case (token.STAR) { aop = ast.mul; }
|
|
|
|
case (token.SLASH) { aop = ast.div; }
|
|
|
|
case (token.PERCENT) { aop = ast.rem; }
|
|
|
|
case (token.CARET) { aop = ast.bitxor; }
|
|
|
|
case (token.AND) { aop = ast.bitand; }
|
|
|
|
case (token.OR) { aop = ast.bitor; }
|
|
|
|
case (token.LSL) { aop = ast.lsl; }
|
|
|
|
case (token.LSR) { aop = ast.lsr; }
|
|
|
|
case (token.ASR) { aop = ast.asr; }
|
|
|
|
}
|
|
|
|
ret @spanned(lo, rhs.span,
|
|
|
|
ast.expr_assign_op(aop, lhs, rhs, ast.ann_none));
|
|
|
|
}
|
2010-12-01 17:08:46 -08:00
|
|
|
case (_) { /* fall through */ }
|
2010-10-19 16:33:11 -07:00
|
|
|
}
|
|
|
|
ret lhs;
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_if_expr(parser p) -> @ast.expr {
|
2010-10-05 18:21:44 -07:00
|
|
|
auto lo = p.get_span();
|
|
|
|
auto hi = lo;
|
|
|
|
|
2010-10-04 15:55:12 -07:00
|
|
|
expect(p, token.IF);
|
|
|
|
expect(p, token.LPAREN);
|
|
|
|
auto cond = parse_expr(p);
|
|
|
|
expect(p, token.RPAREN);
|
|
|
|
auto thn = parse_block(p);
|
2010-11-03 17:10:37 -07:00
|
|
|
let option.t[ast.block] els = none[ast.block];
|
2010-10-05 18:21:44 -07:00
|
|
|
hi = thn.span;
|
2010-10-04 15:55:12 -07:00
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.ELSE) {
|
|
|
|
p.bump();
|
2010-10-05 18:21:44 -07:00
|
|
|
auto eblk = parse_block(p);
|
|
|
|
els = some(eblk);
|
|
|
|
hi = eblk.span;
|
2010-10-04 15:55:12 -07:00
|
|
|
}
|
2010-12-01 17:08:46 -08:00
|
|
|
case (_) { /* fall through */ }
|
2010-10-04 15:55:12 -07:00
|
|
|
}
|
2010-11-03 15:53:53 -07:00
|
|
|
ret @spanned(lo, hi, ast.expr_if(cond, thn, els, ast.ann_none));
|
2010-10-04 15:55:12 -07:00
|
|
|
}
|
|
|
|
|
2010-11-03 11:05:15 -07:00
|
|
|
impure fn parse_while_expr(parser p) -> @ast.expr {
|
|
|
|
auto lo = p.get_span();
|
|
|
|
auto hi = lo;
|
|
|
|
|
|
|
|
expect(p, token.WHILE);
|
|
|
|
expect (p, token.LPAREN);
|
|
|
|
auto cond = parse_expr(p);
|
|
|
|
expect(p, token.RPAREN);
|
|
|
|
auto body = parse_block(p);
|
|
|
|
hi = body.span;
|
2010-11-03 15:53:53 -07:00
|
|
|
ret @spanned(lo, hi, ast.expr_while(cond, body, ast.ann_none));
|
2010-11-03 11:05:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impure fn parse_do_while_expr(parser p) -> @ast.expr {
|
|
|
|
auto lo = p.get_span();
|
|
|
|
auto hi = lo;
|
|
|
|
|
|
|
|
expect(p, token.DO);
|
|
|
|
auto body = parse_block(p);
|
|
|
|
expect(p, token.WHILE);
|
|
|
|
expect (p, token.LPAREN);
|
|
|
|
auto cond = parse_expr(p);
|
|
|
|
expect(p, token.RPAREN);
|
|
|
|
hi = cond.span;
|
2010-11-03 15:53:53 -07:00
|
|
|
ret @spanned(lo, hi, ast.expr_do_while(body, cond, ast.ann_none));
|
2010-11-03 11:05:15 -07:00
|
|
|
}
|
|
|
|
|
2010-11-24 14:42:01 -08:00
|
|
|
impure fn parse_alt_expr(parser p) -> @ast.expr {
|
|
|
|
auto lo = p.get_span();
|
|
|
|
expect(p, token.ALT);
|
|
|
|
expect(p, token.LPAREN);
|
|
|
|
auto discriminant = parse_expr(p);
|
|
|
|
expect(p, token.RPAREN);
|
|
|
|
expect(p, token.LBRACE);
|
|
|
|
|
|
|
|
let vec[ast.arm] arms = vec();
|
|
|
|
while (p.peek() != token.RBRACE) {
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.CASE) {
|
|
|
|
p.bump();
|
|
|
|
expect(p, token.LPAREN);
|
|
|
|
auto pat = parse_pat(p);
|
|
|
|
expect(p, token.RPAREN);
|
2010-12-10 18:08:32 -08:00
|
|
|
auto index = index_arm(pat);
|
2010-11-24 14:42:01 -08:00
|
|
|
auto block = parse_block(p);
|
2010-12-10 18:08:32 -08:00
|
|
|
arms += vec(rec(pat=pat, block=block, index=index));
|
2010-11-24 14:42:01 -08:00
|
|
|
}
|
|
|
|
case (token.RBRACE) { /* empty */ }
|
|
|
|
case (?tok) {
|
|
|
|
p.err("expected 'case' or '}' when parsing 'alt' statement " +
|
|
|
|
"but found " + token.to_str(tok));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-11-24 16:29:44 -08:00
|
|
|
p.bump();
|
2010-11-24 14:42:01 -08:00
|
|
|
|
|
|
|
auto expr = ast.expr_alt(discriminant, arms, ast.ann_none);
|
|
|
|
auto hi = p.get_span();
|
|
|
|
ret @spanned(lo, hi, expr);
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_expr(parser p) -> @ast.expr {
|
2010-10-04 15:55:12 -07:00
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.LBRACE) {
|
2010-10-05 18:21:44 -07:00
|
|
|
auto blk = parse_block(p);
|
|
|
|
ret @spanned(blk.span, blk.span,
|
2010-11-03 15:53:53 -07:00
|
|
|
ast.expr_block(blk, ast.ann_none));
|
2010-10-04 15:55:12 -07:00
|
|
|
}
|
|
|
|
case (token.IF) {
|
|
|
|
ret parse_if_expr(p);
|
|
|
|
}
|
2010-11-03 11:05:15 -07:00
|
|
|
case (token.WHILE) {
|
|
|
|
ret parse_while_expr(p);
|
|
|
|
}
|
|
|
|
case (token.DO) {
|
|
|
|
ret parse_do_while_expr(p);
|
|
|
|
}
|
2010-11-24 14:42:01 -08:00
|
|
|
case (token.ALT) {
|
|
|
|
ret parse_alt_expr(p);
|
|
|
|
}
|
2010-10-04 15:55:12 -07:00
|
|
|
case (_) {
|
2010-10-19 16:33:11 -07:00
|
|
|
ret parse_assign_expr(p);
|
2010-10-04 15:55:12 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2010-09-21 16:22:32 -07:00
|
|
|
}
|
|
|
|
|
2010-11-03 17:10:37 -07:00
|
|
|
impure fn parse_initializer(parser p) -> option.t[@ast.expr] {
|
2010-10-11 18:20:25 -07:00
|
|
|
if (p.peek() == token.EQ) {
|
|
|
|
p.bump();
|
|
|
|
ret some(parse_expr(p));
|
|
|
|
}
|
|
|
|
|
|
|
|
ret none[@ast.expr];
|
|
|
|
}
|
|
|
|
|
2010-11-24 14:42:01 -08:00
|
|
|
impure fn parse_pat(parser p) -> @ast.pat {
|
|
|
|
auto lo = p.get_span();
|
|
|
|
|
2010-11-24 15:45:59 -08:00
|
|
|
auto pat = ast.pat_wild(ast.ann_none); // FIXME: typestate bug
|
2010-11-24 14:42:01 -08:00
|
|
|
alt (p.peek()) {
|
2010-11-24 15:45:59 -08:00
|
|
|
case (token.UNDERSCORE) {
|
|
|
|
p.bump();
|
|
|
|
pat = ast.pat_wild(ast.ann_none);
|
|
|
|
}
|
2010-11-24 14:42:01 -08:00
|
|
|
case (token.QUES) {
|
|
|
|
p.bump();
|
|
|
|
alt (p.peek()) {
|
2010-11-24 15:45:59 -08:00
|
|
|
case (token.IDENT(?id)) {
|
|
|
|
p.bump();
|
2010-12-10 17:24:53 -08:00
|
|
|
pat = ast.pat_bind(id, p.next_def_id(), ast.ann_none);
|
2010-11-24 15:45:59 -08:00
|
|
|
}
|
2010-11-24 14:42:01 -08:00
|
|
|
case (?tok) {
|
|
|
|
p.err("expected identifier after '?' in pattern but " +
|
|
|
|
"found " + token.to_str(tok));
|
|
|
|
fail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case (token.IDENT(?id)) {
|
|
|
|
p.bump();
|
|
|
|
|
|
|
|
let vec[@ast.pat] args;
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.LPAREN) {
|
|
|
|
auto f = parse_pat;
|
|
|
|
args = parse_seq[@ast.pat](token.LPAREN, token.RPAREN,
|
|
|
|
some(token.COMMA), f, p).node;
|
|
|
|
}
|
|
|
|
case (_) { args = vec(); }
|
|
|
|
}
|
|
|
|
|
2010-12-12 16:30:34 -08:00
|
|
|
pat = ast.pat_tag(id, args, none[ast.variant_def], ast.ann_none);
|
2010-11-24 14:42:01 -08:00
|
|
|
}
|
|
|
|
case (?tok) {
|
|
|
|
p.err("expected pattern but found " + token.to_str(tok));
|
|
|
|
fail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto hi = p.get_span();
|
|
|
|
ret @spanned(lo, hi, pat);
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_let(parser p) -> @ast.decl {
|
2010-10-11 18:13:14 -07:00
|
|
|
auto lo = p.get_span();
|
|
|
|
|
|
|
|
expect(p, token.LET);
|
|
|
|
auto ty = parse_ty(p);
|
2010-10-18 18:19:16 -07:00
|
|
|
auto ident = parse_ident(p);
|
2010-10-11 18:20:25 -07:00
|
|
|
auto init = parse_initializer(p);
|
2010-10-11 18:13:14 -07:00
|
|
|
|
2010-10-11 18:20:25 -07:00
|
|
|
auto hi = p.get_span();
|
2010-10-11 18:13:14 -07:00
|
|
|
|
2010-10-18 18:19:16 -07:00
|
|
|
let ast.local local = rec(ty = some(ty),
|
|
|
|
infer = false,
|
|
|
|
ident = ident,
|
|
|
|
init = init,
|
2010-11-12 16:11:33 -08:00
|
|
|
id = p.next_def_id(),
|
|
|
|
ann = ast.ann_none);
|
2010-10-18 18:19:16 -07:00
|
|
|
|
2010-10-19 14:54:10 -07:00
|
|
|
ret @spanned(lo, hi, ast.decl_local(@local));
|
2010-10-18 18:19:16 -07:00
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_auto(parser p) -> @ast.decl {
|
2010-10-18 18:19:16 -07:00
|
|
|
auto lo = p.get_span();
|
|
|
|
|
|
|
|
expect(p, token.AUTO);
|
|
|
|
auto ident = parse_ident(p);
|
|
|
|
auto init = parse_initializer(p);
|
|
|
|
|
|
|
|
auto hi = p.get_span();
|
|
|
|
|
|
|
|
let ast.local local = rec(ty = none[@ast.ty],
|
|
|
|
infer = true,
|
|
|
|
ident = ident,
|
|
|
|
init = init,
|
2010-11-12 16:11:33 -08:00
|
|
|
id = p.next_def_id(),
|
|
|
|
ann = ast.ann_none);
|
2010-10-18 18:19:16 -07:00
|
|
|
|
2010-10-19 14:54:10 -07:00
|
|
|
ret @spanned(lo, hi, ast.decl_local(@local));
|
2010-10-11 18:13:14 -07:00
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_stmt(parser p) -> @ast.stmt {
|
2010-10-05 18:21:44 -07:00
|
|
|
auto lo = p.get_span();
|
2010-09-21 16:22:32 -07:00
|
|
|
alt (p.peek()) {
|
2010-10-05 18:21:44 -07:00
|
|
|
|
2010-09-21 16:22:32 -07:00
|
|
|
case (token.LOG) {
|
|
|
|
p.bump();
|
2010-09-27 18:25:02 -07:00
|
|
|
auto e = parse_expr(p);
|
2010-10-05 18:21:44 -07:00
|
|
|
auto hi = p.get_span();
|
|
|
|
ret @spanned(lo, hi, ast.stmt_log(e));
|
2010-09-21 16:22:32 -07:00
|
|
|
}
|
2010-10-04 15:55:12 -07:00
|
|
|
|
2010-10-22 15:37:42 -07:00
|
|
|
case (token.CHECK) {
|
|
|
|
p.bump();
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.LPAREN) {
|
|
|
|
auto e = parse_expr(p);
|
|
|
|
auto hi = p.get_span();
|
|
|
|
ret @spanned(lo, hi, ast.stmt_check_expr(e));
|
|
|
|
}
|
|
|
|
case (_) {
|
|
|
|
p.get_session().unimpl("constraint-check stmt");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-22 19:23:10 -07:00
|
|
|
case (token.RET) {
|
|
|
|
p.bump();
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.SEMI) {
|
|
|
|
ret @spanned(lo, p.get_span(),
|
|
|
|
ast.stmt_ret(none[@ast.expr]));
|
|
|
|
}
|
|
|
|
case (_) {
|
|
|
|
auto e = parse_expr(p);
|
|
|
|
ret @spanned(lo, e.span,
|
|
|
|
ast.stmt_ret(some[@ast.expr](e)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-10-22 15:37:42 -07:00
|
|
|
|
2010-10-11 18:13:14 -07:00
|
|
|
case (token.LET) {
|
2010-10-18 18:19:16 -07:00
|
|
|
auto decl = parse_let(p);
|
2010-10-11 18:13:14 -07:00
|
|
|
auto hi = p.get_span();
|
2010-10-18 18:19:16 -07:00
|
|
|
ret @spanned(lo, hi, ast.stmt_decl(decl));
|
2010-10-11 18:13:14 -07:00
|
|
|
}
|
|
|
|
|
2010-10-11 18:20:25 -07:00
|
|
|
case (token.AUTO) {
|
2010-10-18 18:19:16 -07:00
|
|
|
auto decl = parse_auto(p);
|
2010-10-11 18:20:25 -07:00
|
|
|
auto hi = p.get_span();
|
2010-10-18 18:19:16 -07:00
|
|
|
ret @spanned(lo, hi, ast.stmt_decl(decl));
|
2010-10-11 18:20:25 -07:00
|
|
|
}
|
|
|
|
|
2010-10-04 15:55:12 -07:00
|
|
|
// Handle the (few) block-expr stmts first.
|
|
|
|
|
|
|
|
case (token.IF) {
|
2010-10-05 18:21:44 -07:00
|
|
|
auto e = parse_expr(p);
|
|
|
|
ret @spanned(lo, e.span, ast.stmt_expr(e));
|
2010-10-04 15:55:12 -07:00
|
|
|
}
|
|
|
|
|
2010-11-03 11:05:15 -07:00
|
|
|
case (token.WHILE) {
|
|
|
|
auto e = parse_expr(p);
|
|
|
|
ret @spanned(lo, e.span, ast.stmt_expr(e));
|
|
|
|
}
|
|
|
|
|
|
|
|
case (token.DO) {
|
|
|
|
auto e = parse_expr(p);
|
|
|
|
ret @spanned(lo, e.span, ast.stmt_expr(e));
|
|
|
|
}
|
|
|
|
|
2010-11-24 16:29:44 -08:00
|
|
|
case (token.ALT) {
|
|
|
|
auto e = parse_expr(p);
|
|
|
|
ret @spanned(lo, e.span, ast.stmt_expr(e));
|
|
|
|
}
|
|
|
|
|
2010-10-04 15:55:12 -07:00
|
|
|
case (token.LBRACE) {
|
2010-10-05 18:21:44 -07:00
|
|
|
auto e = parse_expr(p);
|
|
|
|
ret @spanned(lo, e.span, ast.stmt_expr(e));
|
2010-10-04 15:55:12 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
case (_) {
|
2010-12-31 14:33:49 -08:00
|
|
|
if (peeking_at_item(p)) {
|
|
|
|
// Might be a local item decl.
|
|
|
|
auto i = parse_item(p);
|
|
|
|
auto hi = i.span;
|
|
|
|
auto decl = @spanned(lo, hi, ast.decl_item(i));
|
|
|
|
ret @spanned(lo, hi, ast.stmt_decl(decl));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// Remainder are line-expr stmts.
|
|
|
|
auto e = parse_expr(p);
|
|
|
|
auto hi = p.get_span();
|
|
|
|
ret @spanned(lo, hi, ast.stmt_expr(e));
|
|
|
|
}
|
2010-10-04 15:55:12 -07:00
|
|
|
}
|
2010-09-21 16:22:32 -07:00
|
|
|
}
|
|
|
|
p.err("expected statement");
|
|
|
|
fail;
|
|
|
|
}
|
|
|
|
|
2010-11-29 17:11:03 -08:00
|
|
|
fn index_block(vec[@ast.stmt] stmts, option.t[@ast.expr] expr) -> ast.block_ {
|
2010-10-18 18:19:16 -07:00
|
|
|
auto index = new_str_hash[uint]();
|
|
|
|
auto u = 0u;
|
2010-11-29 17:11:03 -08:00
|
|
|
for (@ast.stmt s in stmts) {
|
2010-10-18 18:19:16 -07:00
|
|
|
// 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) {
|
2010-11-24 16:52:49 -08:00
|
|
|
case (ast.item_fn(?i, _, _, _, _)) {
|
2010-10-18 18:19:16 -07:00
|
|
|
index.insert(i, u-1u);
|
|
|
|
}
|
|
|
|
case (ast.item_mod(?i, _, _)) {
|
|
|
|
index.insert(i, u-1u);
|
|
|
|
}
|
2010-11-24 17:36:22 -08:00
|
|
|
case (ast.item_ty(?i, _, _, _, _)) {
|
2010-10-18 18:19:16 -07:00
|
|
|
index.insert(i, u-1u);
|
|
|
|
}
|
2010-12-31 14:18:19 -08:00
|
|
|
case (ast.item_tag(?i, _, _, _)) {
|
|
|
|
index.insert(i, u-1u);
|
|
|
|
}
|
|
|
|
case (ast.item_obj(?i, _, _, _, _)) {
|
|
|
|
index.insert(i, u-1u);
|
|
|
|
}
|
2010-10-18 18:19:16 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-12-01 17:08:46 -08:00
|
|
|
case (_) { /* fall through */ }
|
2010-10-18 18:19:16 -07:00
|
|
|
}
|
|
|
|
}
|
2010-11-29 17:11:03 -08:00
|
|
|
ret rec(stmts=stmts, expr=expr, index=index);
|
|
|
|
}
|
|
|
|
|
2010-12-10 18:08:32 -08:00
|
|
|
fn index_arm(@ast.pat pat) -> hashmap[ast.ident,ast.def_id] {
|
|
|
|
fn do_index_arm(&hashmap[ast.ident,ast.def_id] index, @ast.pat pat) {
|
|
|
|
alt (pat.node) {
|
|
|
|
case (ast.pat_bind(?i, ?def_id, _)) { index.insert(i, def_id); }
|
|
|
|
case (ast.pat_wild(_)) { /* empty */ }
|
2010-12-12 16:30:34 -08:00
|
|
|
case (ast.pat_tag(_, ?pats, _, _)) {
|
2010-12-10 18:08:32 -08:00
|
|
|
for (@ast.pat p in pats) {
|
|
|
|
do_index_arm(index, p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto index = new_str_hash[ast.def_id]();
|
|
|
|
do_index_arm(index, pat);
|
|
|
|
ret index;
|
|
|
|
}
|
|
|
|
|
2010-11-29 17:11:03 -08:00
|
|
|
fn stmt_to_expr(@ast.stmt stmt) -> option.t[@ast.expr] {
|
|
|
|
alt (stmt.node) {
|
|
|
|
case (ast.stmt_expr(?e)) { ret some[@ast.expr](e); }
|
|
|
|
case (_) { /* fall through */ }
|
|
|
|
}
|
|
|
|
ret none[@ast.expr];
|
|
|
|
}
|
|
|
|
|
|
|
|
fn stmt_ends_with_semi(@ast.stmt stmt) -> bool {
|
|
|
|
alt (stmt.node) {
|
2010-12-31 14:33:49 -08:00
|
|
|
case (ast.stmt_decl(?d)) {
|
|
|
|
alt (d.node) {
|
|
|
|
case (ast.decl_local(_)) { ret true; }
|
|
|
|
case (ast.decl_item(_)) { ret false; }
|
|
|
|
}
|
|
|
|
}
|
2010-11-29 17:11:03 -08:00
|
|
|
case (ast.stmt_ret(_)) { ret true; }
|
|
|
|
case (ast.stmt_log(_)) { ret true; }
|
|
|
|
case (ast.stmt_check_expr(_)) { ret true; }
|
|
|
|
case (ast.stmt_expr(?e)) {
|
|
|
|
alt (e.node) {
|
|
|
|
case (ast.expr_vec(_,_)) { ret true; }
|
|
|
|
case (ast.expr_tup(_,_)) { ret true; }
|
|
|
|
case (ast.expr_rec(_,_)) { ret true; }
|
|
|
|
case (ast.expr_call(_,_,_)) { ret true; }
|
|
|
|
case (ast.expr_binary(_,_,_,_)) { ret true; }
|
|
|
|
case (ast.expr_unary(_,_,_)) { ret true; }
|
|
|
|
case (ast.expr_lit(_,_)) { ret true; }
|
|
|
|
case (ast.expr_cast(_,_,_)) { ret true; }
|
|
|
|
case (ast.expr_if(_,_,_,_)) { ret false; }
|
|
|
|
case (ast.expr_while(_,_,_)) { ret false; }
|
|
|
|
case (ast.expr_do_while(_,_,_)) { ret false; }
|
|
|
|
case (ast.expr_alt(_,_,_)) { ret false; }
|
|
|
|
case (ast.expr_block(_,_)) { ret false; }
|
|
|
|
case (ast.expr_assign(_,_,_)) { ret true; }
|
2010-12-08 14:50:47 -08:00
|
|
|
case (ast.expr_assign_op(_,_,_,_))
|
|
|
|
{ ret true; }
|
2010-11-29 17:11:03 -08:00
|
|
|
case (ast.expr_field(_,_,_)) { ret true; }
|
|
|
|
case (ast.expr_index(_,_,_)) { ret true; }
|
|
|
|
case (ast.expr_name(_,_,_)) { ret true; }
|
|
|
|
case (_) { fail; }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case (_) { fail; }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impure fn parse_block(parser p) -> ast.block {
|
|
|
|
auto lo = p.get_span();
|
|
|
|
|
|
|
|
let vec[@ast.stmt] stmts = vec();
|
|
|
|
let option.t[@ast.expr] expr = none[@ast.expr];
|
|
|
|
|
|
|
|
expect(p, token.LBRACE);
|
|
|
|
while (p.peek() != token.RBRACE) {
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.RBRACE) {
|
|
|
|
// empty; fall through to next iteration
|
|
|
|
}
|
|
|
|
case (token.SEMI) {
|
|
|
|
p.bump();
|
|
|
|
// empty
|
|
|
|
}
|
|
|
|
case (_) {
|
|
|
|
auto stmt = parse_stmt(p);
|
|
|
|
alt (stmt_to_expr(stmt)) {
|
|
|
|
case (some[@ast.expr](?e)) {
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.SEMI) {
|
|
|
|
p.bump();
|
|
|
|
stmts += vec(stmt);
|
|
|
|
}
|
|
|
|
case (token.RBRACE) { expr = some(e); }
|
|
|
|
case (?t) {
|
|
|
|
if (stmt_ends_with_semi(stmt)) {
|
|
|
|
p.err("expected ';' or '}' after " +
|
|
|
|
"expression but found " +
|
|
|
|
token.to_str(t));
|
|
|
|
fail;
|
|
|
|
}
|
|
|
|
stmts += vec(stmt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case (none[@ast.expr]) {
|
|
|
|
// Not an expression statement.
|
|
|
|
stmts += vec(stmt);
|
|
|
|
if (stmt_ends_with_semi(stmt)) {
|
|
|
|
expect(p, token.SEMI);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
p.bump();
|
|
|
|
auto hi = p.get_span();
|
|
|
|
|
|
|
|
auto bloc = index_block(stmts, expr);
|
|
|
|
ret spanned[ast.block_](lo, hi, bloc);
|
2010-09-21 16:22:32 -07:00
|
|
|
}
|
|
|
|
|
2010-11-24 18:01:20 -08:00
|
|
|
impure fn parse_ty_param(parser p) -> ast.ty_param {
|
|
|
|
auto ident = parse_ident(p);
|
|
|
|
ret rec(ident=ident, id=p.next_def_id());
|
|
|
|
}
|
|
|
|
|
2010-11-24 17:15:54 -08:00
|
|
|
impure fn parse_ty_params(parser p) -> vec[ast.ty_param] {
|
2010-11-24 16:52:49 -08:00
|
|
|
let vec[ast.ty_param] ty_params = vec();
|
|
|
|
if (p.peek() == token.LBRACKET) {
|
2010-11-24 18:01:20 -08:00
|
|
|
auto f = parse_ty_param; // FIXME: pass as lval directly
|
2010-11-24 16:52:49 -08:00
|
|
|
ty_params = parse_seq[ast.ty_param](token.LBRACKET, token.RBRACKET,
|
2010-11-24 17:15:54 -08:00
|
|
|
some(token.COMMA), f, p).node;
|
2010-11-24 16:52:49 -08:00
|
|
|
}
|
2010-11-24 17:15:54 -08:00
|
|
|
ret ty_params;
|
|
|
|
}
|
|
|
|
|
2010-12-14 15:32:13 -08:00
|
|
|
impure fn parse_fn(parser p, ast.effect eff) -> ast._fn {
|
2010-10-18 16:15:25 -07:00
|
|
|
auto pf = parse_arg;
|
|
|
|
let util.common.spanned[vec[ast.arg]] inputs =
|
|
|
|
// FIXME: passing parse_arg as an lval doesn't work at the
|
2010-09-21 16:22:32 -07:00
|
|
|
// moment.
|
2010-10-18 16:15:25 -07:00
|
|
|
parse_seq[ast.arg]
|
2010-09-21 16:22:32 -07:00
|
|
|
(token.LPAREN,
|
|
|
|
token.RPAREN,
|
|
|
|
some(token.COMMA),
|
|
|
|
pf, p);
|
|
|
|
|
2010-10-18 18:19:16 -07:00
|
|
|
let @ast.ty output;
|
2010-09-21 16:22:32 -07:00
|
|
|
if (p.peek() == token.RARROW) {
|
|
|
|
p.bump();
|
2010-10-18 18:19:16 -07:00
|
|
|
output = parse_ty(p);
|
2010-09-21 16:22:32 -07:00
|
|
|
} else {
|
2010-12-14 15:32:13 -08:00
|
|
|
output = @spanned(inputs.span, inputs.span, ast.ty_nil);
|
2010-09-21 16:22:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
auto body = parse_block(p);
|
|
|
|
|
2010-12-14 15:32:13 -08:00
|
|
|
ret rec(effect = eff,
|
|
|
|
inputs = inputs.node,
|
|
|
|
output = output,
|
|
|
|
body = body);
|
|
|
|
}
|
2010-09-21 16:22:32 -07:00
|
|
|
|
2010-12-14 15:32:13 -08:00
|
|
|
impure fn parse_item_fn(parser p, ast.effect eff) -> @ast.item {
|
|
|
|
auto lo = p.get_span();
|
|
|
|
expect(p, token.FN);
|
|
|
|
auto id = parse_ident(p);
|
|
|
|
auto ty_params = parse_ty_params(p);
|
|
|
|
auto f = parse_fn(p, eff);
|
2010-11-24 16:52:49 -08:00
|
|
|
auto item = ast.item_fn(id, f, ty_params, p.next_def_id(), ast.ann_none);
|
2010-12-14 15:32:13 -08:00
|
|
|
ret @spanned(lo, f.body.span, item);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impure fn parse_obj_field(parser p) -> ast.obj_field {
|
|
|
|
auto ty = parse_ty(p);
|
|
|
|
auto ident = parse_ident(p);
|
2010-12-16 18:34:04 -08:00
|
|
|
ret rec(ty=ty, ident=ident, id=p.next_def_id(), ann=ast.ann_none);
|
2010-12-14 15:32:13 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impure fn parse_method(parser p) -> @ast.method {
|
|
|
|
auto lo = p.get_span();
|
|
|
|
auto eff = parse_effect(p);
|
|
|
|
expect(p, token.FN);
|
|
|
|
auto ident = parse_ident(p);
|
|
|
|
auto f = parse_fn(p, eff);
|
2010-12-16 18:34:04 -08:00
|
|
|
auto meth = rec(ident=ident, meth=f,
|
|
|
|
id=p.next_def_id(), ann=ast.ann_none);
|
2010-12-14 15:32:13 -08:00
|
|
|
ret @spanned(lo, f.body.span, meth);
|
|
|
|
}
|
|
|
|
|
|
|
|
impure fn parse_item_obj(parser p, ast.layer lyr) -> @ast.item {
|
|
|
|
auto lo = p.get_span();
|
|
|
|
expect(p, token.OBJ);
|
|
|
|
auto ident = parse_ident(p);
|
|
|
|
auto ty_params = parse_ty_params(p);
|
|
|
|
auto pf = parse_obj_field;
|
|
|
|
let util.common.spanned[vec[ast.obj_field]] fields =
|
|
|
|
parse_seq[ast.obj_field]
|
|
|
|
(token.LPAREN,
|
|
|
|
token.RPAREN,
|
|
|
|
some(token.COMMA),
|
|
|
|
pf, p);
|
|
|
|
|
|
|
|
auto pm = parse_method;
|
|
|
|
let util.common.spanned[vec[@ast.method]] meths =
|
|
|
|
parse_seq[@ast.method]
|
|
|
|
(token.LBRACE,
|
|
|
|
token.RBRACE,
|
|
|
|
none[token.token],
|
|
|
|
pm, p);
|
|
|
|
|
|
|
|
let ast._obj ob = rec(fields=fields.node,
|
|
|
|
methods=meths.node);
|
|
|
|
|
|
|
|
auto item = ast.item_obj(ident, ob, ty_params,
|
|
|
|
p.next_def_id(), ast.ann_none);
|
|
|
|
|
|
|
|
ret @spanned(lo, meths.span, item);
|
2010-09-21 16:22:32 -07:00
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_mod_items(parser p, token.token term) -> ast._mod {
|
2010-12-24 17:03:46 -08:00
|
|
|
parse_use_and_imports(p);
|
|
|
|
|
2010-12-01 10:19:20 -08:00
|
|
|
let vec[@ast.item] items = vec();
|
|
|
|
auto index = new_str_hash[ast.mod_index_entry]();
|
2010-10-18 18:19:16 -07:00
|
|
|
let uint u = 0u;
|
2010-11-19 14:59:58 -08:00
|
|
|
while (p.peek() != term) {
|
2010-12-01 10:19:20 -08:00
|
|
|
auto item = parse_item(p);
|
|
|
|
items += vec(item);
|
|
|
|
|
|
|
|
// Index the item.
|
|
|
|
alt (item.node) {
|
2010-12-09 14:37:50 -08:00
|
|
|
case (ast.item_const(?id, _, _, _, _)) {
|
|
|
|
index.insert(id, ast.mie_item(u));
|
|
|
|
}
|
2010-12-01 10:19:20 -08:00
|
|
|
case (ast.item_fn(?id, _, _, _, _)) {
|
|
|
|
index.insert(id, ast.mie_item(u));
|
|
|
|
}
|
|
|
|
case (ast.item_mod(?id, _, _)) {
|
|
|
|
index.insert(id, ast.mie_item(u));
|
|
|
|
}
|
|
|
|
case (ast.item_ty(?id, _, _, _, _)) {
|
|
|
|
index.insert(id, ast.mie_item(u));
|
|
|
|
}
|
|
|
|
case (ast.item_tag(?id, ?variants, _, _)) {
|
|
|
|
index.insert(id, ast.mie_item(u));
|
|
|
|
let uint variant_idx = 0u;
|
|
|
|
for (ast.variant v in variants) {
|
|
|
|
index.insert(v.name, ast.mie_tag_variant(u, variant_idx));
|
|
|
|
variant_idx += 1u;
|
|
|
|
}
|
|
|
|
}
|
2010-12-14 15:32:13 -08:00
|
|
|
case (ast.item_obj(?id, _, _, _, _)) {
|
|
|
|
index.insert(id, ast.mie_item(u));
|
|
|
|
}
|
2010-12-01 10:19:20 -08:00
|
|
|
}
|
|
|
|
|
2010-10-18 18:19:16 -07:00
|
|
|
u += 1u;
|
|
|
|
}
|
|
|
|
ret rec(items=items, index=index);
|
|
|
|
}
|
|
|
|
|
2010-12-09 14:37:50 -08:00
|
|
|
impure fn parse_item_const(parser p) -> @ast.item {
|
|
|
|
auto lo = p.get_span();
|
|
|
|
expect(p, token.CONST);
|
|
|
|
auto ty = parse_ty(p);
|
|
|
|
auto id = parse_ident(p);
|
|
|
|
expect(p, token.EQ);
|
|
|
|
auto e = parse_expr(p);
|
|
|
|
auto hi = p.get_span();
|
|
|
|
expect(p, token.SEMI);
|
|
|
|
auto item = ast.item_const(id, ty, e, p.next_def_id(), ast.ann_none);
|
|
|
|
ret @spanned(lo, hi, item);
|
|
|
|
}
|
|
|
|
|
2010-12-01 10:19:20 -08:00
|
|
|
impure fn parse_item_mod(parser p) -> @ast.item {
|
2010-10-05 18:21:44 -07:00
|
|
|
auto lo = p.get_span();
|
2010-09-23 13:15:51 -07:00
|
|
|
expect(p, token.MOD);
|
|
|
|
auto id = parse_ident(p);
|
|
|
|
expect(p, token.LBRACE);
|
2010-10-18 18:19:16 -07:00
|
|
|
auto m = parse_mod_items(p, token.RBRACE);
|
2010-10-05 18:21:44 -07:00
|
|
|
auto hi = p.get_span();
|
2010-09-23 13:15:51 -07:00
|
|
|
expect(p, token.RBRACE);
|
2010-10-18 18:19:16 -07:00
|
|
|
auto item = ast.item_mod(id, m, p.next_def_id());
|
2010-12-01 10:19:20 -08:00
|
|
|
ret @spanned(lo, hi, item);
|
2010-09-23 13:15:51 -07:00
|
|
|
}
|
|
|
|
|
2010-12-01 10:19:20 -08:00
|
|
|
impure fn parse_item_type(parser p) -> @ast.item {
|
2010-11-19 16:34:47 -08:00
|
|
|
auto lo = p.get_span();
|
|
|
|
expect(p, token.TYPE);
|
|
|
|
auto id = parse_ident(p);
|
2010-11-24 17:36:22 -08:00
|
|
|
auto tps = parse_ty_params(p);
|
|
|
|
|
2010-11-19 16:34:47 -08:00
|
|
|
expect(p, token.EQ);
|
|
|
|
auto ty = parse_ty(p);
|
|
|
|
auto hi = p.get_span();
|
|
|
|
expect(p, token.SEMI);
|
2010-11-24 17:36:22 -08:00
|
|
|
auto item = ast.item_ty(id, ty, tps, p.next_def_id(), ast.ann_none);
|
2010-12-01 10:19:20 -08:00
|
|
|
ret @spanned(lo, hi, item);
|
2010-11-19 16:34:47 -08:00
|
|
|
}
|
|
|
|
|
2010-12-01 10:19:20 -08:00
|
|
|
impure fn parse_item_tag(parser p) -> @ast.item {
|
2010-11-24 11:36:35 -08:00
|
|
|
auto lo = p.get_span();
|
|
|
|
expect(p, token.TAG);
|
|
|
|
auto id = parse_ident(p);
|
2010-11-24 17:15:54 -08:00
|
|
|
auto ty_params = parse_ty_params(p);
|
2010-11-24 11:36:35 -08:00
|
|
|
|
|
|
|
let vec[ast.variant] variants = vec();
|
|
|
|
expect(p, token.LBRACE);
|
|
|
|
while (p.peek() != token.RBRACE) {
|
|
|
|
auto tok = p.peek();
|
|
|
|
alt (tok) {
|
|
|
|
case (token.IDENT(?name)) {
|
|
|
|
p.bump();
|
|
|
|
|
2010-12-03 18:12:51 -08:00
|
|
|
let vec[ast.variant_arg] args = vec();
|
2010-11-24 11:36:35 -08:00
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.LPAREN) {
|
|
|
|
auto f = parse_ty;
|
2010-12-03 18:12:51 -08:00
|
|
|
auto arg_tys = parse_seq[@ast.ty](token.LPAREN,
|
|
|
|
token.RPAREN,
|
|
|
|
some(token.COMMA),
|
|
|
|
f, p);
|
|
|
|
for (@ast.ty ty in arg_tys.node) {
|
|
|
|
args += vec(rec(ty=ty, id=p.next_def_id()));
|
|
|
|
}
|
2010-11-24 11:36:35 -08:00
|
|
|
}
|
2010-12-03 18:12:51 -08:00
|
|
|
case (_) { /* empty */ }
|
2010-11-24 11:36:35 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
expect(p, token.SEMI);
|
|
|
|
|
2010-11-30 12:32:20 -08:00
|
|
|
auto id = p.next_def_id();
|
2010-12-01 15:27:38 -08:00
|
|
|
variants += vec(rec(name=name, args=args, id=id,
|
|
|
|
ann=ast.ann_none));
|
2010-11-24 11:36:35 -08:00
|
|
|
}
|
|
|
|
case (token.RBRACE) { /* empty */ }
|
|
|
|
case (_) {
|
|
|
|
p.err("expected name of variant or '}' but found " +
|
|
|
|
token.to_str(tok));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
p.bump();
|
|
|
|
|
|
|
|
auto hi = p.get_span();
|
2010-11-24 17:15:54 -08:00
|
|
|
auto item = ast.item_tag(id, variants, ty_params, p.next_def_id());
|
2010-12-01 10:19:20 -08:00
|
|
|
ret @spanned(lo, hi, item);
|
2010-11-24 11:36:35 -08:00
|
|
|
}
|
|
|
|
|
2010-12-03 18:03:28 -08:00
|
|
|
impure fn parse_layer(parser p) -> ast.layer {
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.STATE) {
|
|
|
|
p.bump();
|
|
|
|
ret ast.layer_state;
|
|
|
|
}
|
|
|
|
case (token.GC) {
|
|
|
|
p.bump();
|
|
|
|
ret ast.layer_gc;
|
|
|
|
}
|
|
|
|
case (_) {
|
|
|
|
ret ast.layer_value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impure fn parse_effect(parser p) -> ast.effect {
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.IMPURE) {
|
|
|
|
p.bump();
|
|
|
|
ret ast.eff_impure;
|
|
|
|
}
|
|
|
|
case (token.UNSAFE) {
|
|
|
|
p.bump();
|
|
|
|
ret ast.eff_unsafe;
|
|
|
|
}
|
|
|
|
case (_) {
|
|
|
|
ret ast.eff_pure;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fail;
|
|
|
|
}
|
|
|
|
|
2010-12-31 14:33:49 -08:00
|
|
|
fn peeking_at_item(parser p) -> bool {
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.STATE) { ret true; }
|
|
|
|
case (token.GC) { ret true; }
|
|
|
|
case (token.IMPURE) { ret true; }
|
|
|
|
case (token.UNSAFE) { ret true; }
|
|
|
|
case (token.CONST) { ret true; }
|
|
|
|
case (token.FN) { ret true; }
|
|
|
|
case (token.MOD) { ret true; }
|
|
|
|
case (token.TYPE) { ret true; }
|
|
|
|
case (token.TAG) { ret true; }
|
|
|
|
case (token.OBJ) { ret true; }
|
|
|
|
case (_) { ret false; }
|
|
|
|
}
|
|
|
|
ret false;
|
|
|
|
}
|
|
|
|
|
2010-12-01 10:19:20 -08:00
|
|
|
impure fn parse_item(parser p) -> @ast.item {
|
2010-12-03 18:03:28 -08:00
|
|
|
let ast.effect eff = parse_effect(p);
|
|
|
|
let ast.layer lyr = parse_layer(p);
|
|
|
|
|
2010-09-21 16:22:32 -07:00
|
|
|
alt (p.peek()) {
|
2010-12-09 14:37:50 -08:00
|
|
|
case (token.CONST) {
|
|
|
|
check (eff == ast.eff_pure);
|
|
|
|
check (lyr == ast.layer_value);
|
|
|
|
ret parse_item_const(p);
|
|
|
|
}
|
|
|
|
|
2010-09-21 16:22:32 -07:00
|
|
|
case (token.FN) {
|
2010-12-03 18:03:28 -08:00
|
|
|
check (lyr == ast.layer_value);
|
|
|
|
ret parse_item_fn(p, eff);
|
2010-09-21 16:22:32 -07:00
|
|
|
}
|
2010-09-23 13:15:51 -07:00
|
|
|
case (token.MOD) {
|
2010-12-03 18:03:28 -08:00
|
|
|
check (eff == ast.eff_pure);
|
|
|
|
check (lyr == ast.layer_value);
|
2010-11-19 16:34:47 -08:00
|
|
|
ret parse_item_mod(p);
|
|
|
|
}
|
|
|
|
case (token.TYPE) {
|
2010-12-03 18:03:28 -08:00
|
|
|
check (eff == ast.eff_pure);
|
2010-11-19 16:34:47 -08:00
|
|
|
ret parse_item_type(p);
|
2010-09-23 13:15:51 -07:00
|
|
|
}
|
2010-11-24 11:36:35 -08:00
|
|
|
case (token.TAG) {
|
2010-12-03 18:03:28 -08:00
|
|
|
check (eff == ast.eff_pure);
|
2010-11-24 11:36:35 -08:00
|
|
|
ret parse_item_tag(p);
|
|
|
|
}
|
2010-12-14 15:32:13 -08:00
|
|
|
case (token.OBJ) {
|
|
|
|
check (eff == ast.eff_pure);
|
|
|
|
ret parse_item_obj(p, lyr);
|
|
|
|
}
|
2010-11-22 11:43:25 -08:00
|
|
|
case (?t) {
|
|
|
|
p.err("expected item but found " + token.to_str(t));
|
|
|
|
}
|
2010-09-21 16:22:32 -07:00
|
|
|
}
|
|
|
|
fail;
|
|
|
|
}
|
|
|
|
|
2010-12-30 11:21:37 -05:00
|
|
|
impure fn parse_meta_item(parser p) -> @ast.meta_item {
|
|
|
|
auto lo = p.get_span();
|
|
|
|
auto hi = lo;
|
2010-12-24 17:03:46 -08:00
|
|
|
auto ident = parse_ident(p);
|
|
|
|
expect(p, token.EQ);
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.LIT_STR(?s)) {
|
|
|
|
p.bump();
|
2010-12-30 11:21:37 -05:00
|
|
|
ret @spanned(lo, hi, rec(name = ident, value = s));
|
2010-12-24 17:03:46 -08:00
|
|
|
}
|
|
|
|
case (_) {
|
|
|
|
p.err("Metadata items must be string literals");
|
|
|
|
}
|
|
|
|
}
|
2010-12-30 11:21:37 -05:00
|
|
|
fail;
|
2010-12-24 17:03:46 -08:00
|
|
|
}
|
|
|
|
|
2010-12-30 11:21:37 -05:00
|
|
|
impure fn parse_meta(parser p) -> vec[@ast.meta_item] {
|
2010-12-24 17:03:46 -08:00
|
|
|
auto pf = parse_meta_item;
|
2010-12-30 11:21:37 -05:00
|
|
|
ret parse_seq[@ast.meta_item](token.LPAREN, token.RPAREN,
|
|
|
|
some(token.COMMA), pf, p).node;
|
2010-12-24 17:03:46 -08:00
|
|
|
}
|
|
|
|
|
2010-12-30 11:21:37 -05:00
|
|
|
impure fn parse_optional_meta(parser p) -> vec[@ast.meta_item] {
|
|
|
|
auto lo = p.get_span();
|
|
|
|
auto hi = lo;
|
2010-12-24 17:03:46 -08:00
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.LPAREN) {
|
|
|
|
ret parse_meta(p);
|
|
|
|
}
|
|
|
|
case (_) {
|
2010-12-30 11:21:37 -05:00
|
|
|
let vec[@ast.meta_item] v = vec();
|
|
|
|
ret v;
|
2010-12-24 17:03:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-30 11:21:37 -05:00
|
|
|
impure fn parse_use(parser p) -> @ast.use_node {
|
|
|
|
auto lo = p.get_span();
|
|
|
|
auto hi = lo;
|
|
|
|
expect(p, token.USE);
|
|
|
|
auto ident = parse_ident(p);
|
|
|
|
auto metadata = parse_optional_meta(p);
|
|
|
|
expect(p, token.SEMI);
|
|
|
|
ret @spanned(lo, hi, rec(name = ident, metadata = metadata));
|
|
|
|
}
|
|
|
|
|
|
|
|
impure fn parse_rest_import_name(parser p, ast.ident id) -> @ast.import_node {
|
|
|
|
auto lo = p.get_span();
|
|
|
|
auto hi = lo;
|
|
|
|
let vec[ast.ident] identifiers = vec();
|
|
|
|
identifiers += id;
|
2010-12-24 23:25:02 -05:00
|
|
|
while (p.peek() != token.SEMI) {
|
|
|
|
expect(p, token.DOT);
|
2010-12-30 11:21:37 -05:00
|
|
|
auto i = parse_ident(p);
|
|
|
|
identifiers += i;
|
2010-12-24 23:25:02 -05:00
|
|
|
}
|
2010-12-30 11:21:37 -05:00
|
|
|
p.bump();
|
|
|
|
ret @spanned(lo, hi, rec(identifiers = identifiers));
|
2010-12-24 23:25:02 -05:00
|
|
|
}
|
|
|
|
|
2010-12-30 11:21:37 -05:00
|
|
|
impure fn parse_full_import_name(parser p) -> @ast.import_node {
|
2010-12-24 23:25:02 -05:00
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.IDENT(?ident)) {
|
|
|
|
p.bump();
|
2010-12-30 11:21:37 -05:00
|
|
|
ret parse_rest_import_name(p, ident);
|
2010-12-24 23:25:02 -05:00
|
|
|
}
|
|
|
|
case (_) {
|
|
|
|
p.err("expecting an identifier");
|
|
|
|
}
|
|
|
|
}
|
2010-12-30 11:21:37 -05:00
|
|
|
fail;
|
2010-12-24 23:25:02 -05:00
|
|
|
}
|
|
|
|
|
2010-12-30 11:21:37 -05:00
|
|
|
impure fn parse_import(parser p) -> @ast.import_node {
|
|
|
|
expect(p, token.IMPORT);
|
2010-12-24 23:25:02 -05:00
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.IDENT(?ident)) {
|
|
|
|
p.bump();
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.EQ) {
|
|
|
|
p.bump();
|
2010-12-30 11:21:37 -05:00
|
|
|
ret parse_full_import_name(p);
|
2010-12-24 23:25:02 -05:00
|
|
|
}
|
|
|
|
case (_) {
|
2010-12-30 11:21:37 -05:00
|
|
|
ret parse_rest_import_name(p, ident);
|
2010-12-24 23:25:02 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case (_) {
|
|
|
|
p.err("expecting an identifier");
|
|
|
|
}
|
|
|
|
}
|
2010-12-30 11:21:37 -05:00
|
|
|
fail;
|
2010-12-24 23:25:02 -05:00
|
|
|
}
|
|
|
|
|
2010-12-30 11:21:37 -05:00
|
|
|
impure fn parse_use_and_imports(parser p) -> vec[ast.use_or_import] {
|
|
|
|
let vec[ast.use_or_import] items = vec();
|
2010-12-24 17:03:46 -08:00
|
|
|
while (true) {
|
|
|
|
alt (p.peek()) {
|
|
|
|
case (token.USE) {
|
2010-12-30 11:21:37 -05:00
|
|
|
items += vec(ast.use_or_import_use(parse_use(p)));
|
2010-12-24 17:03:46 -08:00
|
|
|
}
|
2010-12-24 23:25:02 -05:00
|
|
|
case (token.IMPORT) {
|
2010-12-30 11:21:37 -05:00
|
|
|
items += vec(ast.use_or_import_import(parse_import(p)));
|
2010-12-24 23:25:02 -05:00
|
|
|
}
|
2010-12-24 17:03:46 -08:00
|
|
|
case (_) {
|
2010-12-30 11:21:37 -05:00
|
|
|
ret items;
|
2010-12-24 17:03:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-02 11:11:58 -07:00
|
|
|
impure fn parse_crate(parser p) -> @ast.crate {
|
2010-10-05 18:21:44 -07:00
|
|
|
auto lo = p.get_span();
|
|
|
|
auto hi = lo;
|
2010-10-18 18:19:16 -07:00
|
|
|
auto m = parse_mod_items(p, token.EOF);
|
2010-10-06 18:36:28 -07:00
|
|
|
ret @spanned(lo, hi, rec(module=m));
|
2010-09-21 16:22:32 -07:00
|
|
|
}
|
|
|
|
|
2010-08-12 10:29:23 -07:00
|
|
|
//
|
|
|
|
// Local Variables:
|
|
|
|
// mode: rust
|
|
|
|
// fill-column: 78;
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
// c-basic-offset: 4
|
|
|
|
// buffer-file-coding-system: utf-8-unix
|
|
|
|
// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
|
|
|
// End:
|
|
|
|
//
|