Generate top-level code from symbol tables

This commit is contained in:
2025-06-19 14:03:03 +02:00
parent f524311f06
commit 6da2a70329
14 changed files with 434 additions and 397 deletions

View File

@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#include <string>
#include <vector>
#include <optional>
#include "elna/boot/symbol.h"
#include "elna/boot/result.h"
namespace elna::boot
@ -423,6 +424,8 @@ namespace elna::boot
expression *m_value;
public:
type expression_type;
cast_expression(const struct position position, type_expression *target, expression *value);
void accept(parser_visitor *visitor) override;
cast_expression *is_cast() override;
@ -438,6 +441,7 @@ namespace elna::boot
public:
std::vector<type_expression *> parameters;
const std::string name;
std::vector<type> types;
traits_expression(const struct position position, const std::string& name);
~traits_expression();

View File

@ -48,6 +48,16 @@ namespace elna::boot
std::string what() const override;
};
class field_duplication_error : public error
{
std::string field_name;
public:
field_duplication_error(const std::string& field_name, const char *path, const struct position);
std::string what() const override;
};
class declaration_visitor final : public parser_visitor, public error_container
{
type current_type;
@ -57,6 +67,7 @@ namespace elna::boot
std::unordered_map<std::string, std::shared_ptr<alias_type>> unresolved;
procedure_type build_procedure(procedure_type_expression& type_expression);
std::vector<type_field> build_composite_type(const std::vector<field_declaration>& fields);
public:
explicit declaration_visitor(const char *path, std::shared_ptr<symbol_table> symbols);

View File

@ -168,46 +168,6 @@ namespace elna::boot
virtual std::shared_ptr<variable_info> is_variable();
};
class type_info : public info
{
public:
const type symbol;
explicit type_info(const type symbol);
std::shared_ptr<type_info> is_type() override;
};
class procedure_info : public info
{
public:
const procedure_type symbol;
const std::vector<std::string> names;
procedure_info(const procedure_type symbol, const std::vector<std::string> names);
std::shared_ptr<procedure_info> is_procedure() override;
};
class constant_info : public info
{
public:
using variant = typename
std::variant<std::int32_t, std::uint32_t, double, bool, unsigned char, std::nullptr_t, std::string>;
const variant symbol;
explicit constant_info(const variant& symbol);
std::shared_ptr<constant_info> is_constant() override;
};
class variable_info : public info
{
public:
const type symbol;
variable_info(const type symbol);
std::shared_ptr<variable_info> is_variable() override;
};
/**
* Symbol table.
*/
@ -322,5 +282,47 @@ namespace elna::boot
using symbol_table = symbol_map<std::shared_ptr<info>, std::nullptr_t, nullptr>;
class type_info : public info
{
public:
const type symbol;
explicit type_info(const type symbol);
std::shared_ptr<type_info> is_type() override;
};
class procedure_info : public info
{
public:
const procedure_type symbol;
const std::vector<std::string> names;
std::shared_ptr<symbol_table> symbols;
procedure_info(const procedure_type symbol, const std::vector<std::string> names,
std::shared_ptr<symbol_table> parent_table = nullptr);
std::shared_ptr<procedure_info> is_procedure() override;
};
class constant_info : public info
{
public:
using variant = typename
std::variant<std::int32_t, std::uint32_t, double, bool, unsigned char, std::nullptr_t, std::string>;
const variant symbol;
explicit constant_info(const variant& symbol);
std::shared_ptr<constant_info> is_constant() override;
};
class variable_info : public info
{
public:
const type symbol;
variable_info(const type symbol);
std::shared_ptr<variable_info> is_variable() override;
};
std::shared_ptr<symbol_table> builtin_symbol_table();
}

View File

@ -29,4 +29,12 @@ 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);
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);
void declare_procedure(const std::string& name, const boot::procedure_info& info,
std::shared_ptr<symbol_table> symbols);
}

View File

@ -33,22 +33,11 @@ along with GCC; see the file COPYING3. If not see
namespace elna::gcc
{
std::unordered_map<std::string, tree> do_semantic_analysis(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::unordered_map<std::string, tree>& unresolved,
std::vector<std::string>& path);
class generic_visitor final : public boot::parser_visitor
{
tree current_expression{ NULL_TREE };
std::shared_ptr<symbol_table> symbols;
std::unordered_map<std::string, tree> unresolved;
void declare_procedure(boot::procedure_declaration *const definition);
tree build_procedure_type(boot::procedure_type_expression& type);
void build_composite_type(const std::vector<boot::field_declaration>& fields,
tree composite_type_node);
std::shared_ptr<boot::symbol_table> info_table;
void enter_scope();
tree leave_scope();
@ -74,8 +63,7 @@ namespace elna::gcc
bool assert_constant(location_t expression_location);
public:
generic_visitor(std::shared_ptr<symbol_table> symbol_table,
std::unordered_map<std::string, tree>&& unresolved);
generic_visitor(std::shared_ptr<symbol_table> symbol_table, std::shared_ptr<boot::symbol_table> info_table);
void visit(boot::program *program) override;
void visit(boot::procedure_declaration *definition) override;
@ -92,7 +80,7 @@ namespace elna::gcc
void visit(boot::binary_expression *expression) override;
void visit(boot::unary_expression *expression) override;
void visit(boot::constant_declaration *definition) override;
void visit(boot::type_declaration *definition) override;
void visit(boot::type_declaration *declaration) override;
void visit(boot::variable_declaration *declaration) override;
void visit(boot::variable_expression *expression) override;
void visit(boot::array_access_expression *expression) override;
@ -104,12 +92,12 @@ namespace elna::gcc
void visit(boot::import_declaration *) override;
void visit(boot::while_statement *statement) override;
void visit(boot::named_type_expression *type) override;
void visit(boot::array_type_expression *type) override;
void visit(boot::array_type_expression *) override;
void visit(boot::pointer_type_expression *type) override;
void visit(boot::record_type_expression *type) override;
void visit(boot::union_type_expression *type) override;
void visit(boot::procedure_type_expression *type) override;
void visit(boot::enumeration_type_expression *type) override;
void visit(boot::record_type_expression *) override;
void visit(boot::union_type_expression *) override;
void visit(boot::procedure_type_expression *) override;
void visit(boot::enumeration_type_expression *) override;
void visit(boot::return_statement *statement) override;
void visit(boot::defer_statement *statement) override;
void visit(boot::case_statement *statement) override;

View File

@ -82,6 +82,8 @@ namespace elna::gcc
tree build_field(location_t location, tree record_type, const std::string name, tree type);
tree find_field_by_name(location_t expression_location, tree type, const std::string& field_name);
tree build_global_pointer_type(tree type);
tree build_static_array_type(tree type, const std::uint64_t size);
tree build_enumeration_type(const std::vector<std::string>& members);
tree build_label_decl(const char *name, location_t loc);
tree extract_constant(tree expression);