parser.rs 26.1 KB
Newer Older
1
import std._io;
2 3 4
import std.option;
import std.option.some;
import std.option.none;
5
import std.map.hashmap;
6

7 8
import driver.session;
import util.common;
9
import util.common.append;
10
import util.common.span;
11
import util.common.new_str_hash;
12 13 14

state type parser =
    state obj {
15
          fn peek() -> token.token;
16 17
          impure fn bump();
          impure fn err(str s);
18 19
          fn get_session() -> session.session;
          fn get_span() -> common.span;
20
          fn next_def_id() -> ast.def_id;
21 22
    };

23
impure fn new_parser(session.session sess,
24
                 ast.crate_num crate, str path) -> parser {
25 26 27 28
    state obj stdio_parser(session.session sess,
                           mutable token.token tok,
                           mutable common.pos lo,
                           mutable common.pos hi,
29 30
                           mutable ast.def_num def,
                           ast.crate_num crate,
31
                           lexer.reader rdr)
32
        {
33
            fn peek() -> token.token {
34
                // log token.to_str(tok);
35 36
                ret tok;
            }
37

38
            impure fn bump() {
39
                tok = lexer.next_token(rdr);
40 41 42 43
                lo = rdr.get_mark_pos();
                hi = rdr.get_curr_pos();
            }

44
            impure fn err(str m) {
45 46 47 48 49 50 51 52 53 54 55 56
                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);
57
            }
58 59 60 61 62

            fn next_def_id() -> ast.def_id {
                def += 1;
                ret tup(crate, def);
            }
63
        }
64 65
    auto srdr = _io.new_stdio_reader(path);
    auto rdr = lexer.new_reader(srdr, path);
66
    auto npos = rdr.get_curr_pos();
67 68
    ret stdio_parser(sess, lexer.next_token(rdr),
                     npos, npos, 0, crate, rdr);
69 70
}

71
impure fn expect(parser p, token.token t) {
72
    if (p.peek() == t) {
73 74 75 76 77
        p.bump();
    } else {
        let str s = "expecting ";
        s += token.to_str(t);
        s += ", found ";
78
        s += token.to_str(p.peek());
79 80 81 82
        p.err(s);
    }
}

83 84 85 86 87 88
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));
}

89
impure fn parse_ident(parser p) -> ast.ident {
90
    alt (p.peek()) {
91
        case (token.IDENT(?i)) { p.bump(); ret i; }
92 93 94 95 96 97 98
        case (_) {
            p.err("expecting ident");
            fail;
        }
    }
}

99
impure fn parse_possibly_mutable_ty(parser p) -> tup(bool, @ast.ty) {
P
Patrick Walton 已提交
100 101 102 103 104 105 106 107 108 109 110
    auto mut;
    if (p.peek() == token.MUTABLE) {
        p.bump();
        mut = true;
    } else {
        mut = false;
    }

    ret tup(mut, parse_ty(p));
}

111
impure fn parse_ty(parser p) -> @ast.ty {
112 113
    auto lo = p.get_span();
    let ast.ty_ t;
114
    alt (p.peek()) {
115 116 117 118 119
        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); }
P
Patrick Walton 已提交
120

P
Patrick Walton 已提交
121 122
        case (token.AT) { p.bump(); t = ast.ty_box(parse_ty(p)); }

P
Patrick Walton 已提交
123 124 125 126 127 128 129
        case (token.VEC) {
            p.bump();
            expect(p, token.LBRACKET);
            t = ast.ty_vec(parse_ty(p));
            expect(p, token.RBRACKET);
        }

P
Patrick Walton 已提交
130 131 132 133 134 135 136 137
        case (token.TUP) {
            p.bump();
            auto f = parse_possibly_mutable_ty; // FIXME: trans_const_lval bug
            auto elems = parse_seq[tup(bool, @ast.ty)](token.LPAREN,
                token.RPAREN, some(token.COMMA), f, p);
            t = ast.ty_tup(elems.node);
        }

138 139 140 141 142
        case (_) {
            p.err("expecting type");
            t = ast.ty_nil;
            fail;
        }
143
    }
