aboutsummaryrefslogtreecommitdiff
path: root/src/comp/front
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
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')
-rw-r--r--src/comp/front/ast.rs30
-rw-r--r--src/comp/front/parser.rs230
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);
}