Teach rustc about phi nodes, block relationships. Translate if- and block-expressions.

This commit is contained in:
Graydon Hoare 2010-10-04 15:55:12 -07:00
parent a87e81b929
commit 44e4b2d63a
5 changed files with 325 additions and 113 deletions

View file

@ -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 {

View file

@ -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;