144
    ret @spanned(lo, lo, t);
145 146
}

147
impure fn parse_arg(parser p) -> ast.arg {
148 149 150 151 152
    let ast.mode m = ast.val;
    if (p.peek() == token.BINOP(token.AND)) {
        m = ast.alias;
        p.bump();
    }
153
    let @ast.ty t = parse_ty(p);
154 155
    let ast.ident i = parse_ident(p);
    ret rec(mode=m, ty=t, ident=i, id=p.next_def_id());
156 157
}

158
impure fn parse_seq[T](token.token bra,
159
                      token.token ket,
160
                      option.t[token.token] sep,
161
                      (impure fn(parser) -> T) f,
162
                      parser p) -> util.common.spanned[vec[T]] {
163
    let bool first = true;
164
    auto lo = p.get_span();
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
    expect(p, bra);
    let vec[T] v = vec();
    while (p.peek() != ket) {
        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);
    }
183
    auto hi = p.get_span();
184
    expect(p, ket);
185
    ret spanned(lo, hi, v);
186 187
}

188
impure fn parse_lit(parser p) -> option.t[ast.lit] {
189 190
    auto lo = p.get_span();
    let ast.lit_ lit;
191
    alt (p.peek()) {
192 193
        case (token.LIT_INT(?i)) {
            p.bump();
194
            lit = ast.lit_int(i);
195 196
        }
        case (token.LIT_UINT(?u)) {
197
            p.bump();
198
            lit = ast.lit_uint(u);
199 200 201
        }
        case (token.LIT_CHAR(?c)) {
            p.bump();
202
            lit = ast.lit_char(c);
203 204 205
        }
        case (token.LIT_BOOL(?b)) {
            p.bump();
206
            lit = ast.lit_bool(b);
207
        }
208 209
        case (token.LIT_STR(?s)) {
            p.bump();
210 211 212
            lit = ast.lit_str(s);
        }
        case (_) {
213 214
            lit = ast.lit_nil;  // FIXME: typestate bug requires this
            ret none[ast.lit];
215
        }
216
    }
217
    ret some(spanned(lo, lo, lit));
218
}
219

220
impure fn parse_name(parser p, ast.ident id) -> ast.name {
221 222 223

    auto lo = p.get_span();

224
    p.bump();
225

226 227
    let vec[@ast.ty] v = vec();
    let util.common.spanned[vec[@ast.ty]] tys = rec(node=v, span=lo);
228 229 230 231

    alt (p.peek()) {
        case (token.LBRACKET) {
            auto pf = parse_ty;
232 233 234 235
            tys = parse_seq[@ast.ty](token.LBRACKET,
                                     token.RBRACKET,
                                     some(token.COMMA),
                                     pf, p);
236 237 238 239
        }
        case (_) {
        }
    }
240
    ret spanned(lo, tys.span, rec(ident=id, types=tys.node));
241
}
242

243
impure fn parse_possibly_mutable_expr(parser p) -> tup(bool, @ast.expr) {
244 245 246 247 248 249 250 251 252 253 254
    auto mut;
    if (p.peek() == token.MUTABLE) {
        p.bump();
        mut = true;
    } else {
        mut = false;
    }

    ret tup(mut, parse_expr(p));
}

