Document symbol bag class and methods
This commit is contained in:
@@ -217,12 +217,6 @@ namespace elna::boot
|
||||
virtual literal_expression *is_literal();
|
||||
};
|
||||
|
||||
struct identifier_definition
|
||||
{
|
||||
std::string identifier;
|
||||
bool exported;
|
||||
};
|
||||
|
||||
/**
|
||||
* Symbol definition.
|
||||
*/
|
||||
|
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include <fstream>
|
||||
#include "elna/boot/result.h"
|
||||
#include "elna/boot/ast.h"
|
||||
#include "elna/boot/symbol.h"
|
||||
|
||||
namespace elna::boot
|
||||
{
|
||||
|
@@ -106,4 +106,19 @@ namespace elna::boot
|
||||
T proper_type{};
|
||||
bool no_return{ false };
|
||||
};
|
||||
|
||||
struct identifier_definition
|
||||
{
|
||||
std::string name;
|
||||
bool exported;
|
||||
|
||||
bool operator==(const identifier_definition& that) const;
|
||||
bool operator==(const std::string& that) const;
|
||||
};
|
||||
}
|
||||
|
||||
template<>
|
||||
struct std::hash<elna::boot::identifier_definition>
|
||||
{
|
||||
std::size_t operator()(const elna::boot::identifier_definition& key) const noexcept;
|
||||
};
|
||||
|
@@ -93,22 +93,26 @@ namespace elna::boot
|
||||
class type_analysis_visitor final : public empty_visitor, public error_container
|
||||
{
|
||||
bool returns;
|
||||
symbol_bag bag;
|
||||
|
||||
bool check_unresolved_symbol(std::shared_ptr<alias_type> alias,
|
||||
std::vector<std::string>& path);
|
||||
|
||||
public:
|
||||
explicit type_analysis_visitor(const char *path);
|
||||
explicit type_analysis_visitor(const char *path, symbol_bag bag);
|
||||
|
||||
void visit(program *program) override;
|
||||
|
||||
void visit(procedure_declaration *definition) override;
|
||||
void visit(assign_statement *) override;
|
||||
void visit(if_statement *) override;
|
||||
void visit(import_declaration *) override;
|
||||
void visit(while_statement *) override;
|
||||
void visit(return_statement *) override;
|
||||
void visit(defer_statement *) override;
|
||||
void visit(case_statement *) override;
|
||||
void visit(procedure_call *) override;
|
||||
void visit(unit *unit) override;
|
||||
void visit(type_declaration *definition) override;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -124,9 +128,6 @@ 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:
|
||||
name_analysis_visitor(const char *path, symbol_bag bag);
|
||||
|
||||
@@ -175,13 +176,14 @@ namespace elna::boot
|
||||
class declaration_visitor final : public empty_visitor, public error_container
|
||||
{
|
||||
public:
|
||||
std::unordered_map<std::string, std::shared_ptr<alias_type>> unresolved;
|
||||
forward_table unresolved;
|
||||
|
||||
explicit declaration_visitor(const char *path);
|
||||
|
||||
void visit(program *program) override;
|
||||
void visit(import_declaration *) override;
|
||||
void visit(unit *unit) override;
|
||||
void visit(type_declaration *definition) override;
|
||||
void visit(variable_declaration *declaration) override;
|
||||
void visit(procedure_declaration *definition) override;
|
||||
};
|
||||
|
@@ -161,6 +161,8 @@ namespace elna::boot
|
||||
class info : public std::enable_shared_from_this<info>
|
||||
{
|
||||
public:
|
||||
bool exported{ false };
|
||||
|
||||
virtual ~info() = 0;
|
||||
|
||||
virtual std::shared_ptr<type_info> is_type();
|
||||
@@ -231,6 +233,7 @@ namespace elna::boot
|
||||
* can not be found.
|
||||
*
|
||||
* \param name Symbol name.
|
||||
*
|
||||
* \return Symbol from the table if found.
|
||||
*/
|
||||
symbol_ptr lookup(const std::string& name)
|
||||
@@ -250,6 +253,7 @@ namespace elna::boot
|
||||
|
||||
/**
|
||||
* \param name Symbol name.
|
||||
*
|
||||
* \return Whether the table contains a symbol with the given name.
|
||||
*/
|
||||
bool contains(const std::string& name)
|
||||
@@ -293,16 +297,37 @@ namespace elna::boot
|
||||
std::shared_ptr<type_info> is_type() override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Procedure symbol information.
|
||||
*/
|
||||
class procedure_info : public info
|
||||
{
|
||||
public:
|
||||
/// Procedure type.
|
||||
const procedure_type symbol;
|
||||
const std::vector<std::string> names;
|
||||
std::shared_ptr<symbol_table> symbols;
|
||||
|
||||
/// Parameter names.
|
||||
const std::vector<std::string> names;
|
||||
|
||||
/// Local definitions.
|
||||
std::shared_ptr<symbol_table> scope;
|
||||
|
||||
/**
|
||||
* Constructs procedure symbol information.
|
||||
*
|
||||
* \param symbol Procedure type.
|
||||
* \param names Parameter names.
|
||||
* \param scope Local definition (is `nullptr` for extern symbols).
|
||||
*/
|
||||
procedure_info(const procedure_type symbol, const std::vector<std::string> names,
|
||||
std::shared_ptr<symbol_table> scope = nullptr);
|
||||
|
||||
std::shared_ptr<procedure_info> is_procedure() override;
|
||||
|
||||
/**
|
||||
* \return Whether this is an extern symbol.
|
||||
*/
|
||||
bool is_extern() const;
|
||||
};
|
||||
|
||||
class constant_info : public info
|
||||
@@ -317,35 +342,116 @@ namespace elna::boot
|
||||
std::shared_ptr<constant_info> is_constant() override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable symbol information.
|
||||
*/
|
||||
class variable_info : public info
|
||||
{
|
||||
public:
|
||||
/// Variable type.
|
||||
const type symbol;
|
||||
|
||||
variable_info(const type symbol);
|
||||
/// Whether this is an extern symbol.
|
||||
const bool is_extern;
|
||||
|
||||
/**
|
||||
* Constructs a variable symbol information.
|
||||
*
|
||||
* \param symbol Variable type.
|
||||
* \param is_extern Whether this is an extern symbol.
|
||||
*/
|
||||
variable_info(const type symbol, bool is_extern);
|
||||
|
||||
std::shared_ptr<variable_info> is_variable() override;
|
||||
};
|
||||
|
||||
std::shared_ptr<symbol_table> builtin_symbol_table();
|
||||
|
||||
/**
|
||||
* Symbol bag contains:
|
||||
*
|
||||
* - the symbol table of a module itself
|
||||
* - symbol tables of imported modules
|
||||
* - forward declarations
|
||||
*/
|
||||
class symbol_bag
|
||||
{
|
||||
std::shared_ptr<symbol_table> symbols;
|
||||
std::forward_list<std::shared_ptr<symbol_table>> imports;
|
||||
|
||||
public:
|
||||
forward_table unresolved;
|
||||
|
||||
symbol_bag();
|
||||
symbol_bag(forward_table&& unresolved, std::shared_ptr<symbol_table> symbols);
|
||||
public:
|
||||
|
||||
/**
|
||||
* \param unresolved Forward declarations collected in the previous step.
|
||||
* \param global_table Global symbols.
|
||||
*/
|
||||
symbol_bag(forward_table&& unresolved, std::shared_ptr<symbol_table> global_table);
|
||||
|
||||
/**
|
||||
* Looks up a symbol in the current and imported modules.
|
||||
*
|
||||
* \param name Symbol name to look up.
|
||||
*
|
||||
* \return Symbol from one of the symbol tables if found.
|
||||
*/
|
||||
std::shared_ptr<info> lookup(const std::string& name);
|
||||
bool enter(const std::string& name, std::shared_ptr<info> entry);
|
||||
std::shared_ptr<symbol_table> enter();
|
||||
void enter(std::shared_ptr<symbol_table> child);
|
||||
void leave();
|
||||
|
||||
void add_import(std::shared_ptr<symbol_table> table);
|
||||
/**
|
||||
* Inserts a symbol into the current scope.
|
||||
*
|
||||
* \param name Symbol name.
|
||||
* \param entry Symbol info.
|
||||
*
|
||||
* \return Whether the insertion took place.
|
||||
*/
|
||||
bool enter(const std::string& name, std::shared_ptr<info> entry);
|
||||
|
||||
/**
|
||||
* Enters a new scope.
|
||||
*
|
||||
* \return Reference to the allocated scope.
|
||||
*/
|
||||
std::shared_ptr<symbol_table> enter();
|
||||
|
||||
/**
|
||||
* Sets the current scope to \a child.
|
||||
*
|
||||
* \param child New scope.
|
||||
*/
|
||||
void enter(std::shared_ptr<symbol_table> child);
|
||||
|
||||
/**
|
||||
* Leave the current scope.
|
||||
*
|
||||
* \return Left scope.
|
||||
*/
|
||||
std::shared_ptr<symbol_table> leave();
|
||||
|
||||
/**
|
||||
* Checks whether there is a forward declaration \a symbol_name and
|
||||
* returns it if so.
|
||||
*
|
||||
* \param symbol_name Type name to look up.
|
||||
* \return Forward declaration or `nullptr` if the symbol is not declared.
|
||||
*/
|
||||
std::shared_ptr<alias_type> declared(const std::string& symbol_name);
|
||||
|
||||
/**
|
||||
* Completes the forward-declared type \a symbol_name and defines it to
|
||||
* be \a resolution.
|
||||
*
|
||||
* \param symbol_name Type name.
|
||||
* \param resolution Type definition.
|
||||
* \return Alias to the defined type.
|
||||
*/
|
||||
std::shared_ptr<alias_type> resolve(const std::string& symbol_name, type& resolution);
|
||||
|
||||
/**
|
||||
* Add imported symbols to the scope.
|
||||
*
|
||||
* \param bag Symbol bag of another module.
|
||||
*/
|
||||
void add_import(const symbol_bag& bag);
|
||||
};
|
||||
}
|
||||
|
@@ -36,4 +36,6 @@ namespace elna::gcc
|
||||
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);
|
||||
tree declare_variable(const std::string& name, const boot::variable_info& info,
|
||||
std::shared_ptr<symbol_table> symbols);
|
||||
}
|
||||
|
Reference in New Issue
Block a user