Generate top-level code from symbol tables
This commit is contained in:
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user