255
impure fn parse_bottom_expr(parser p) -> @ast.expr {
256 257 258 259 260 261

    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.
P
Patrick Walton 已提交
262
    auto lit = @spanned(lo, lo, ast.lit_nil);
263
    let ast.expr_ ex = ast.expr_lit(lit, ast.ann_none);
264

265
    alt (p.peek()) {
266 267 268 269

        case (token.IDENT(?i)) {
            auto n = parse_name(p, i);
            hi = n.span;
270
            ex = ast.expr_name(n, none[ast.def], ast.ann_none);
G
Graydon Hoare 已提交
271 272 273 274 275 276 277 278 279
            alt (p.peek()) {
                case (token.LPAREN) {
                    // Call expr.
                    auto pf = parse_expr;
                    auto es = parse_seq[@ast.expr](token.LPAREN,
                                                   token.RPAREN,
                                                   some(token.COMMA),
                                                   pf, p);
                    ex = ast.expr_call(@spanned(lo, hi, ex),
280
                                       es.node, ast.ann_none);
G
Graydon Hoare 已提交
281 282 283
                    hi = es.span;
                }
            }
284 285
        }

286 287 288
        case (token.LPAREN) {
            p.bump();
            auto e = parse_expr(p);
289
            hi = p.get_span();
290
            expect(p, token.RPAREN);
291
            ret @spanned(lo, hi, e.node);
292 293
        }

G
Graydon Hoare 已提交
294 295
        case (token.TUP) {
            p.bump();
296 297 298 299 300
            auto pf = parse_possibly_mutable_expr;
            auto es = parse_seq[tup(bool, @ast.expr)](token.LPAREN,
                                                      token.RPAREN,
                                                      some(token.COMMA),
                                                      pf, p);
301
            hi = es.span;
302
            ex = ast.expr_tup(es.node, ast.ann_none);
G
Graydon Hoare 已提交
303 304 305 306 307 308 309 310 311
        }

        case (token.VEC) {
            p.bump();
            auto pf = parse_expr;
            auto es = parse_seq[@ast.expr](token.LPAREN,
                                           token.RPAREN,
                                           some(token.COMMA),
                                           pf, p);
312
            hi = es.span;
313
            ex = ast.expr_vec(es.node, ast.ann_none);
G
Graydon Hoare 已提交
314 315 316 317
        }

        case (token.REC) {
            p.bump();
318
            impure fn parse_entry(parser p) ->
G
Graydon Hoare 已提交
319 320 321 322 323 324 325 326 327 328 329 330
                tup(ast.ident, @ast.expr) {
                auto i = parse_ident(p);
                expect(p, token.EQ);
                auto e = parse_expr(p);
                ret tup(i, e);
            }
            auto pf = parse_entry;
            auto es =
                parse_seq[tup(ast.ident, @ast.expr)](token.LPAREN,
                                                     token.RPAREN,
                                                     some(token.COMMA),
                                                     pf, p);
331
            hi = es.span;
332
            ex = ast.expr_rec(es.node, ast.ann_none);
G
Graydon Hoare 已提交
333 334
        }

335
        case (_) {
336 337 338
            alt (parse_lit(p)) {
                case (some[ast.lit](?lit)) {
                    hi = lit.span;
339
                    ex = ast.expr_lit(@lit, ast.ann_none);
340
                }
341 342
                case (none[ast.lit]) {
                    p.err("expecting expression");
343 344
                }
            }
345 346
        }
    }
347

348
    ret @spanned(lo, hi, ex);
349 350
}

351
impure fn parse_path_expr(parser p) -> @ast.expr {
352
    auto lo = p.get_span();
G
Graydon Hoare 已提交
353
    auto e = parse_bottom_expr(p);
354
    auto hi = e.span;
G
Graydon Hoare 已提交
355 356 357 358 359 360 361
    while (true) {
        alt (p.peek()) {
            case (token.DOT) {
                p.bump();
                alt (p.peek()) {

                    case (token.IDENT(?i)) {
362
                        hi = p.get_span();
G
Graydon Hoare 已提交
363
                        p.bump();
364
                        auto e_ = ast.expr_field(e, i, ast.ann_none);
P
Patrick Walton 已提交
365
                        e = @spanned(lo, hi, e_);
G
Graydon Hoare 已提交
366 367 368 369
                    }

                    case (token.LPAREN) {
                        auto ix = parse_bottom_expr(p);
370
                        hi = ix.span;
371
                        auto e_ = ast.expr_index(e, ix, ast.ann_none);
P
Patrick Walton 已提交
372
                        e = @spanned(lo, hi, e_);
G
Graydon Hoare 已提交
373 374 375 376 377 378 379 380 381 382
                    }
                }
            }
            case (_) {
                ret e;
            }
        }
    }
    ret e;
}
383

