/* 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 . */ #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 clone(const std::vector& items) { std::vector result; result.reserve(items.size()); for (AnyV item : items) { result.push_back(clone(item)); } return result; } std::vector clone(const std::vector& items) { std::vector result; result.reserve(items.size()); for (AnyExprV item : items) { result.push_back(clone(item)); } return result; } // expressions virtual V clone(V v) { return createV(v->loc); } virtual V clone(V v) { return createV(v->loc, clone(v->get_expr())); } virtual V clone(V v) { return createV(v->loc, clone(v->get_items())); } virtual V clone(V v) { return createV(v->loc, clone(v->get_items())); } virtual V clone(V v) { return createV(v->loc, clone(v->get_identifier()), v->has_instantiationTs() ? clone(v->get_instantiationTs()) : nullptr); } virtual V clone(V v) { return createV(v->loc, clone(v->get_identifier()), clone(v->declared_type), v->is_immutable, v->marked_as_redef); } virtual V clone(V v) { return createV(v->loc, clone(v->get_expr())); } virtual V clone(V v) { return createV(v->loc, v->intval, v->orig_str); } virtual V clone(V v) { return createV(v->loc, v->str_val, v->modifier); } virtual V clone(V v) { return createV(v->loc, v->bool_val); } virtual V clone(V v) { return createV(v->loc); } virtual V clone(V v) { return createV(v->loc, clone(v->get_expr()), v->passed_as_mutate); } virtual V clone(V v) { return createV(v->loc, clone(v->get_arguments())); } virtual V clone(V v) { return createV(v->loc, clone(v->get_obj()), clone(v->get_identifier()), v->has_instantiationTs() ? clone(v->get_instantiationTs()) : nullptr); } virtual V clone(V v) { return createV(v->loc, clone(v->get_callee()), clone(v->get_arg_list())); } virtual V clone(V v) { return createV(v->loc); } virtual V clone(V v) { return createV(v->loc, clone(v->get_lhs()), clone(v->get_rhs())); } virtual V clone(V v) { return createV(v->loc, v->operator_name, v->tok, clone(v->get_lhs()), clone(v->get_rhs())); } virtual V clone(V v) { return createV(v->loc, v->operator_name, v->tok, clone(v->get_rhs())); } virtual V clone(V v) { return createV(v->loc, v->operator_name, v->tok, clone(v->get_lhs()), clone(v->get_rhs())); } virtual V clone(V v) { return createV(v->loc, clone(v->get_cond()), clone(v->get_when_true()), clone(v->get_when_false())); } virtual V clone(V v) { return createV(v->loc, clone(v->get_expr()), clone(v->cast_to_type)); } virtual V clone(V v) { return createV(v->loc, clone(v->get_expr())); } virtual V clone(V v) { return createV(v->loc, clone(v->get_expr()), v->is_negated); } // statements virtual V clone(V v) { return createV(v->loc); } virtual V clone(V v) { return createV(v->loc, v->loc_end, clone(v->get_items())); } virtual V clone(V v) { return createV(v->loc, clone(v->get_return_value())); } virtual V clone(V v) { return createV(v->loc, v->is_ifnot, clone(v->get_cond()), clone(v->get_if_body()), clone(v->get_else_body())); } virtual V clone(V v) { return createV(v->loc, clone(v->get_cond()), clone(v->get_body())); } virtual V clone(V v) { return createV(v->loc, clone(v->get_cond()), clone(v->get_body())); } virtual V clone(V v) { return createV(v->loc, clone(v->get_body()), clone(v->get_cond())); } virtual V clone(V v) { return createV(v->loc, clone(v->get_thrown_code()), clone(v->get_thrown_arg())); } virtual V clone(V v) { return createV(v->loc, clone(v->get_cond()), clone(v->get_thrown_code())); } virtual V clone(V v) { return createV(v->loc, clone(v->get_try_body()), clone(v->get_catch_expr()), clone(v->get_catch_body())); } virtual V clone(V v) { return createV(v->loc, v->arg_order, v->ret_order, clone(v->get_asm_commands())); } // other virtual V clone(V v) { return createV(v->loc, v->name); } virtual V clone(V v) { return createV(v->loc, clone(v->substituted_type)); } virtual V clone(V v) { return createV(v->loc, clone(v->get_items())); } virtual V clone(V v) { return createV(v->loc, v->param_name, clone(v->declared_type), v->declared_as_mutate); } virtual V clone(V v) { return createV(v->loc, clone(v->get_params())); } AnyExprV clone(AnyExprV v) final { switch (v->type) { case ast_empty_expression: return clone(v->as()); case ast_parenthesized_expression: return clone(v->as()); case ast_tensor: return clone(v->as()); case ast_typed_tuple: return clone(v->as()); case ast_reference: return clone(v->as()); case ast_local_var_lhs: return clone(v->as()); case ast_local_vars_declaration: return clone(v->as()); case ast_int_const: return clone(v->as()); case ast_string_const: return clone(v->as()); case ast_bool_const: return clone(v->as()); case ast_null_keyword: return clone(v->as()); case ast_argument: return clone(v->as()); case ast_argument_list: return clone(v->as()); case ast_dot_access: return clone(v->as()); case ast_function_call: return clone(v->as()); case ast_underscore: return clone(v->as()); case ast_assign: return clone(v->as()); case ast_set_assign: return clone(v->as()); case ast_unary_operator: return clone(v->as()); case ast_binary_operator: return clone(v->as()); case ast_ternary_operator: return clone(v->as()); case ast_cast_as_operator: return clone(v->as()); case ast_not_null_operator: return clone(v->as()); case ast_is_null_check: return clone(v->as()); default: throw UnexpectedASTNodeType(v, "ASTReplicatorFunction::clone"); } } AnyV clone(AnyV v) final { switch (v->type) { case ast_empty_statement: return clone(v->as()); case ast_sequence: return clone(v->as()); case ast_return_statement: return clone(v->as()); case ast_if_statement: return clone(v->as()); case ast_repeat_statement: return clone(v->as()); case ast_while_statement: return clone(v->as()); case ast_do_while_statement: return clone(v->as()); case ast_throw_statement: return clone(v->as()); case ast_assert_statement: return clone(v->as()); case ast_try_catch_statement: return clone(v->as()); case ast_asm_body: return clone(v->as()); // other AST nodes that can be children of ast nodes of function body case ast_identifier: return clone(v->as()); case ast_instantiationT_item: return clone(v->as()); case ast_instantiationT_list: return clone(v->as()); case ast_parameter: return clone(v->as()); case ast_parameter_list: return clone(v->as()); default: { // be very careful, don't forget to handle all statements/other (not expressions) above! AnyExprV as_expr = reinterpret_cast(v); return clone(as_expr); } } } TypePtr clone(TypePtr t) override { return t; } public: virtual V clone_function_body(V v_function) { return createV( v_function->loc, clone(v_function->get_identifier()), clone(v_function->get_param_list()), clone(v_function->get_body()->as()), clone(v_function->declared_return_type), v_function->genericsT_list, v_function->method_id, v_function->flags ); } }; } // namespace tolk