Skip to content

Commit

Permalink
Evaluate Comparison Expressions with Constant Operands during Compila…
Browse files Browse the repository at this point in the history
…tion

This patch supports evaluation of comparison expressions with
constants as operands during compile time.
  • Loading branch information
Nirhar committed Jun 30, 2024
1 parent 668f9f2 commit c61105c
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 0 deletions.
144 changes: 144 additions & 0 deletions src/sema/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,150 @@ pub(crate) fn eval_constants_in_expression(
(None, true)
}
}
Expression::More {
loc,
left,
right,
} => {
let left = eval_constants_in_expression(left, diagnostics).0;
let right = eval_constants_in_expression(right, diagnostics).0;

if let (
Some(Expression::NumberLiteral { value: left, .. }),
Some(Expression::NumberLiteral { value: right, .. }),
) = (&left, &right)
{
(
Some(Expression::BoolLiteral {
loc: *loc,
value: left > right
}),
true,
)
} else {
(None, true)
}
}
Expression::Less {
loc,
left,
right,
} => {
let left = eval_constants_in_expression(left, diagnostics).0;
let right = eval_constants_in_expression(right, diagnostics).0;

if let (
Some(Expression::NumberLiteral { value: left, .. }),
Some(Expression::NumberLiteral { value: right, .. }),
) = (&left, &right)
{
(
Some(Expression::BoolLiteral {
loc: *loc,
value: left < right
}),
true,
)
} else {
(None, true)
}
}
Expression::Equal {
loc,
left,
right,
} => {
let left = eval_constants_in_expression(left, diagnostics).0;
let right = eval_constants_in_expression(right, diagnostics).0;

if let (
Some(Expression::NumberLiteral { value: left, .. }),
Some(Expression::NumberLiteral { value: right, .. }),
) = (&left, &right)
{
(
Some(Expression::BoolLiteral {
loc: *loc,
value: left == right
}),
true,
)
} else {
(None, true)
}
}
Expression::NotEqual {
loc,
left,
right,
} => {
let left = eval_constants_in_expression(left, diagnostics).0;
let right = eval_constants_in_expression(right, diagnostics).0;

if let (
Some(Expression::NumberLiteral { value: left, .. }),
Some(Expression::NumberLiteral { value: right, .. }),
) = (&left, &right)
{
(
Some(Expression::BoolLiteral {
loc: *loc,
value: left != right
}),
true,
)
} else {
(None, true)
}
}
Expression::MoreEqual {
loc,
left,
right,
} => {
let left = eval_constants_in_expression(left, diagnostics).0;
let right = eval_constants_in_expression(right, diagnostics).0;

if let (
Some(Expression::NumberLiteral { value: left, .. }),
Some(Expression::NumberLiteral { value: right, .. }),
) = (&left, &right)
{
(
Some(Expression::BoolLiteral {
loc: *loc,
value: left >= right
}),
true,
)
} else {
(None, true)
}
}
Expression::LessEqual {
loc,
left,
right,
} => {
let left = eval_constants_in_expression(left, diagnostics).0;
let right = eval_constants_in_expression(right, diagnostics).0;

if let (
Some(Expression::NumberLiteral { value: left, .. }),
Some(Expression::NumberLiteral { value: right, .. }),
) = (&left, &right)
{
(
Some(Expression::BoolLiteral {
loc: *loc,
value: left <= right
}),
true,
)
} else {
(None, true)
}
}
Expression::ZeroExt { loc, to, expr } => {
let expr = eval_constants_in_expression(expr, diagnostics).0;
if let Some(Expression::NumberLiteral { value, .. }) = expr {
Expand Down
11 changes: 11 additions & 0 deletions tests/codegen_testcases/solidity/const_expr_eval.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// RUN: --target polkadot --emit cfg
contract ConstExprEvaluate {
// BEGIN-CHECK: ConstExprEvaluate::ConstExprEvaluate::function::less
function less() public pure returns (bool r) {
int a = 100;
int b = 200;

// CHECK: return true
r = a < b;
}
}

0 comments on commit c61105c

Please sign in to comment.