384
impure fn parse_prefix_expr(parser p) -> @ast.expr {
385 386 387 388 389 390

    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.
P
Patrick Walton 已提交
391
    auto lit = @spanned(lo, lo, ast.lit_nil);
392
    let ast.expr_ ex = ast.expr_lit(lit, ast.ann_none);
393

394 395 396
    alt (p.peek()) {

        case (token.NOT) {
397
            p.bump();
G
Graydon Hoare 已提交
398
            auto e = parse_prefix_expr(p);
399
            hi = e.span;
400
            ex = ast.expr_unary(ast.not, e, ast.ann_none);
401 402 403
        }

        case (token.TILDE) {
404
            p.bump();
G
Graydon Hoare 已提交
405
            auto e = parse_prefix_expr(p);
406
            hi = e.span;
407
            ex = ast.expr_unary(ast.bitnot, e, ast.ann_none);
408 409
        }

G
Graydon Hoare 已提交
410 411 412
        case (token.BINOP(?b)) {
            alt (b) {
                case (token.MINUS) {
413
                    p.bump();
G
Graydon Hoare 已提交
414
                    auto e = parse_prefix_expr(p);
415
                    hi = e.span;
416
                    ex = ast.expr_unary(ast.neg, e, ast.ann_none);
G
Graydon Hoare 已提交
417 418 419
                }

                case (token.STAR) {
420
                    p.bump();
G
Graydon Hoare 已提交
421
                    auto e = parse_prefix_expr(p);
422
                    hi = e.span;
423
                    ex = ast.expr_unary(ast.deref, e, ast.ann_none);
G
Graydon Hoare 已提交
424 425 426 427 428 429 430 431 432 433 434
                }

                case (_) {
                    ret parse_path_expr(p);
                }
            }
        }

        case (token.AT) {
            p.bump();
            auto e = parse_prefix_expr(p);
435
            hi = e.span;
436
            ex = ast.expr_unary(ast.box, e, ast.ann_none);
G
Graydon Hoare 已提交
437 438
        }

439
        case (_) {
G
Graydon Hoare 已提交
440 441 442
            ret parse_path_expr(p);
        }
    }
443
    ret @spanned(lo, hi, ex);
G
Graydon Hoare 已提交
444 445
}

446 447
impure fn parse_binops(parser p,
                   (impure fn(parser) -> @ast.expr) sub,
448
                   vec[tup(token.binop, ast.binop)] ops)
G
Graydon Hoare 已提交
449
    -> @ast.expr {
450 451
    auto lo = p.get_span();
    auto hi = lo;
G
Graydon Hoare 已提交
452 453 454 455
    auto e = sub(p);
    auto more = true;
    while (more) {
        more = false;
456 457 458
        for (tup(token.binop, ast.binop) pair in ops) {
            alt (p.peek()) {
                case (token.BINOP(?op)) {
G
Graydon Hoare 已提交
459
                    if (pair._0 == op) {
460
                        p.bump();
461 462
                        auto rhs = sub(p);
                        hi = rhs.span;
P
Patrick Walton 已提交
463
                        auto exp = ast.expr_binary(pair._1, e, rhs,
464
                                                   ast.ann_none);
465
                        e = @spanned(lo, hi, exp);
G
Graydon Hoare 已提交
466 467 468 469 470 471 472 473 474
                        more = true;
                    }
                }
            }
        }
    }
    ret e;
}

475 476
impure fn parse_binary_exprs(parser p,
                            (impure fn(parser) -> @ast.expr) sub,
G
Graydon Hoare 已提交
477 478
                            vec[tup(token.token, ast.binop)] ops)
    -> @ast.expr {
479 480
    auto lo = p.get_span();
    auto hi = lo;
G
Graydon Hoare 已提交
481 482 483 484 485
    auto e = sub(p);
    auto more = true;
    while (more) {
        more = false;
        for (tup(token.token, ast.binop) pair in ops) {
486 487
            if (pair._0 == p.peek()) {
                p.bump();
488 489
                auto rhs = sub(p);
                hi = rhs.span;
490
                auto exp = ast.expr_binary(pair._1, e, rhs, ast.ann_none);
491
                e = @spanned(lo, hi, exp);
G
Graydon Hoare 已提交
492 493
                more = true;
            }
494 495
        }
    }
G
Graydon Hoare 已提交
496 497 498
    ret e;
}

