rustc: Move eval_const_expr to its own mod
This commit is contained in:
parent
b7a741b5d0
commit
a477aaba08
8 changed files with 180 additions and 178 deletions
|
@ -1,7 +1,7 @@
|
|||
|
||||
import syntax::ast::*;
|
||||
import syntax::ast_util::{variant_def_ids, dummy_sp, compare_lit_exprs,
|
||||
lit_expr_eq, unguarded_pat};
|
||||
import syntax::ast_util::{variant_def_ids, dummy_sp, unguarded_pat};
|
||||
import middle::const_eval::{compare_lit_exprs, lit_expr_eq};
|
||||
import syntax::codemap::span;
|
||||
import pat_util::*;
|
||||
import syntax::visit;
|
||||
|
|
167
src/rustc/middle/const_eval.rs
Normal file
167
src/rustc/middle/const_eval.rs
Normal file
|
@ -0,0 +1,167 @@
|
|||
import syntax::ast::*;
|
||||
|
||||
// FIXME this doesn't handle big integer/float literals correctly (nor does
|
||||
// the rest of our literal handling)
|
||||
enum const_val {
|
||||
const_float(float),
|
||||
const_int(i64),
|
||||
const_uint(u64),
|
||||
const_str(str),
|
||||
}
|
||||
|
||||
// FIXME: issue #1417
|
||||
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 check e.node {
|
||||
expr_unary(neg, 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) }
|
||||
}
|
||||
}
|
||||
expr_unary(not, inner) {
|
||||
alt check eval_const_expr(tcx, inner) {
|
||||
const_int(i) { const_int(!i) }
|
||||
const_uint(i) { const_uint(!i) }
|
||||
}
|
||||
}
|
||||
expr_binary(op, a, b) {
|
||||
alt check (eval_const_expr(tcx, a), eval_const_expr(tcx, b)) {
|
||||
(const_float(a), const_float(b)) {
|
||||
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) }
|
||||
}
|
||||
}
|
||||
(const_int(a), const_int(b)) {
|
||||
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) }
|
||||
or | bitor { const_int(a | b) } bitxor { const_int(a ^ b) }
|
||||
lsl { const_int(a << b) } lsr { const_int(a >> b) }
|
||||
asr { const_int(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) }
|
||||
}
|
||||
|
||||
}
|
||||
(const_uint(a), const_uint(b)) {
|
||||
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) }
|
||||
or | bitor { const_uint(a | b) } bitxor { const_uint(a ^ b) }
|
||||
lsl { const_int((a << b) as i64) }
|
||||
lsr { const_int((a >> b) as i64) }
|
||||
asr { const_int((a >>> b) as i64) }
|
||||
eq { fromb(a == b) } lt { fromb(a < b) }
|
||||
le { fromb(a <= b) } ne { fromb(a != b) }
|
||||
ge { fromb(a >= b) } gt { fromb(a > b) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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) }
|
||||
}
|
||||
}
|
||||
|
||||
fn lit_to_const(lit: @lit) -> const_val {
|
||||
alt lit.node {
|
||||
lit_str(s) { const_str(s) }
|
||||
lit_int(n, _) { const_int(n) }
|
||||
lit_uint(n, _) { const_uint(n) }
|
||||
lit_float(n, _) { const_float(option::get(float::from_str(n))) }
|
||||
lit_nil { const_int(0i64) }
|
||||
lit_bool(b) { const_int(b as i64) }
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_const_vals(a: const_val, b: const_val) -> int {
|
||||
alt (a, b) {
|
||||
(const_int(a), const_int(b)) {
|
||||
if a == b {
|
||||
0
|
||||
} else if a < b {
|
||||
-1
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
(const_uint(a), const_uint(b)) {
|
||||
if a == b {
|
||||
0
|
||||
} else if a < b {
|
||||
-1
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
(const_float(a), const_float(b)) {
|
||||
if a == b {
|
||||
0
|
||||
} else if a < b {
|
||||
-1
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
(const_str(a), const_str(b)) {
|
||||
if a == b {
|
||||
0
|
||||
} else if a < b {
|
||||
-1
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
_ {
|
||||
fail "compare_const_vals: ill-typed comparison";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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(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
|
||||
}
|
|
@ -25,10 +25,10 @@ enum opt {
|
|||
}
|
||||
fn opt_eq(tcx: ty::ctxt, a: opt, b: opt) -> bool {
|
||||
alt (a, b) {
|
||||
(lit(a), lit(b)) { ast_util::compare_lit_exprs(tcx, a, b) == 0 }
|
||||
(lit(a), lit(b)) { const_eval::compare_lit_exprs(tcx, a, b) == 0 }
|
||||
(range(a1, a2), range(b1, b2)) {
|
||||
ast_util::compare_lit_exprs(tcx, a1, b1) == 0 &&
|
||||
ast_util::compare_lit_exprs(tcx, a2, b2) == 0
|
||||
const_eval::compare_lit_exprs(tcx, a1, b1) == 0 &&
|
||||
const_eval::compare_lit_exprs(tcx, a2, b2) == 0
|
||||
}
|
||||
(var(a, _), var(b, _)) { a == b }
|
||||
_ { false }
|
||||
|
|
|
@ -676,7 +676,7 @@ fn pred_args_matches(pattern: [constr_arg_general_<inst>], desc: pred_args) ->
|
|||
carg_base { if n != carg_base { ret false; } }
|
||||
carg_lit(l) {
|
||||
alt n {
|
||||
carg_lit(m) { if !lit_eq(l, m) { ret false; } }
|
||||
carg_lit(m) { if !const_eval::lit_eq(l, m) { ret false; } }
|
||||
_ { ret false; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1306,7 +1306,7 @@ fn arg_eq<T>(eq: fn(T, T) -> bool,
|
|||
}
|
||||
ast::carg_lit(l) {
|
||||
alt b.node {
|
||||
ast::carg_lit(m) { ret ast_util::lit_eq(l, m); } _ { ret false; }
|
||||
ast::carg_lit(m) { ret const_eval::lit_eq(l, m); } _ { ret false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1894,8 +1894,8 @@ fn enum_variants(cx: ctxt, id: ast::def_id) -> @[variant_info] {
|
|||
alt variant.node.disr_expr {
|
||||
some (ex) {
|
||||
// FIXME: issue #1417
|
||||
disr_val = alt syntax::ast_util::eval_const_expr(cx, ex) {
|
||||
ast_util::const_int(val) {val as int}
|
||||
disr_val = alt const_eval::eval_const_expr(cx, ex) {
|
||||
const_eval::const_int(val) {val as int}
|
||||
_ { cx.sess.bug("tag_variants: bad disr expr"); }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1645,7 +1645,7 @@ fn check_lit(ccx: @crate_ctxt, lit: @ast::lit) -> ty::t {
|
|||
|
||||
fn valid_range_bounds(tcx: ty::ctxt, from: @ast::expr, to: @ast::expr)
|
||||
-> bool {
|
||||
ast_util::compare_lit_exprs(tcx, from, to) <= 0
|
||||
const_eval::compare_lit_exprs(tcx, from, to) <= 0
|
||||
}
|
||||
|
||||
type pat_ctxt = {
|
||||
|
@ -3404,8 +3404,8 @@ fn check_enum_variants(ccx: @crate_ctxt, sp: span, vs: [ast::variant],
|
|||
// Also, check_expr (from check_const pass) doesn't guarantee that
|
||||
// the expression in an form that eval_const_expr can handle, so
|
||||
// we may still get an internal compiler error
|
||||
alt syntax::ast_util::eval_const_expr(ccx.tcx, e) {
|
||||
syntax::ast_util::const_int(val) {
|
||||
alt const_eval::eval_const_expr(ccx.tcx, e) {
|
||||
const_eval::const_int(val) {
|
||||
disr_val = val as int;
|
||||
}
|
||||
_ {
|
||||
|
|
|
@ -50,6 +50,7 @@ mod middle {
|
|||
mod pat_util;
|
||||
mod region;
|
||||
mod regionck;
|
||||
mod const_eval;
|
||||
|
||||
mod tstate {
|
||||
mod ck;
|
||||
|
|
|
@ -242,172 +242,6 @@ fn default_block(stmts1: [@stmt], expr1: option<@expr>, id1: node_id) ->
|
|||
{view_items: [], stmts: stmts1, expr: expr1, id: id1, rules: default_blk}
|
||||
}
|
||||
|
||||
// FIXME this doesn't handle big integer/float literals correctly (nor does
|
||||
// the rest of our literal handling)
|
||||
enum const_val {
|
||||
const_float(float),
|
||||
const_int(i64),
|
||||
const_uint(u64),
|
||||
const_str(str),
|
||||
}
|
||||
|
||||
// FIXME: issue #1417
|
||||
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 check e.node {
|
||||
expr_unary(neg, 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) }
|
||||
}
|
||||
}
|
||||
expr_unary(not, inner) {
|
||||
alt check eval_const_expr(tcx, inner) {
|
||||
const_int(i) { const_int(!i) }
|
||||
const_uint(i) { const_uint(!i) }
|
||||
}
|
||||
}
|
||||
expr_binary(op, a, b) {
|
||||
alt check (eval_const_expr(tcx, a), eval_const_expr(tcx, b)) {
|
||||
(const_float(a), const_float(b)) {
|
||||
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) }
|
||||
}
|
||||
}
|
||||
(const_int(a), const_int(b)) {
|
||||
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) }
|
||||
or | bitor { const_int(a | b) } bitxor { const_int(a ^ b) }
|
||||
lsl { const_int(a << b) } lsr { const_int(a >> b) }
|
||||
asr { const_int(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) }
|
||||
}
|
||||
|
||||
}
|
||||
(const_uint(a), const_uint(b)) {
|
||||
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) }
|
||||
or | bitor { const_uint(a | b) } bitxor { const_uint(a ^ b) }
|
||||
lsl { const_int((a << b) as i64) }
|
||||
lsr { const_int((a >> b) as i64) }
|
||||
asr { const_int((a >>> b) as i64) }
|
||||
eq { fromb(a == b) } lt { fromb(a < b) }
|
||||
le { fromb(a <= b) } ne { fromb(a != b) }
|
||||
ge { fromb(a >= b) } gt { fromb(a > b) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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) }
|
||||
}
|
||||
}
|
||||
|
||||
fn lit_to_const(lit: @lit) -> const_val {
|
||||
alt lit.node {
|
||||
lit_str(s) { const_str(s) }
|
||||
lit_int(n, _) { const_int(n) }
|
||||
lit_uint(n, _) { const_uint(n) }
|
||||
lit_float(n, _) { const_float(option::get(float::from_str(n))) }
|
||||
lit_nil { const_int(0i64) }
|
||||
lit_bool(b) { const_int(b as i64) }
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_const_vals(a: const_val, b: const_val) -> int {
|
||||
alt (a, b) {
|
||||
(const_int(a), const_int(b)) {
|
||||
if a == b {
|
||||
0
|
||||
} else if a < b {
|
||||
-1
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
(const_uint(a), const_uint(b)) {
|
||||
if a == b {
|
||||
0
|
||||
} else if a < b {
|
||||
-1
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
(const_float(a), const_float(b)) {
|
||||
if a == b {
|
||||
0
|
||||
} else if a < b {
|
||||
-1
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
(const_str(a), const_str(b)) {
|
||||
if a == b {
|
||||
0
|
||||
} else if a < b {
|
||||
-1
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
_ {
|
||||
fail "compare_const_vals: ill-typed comparison";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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(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
|
||||
}
|
||||
|
||||
fn ident_to_path(s: span, i: ident) -> @path {
|
||||
@respan(s, {global: false, idents: [i], types: []})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue