diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2012-03-14 18:04:03 +0100 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2012-03-14 18:05:28 +0100 |
| commit | de79caa97ebfb86adaaae1c54237a94a610f94c0 (patch) | |
| tree | e434939aacae6c1777d971d125be161cca1ea00a /src/rustc/syntax | |
| parent | c988800cf5611130e468761caa4d2f5adbdc6781 (diff) | |
| download | rust-de79caa97ebfb86adaaae1c54237a94a610f94c0.tar.gz rust-de79caa97ebfb86adaaae1c54237a94a610f94c0.zip | |
Add crude support for casts in constant expressions
Only casts to integral and float types are supported Closes #1975
Diffstat (limited to 'src/rustc/syntax')
| -rw-r--r-- | src/rustc/syntax/ast_util.rs | 63 |
1 files changed, 42 insertions, 21 deletions
diff --git a/src/rustc/syntax/ast_util.rs b/src/rustc/syntax/ast_util.rs index a6e34f3b24d..e5a15edf1a3 100644 --- a/src/rustc/syntax/ast_util.rs +++ b/src/rustc/syntax/ast_util.rs @@ -250,38 +250,36 @@ enum const_val { } // FIXME: issue #1417 -fn eval_const_expr(e: @expr) -> const_val { +fn eval_const_expr(tcx: middle::ty::ctxt, e: @expr) -> const_val { + import middle::ty; fn fromb(b: bool) -> const_val { const_int(b as i64) } - alt e.node { + alt check e.node { expr_unary(neg, inner) { - alt eval_const_expr(inner) { + alt check eval_const_expr(tcx, inner) { const_float(f) { const_float(-f) } const_int(i) { const_int(-i) } const_uint(i) { const_uint(-i) } - _ { fail "eval_const_expr: bad neg argument"; } } } expr_unary(not, inner) { - alt eval_const_expr(inner) { + alt check eval_const_expr(tcx, inner) { const_int(i) { const_int(!i) } const_uint(i) { const_uint(!i) } - _ { fail "eval_const_expr: bad not argument"; } } } expr_binary(op, a, b) { - alt (eval_const_expr(a), eval_const_expr(b)) { + alt check (eval_const_expr(tcx, a), eval_const_expr(tcx, b)) { (const_float(a), const_float(b)) { - alt op { + alt check op { add { const_float(a + b) } subtract { const_float(a - b) } mul { const_float(a * b) } div { const_float(a / b) } rem { const_float(a % b) } eq { fromb(a == b) } lt { fromb(a < b) } le { fromb(a <= b) } ne { fromb(a != b) } ge { fromb(a >= b) } gt { fromb(a > b) } - _ { fail "eval_const_expr: can't apply this binop to floats"; } } } (const_int(a), const_int(b)) { - alt op { + alt check op { add { const_int(a + b) } subtract { const_int(a - b) } mul { const_int(a * b) } div { const_int(a / b) } rem { const_int(a % b) } and | bitand { const_int(a & b) } @@ -291,11 +289,11 @@ fn eval_const_expr(e: @expr) -> const_val { eq { fromb(a == b) } lt { fromb(a < b) } le { fromb(a <= b) } ne { fromb(a != b) } ge { fromb(a >= b) } gt { fromb(a > b) } - _ { fail "eval_const_expr: can't apply this binop to ints"; } } + } (const_uint(a), const_uint(b)) { - alt op { + alt check op { add { const_uint(a + b) } subtract { const_uint(a - b) } mul { const_uint(a * b) } div { const_uint(a / b) } rem { const_uint(a % b) } and | bitand { const_uint(a & b) } @@ -306,17 +304,38 @@ fn eval_const_expr(e: @expr) -> const_val { eq { fromb(a == b) } lt { fromb(a < b) } le { fromb(a <= b) } ne { fromb(a != b) } ge { fromb(a >= b) } gt { fromb(a > b) } - _ { fail "eval_const_expr: can't apply this binop to uints"; } } } - _ { fail "eval_constr_expr: bad binary arguments"; } } } - expr_lit(lit) { lit_to_const(lit) } - // Precondition? - _ { - fail "eval_const_expr: non-constant expression"; + expr_cast(base, _) { + let ety = ty::expr_ty(tcx, e); + let base = eval_const_expr(tcx, base); + alt check ty::get(ety).struct { + ty::ty_float(_) { + alt check base { + const_uint(u) { const_float(u as f64) } + const_int(i) { const_float(i as f64) } + const_float(_) { base } + } + } + ty::ty_uint(_) { + alt check base { + const_uint(_) { base } + const_int(i) { const_uint(i as u64) } + const_float(f) { const_uint(f as u64) } + } + } + ty::ty_int(_) | ty::ty_bool { + alt check base { + const_uint(u) { const_int(u as i64) } + const_int(_) { base } + const_float(f) { const_int(f as i64) } + } + } + } } + expr_lit(lit) { lit_to_const(lit) } } } @@ -375,11 +394,13 @@ fn compare_const_vals(a: const_val, b: const_val) -> int { } } -fn compare_lit_exprs(a: @expr, b: @expr) -> int { - compare_const_vals(eval_const_expr(a), eval_const_expr(b)) +fn compare_lit_exprs(tcx: middle::ty::ctxt, a: @expr, b: @expr) -> int { + compare_const_vals(eval_const_expr(tcx, a), eval_const_expr(tcx, b)) } -fn lit_expr_eq(a: @expr, b: @expr) -> bool { compare_lit_exprs(a, b) == 0 } +fn lit_expr_eq(tcx: middle::ty::ctxt, a: @expr, b: @expr) -> bool { + compare_lit_exprs(tcx, a, b) == 0 +} fn lit_eq(a: @lit, b: @lit) -> bool { compare_const_vals(lit_to_const(a), lit_to_const(b)) == 0 |