499
impure fn parse_factor_expr(parser p) -> @ast.expr {
G
Graydon Hoare 已提交
500 501 502 503 504 505
    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)));
}

506
impure fn parse_term_expr(parser p) -> @ast.expr {
G
Graydon Hoare 已提交
507 508 509 510 511
    auto sub = parse_factor_expr;
    ret parse_binops(p, sub, vec(tup(token.PLUS, ast.add),
                                 tup(token.MINUS, ast.sub)));
}

512
impure fn parse_shift_expr(parser p) -> @ast.expr {
G
Graydon Hoare 已提交
513 514 515 516 517 518
    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)));
}

519
impure fn parse_bitand_expr(parser p) -> @ast.expr {
G
Graydon Hoare 已提交
520 521 522 523
    auto sub = parse_shift_expr;
    ret parse_binops(p, sub, vec(tup(token.AND, ast.bitand)));
}

524
impure fn parse_bitxor_expr(parser p) -> @ast.expr {
G
Graydon Hoare 已提交
525 526 527 528
    auto sub = parse_bitand_expr;
    ret parse_binops(p, sub, vec(tup(token.CARET, ast.bitxor)));
}

529
impure fn parse_bitor_expr(parser p) -> @ast.expr {
G
Graydon Hoare 已提交
530 531 532 533
    auto sub = parse_bitxor_expr;
    ret parse_binops(p, sub, vec(tup(token.OR, ast.bitor)));
}

534
impure fn parse_cast_expr(parser p) -> @ast.expr {
535
    auto lo = p.get_span();
G
Graydon Hoare 已提交
536
    auto e = parse_bitor_expr(p);
537
    auto hi = e.span;
G
Graydon Hoare 已提交
538 539 540 541 542
    while (true) {
        alt (p.peek()) {
            case (token.AS) {
                p.bump();
                auto t = parse_ty(p);
543
                hi = t.span;
544
                e = @spanned(lo, hi, ast.expr_cast(e, t, ast.ann_none));
G
Graydon Hoare 已提交
545 546 547 548 549 550 551 552 553 554
            }

            case (_) {
                ret e;
            }
        }
    }
    ret e;
}

555
impure fn parse_relational_expr(parser p) -> @ast.expr {
G
Graydon Hoare 已提交
556 557 558 559 560 561 562 563
    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)));
}


564
impure fn parse_equality_expr(parser p) -> @ast.expr {
G
Graydon Hoare 已提交
565 566 567 568 569
    auto sub = parse_relational_expr;
    ret parse_binary_exprs(p, sub, vec(tup(token.EQEQ, ast.eq),
                                       tup(token.NE, ast.ne)));
}

570
impure fn parse_and_expr(parser p) -> @ast.expr {
G
Graydon Hoare 已提交
571 572 573 574
    auto sub = parse_equality_expr;
    ret parse_binary_exprs(p, sub, vec(tup(token.ANDAND, ast.and)));
}

575
impure fn parse_or_expr(parser p) -> @ast.expr {
G
Graydon Hoare 已提交
576 577
    auto sub = parse_and_expr;
    ret parse_binary_exprs(p, sub, vec(tup(token.OROR, ast.or)));
578 579
}

580
impure fn parse_assign_expr(parser p) -> @ast.expr {
G
Graydon Hoare 已提交
581 582 583 584 585 586 587
    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,
588
                         ast.expr_assign(lhs, rhs, ast.ann_none));
G
Graydon Hoare 已提交
589 590 591 592 593
        }
    }
    ret lhs;
}

594
impure fn parse_if_expr(parser p) -> @ast.expr {
595 596 597
    auto lo = p.get_span();
    auto hi = lo;

598 599 600 601 602
    expect(p, token.IF);
    expect(p, token.LPAREN);
    auto cond = parse_expr(p);
    expect(p, token.RPAREN);
    auto thn = parse_block(p);
603
    let option.t[ast.block] els = none[ast.block];
604
    hi = thn.span;
605 606 607
    alt (p.peek()) {
        case (token.ELSE) {
            p.bump();
608 609 610
            auto eblk = parse_block(p);
            els = some(eblk);
            hi = eblk.span;
611 612
        }
    }
613
    ret @spanned(lo, hi, ast.expr_if(cond, thn, els, ast.ann_none));
614 615
}

