Teach rustc about phi nodes, block relationships. Translate if- and block-expressions.
This commit is contained in:
parent
a87e81b929
commit
44e4b2d63a
5 changed files with 325 additions and 113 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue