mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
[Tolk] Change order of assignment evaluation, lhs first
In FunC (and in Tolk before), the assignment > lhs = rhs evaluation order (at IR level) was "rhs first, lhs second". In practice, this did not matter, because lhs could only be a primitive: > (v1, v2) = getValue() Left side of assignment actually has no "evaluation". Since Tolk implemented indexed access, there could be > getTensor().0 = getValue() or (in the future) > getObject().field = getValue() where evaluation order becomes significant. Now evaluation order will be to "lhs first, rhs second" (more expected from user's point of view), which will become significant when building control flow graph.
This commit is contained in:
parent
2a68c8610b
commit
1389ff6789
20 changed files with 602 additions and 456 deletions
|
@ -25,7 +25,6 @@
|
|||
*
|
||||
* Example: `boolVar == true` -> `boolVar`.
|
||||
* Example: `!!boolVar` -> `boolVar`.
|
||||
* Also in unwraps parenthesis inside if condition and similar: `assert(((x)), 404)` -> `assert(x, 404)`
|
||||
*
|
||||
* todo some day, replace && || with & | when it's safe (currently, && always produces IFs in Fift)
|
||||
* It's tricky to implement whether replacing is safe.
|
||||
|
@ -35,13 +34,6 @@
|
|||
|
||||
namespace tolk {
|
||||
|
||||
static AnyExprV unwrap_parenthesis(AnyExprV v) {
|
||||
while (v->type == ast_parenthesized_expression) {
|
||||
v = v->as<ast_parenthesized_expression>()->get_expr();
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
struct OptimizerBooleanExpressionsReplacer final : ASTReplacerInFunctionBody {
|
||||
static V<ast_int_const> create_int_const(SrcLocation loc, td::RefInt256&& intval) {
|
||||
auto v_int = createV<ast_int_const>(loc, std::move(intval), {});
|
||||
|
@ -117,9 +109,6 @@ protected:
|
|||
|
||||
AnyV replace(V<ast_if_statement> v) override {
|
||||
parent::replace(v);
|
||||
if (v->get_cond()->type == ast_parenthesized_expression) {
|
||||
v = createV<ast_if_statement>(v->loc, v->is_ifnot, unwrap_parenthesis(v->get_cond()), v->get_if_body(), v->get_else_body());
|
||||
}
|
||||
|
||||
// `if (!x)` -> ifnot(x)
|
||||
while (auto v_cond_unary = v->get_cond()->try_as<ast_unary_operator>()) {
|
||||
|
@ -132,33 +121,6 @@ protected:
|
|||
return v;
|
||||
}
|
||||
|
||||
AnyV replace(V<ast_while_statement> v) override {
|
||||
parent::replace(v);
|
||||
|
||||
if (v->get_cond()->type == ast_parenthesized_expression) {
|
||||
v = createV<ast_while_statement>(v->loc, unwrap_parenthesis(v->get_cond()), v->get_body());
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
AnyV replace(V<ast_do_while_statement> v) override {
|
||||
parent::replace(v);
|
||||
|
||||
if (v->get_cond()->type == ast_parenthesized_expression) {
|
||||
v = createV<ast_do_while_statement>(v->loc, v->get_body(), unwrap_parenthesis(v->get_cond()));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
AnyV replace(V<ast_assert_statement> v) override {
|
||||
parent::replace(v);
|
||||
|
||||
if (v->get_cond()->type == ast_parenthesized_expression) {
|
||||
v = createV<ast_assert_statement>(v->loc, unwrap_parenthesis(v->get_cond()), v->get_thrown_code());
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
public:
|
||||
bool should_visit_function(const FunctionData* fun_ref) override {
|
||||
return fun_ref->is_code_function() && !fun_ref->is_generic_function();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue