aboutsummaryrefslogtreecommitdiff
path: root/src/comp/front/parser.rs
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2010-09-28 10:30:34 -0700
committerGraydon Hoare <[email protected]>2010-09-28 10:30:34 -0700
commitfbea4d04b7053e5885d2867f1519416458a37140 (patch)
tree3f649b21df47ba83f24651494b3389ca52ec5d46 /src/comp/front/parser.rs
parentStart building up the expression tower. (diff)
downloadrust-fbea4d04b7053e5885d2867f1519416458a37140.tar.xz
rust-fbea4d04b7053e5885d2867f1519416458a37140.zip
More rustc expr-parsing logic.
Diffstat (limited to 'src/comp/front/parser.rs')
-rw-r--r--src/comp/front/parser.rs230
1 files changed, 224 insertions, 6 deletions
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);
}