1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-02-12 11:12:16 +00:00
ton/tolk/ast-replicator.h
2025-02-11 22:49:26 +04:00

263 lines
12 KiB
C++

/*
This file is part of TON Blockchain Library.
TON Blockchain Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
TON Blockchain Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "ast.h"
#include "platform-utils.h"
namespace tolk {
class ASTReplicator {
protected:
virtual AnyV clone(AnyV v) = 0;
virtual AnyExprV clone(AnyExprV v) = 0;
virtual TypePtr clone(TypePtr) = 0;
public:
virtual ~ASTReplicator() = default;
};
class ASTReplicatorFunction : public ASTReplicator {
protected:
using parent = ASTReplicatorFunction;
std::vector<AnyV> clone(const std::vector<AnyV>& items) {
std::vector<AnyV> result;
result.reserve(items.size());
for (AnyV item : items) {
result.push_back(clone(item));
}
return result;
}
std::vector<AnyExprV> clone(const std::vector<AnyExprV>& items) {
std::vector<AnyExprV> result;
result.reserve(items.size());
for (AnyExprV item : items) {
result.push_back(clone(item));
}
return result;
}
// expressions
virtual V<ast_empty_expression> clone(V<ast_empty_expression> v) {
return createV<ast_empty_expression>(v->loc);
}
virtual V<ast_parenthesized_expression> clone(V<ast_parenthesized_expression> v) {
return createV<ast_parenthesized_expression>(v->loc, clone(v->get_expr()));
}
virtual V<ast_tensor> clone(V<ast_tensor> v) {
return createV<ast_tensor>(v->loc, clone(v->get_items()));
}
virtual V<ast_typed_tuple> clone(V<ast_typed_tuple> v) {
return createV<ast_typed_tuple>(v->loc, clone(v->get_items()));
}
virtual V<ast_reference> clone(V<ast_reference> v) {
return createV<ast_reference>(v->loc, clone(v->get_identifier()), v->has_instantiationTs() ? clone(v->get_instantiationTs()) : nullptr);
}
virtual V<ast_local_var_lhs> clone(V<ast_local_var_lhs> v) {
return createV<ast_local_var_lhs>(v->loc, clone(v->get_identifier()), clone(v->declared_type), v->is_immutable, v->marked_as_redef);
}
virtual V<ast_local_vars_declaration> clone(V<ast_local_vars_declaration> v) {
return createV<ast_local_vars_declaration>(v->loc, clone(v->get_expr()));
}
virtual V<ast_int_const> clone(V<ast_int_const> v) {
return createV<ast_int_const>(v->loc, v->intval, v->orig_str);
}
virtual V<ast_string_const> clone(V<ast_string_const> v) {
return createV<ast_string_const>(v->loc, v->str_val, v->modifier);
}
virtual V<ast_bool_const> clone(V<ast_bool_const> v) {
return createV<ast_bool_const>(v->loc, v->bool_val);
}
virtual V<ast_null_keyword> clone(V<ast_null_keyword> v) {
return createV<ast_null_keyword>(v->loc);
}
virtual V<ast_argument> clone(V<ast_argument> v) {
return createV<ast_argument>(v->loc, clone(v->get_expr()), v->passed_as_mutate);
}
virtual V<ast_argument_list> clone(V<ast_argument_list> v) {
return createV<ast_argument_list>(v->loc, clone(v->get_arguments()));
}
virtual V<ast_dot_access> clone(V<ast_dot_access> v) {
return createV<ast_dot_access>(v->loc, clone(v->get_obj()), clone(v->get_identifier()), v->has_instantiationTs() ? clone(v->get_instantiationTs()) : nullptr);
}
virtual V<ast_function_call> clone(V<ast_function_call> v) {
return createV<ast_function_call>(v->loc, clone(v->get_callee()), clone(v->get_arg_list()));
}
virtual V<ast_underscore> clone(V<ast_underscore> v) {
return createV<ast_underscore>(v->loc);
}
virtual V<ast_assign> clone(V<ast_assign> v) {
return createV<ast_assign>(v->loc, clone(v->get_lhs()), clone(v->get_rhs()));
}
virtual V<ast_set_assign> clone(V<ast_set_assign> v) {
return createV<ast_set_assign>(v->loc, v->operator_name, v->tok, clone(v->get_lhs()), clone(v->get_rhs()));
}
virtual V<ast_unary_operator> clone(V<ast_unary_operator> v) {
return createV<ast_unary_operator>(v->loc, v->operator_name, v->tok, clone(v->get_rhs()));
}
virtual V<ast_binary_operator> clone(V<ast_binary_operator> v) {
return createV<ast_binary_operator>(v->loc, v->operator_name, v->tok, clone(v->get_lhs()), clone(v->get_rhs()));
}
virtual V<ast_ternary_operator> clone(V<ast_ternary_operator> v) {
return createV<ast_ternary_operator>(v->loc, clone(v->get_cond()), clone(v->get_when_true()), clone(v->get_when_false()));
}
virtual V<ast_cast_as_operator> clone(V<ast_cast_as_operator> v) {
return createV<ast_cast_as_operator>(v->loc, clone(v->get_expr()), clone(v->cast_to_type));
}
virtual V<ast_not_null_operator> clone(V<ast_not_null_operator> v) {
return createV<ast_not_null_operator>(v->loc, clone(v->get_expr()));
}
virtual V<ast_is_null_check> clone(V<ast_is_null_check> v) {
return createV<ast_is_null_check>(v->loc, clone(v->get_expr()), v->is_negated);
}
// statements
virtual V<ast_empty_statement> clone(V<ast_empty_statement> v) {
return createV<ast_empty_statement>(v->loc);
}
virtual V<ast_sequence> clone(V<ast_sequence> v) {
return createV<ast_sequence>(v->loc, v->loc_end, clone(v->get_items()));
}
virtual V<ast_return_statement> clone(V<ast_return_statement> v) {
return createV<ast_return_statement>(v->loc, clone(v->get_return_value()));
}
virtual V<ast_if_statement> clone(V<ast_if_statement> v) {
return createV<ast_if_statement>(v->loc, v->is_ifnot, clone(v->get_cond()), clone(v->get_if_body()), clone(v->get_else_body()));
}
virtual V<ast_repeat_statement> clone(V<ast_repeat_statement> v) {
return createV<ast_repeat_statement>(v->loc, clone(v->get_cond()), clone(v->get_body()));
}
virtual V<ast_while_statement> clone(V<ast_while_statement> v) {
return createV<ast_while_statement>(v->loc, clone(v->get_cond()), clone(v->get_body()));
}
virtual V<ast_do_while_statement> clone(V<ast_do_while_statement> v) {
return createV<ast_do_while_statement>(v->loc, clone(v->get_body()), clone(v->get_cond()));
}
virtual V<ast_throw_statement> clone(V<ast_throw_statement> v) {
return createV<ast_throw_statement>(v->loc, clone(v->get_thrown_code()), clone(v->get_thrown_arg()));
}
virtual V<ast_assert_statement> clone(V<ast_assert_statement> v) {
return createV<ast_assert_statement>(v->loc, clone(v->get_cond()), clone(v->get_thrown_code()));
}
virtual V<ast_try_catch_statement> clone(V<ast_try_catch_statement> v) {
return createV<ast_try_catch_statement>(v->loc, clone(v->get_try_body()), clone(v->get_catch_expr()), clone(v->get_catch_body()));
}
virtual V<ast_asm_body> clone(V<ast_asm_body> v) {
return createV<ast_asm_body>(v->loc, v->arg_order, v->ret_order, clone(v->get_asm_commands()));
}
// other
virtual V<ast_identifier> clone(V<ast_identifier> v) {
return createV<ast_identifier>(v->loc, v->name);
}
virtual V<ast_instantiationT_item> clone(V<ast_instantiationT_item> v) {
return createV<ast_instantiationT_item>(v->loc, clone(v->substituted_type));
}
virtual V<ast_instantiationT_list> clone(V<ast_instantiationT_list> v) {
return createV<ast_instantiationT_list>(v->loc, clone(v->get_items()));
}
virtual V<ast_parameter> clone(V<ast_parameter> v) {
return createV<ast_parameter>(v->loc, v->param_name, clone(v->declared_type), v->declared_as_mutate);
}
virtual V<ast_parameter_list> clone(V<ast_parameter_list> v) {
return createV<ast_parameter_list>(v->loc, clone(v->get_params()));
}
AnyExprV clone(AnyExprV v) final {
switch (v->type) {
case ast_empty_expression: return clone(v->as<ast_empty_expression>());
case ast_parenthesized_expression: return clone(v->as<ast_parenthesized_expression>());
case ast_tensor: return clone(v->as<ast_tensor>());
case ast_typed_tuple: return clone(v->as<ast_typed_tuple>());
case ast_reference: return clone(v->as<ast_reference>());
case ast_local_var_lhs: return clone(v->as<ast_local_var_lhs>());
case ast_local_vars_declaration: return clone(v->as<ast_local_vars_declaration>());
case ast_int_const: return clone(v->as<ast_int_const>());
case ast_string_const: return clone(v->as<ast_string_const>());
case ast_bool_const: return clone(v->as<ast_bool_const>());
case ast_null_keyword: return clone(v->as<ast_null_keyword>());
case ast_argument: return clone(v->as<ast_argument>());
case ast_argument_list: return clone(v->as<ast_argument_list>());
case ast_dot_access: return clone(v->as<ast_dot_access>());
case ast_function_call: return clone(v->as<ast_function_call>());
case ast_underscore: return clone(v->as<ast_underscore>());
case ast_assign: return clone(v->as<ast_assign>());
case ast_set_assign: return clone(v->as<ast_set_assign>());
case ast_unary_operator: return clone(v->as<ast_unary_operator>());
case ast_binary_operator: return clone(v->as<ast_binary_operator>());
case ast_ternary_operator: return clone(v->as<ast_ternary_operator>());
case ast_cast_as_operator: return clone(v->as<ast_cast_as_operator>());
case ast_not_null_operator: return clone(v->as<ast_not_null_operator>());
case ast_is_null_check: return clone(v->as<ast_is_null_check>());
default:
throw UnexpectedASTNodeType(v, "ASTReplicatorFunction::clone");
}
}
AnyV clone(AnyV v) final {
switch (v->type) {
case ast_empty_statement: return clone(v->as<ast_empty_statement>());
case ast_sequence: return clone(v->as<ast_sequence>());
case ast_return_statement: return clone(v->as<ast_return_statement>());
case ast_if_statement: return clone(v->as<ast_if_statement>());
case ast_repeat_statement: return clone(v->as<ast_repeat_statement>());
case ast_while_statement: return clone(v->as<ast_while_statement>());
case ast_do_while_statement: return clone(v->as<ast_do_while_statement>());
case ast_throw_statement: return clone(v->as<ast_throw_statement>());
case ast_assert_statement: return clone(v->as<ast_assert_statement>());
case ast_try_catch_statement: return clone(v->as<ast_try_catch_statement>());
case ast_asm_body: return clone(v->as<ast_asm_body>());
// other AST nodes that can be children of ast nodes of function body
case ast_identifier: return clone(v->as<ast_identifier>());
case ast_instantiationT_item: return clone(v->as<ast_instantiationT_item>());
case ast_instantiationT_list: return clone(v->as<ast_instantiationT_list>());
case ast_parameter: return clone(v->as<ast_parameter>());
case ast_parameter_list: return clone(v->as<ast_parameter_list>());
default: {
// be very careful, don't forget to handle all statements/other (not expressions) above!
AnyExprV as_expr = reinterpret_cast<const ASTNodeExpressionBase*>(v);
return clone(as_expr);
}
}
}
TypePtr clone(TypePtr t) override {
return t;
}
public:
virtual V<ast_function_declaration> clone_function_body(V<ast_function_declaration> v_function) {
return createV<ast_function_declaration>(
v_function->loc,
clone(v_function->get_identifier()),
clone(v_function->get_param_list()),
clone(v_function->get_body()->as<ast_sequence>()),
clone(v_function->declared_return_type),
v_function->genericsT_list,
v_function->method_id,
v_function->flags
);
}
};
} // namespace tolk