Detect alias cycles
This commit is contained in:
		@@ -914,8 +914,8 @@ namespace elna::boot
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while_statement::while_statement(const struct position position, conditional_statements *body,
 | 
			
		||||
            std::vector<conditional_statements *>&& branches, std::vector<statement *> *alternative)
 | 
			
		||||
        : node(position), m_body(body), branches(std::move(branches)), alternative(alternative)
 | 
			
		||||
            std::vector<conditional_statements *>&& branches)
 | 
			
		||||
        : node(position), m_body(body), branches(std::move(branches))
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -410,10 +410,10 @@ designator_expression:
 | 
			
		||||
statement:
 | 
			
		||||
    designator_expression ":=" expression
 | 
			
		||||
        { $$ = new boot::assign_statement(boot::make_position(@1), $1, $3); }
 | 
			
		||||
    | "while" expression "do" optional_statements elsif_do_statements else_statements "end"
 | 
			
		||||
    | "while" expression "do" optional_statements elsif_do_statements "end"
 | 
			
		||||
        {
 | 
			
		||||
            boot::conditional_statements *body = new boot::conditional_statements($2, std::move($4));
 | 
			
		||||
            $$ = new boot::while_statement(boot::make_position(@1), body, std::move($5), $6);
 | 
			
		||||
            $$ = new boot::while_statement(boot::make_position(@1), body, std::move($5));
 | 
			
		||||
        }
 | 
			
		||||
    | "if" expression "then" optional_statements elsif_then_statements else_statements "end"
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ along with GCC; see the file COPYING3.  If not see
 | 
			
		||||
 | 
			
		||||
#include "elna/boot/semantic.h"
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <set>
 | 
			
		||||
 | 
			
		||||
namespace elna::boot
 | 
			
		||||
@@ -44,7 +45,7 @@ namespace elna::boot
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    field_duplication_error::field_duplication_error(const std::string& field_name,
 | 
			
		||||
            const char *path, const struct position)
 | 
			
		||||
            const char *path, const struct position position)
 | 
			
		||||
        : error(path, position), field_name(field_name)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
