/*
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