aboutsummaryrefslogtreecommitdiff
path: root/src/comp/front
diff options
context:
space:
mode:
Diffstat (limited to 'src/comp/front')
-rw-r--r--src/comp/front/ast.rs9
-rw-r--r--src/comp/front/parser.rs60
2 files changed, 57 insertions, 12 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index c74e1620..48ba9187 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -1,7 +1,10 @@
-import std.util.option;
+import util.common.option;
import std.map.hashmap;
import util.common.span;
+import util.common.option;
+import util.common.some;
+import util.common.none;
type ident = str;
@@ -40,10 +43,10 @@ tag unop {
}
tag stmt {
- stmt_block(block);
stmt_decl(@decl);
stmt_ret(option[@expr]);
stmt_log(@expr);
+ stmt_expr(@expr);
}
tag decl {
@@ -63,6 +66,8 @@ tag expr {
expr_field(@expr, ident);
expr_index(@expr, @expr);
expr_cast(@expr, ty);
+ expr_if(@expr, block, option[block]);
+ expr_block(block);
}
tag lit {
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index 44bddf08..12a1f072 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -2,15 +2,9 @@ import std._io;
import driver.session;
import util.common;
import util.common.new_str_hash;
-
-// FIXME: import std.util.option and use it here.
-// import std.util.option;
-
-tag option[T] {
- none;
- some(T);
-}
-
+import util.common.option;
+import util.common.some;
+import util.common.none;
state type parser =
state obj {
@@ -414,8 +408,35 @@ io fn parse_or_expr(parser p) -> @ast.expr {
ret parse_binary_exprs(p, sub, vec(tup(token.OROR, ast.or)));
}
+io fn parse_if_expr(parser p) -> @ast.expr {
+ expect(p, token.IF);
+ expect(p, token.LPAREN);
+ auto cond = parse_expr(p);
+ expect(p, token.RPAREN);
+ auto thn = parse_block(p);
+ let option[ast.block] els = none[ast.block];
+ alt (p.peek()) {
+ case (token.ELSE) {
+ p.bump();
+ els = some(parse_block(p));
+ }
+ }
+ ret @ast.expr_if(cond, thn, els);
+}
+
io fn parse_expr(parser p) -> @ast.expr {
- ret parse_or_expr(p);
+ alt (p.peek()) {
+ case (token.LBRACE) {
+ ret @ast.expr_block(parse_block(p));
+ }
+ case (token.IF) {
+ ret parse_if_expr(p);
+ }
+ case (_) {
+ ret parse_or_expr(p);
+ }
+
+ }
}
io fn parse_stmt(parser p) -> @ast.stmt {
@@ -426,6 +447,25 @@ io fn parse_stmt(parser p) -> @ast.stmt {
expect(p, token.SEMI);
ret @ast.stmt_log(e);
}
+
+ // Handle the (few) block-expr stmts first.
+
+ case (token.IF) {
+ ret @ast.stmt_expr(parse_expr(p));
+ }
+
+ case (token.LBRACE) {
+ ret @ast.stmt_expr(parse_expr(p));
+ }
+
+
+ // Remainder are line-expr stmts.
+
+ case (_) {
+ auto e = parse_expr(p);
+ expect(p, token.SEMI);
+ ret @ast.stmt_expr(e);
+ }
}
p.err("expected statement");
fail;