about summary refs log tree commit diff
path: root/src/comp/front
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2010-09-28 10:30:34 -0700
committerGraydon Hoare <graydon@mozilla.com>2010-09-28 10:30:34 -0700
commitfbea4d04b7053e5885d2867f1519416458a37140 (patch)
tree3f649b21df47ba83f24651494b3389ca52ec5d46 /src/comp/front
parent5b4b035c7a041badcc656e3c403417f16d9a05f8 (diff)
downloadrust-fbea4d04b7053e5885d2867f1519416458a37140.tar.gz
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 d4e8aaaf752..c74e16202ac 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 0dc4e50e683..ea983968544 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);
 }