616 617 618 619 620 621 622 623 624 625
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;
626
    ret @spanned(lo, hi, ast.expr_while(cond, body, ast.ann_none));
627 628 629 630 631 632 633 634 635 636 637 638
}

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);
639
    expect(p, token.SEMI);
640
    hi = cond.span;
641
    ret @spanned(lo, hi, ast.expr_do_while(body, cond, ast.ann_none));
642 643
}

644
impure fn parse_expr(parser p) -> @ast.expr {
645 646
    alt (p.peek()) {
        case (token.LBRACE) {
647 648
            auto blk = parse_block(p);
            ret @spanned(blk.span, blk.span,
649
                         ast.expr_block(blk, ast.ann_none));
650 651 652 653
        }
        case (token.IF) {
            ret parse_if_expr(p);
        }
654 655 656 657 658 659
        case (token.WHILE) {
            ret parse_while_expr(p);
        }
        case (token.DO) {
            ret parse_do_while_expr(p);
        }
660
        case (_) {
G
Graydon Hoare 已提交
661
            ret parse_assign_expr(p);
662 663 664
        }

    }
665 666
}

667
impure fn parse_initializer(parser p) -> option.t[@ast.expr] {
P
Patrick Walton 已提交
668 669 670 671 672 673 674 675
    if (p.peek() == token.EQ) {
        p.bump();
        ret some(parse_expr(p));
    }

    ret none[@ast.expr];
}

676
impure fn parse_let(parser p) -> @ast.decl {
P
Patrick Walton 已提交
677 678 679 680
    auto lo = p.get_span();

    expect(p, token.LET);
    auto ty = parse_ty(p);
681
    auto ident = parse_ident(p);
P
Patrick Walton 已提交
682
    auto init = parse_initializer(p);
P
Patrick Walton 已提交
683

P
Patrick Walton 已提交
684
    auto hi = p.get_span();
P
Patrick Walton 已提交
685 686
    expect(p, token.SEMI);

687 688 689 690 691 692
    let ast.local local = rec(ty = some(ty),
                              infer = false,
                              ident = ident,
                              init = init,
                              id = p.next_def_id());

693
    ret @spanned(lo, hi, ast.decl_local(@local));
694 695
}

696
impure fn parse_auto(parser p) -> @ast.decl {
697 698 699 700 701 702 703 704 705 706 707 708 709 710 711
    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());

712
    ret @spanned(lo, hi, ast.decl_local(@local));
P
Patrick Walton 已提交
713 714
}

715
impure fn parse_stmt(parser p) -> @ast.stmt {
716
    auto lo = p.get_span();
717
    alt (p.peek()) {
718

719 720
        case (token.LOG) {
            p.bump();
721
            auto e = parse_expr(p);
722
            auto hi = p.get_span();
723
            expect(p, token.SEMI);
724
            ret @spanned(lo, hi, ast.stmt_log(e));
725
        }
726

727 728 729 730 731 732 733 734 735 736 737 738 739 740 741
        case (token.CHECK) {
            p.bump();
            alt (p.peek()) {
                case (token.LPAREN) {
                    auto e = parse_expr(p);
                    auto hi = p.get_span();
                    expect(p, token.SEMI);
                    ret @spanned(lo, hi, ast.stmt_check_expr(e));
                }
                case (_) {
                    p.get_session().unimpl("constraint-check stmt");
                }
            }
        }

742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
        case (token.RET) {
            p.bump();
            alt (p.peek()) {
                case (token.SEMI) {
                    p.bump();
                    ret @spanned(lo, p.get_span(),
                                 ast.stmt_ret(none[@ast.expr]));
                }
                case (_) {
                    auto e = parse_expr(p);
                    expect(p, token.SEMI);
                    ret @spanned(lo, e.span,
                                 ast.stmt_ret(some[@ast.expr](e)));
                }
            }
        }
758

P
Patrick Walton 已提交
759
        case (token.LET) {
760
            auto decl = parse_let(p);
P
Patrick Walton 已提交
761
            auto hi = p.get_span();
762
            ret @spanned(lo, hi, ast.stmt_decl(decl));
P
Patrick Walton 已提交
763 764
        }

P
Patrick Walton 已提交
765
        case (token.AUTO) {
766
            auto decl = parse_auto(p);
P
Patrick Walton 已提交
767
            auto hi = p.get_span();
768
            ret @spanned(lo, hi, ast.stmt_decl(decl));
P
Patrick Walton 已提交
769 770
        }

771 772 773
        // Handle the (few) block-expr stmts first.

        case (token.IF) {
774 775
            auto e = parse_expr(p);
            ret @spanned(lo, e.span, ast.stmt_expr(e));
776 777
        }

778 779 780 781 782 783 784 785 786 787
        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));
        }

