瀏覽代碼

sema should not replace rational constant expressions

sema should not do constant folding and reduce the ast.

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 3 年之前
父節點
當前提交
1aed4d6f58
共有 3 個文件被更改,包括 26 次插入22 次删除
  1. 5 1
      src/codegen/expression.rs
  2. 1 7
      src/sema/expression.rs
  3. 20 14
      tests/contract_testcases/solana/negative_exponent.dot

+ 5 - 1
src/codegen/expression.rs

@@ -527,7 +527,11 @@ pub fn expression(
             }
             }
         }
         }
         ast::Expression::Cast(loc, ty, e) => {
         ast::Expression::Cast(loc, ty, e) => {
-            if matches!(ty, Type::String | Type::DynamicBytes)
+            if e.ty() == Type::Rational {
+                let (_, n) = eval_const_rational(e, ns).unwrap();
+
+                Expression::NumberLiteral(*loc, ty.clone(), n.to_integer())
+            } else if matches!(ty, Type::String | Type::DynamicBytes)
                 && matches!(expr.ty(), Type::String | Type::DynamicBytes)
                 && matches!(expr.ty(), Type::String | Type::DynamicBytes)
             {
             {
                 expression(e, cfg, contract_no, func, ns, vartab, opt)
                 expression(e, cfg, contract_no, func, ns, vartab, opt)

+ 1 - 7
src/sema/expression.rs

@@ -784,13 +784,7 @@ impl Expression {
                 match eval_const_rational(self, ns) {
                 match eval_const_rational(self, ns) {
                     Ok((_, big_number)) => {
                     Ok((_, big_number)) => {
                         if big_number.is_integer() {
                         if big_number.is_integer() {
-                            let expr = Expression::NumberLiteral(
-                                self.loc(),
-                                to.clone(),
-                                big_number.to_integer(),
-                            );
-
-                            return expr.cast(loc, to, true, ns, diagnostics);
+                            return Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())));
                         }
                         }
 
 
                         diagnostics.push(Diagnostic::type_error(
                         diagnostics.push(Diagnostic::type_error(

+ 20 - 14
tests/contract_testcases/solana/negative_exponent.dot

@@ -3,28 +3,34 @@ strict digraph "tests/contract_testcases/solana/negative_exponent.sol" {
 	f [label="function f\ncontract: c\ntests/contract_testcases/solana/negative_exponent.sol:2:5-44\nsignature f()\nvisibility public\nmutability pure"]
 	f [label="function f\ncontract: c\ntests/contract_testcases/solana/negative_exponent.sol:2:5-44\nsignature f()\nvisibility public\nmutability pure"]
 	returns [label="returns\nuint256 "]
 	returns [label="returns\nuint256 "]
 	return [label="return\ntests/contract_testcases/solana/negative_exponent.sol:3:2-20"]
 	return [label="return\ntests/contract_testcases/solana/negative_exponent.sol:3:2-20"]
-	number_literal [label="uint256 literal: 2\ntests/contract_testcases/solana/negative_exponent.sol:3:14-15"]
+	cast [label="cast uint256\ntests/contract_testcases/solana/negative_exponent.sol:3:2-20"]
+	add [label="add\nrational\ntests/contract_testcases/solana/negative_exponent.sol:3:14-15"]
+	rational_literal [label="rational rational literal: 1/20\ntests/contract_testcases/solana/negative_exponent.sol:3:9-13"]
+	rational_literal_9 [label="rational rational literal: 39/20\ntests/contract_testcases/solana/negative_exponent.sol:3:16-20"]
 	g [label="function g\ncontract: c\ntests/contract_testcases/solana/negative_exponent.sol:5:5-44\nsignature g()\nvisibility public\nmutability pure"]
 	g [label="function g\ncontract: c\ntests/contract_testcases/solana/negative_exponent.sol:5:5-44\nsignature g()\nvisibility public\nmutability pure"]
-	returns_8 [label="returns\nuint256 "]
-	return_9 [label="return\ntests/contract_testcases/solana/negative_exponent.sol:6:9-26"]
-	number_literal_10 [label="uint256 literal: 2\ntests/contract_testcases/solana/negative_exponent.sol:6:16-26"]
+	returns_11 [label="returns\nuint256 "]
+	return_12 [label="return\ntests/contract_testcases/solana/negative_exponent.sol:6:9-26"]
+	number_literal [label="uint256 literal: 2\ntests/contract_testcases/solana/negative_exponent.sol:6:16-26"]
 	h [label="function h\ncontract: c\ntests/contract_testcases/solana/negative_exponent.sol:8:5-44\nsignature h()\nvisibility public\nmutability pure"]
 	h [label="function h\ncontract: c\ntests/contract_testcases/solana/negative_exponent.sol:8:5-44\nsignature h()\nvisibility public\nmutability pure"]
-	returns_12 [label="returns\nuint256 "]
+	returns_15 [label="returns\nuint256 "]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/solana/negative_exponent.sol:1:1-12"]
 	diagnostic [label="found contract 'c'\nlevel Debug\ntests/contract_testcases/solana/negative_exponent.sol:1:1-12"]
-	diagnostic_15 [label="ethereum currency unit used while not targetting ethereum\nlevel Warning\ntests/contract_testcases/solana/negative_exponent.sol:6:23-26"]
-	diagnostic_16 [label="conversion to uint256 from rational not allowed\nlevel Error\ntests/contract_testcases/solana/negative_exponent.sol:9:2-20"]
+	diagnostic_18 [label="ethereum currency unit used while not targetting ethereum\nlevel Warning\ntests/contract_testcases/solana/negative_exponent.sol:6:23-26"]
+	diagnostic_19 [label="conversion to uint256 from rational not allowed\nlevel Error\ntests/contract_testcases/solana/negative_exponent.sol:9:2-20"]
 	contracts -> contract
 	contracts -> contract
 	contract -> f [label="function"]
 	contract -> f [label="function"]
 	f -> returns [label="returns"]
 	f -> returns [label="returns"]
 	f -> return [label="body"]
 	f -> return [label="body"]
-	return -> number_literal [label="expr"]
+	return -> cast [label="expr"]
+	cast -> add [label="expr"]
+	add -> rational_literal [label="left"]
+	add -> rational_literal_9 [label="right"]
 	contract -> g [label="function"]
 	contract -> g [label="function"]
-	g -> returns_8 [label="returns"]
-	g -> return_9 [label="body"]
-	return_9 -> number_literal_10 [label="expr"]
+	g -> returns_11 [label="returns"]
+	g -> return_12 [label="body"]
+	return_12 -> number_literal [label="expr"]
 	contract -> h [label="function"]
 	contract -> h [label="function"]
-	h -> returns_12 [label="returns"]
+	h -> returns_15 [label="returns"]
 	diagnostics -> diagnostic [label="Debug"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_15 [label="Warning"]
-	diagnostics -> diagnostic_16 [label="Error"]
+	diagnostics -> diagnostic_18 [label="Warning"]
+	diagnostics -> diagnostic_19 [label="Error"]
 }
 }