diff options
author | John Hodge <tpg@mutabah.net> | 2016-10-22 16:24:51 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-10-22 16:24:51 +0800 |
commit | 58f0cafeeffaa878ff711838bab6b078e58b5de7 (patch) | |
tree | 1736211085abf5a19b7cdc66c2204702044cc54f | |
parent | 59c451383ca6b3d2310a509162f2b49b404eda6c (diff) | |
download | mrust-58f0cafeeffaa878ff711838bab6b078e58b5de7.tar.gz |
HIR Const Eval - Rough MIR binop support
-rw-r--r-- | src/hir_conv/constant_evaluation.cpp | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index 8834b6a8..727031d2 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -886,10 +886,59 @@ namespace { ) ), (BinOp, - TODO(sp, "RValue::BinOp"); + auto inval_l = read_lval(e.val_l); + auto inval_r = read_lval(e.val_r); + ASSERT_BUG(sp, inval_l.tag() == inval_r.tag(), "Mismatched literal types in binop - " << inval_l << " and " << inval_r); + TU_MATCH_DEF( ::HIR::Literal, (inval_l, inval_r), (l, r), + ( + TODO(sp, "RValue::BinOp - " << sa.src << ", val = " << inval_l << " , " << inval_r); + ), + (Integer, + switch(e.op) + { + case ::MIR::eBinOp::ADD: val = ::HIR::Literal( l + r ); break; + case ::MIR::eBinOp::SUB: val = ::HIR::Literal( l - r ); break; + case ::MIR::eBinOp::MUL: val = ::HIR::Literal( l * r ); break; + case ::MIR::eBinOp::DIV: val = ::HIR::Literal( l / r ); break; + case ::MIR::eBinOp::MOD: val = ::HIR::Literal( l % r ); break; + case ::MIR::eBinOp::ADD_OV: + case ::MIR::eBinOp::SUB_OV: + case ::MIR::eBinOp::MUL_OV: + case ::MIR::eBinOp::DIV_OV: + TODO(sp, "RValue::BinOp - " << sa.src << ", val = " << inval_l << " , " << inval_r); + + case ::MIR::eBinOp::BIT_OR : val = ::HIR::Literal( l | r ); break; + case ::MIR::eBinOp::BIT_AND: val = ::HIR::Literal( l & r ); break; + case ::MIR::eBinOp::BIT_XOR: val = ::HIR::Literal( l ^ r ); break; + case ::MIR::eBinOp::BIT_SHL: val = ::HIR::Literal( l << r ); break; + case ::MIR::eBinOp::BIT_SHR: val = ::HIR::Literal( l >> r ); break; + // TODO: GT/LT are incorrect for signed integers + case ::MIR::eBinOp::EQ: val = ::HIR::Literal( static_cast<uint64_t>(l == r) ); break; + case ::MIR::eBinOp::NE: val = ::HIR::Literal( static_cast<uint64_t>(l != r) ); break; + case ::MIR::eBinOp::GT: val = ::HIR::Literal( static_cast<uint64_t>(l > r) ); break; + case ::MIR::eBinOp::GE: val = ::HIR::Literal( static_cast<uint64_t>(l >= r) ); break; + case ::MIR::eBinOp::LT: val = ::HIR::Literal( static_cast<uint64_t>(l < r) ); break; + case ::MIR::eBinOp::LE: val = ::HIR::Literal( static_cast<uint64_t>(l <= r) ); break; + } + ) + ) ), (UniOp, - TODO(sp, "RValue::UniOp"); + auto inval = read_lval(e.val); + TU_IFLET( ::HIR::Literal, inval, Integer, i, + switch( e.op ) + { + case ::MIR::eUniOp::INV: + val = ::HIR::Literal( ~i ); + break; + case ::MIR::eUniOp::NEG: + val = ::HIR::Literal( -i ); + break; + } + ) + else { + BUG(sp, "Invalid invert of " << inval.tag_str()); + } ), (DstMeta, TODO(sp, "RValue::DstMeta"); |