@@ -55,14 +56,22 @@ namespace elna::boot
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cyclic_declaration_error::cyclic_declaration_error(const std::vector<std::string>& cycle,
 | 
			
		||||
            const char *path, const struct position)
 | 
			
		||||
            const char *path, const struct position position)
 | 
			
		||||
        : error(path, position), cycle(cycle)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string cyclic_declaration_error::what() const
 | 
			
		||||
    {
 | 
			
		||||
        return "Type declaration forms a cycle";
 | 
			
		||||
        auto segment = std::cbegin(this->cycle);
 | 
			
		||||
        std::string message = "Type declaration forms a cycle: " + *segment;
 | 
			
		||||
 | 
			
		||||
        ++segment;
 | 
			
		||||
        for (; segment != std::cend(this->cycle); ++segment)
 | 
			
		||||
        {
 | 
			
		||||
            message += " -> " + *segment;
 | 
			
		||||
        }
 | 
			
		||||
        return message;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    name_analysis_visitor::name_analysis_visitor(const char *path, std::shared_ptr<symbol_table> symbols,
 | 
			
		||||
@@ -348,6 +357,22 @@ namespace elna::boot
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool name_analysis_visitor::check_unresolved_symbol(std::shared_ptr<alias_type> alias,
 | 
			
		||||
            std::vector<std::string>& path)
 | 
			
		||||
    {
 | 
			
		||||
        if (std::find(std::cbegin(path), std::cend(path), alias->name) != std::cend(path))
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        path.push_back(alias->name);
 | 
			
		||||
 | 
			
		||||
        if (auto another_alias = alias->reference.get<alias_type>())
 | 
			
		||||
        {
 | 
			
		||||
            return check_unresolved_symbol(another_alias, path);
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void name_analysis_visitor::visit(unit *unit)
 | 
			
		||||
    {
 | 
			
		||||
        for (type_declaration *const type : unit->types)
 | 
			
		||||
@@ -356,8 +381,17 @@ namespace elna::boot
 | 
			
		||||
        }
 | 
			
		||||
        for (auto& unresolved : this->unresolved)
 | 
			
		||||
        {
 | 
			
		||||
            auto info = std::make_shared<type_info>(type_info(type(unresolved.second)));
 | 
			
		||||
            this->symbols->enter(std::move(unresolved.first), info);
 | 
			
		||||
            std::vector<std::string> path;
 | 
			
		||||
 | 
			
		||||
            if (check_unresolved_symbol(unresolved.second, path))
 | 
			
		||||
            {
 | 
			
		||||
                auto info = std::make_shared<type_info>(type_info(type(unresolved.second)));
 | 
			
		||||
                this->symbols->enter(std::move(unresolved.first), info);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                add_error<cyclic_declaration_error>(path, this->input_file, position{ 0, 0 });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        for (variable_declaration *const variable : unit->variables)
 | 
			
		||||
        {
 | 
			
		||||
@@ -539,6 +573,10 @@ namespace elna::boot
 | 
			
		||||
 | 
			
		||||
    void declaration_visitor::visit(unit *unit)
 | 
			
		||||
    {
 | 
			
		||||
        for (import_declaration *const _import : unit->imports)
 | 
			
		||||
        {
 | 
			
		||||
            _import->accept(this);
 | 
			
		||||
        }
 | 
			
		||||
        for (type_declaration *const type : unit->types)
 | 
			
		||||
        {
 | 
			
		||||
            const std::string& type_identifier = type->identifier.identifier;
 | 
			
		||||
@@ -547,10 +585,6 @@ namespace elna::boot
 | 
			
		||||
            {
 | 
			
		||||
                add_error<already_declared_error>(type->identifier.identifier, this->input_file, type->position());
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                type->accept(this);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -101,11 +101,11 @@ namespace elna::gcc
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tree build_composite_type(const std::vector<boot::type_field>& fields, tree composite_type_node,
 | 
			
		||||
            std::shared_ptr<symbol_table> symbols, std::vector<std::string>& path)
 | 
			
		||||
            std::shared_ptr<symbol_table> symbols)
 | 
			
		||||
    {
 | 
			
		||||
        for (auto& field : fields)
 | 
			
		||||
        {
 | 
			
		||||
            tree rewritten_field = get_inner_alias(field.second, symbols, path);
 | 
			
		||||
            tree rewritten_field = get_inner_alias(field.second, symbols);
 | 
			
		||||
            tree field_declaration = build_field(UNKNOWN_LOCATION,
 | 
			
		||||
                    composite_type_node, field.first, rewritten_field);
 | 
			
		||||
            TYPE_FIELDS(composite_type_node) = chainon(TYPE_FIELDS(composite_type_node), field_declaration);
 | 
			
		||||
@@ -114,25 +114,24 @@ namespace elna::gcc
 | 
			
		||||
        return composite_type_node;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tree build_procedure_type(const boot::procedure_type& procedure, std::shared_ptr<symbol_table> symbols,
 | 
			
		||||
            std::vector<std::string>& path)
 | 
			
		||||
    tree build_procedure_type(const boot::procedure_type& procedure, std::shared_ptr<symbol_table> symbols)
 | 
			
		||||
    {
 | 
			
		||||
        std::vector<tree> parameter_types(procedure.parameters.size());
 | 
			
		||||
 | 
			
		||||
        for (std::size_t i = 0; i < procedure.parameters.size(); ++i)
 | 
			
		||||
        {
 | 
			
		||||
            parameter_types[i] = get_inner_alias(procedure.parameters.at(i), symbols, path);
 | 
			
		||||
            parameter_types[i] = get_inner_alias(procedure.parameters.at(i), symbols);
 | 
			
		||||
        }
 | 
			
		||||
        tree return_type = void_type_node;
 | 
			
		||||
 | 
			
		||||
        if (!procedure.return_type.proper_type.empty())
 | 
			
		||||
        {
 | 
			
		||||
            return_type = get_inner_alias(procedure.return_type.proper_type, symbols, path);
 | 
			
		||||
            return_type = get_inner_alias(procedure.return_type.proper_type, symbols);
 | 
			
		||||
        }
 | 
			
		||||
        return build_function_type_array(return_type, procedure.parameters.size(), parameter_types.data());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tree get_inner_alias(const boot::type& type, std::shared_ptr<symbol_table> symbols, std::vector<std::string>& path)
 | 
			
		||||
    tree get_inner_alias(const boot::type& type, std::shared_ptr<symbol_table> symbols)
 | 
			
		||||
    {
 | 
			
		||||
        if (auto reference = type.get<boot::primitive_type>())
 | 
			
		||||
        {
 | 
			
		||||
@@ -145,7 +144,7 @@ namespace elna::gcc
 | 
			
		||||
        {
 | 
			
		||||
            tree composite_type_node = make_node(RECORD_TYPE);
 | 
			
		||||
 | 
			
		||||
            build_composite_type(reference->fields, composite_type_node, symbols, path);
 | 
			
		||||
            build_composite_type(reference->fields, composite_type_node, symbols);
 | 
			
		||||
 | 
			
		||||
            return composite_type_node;
 | 
			
		||||
        }
 | 
			
		||||
@@ -153,7 +152,7 @@ namespace elna::gcc
 | 
			
		||||
        {
 | 
			
		||||
            tree composite_type_node = make_node(UNION_TYPE);
 | 
			
		||||
 | 
			
		||||
            build_composite_type(reference->fields, composite_type_node, symbols, path);
 | 
			
		||||
            build_composite_type(reference->fields, composite_type_node, symbols);
 | 
			
		||||
 | 
			
		||||
            return composite_type_node;
 | 
			
		||||
        }
 | 
			
		||||
@@ -163,42 +162,35 @@ namespace elna::gcc
 | 
			
		||||
        }
 | 
			
		||||
        else if (auto reference = type.get<boot::pointer_type>())
 | 
			
		||||
        {
 | 
			
		||||
            return build_global_pointer_type(get_inner_alias(reference->base, symbols, path));
 | 
			
		||||
            return build_global_pointer_type(get_inner_alias(reference->base, symbols));
 | 
			
		||||
        }
 | 
			
		||||
        else if (auto reference = type.get<boot::array_type>())
 | 
			
		||||
        {
 | 
			
		||||
            tree base = get_inner_alias(reference->base, symbols, path);
 | 
			
		||||
            tree base = get_inner_alias(reference->base, symbols);
 | 
			
		||||
 | 
			
		||||
            return build_static_array_type(base, reference->size);
 | 
			
		||||
        }
 | 
			
		||||
        else if (auto reference = type.get<boot::procedure_type>())
 | 
			
		||||
        {
 | 
			
		||||
            auto procedure = build_procedure_type(*reference, symbols, path);
 | 
			
		||||
            auto procedure = build_procedure_type(*reference, symbols);
 | 
			
		||||
 | 
			
		||||
            return build_global_pointer_type(procedure);
 | 
			
		||||
        }
 | 
			
		||||
        else if (auto reference = type.get<boot::alias_type>())
 | 
			
		||||
        {
 | 
			
		||||
            return handle_symbol(reference->name, reference, symbols, path);
 | 
			
		||||
            return handle_symbol(reference->name, reference, symbols);
 | 
			
		||||
        }
 | 
			
		||||
        return error_mark_node;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tree handle_symbol(const std::string& symbol_name, std::shared_ptr<boot::alias_type> reference,
 | 
			
		||||
            std::shared_ptr<symbol_table> symbols, std::vector<std::string>& path)
 | 
			
		||||
            std::shared_ptr<symbol_table> symbols)
 | 
			
		||||
    {
 | 
			
		||||
        path.push_back(symbol_name);
 | 
			
		||||
        std::vector<std::string>::const_iterator head_peace = std::cbegin(path);
 | 
			
		||||
 | 
			
		||||
        if (std::find(std::next(head_peace), std::cend(path), *head_peace) != std::cend(path))
 | 
			
		||||
        {
 | 
			
		||||
            return error_mark_node;
 | 
			
		||||
        }
 | 
			
		||||
        tree looked_up = symbols->lookup(symbol_name);
 | 
			
		||||
 | 
			
		||||
        if (looked_up == NULL_TREE)
 | 
			
		||||
        {
 | 
			
		||||
            looked_up = get_inner_alias(reference->reference, symbols, path);
 | 
			
		||||
            looked_up = get_inner_alias(reference->reference, symbols);
 | 
			
		||||
 | 
			
		||||
            symbols->enter(symbol_name, build_type_declaration(symbol_name, looked_up));
 | 
			
		||||
        }
 | 
			
		||||
@@ -212,8 +204,7 @@ namespace elna::gcc
 | 
			
		||||
    void declare_procedure(const std::string& name, const boot::procedure_info& info,
 | 
			
		||||
            std::shared_ptr<symbol_table> symbols)
 | 
			
		||||
    {
 | 
			
		||||
        std::vector<std::string> path;
 | 
			
		||||
        tree declaration_type = gcc::build_procedure_type(info.symbol, symbols, path);
 | 
			
		||||
        tree declaration_type = gcc::build_procedure_type(info.symbol, symbols);
 | 
			
		||||
        tree fndecl = build_fn_decl(name.c_str(), declaration_type);
 | 
			
		||||
        symbols->enter(name, fndecl);
 | 
			
		||||
 | 
			
		||||
@@ -247,18 +238,16 @@ namespace elna::gcc
 | 
			
		||||
        DECL_EXTERNAL(fndecl) = info.symbols == nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void do_semantic_analysis(std::shared_ptr<boot::symbol_table> info_table, std::shared_ptr<symbol_table> symbols)
 | 
			
		||||
    void rewrite_symbol_table(std::shared_ptr<boot::symbol_table> info_table, std::shared_ptr<symbol_table> symbols)
 | 
			
		||||
    {
 | 
			
		||||
        for (auto& [symbol_name, symbol_info] : *info_table)
 | 
			
		||||
        {
 | 
			
		||||
            std::vector<std::string> type_path;
 | 
			
		||||
 | 
			
		||||
            if (auto type_info = symbol_info->is_type())
 | 
			
		||||
            {
 | 
			
		||||
                // The top level symbol table has basic (builtin) types in it which are not aliases.
 | 
			
		||||
                if (auto alias_type = type_info->symbol.get<boot::alias_type>())
 | 
			
		||||
                {
 | 
			
		||||
                    handle_symbol(symbol_name, alias_type, symbols, type_path);
 | 
			
		||||
                    handle_symbol(symbol_name, alias_type, symbols);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else if (auto procedure_info = symbol_info->is_procedure())
 | 
			
		||||
 
 | 
			
		||||
@@ -145,8 +145,12 @@ namespace elna::gcc
 | 
			
		||||
    {
 | 
			
		||||
        for (const auto& error : errors)
 | 
			
		||||
        {
 | 
			
		||||
            auto gcc_location = elna::gcc::get_location(&error->position);
 | 
			
		||||
            location_t gcc_location{ UNKNOWN_LOCATION };
 | 
			
		||||
 | 
			
		||||
            if (error->position.line != 0 || error->position.column != 0)
 | 
			
		||||
            {
 | 
			
		||||
                gcc_location = elna::gcc::get_location(&error->position);
 | 
			
		||||
            }
 | 
			
		||||
            error_at(gcc_location, error->what().c_str());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -217,8 +217,7 @@ namespace elna::gcc
 | 
			
		||||
 | 
			
		||||
    void generic_visitor::visit(boot::cast_expression *expression)
 | 
			
		||||
    {
 | 
			
		||||
        std::vector<std::string> path;
 | 
			
		||||
        tree cast_target = get_inner_alias(expression->expression_type, this->symbols->scope(), path);
 | 
			
		||||
        tree cast_target = get_inner_alias(expression->expression_type, this->symbols->scope());
 | 
			
		||||
 | 
			
		||||
        expression->value().accept(this);
 | 
			
		||||
        tree cast_source = TREE_TYPE(this->current_expression);
 | 
			
		||||
@@ -746,10 +745,9 @@ namespace elna::gcc
 | 
			
		||||
 | 
			
		||||
    void generic_visitor::visit(boot::variable_declaration *declaration)
 | 
			
		||||
    {
 | 
			
		||||
        std::vector<std::string> path;
 | 
			
		||||
        this->current_expression = get_inner_alias(
 | 
			
		||||
                this->info_table->lookup(declaration->identifier.identifier)->is_variable()->symbol,
 | 
			
		||||
                this->symbols->scope(), path);
 | 
			
		||||
                this->symbols->scope());
 | 
			
		||||
 | 
			
		||||
        location_t declaration_location = get_location(&declaration->position());
 | 
			
		||||
        tree declaration_tree = build_decl(declaration_location, VAR_DECL,
 | 
			
		||||
@@ -854,8 +852,7 @@ namespace elna::gcc
 | 
			
		||||
            this->current_expression = error_mark_node;
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        std::vector<std::string> path;
 | 
			
		||||
        this->current_expression = get_inner_alias(trait->types.front(), this->symbols, path);
 | 
			
		||||
        this->current_expression = get_inner_alias(trait->types.front(), this->symbols);
 | 
			
		||||
 | 
			
		||||
        return this->current_expression != error_mark_node;
 | 
			
		||||
    }
 | 
			
		||||
@@ -919,8 +916,7 @@ namespace elna::gcc
 | 
			
		||||
                this->current_expression = error_mark_node;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            std::vector<std::string> path;
 | 
			
		||||
            this->current_expression = get_inner_alias(trait->types.front(), this->symbols, path);
 | 
			
		||||
            this->current_expression = get_inner_alias(trait->types.front(), this->symbols);
 | 
			
		||||
            auto field_type = trait->parameters.at(1)->is_named();
 | 
			
		||||
 | 
			
		||||
            if (field_type == nullptr)
 | 
			
		||||
@@ -1128,13 +1124,6 @@ namespace elna::gcc
 | 
			
		||||
        {
 | 
			
		||||
            make_if_branch(*branch, goto_check);
 | 
			
		||||
        }
 | 
			
		||||
        if (statement->alternative != nullptr)
 | 
			
		||||
        {
 | 
			
		||||
            enter_scope();
 | 
			
		||||
            visit_statements(*statement->alternative);
 | 
			
		||||
            tree mapping = leave_scope();
 | 
			
		||||
            append_statement(mapping);
 | 
			
		||||
        }
 | 
			
		||||
        append_statement(branch_end_expression);
 | 
			
		||||
        this->current_expression = NULL_TREE;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -95,7 +95,7 @@ static void elna_parse_file(const char *filename)
 | 
			
		||||
 | 
			
		||||
                if (name_analysis_visitor.errors().empty())
 | 
			
		||||
                {
 | 
			
		||||
                    elna::gcc::do_semantic_analysis(info_table, symbol_table);
 | 
			
		||||
                    elna::gcc::rewrite_symbol_table(info_table, symbol_table);
 | 
			
		||||
 | 
			
		||||
                    elna::gcc::generic_visitor generic_visitor{ symbol_table, info_table };
 | 
			
		||||
                    generic_visitor.visit(module_tree.get());
 | 
			
		||||
 
 | 
			
		||||
@@ -659,10 +659,9 @@ namespace elna::boot
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        const std::vector<conditional_statements *> branches;
 | 
			
		||||
        const std::vector<statement *> *alternative;
 | 
			
		||||
 | 
			
		||||
        while_statement(const struct position position, conditional_statements *body,
 | 
			
		||||
                std::vector<conditional_statements *>&& branches, std::vector<statement *> *alternative = nullptr);
 | 
			
		||||
                std::vector<conditional_statements *>&& branches);
 | 
			
		||||
        void accept(parser_visitor *visitor) override;
 | 
			
		||||
 | 
			
		||||
        conditional_statements& body();
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,7 @@ namespace elna::boot
 | 
			
		||||
        const std::string field_name;
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        field_duplication_error(const std::string& field_name, const char *path, const struct position);
 | 
			
		||||
        field_duplication_error(const std::string& field_name, const char *path, const struct position position);
 | 
			
		||||
 | 
			
		||||
        std::string what() const override;
 | 
			
		||||
    };
 | 
			
		||||
@@ -63,7 +63,8 @@ namespace elna::boot
 | 
			
		||||
        const std::vector<std::string> cycle;
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        cyclic_declaration_error(const std::vector<std::string>& cycle, const char *path, const struct position);
 | 
			
		||||
        cyclic_declaration_error(const std::vector<std::string>& cycle,
 | 
			
		||||
                const char *path, const struct position position);
 | 
			
		||||
 | 
			
		||||
        std::string what() const override;
 | 
			
		||||
    };
 | 
			
		||||
@@ -82,6 +83,9 @@ namespace elna::boot
 | 
			
		||||
        procedure_type build_procedure(procedure_type_expression& type_expression);
 | 
			
		||||
        std::vector<type_field> build_composite_type(const std::vector<field_declaration>& fields);
 | 
			
		||||
 | 
			
		||||
        bool check_unresolved_symbol(std::shared_ptr<alias_type> alias,
 | 
			
		||||
                std::vector<std::string>& path);
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
        explicit name_analysis_visitor(const char *path, std::shared_ptr<symbol_table> symbols,
 | 
			
		||||
                std::unordered_map<std::string, std::shared_ptr<alias_type>>&& unresolved);
 | 
			
		||||
 
 | 
			
		||||
@@ -30,11 +30,10 @@ namespace elna::gcc
 | 
			
		||||
    void init_ttree();
 | 
			
		||||
    std::shared_ptr<symbol_table> builtin_symbol_table();
 | 
			
		||||
 | 
			
		||||
    void do_semantic_analysis(std::shared_ptr<boot::symbol_table> info_table, std::shared_ptr<symbol_table> symbols);
 | 
			
		||||
    void rewrite_symbol_table(std::shared_ptr<boot::symbol_table> info_table, std::shared_ptr<symbol_table> symbols);
 | 
			
		||||
    tree handle_symbol(const std::string& symbol_name, std::shared_ptr<boot::alias_type> reference,
 | 
			
		||||
            std::shared_ptr<symbol_table> symbols, std::vector<std::string>& path);
 | 
			
		||||
    tree get_inner_alias(const boot::type& type, std::shared_ptr<symbol_table> symbols,
 | 
			
		||||
            std::vector<std::string>& path);
 | 
			
		||||
            std::shared_ptr<symbol_table> symbols);
 | 
			
		||||
    tree get_inner_alias(const boot::type& type, std::shared_ptr<symbol_table> symbols);
 | 
			
		||||
    void declare_procedure(const std::string& name, const boot::procedure_info& info,
 | 
			
		||||
            std::shared_ptr<symbol_table> symbols);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user