diff options
| author | Graydon Hoare <[email protected]> | 2010-09-28 10:30:34 -0700 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2010-09-28 10:30:34 -0700 |
| commit | fbea4d04b7053e5885d2867f1519416458a37140 (patch) | |
| tree | 3f649b21df47ba83f24651494b3389ca52ec5d46 /src/comp/front | |
| parent | Start building up the expression tower. (diff) | |
| download | rust-fbea4d04b7053e5885d2867f1519416458a37140.tar.xz rust-fbea4d04b7053e5885d2867f1519416458a37140.zip | |
More rustc expr-parsing logic.
Diffstat (limited to 'src/comp/front')
| -rw-r--r-- | src/comp/front/ast.rs | 30 | ||||
| -rw-r--r-- | src/comp/front/parser.rs | 230 |
2 files changed, 238 insertions, 22 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index d4e8aaaf..c74e1620 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -10,12 +10,14 @@ type crate = rec(_mod module); type block = vec[@stmt]; tag binop { - plus; - minus; - star; - slash; - percent; - caret; + add; + sub; + mul; + div; + rem; + and; + or; + bitxor; bitand; bitor; lsl; @@ -30,11 +32,11 @@ tag binop { } tag unop { + box; + deref; bitnot; not; neg; - deref; - cast(@ty); } tag stmt { @@ -49,14 +51,7 @@ tag decl { decl_item(ident, @item); } -tag lval { - lval_ident(ident); - lval_ext(@lval, ident); - lval_idx(@lval, @expr); -} - tag expr { - expr_box(@expr); expr_vec(vec[@expr]); expr_tup(vec[@expr]); expr_rec(vec[tup(ident,@expr)]); @@ -64,7 +59,10 @@ tag expr { expr_binary(binop, @expr, @expr); expr_unary(unop, @expr); expr_lit(@lit); - expr_lval(@lval); + expr_ident(ident); + expr_field(@expr, ident); + expr_index(@expr, @expr); + expr_cast(@expr, ty); } tag lit { diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 0dc4e50e..ea983968 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -166,34 +166,252 @@ state fn parse_bottom_expr(parser p) -> @ast.expr { ret e; } + case (token.TUP) { + p.bump(); + auto pf = parse_expr; + auto es = parse_seq[@ast.expr](token.LPAREN, + token.RPAREN, + some(token.COMMA), + pf, p); + ret @ast.expr_tup(es); + } + + case (token.VEC) { + p.bump(); + auto pf = parse_expr; + auto es = parse_seq[@ast.expr](token.LPAREN, + token.RPAREN, + some(token.COMMA), + pf, p); + ret @ast.expr_vec(es); + } + + case (token.REC) { + p.bump(); + state fn parse_entry(parser p) -> + 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); + ret @ast.expr_rec(es); + } + + case (token.IDENT(?i)) { + p.bump(); + ret @ast.expr_ident(i); + } + case (_) { ret @ast.expr_lit(parse_lit(p)); } } } +state fn parse_path_expr(parser p) -> @ast.expr { + auto e = parse_bottom_expr(p); + while (true) { + alt (p.peek()) { + case (token.DOT) { + p.bump(); + alt (p.peek()) { + + case (token.IDENT(?i)) { + p.bump(); + e = @ast.expr_field(e, i); + } + + case (token.LPAREN) { + auto ix = parse_bottom_expr(p); + e = @ast.expr_index(e, ix); + } + } + } + case (_) { + ret e; + } + } + } + ret e; +} -state fn parse_negation_expr(parser p) -> @ast.expr { +state fn parse_prefix_expr(parser p) -> @ast.expr { alt (p.peek()) { case (token.NOT) { - auto e = parse_negation_expr(p); + auto e = parse_prefix_expr(p); ret @ast.expr_unary(ast.not, e); } case (token.TILDE) { - auto e = parse_negation_expr(p); + auto e = parse_prefix_expr(p); ret @ast.expr_unary(ast.bitnot, e); } + case (token.BINOP(?b)) { + alt (b) { + + case (token.MINUS) { + auto e = parse_prefix_expr(p); + ret @ast.expr_unary(ast.neg, e); + } + + case (token.STAR) { + auto e = parse_prefix_expr(p); + ret @ast.expr_unary(ast.deref, e); + } + + case (_) { + ret parse_path_expr(p); + } + } + } + + case (token.AT) { + p.bump(); + auto e = parse_prefix_expr(p); + ret @ast.expr_unary(ast.box, e); + } + case (_) { - ret parse_bottom_expr(p); + ret parse_path_expr(p); + } + } +} + +state fn parse_binops(parser p, + (state fn(parser) -> @ast.expr) sub, + vec[tup(token.binop, ast.binop)] ops) + -> @ast.expr { + auto e = sub(p); + auto more = true; + while (more) { + more = false; + auto t = p.peek(); + alt (t) { + case (token.BINOP(?op)) { + for (tup(token.binop, ast.binop) pair in ops) { + if (pair._0 == op) { + e = @ast.expr_binary(pair._1, e, sub(p)); + more = true; + t = p.peek(); + } + } + } + case (_) { + } + } + } + ret e; +} + +state fn parse_binary_exprs(parser p, + (state fn(parser) -> @ast.expr) sub, + vec[tup(token.token, ast.binop)] ops) + -> @ast.expr { + auto e = sub(p); + auto more = true; + while (more) { + more = false; + auto t = p.peek(); + for (tup(token.token, ast.binop) pair in ops) { + if (pair._0 == t) { + e = @ast.expr_binary(pair._1, e, sub(p)); + more = true; + t = p.peek(); + } } } + ret e; +} + +state fn parse_factor_expr(parser p) -> @ast.expr { + 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))); +} + +state fn parse_term_expr(parser p) -> @ast.expr { + auto sub = parse_factor_expr; + ret parse_binops(p, sub, vec(tup(token.PLUS, ast.add), + tup(token.MINUS, ast.sub))); +} + +state fn parse_shift_expr(parser p) -> @ast.expr { + 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))); +} + +state fn parse_bitand_expr(parser p) -> @ast.expr { + auto sub = parse_shift_expr; + ret parse_binops(p, sub, vec(tup(token.AND, ast.bitand))); +} + +state fn parse_bitxor_expr(parser p) -> @ast.expr { + auto sub = parse_bitand_expr; + ret parse_binops(p, sub, vec(tup(token.CARET, ast.bitxor))); +} + +state fn parse_bitor_expr(parser p) -> @ast.expr { + auto sub = parse_bitxor_expr; + ret parse_binops(p, sub, vec(tup(token.OR, ast.bitor))); +} + +state fn parse_cast_expr(parser p) -> @ast.expr { + auto e = parse_bitor_expr(p); + while (true) { + alt (p.peek()) { + case (token.AS) { + p.bump(); + auto t = parse_ty(p); + e = @ast.expr_cast(e, t); + } + + case (_) { + ret e; + } + } + } + ret e; +} + +state fn parse_relational_expr(parser p) -> @ast.expr { + 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))); +} + + +state fn parse_equality_expr(parser p) -> @ast.expr { + auto sub = parse_relational_expr; + ret parse_binary_exprs(p, sub, vec(tup(token.EQEQ, ast.eq), + tup(token.NE, ast.ne))); +} + +state fn parse_and_expr(parser p) -> @ast.expr { + auto sub = parse_equality_expr; + ret parse_binary_exprs(p, sub, vec(tup(token.ANDAND, ast.and))); +} + +state fn parse_or_expr(parser p) -> @ast.expr { + auto sub = parse_and_expr; + ret parse_binary_exprs(p, sub, vec(tup(token.OROR, ast.or))); } state fn parse_expr(parser p) -> @ast.expr { - ret parse_negation_expr(p); + ret parse_or_expr(p); } state fn parse_stmt(parser p) -> @ast.stmt { @@ -221,7 +439,7 @@ state fn parse_block(parser p) -> ast.block { state fn parse_slot_ident_pair(parser p) -> rec(ast.slot slot, ast.ident ident) { auto s = parse_slot(p); - auto i = parse_ident(p); + auto i = parse_ident(p); ret rec(slot=s, ident=i); } |