788
        case (token.LBRACE) {
789 790
            auto e = parse_expr(p);
            ret @spanned(lo, e.span, ast.stmt_expr(e));
791 792 793 794 795 796 797
        }


        // Remainder are line-expr stmts.

        case (_) {
            auto e = parse_expr(p);
798
            auto hi = p.get_span();
799
            expect(p, token.SEMI);
800
            ret @spanned(lo, hi, ast.stmt_expr(e));
801
        }
802 803 804 805 806
    }
    p.err("expected statement");
    fail;
}

807
impure fn parse_block(parser p) -> ast.block {
808 809
    auto f = parse_stmt;
    // FIXME: passing parse_stmt as an lval doesn't work at the moment.
810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844
    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);
845 846
}

847
impure fn parse_fn(parser p) -> tup(ast.ident, @ast.item) {
848
    auto lo = p.get_span();
849 850
    expect(p, token.FN);
    auto id = parse_ident(p);
851 852 853
    auto pf = parse_arg;
    let util.common.spanned[vec[ast.arg]] inputs =
        // FIXME: passing parse_arg as an lval doesn't work at the
854
        // moment.
855
        parse_seq[ast.arg]
856 857 858 859 860
        (token.LPAREN,
         token.RPAREN,
         some(token.COMMA),
         pf, p);

861
    let @ast.ty output;
862 863
    if (p.peek() == token.RARROW) {
        p.bump();
864
        output = parse_ty(p);
865
    } else {
866
        output = @spanned(lo, inputs.span, ast.ty_nil);
867 868 869 870
    }

    auto body = parse_block(p);

871
    let ast._fn f = rec(inputs = inputs.node,
872 873 874
                        output = output,
                        body = body);

875 876
    auto item = ast.item_fn(id, f, p.next_def_id());
    ret tup(id, @spanned(lo, body.span, item));
877 878
}

879
impure fn parse_mod_items(parser p, token.token term) -> ast._mod {
880 881 882 883 884 885 886 887 888 889 890 891
   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);
 }

892
impure fn parse_mod(parser p) -> tup(ast.ident, @ast.item) {
893
    auto lo = p.get_span();
894 895 896
    expect(p, token.MOD);
    auto id = parse_ident(p);
    expect(p, token.LBRACE);
897
    auto m = parse_mod_items(p, token.RBRACE);
898
    auto hi = p.get_span();
899
    expect(p, token.RBRACE);
900 901
    auto item = ast.item_mod(id, m, p.next_def_id());
    ret tup(id, @spanned(lo, hi, item));
902 903
}

904
impure fn parse_item(parser p) -> tup(ast.ident, @ast.item) {
905 906 907 908
    alt (p.peek()) {
        case (token.FN) {
            ret parse_fn(p);
        }
909 910 911
        case (token.MOD) {
            ret parse_mod(p);
        }
912 913 914 915 916
    }
    p.err("expectied item");
    fail;
}

917
impure fn parse_crate(parser p) -> @ast.crate {
918 919
    auto lo = p.get_span();
    auto hi = lo;
920
    auto m = parse_mod_items(p, token.EOF);
921
    ret @spanned(lo, hi, rec(module=m));
922 923
}

924 925 926 927 928 929 930 931 932 933
//
// 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:
//