1
0
Fork 0
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:
tolk-vm 2025-02-10 12:57:25 +04:00
parent 2a68c8610b
commit 1389ff6789
No known key found for this signature in database
GPG key ID: 7905DD7FE0324B12
20 changed files with 602 additions and 456 deletions

View file

@ -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();