Skip to content

Commit c8fae5d

Browse files
jwisebrson
authored andcommitted
trans: Add binops (except for logic and comparators) and unops to trans_const_expr. Working towards issue #570.
1 parent e674a7e commit c8fae5d

File tree

2 files changed

+78
-2
lines changed

2 files changed

+78
-2
lines changed

src/comp/middle/check_const.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,20 @@ fn check_const_expr(tcx: ty::ctxt, ex: @expr, &&s: (), v: visit::vt<()>) {
2727
visit::visit_expr(ex, s, v);
2828
alt ex.node {
2929
expr_lit(_) { }
30+
expr_binary(_, _, _) { /* subexps covered by visit */ }
31+
expr_unary(u, _) {
32+
alt u {
33+
box(_) |
34+
uniq(_) |
35+
deref. {
36+
tcx.sess.span_err(ex.span,
37+
"disallowed operator in constant expression");
38+
}
39+
_ { }
40+
}
41+
}
3042
_ { tcx.sess.span_err(ex.span,
31-
"constant contains unimplemented expression type"); }
43+
"constant contains unimplemented expression type"); }
3244
}
3345
}
3446

src/comp/middle/trans.rs

+65-1
Original file line numberDiff line numberDiff line change
@@ -5290,7 +5290,71 @@ fn trans_tag_variant(cx: @local_ctxt, tag_id: ast::node_id,
52905290
fn trans_const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
52915291
alt e.node {
52925292
ast::expr_lit(lit) { ret trans_crate_lit(cx, *lit); }
5293-
_ { cx.sess.span_unimpl(e.span, "consts that's not a plain literal"); }
5293+
ast::expr_binary(b, e1, e2) {
5294+
let te1 = trans_const_expr(cx, e1);
5295+
let te2 = trans_const_expr(cx, e2);
5296+
/* Neither type is bottom, and we expect them to be unified already,
5297+
* so the following is safe. */
5298+
let ty = ty::expr_ty(ccx_tcx(cx), e1);
5299+
let is_float = ty::type_is_fp(ccx_tcx(cx), ty);
5300+
let signed = ty::type_is_signed(ccx_tcx(cx), ty);
5301+
ret alt b {
5302+
ast::add. {
5303+
if is_float { llvm::LLVMConstFAdd(te1, te2) }
5304+
else { llvm::LLVMConstAdd(te1, te2) }
5305+
}
5306+
ast::sub. {
5307+
if is_float { llvm::LLVMConstFSub(te1, te2) }
5308+
else { llvm::LLVMConstSub(te1, te2) }
5309+
}
5310+
ast::mul. {
5311+
if is_float { llvm::LLVMConstFMul(te1, te2) }
5312+
else { llvm::LLVMConstMul(te1, te2) }
5313+
}
5314+
ast::div. {
5315+
if is_float { llvm::LLVMConstFDiv(te1, te2) }
5316+
else if signed { llvm::LLVMConstSDiv(te1, te2) }
5317+
else { llvm::LLVMConstUDiv(te1, te2) }
5318+
}
5319+
ast::rem. {
5320+
if is_float { llvm::LLVMConstFRem(te1, te2) }
5321+
else if signed { llvm::LLVMConstSRem(te1, te2) }
5322+
else { llvm::LLVMConstURem(te1, te2) }
5323+
}
5324+
ast::and. |
5325+
ast::or. { cx.sess.span_unimpl(e.span, "binop logic"); }
5326+
ast::bitxor. { llvm::LLVMConstXor(te1, te2) }
5327+
ast::bitand. { llvm::LLVMConstAnd(te1, te2) }
5328+
ast::bitor. { llvm::LLVMConstOr(te1, te2) }
5329+
ast::lsl. { llvm::LLVMConstShl(te1, te2) }
5330+
ast::lsr. { llvm::LLVMConstLShr(te1, te2) }
5331+
ast::asr. { llvm::LLVMConstAShr(te1, te2) }
5332+
ast::eq. |
5333+
ast::lt. |
5334+
ast::le. |
5335+
ast::ne. |
5336+
ast::ge. |
5337+
ast::gt. { cx.sess.span_unimpl(e.span, "binop comparator"); }
5338+
}
5339+
}
5340+
ast::expr_unary(u, e) {
5341+
let te = trans_const_expr(cx, e);
5342+
let ty = ty::expr_ty(ccx_tcx(cx), e);
5343+
let is_float = ty::type_is_fp(ccx_tcx(cx), ty);
5344+
ret alt u {
5345+
ast::box(_) |
5346+
ast::uniq(_) |
5347+
ast::deref. { cx.sess.span_bug(e.span,
5348+
"bad unop type in trans_const_expr"); }
5349+
ast::not. { llvm::LLVMConstNot(te) }
5350+
ast::neg. {
5351+
if is_float { llvm::LLVMConstFNeg(te) }
5352+
else { llvm::LLVMConstNeg(te) }
5353+
}
5354+
}
5355+
}
5356+
_ { cx.sess.span_bug(e.span,
5357+
"bad constant expression type in trans_const_expr"); }
52945358
}
52955359
}
52965360

0 commit comments

Comments
 (0)