Unify the build_type function

This commit is contained in:
2025-03-06 22:59:41 +01:00
parent dbeaca7cbf
commit dc5760394b
8 changed files with 261 additions and 175 deletions

View File

@ -294,15 +294,14 @@ namespace boot
type_expression& base();
};
using field_t = std::pair<std::string, std::shared_ptr<type_expression>>;
using fields_t = std::vector<field_t>;
using field_declaration = std::pair<std::string, std::shared_ptr<type_expression>>;
class record_type_expression : public type_expression
{
public:
fields_t fields;
const std::vector<field_declaration> fields;
record_type_expression(const struct position position, fields_t&& fields);
record_type_expression(const struct position position, std::vector<field_declaration>&& fields);
void accept(parser_visitor *visitor);
std::shared_ptr<record_type_expression> is_record() override;
@ -311,9 +310,9 @@ namespace boot
class union_type_expression : public type_expression
{
public:
fields_t fields;
std::vector<field_declaration> fields;
union_type_expression(const struct position position, fields_t&& fields);
union_type_expression(const struct position position, std::vector<field_declaration>&& fields);
void accept(parser_visitor *visitor);
std::shared_ptr<union_type_expression> is_union() override;

View File

@ -17,59 +17,105 @@ along with GCC; see the file COPYING3. If not see
#include <string>
#include <vector>
#include <unordered_map>
#include "elna/boot/ast.h"
namespace elna
{
namespace boot
{
class alias_type;
class primitive_type;
class record_type;
class union_type;
class primitive_type;
class pointer_type;
class type
{
public:
virtual alias_type *is_alias();
virtual primitive_type *is_primitive();
virtual record_type *is_record();
virtual union_type *is_union();
enum class type_tag
{
empty,
alias,
primitive,
record,
_union,
pointer,
};
union
{
nullptr_t empty;
alias_type *alias;
primitive_type *primitive;
record_type *record;
union_type *_union;
pointer_type *pointer;
} payload{ .empty = nullptr };
virtual ~type() = 0;
type_tag tag{ type_tag::empty };
public:
type() = default;
explicit type(alias_type *alias);
explicit type(primitive_type *primitive);
explicit type(record_type *record);
explicit type(union_type *_union);
explicit type(pointer_type *pointer);
template<typename T>
T *const get() const;
bool empty() const;
};
class alias_type : public type
struct alias_type
{
public:
alias_type *is_alias() override;
type *reference{ nullptr };
type reference;
};
class primitive_type : public type
struct pointer_type
{
public:
std::string identifier;
const type base;
primitive_type(const std::string& identifier);
primitive_type *is_primitive() override;
explicit pointer_type(type base);
};
class record_type : public type
struct primitive_type
{
public:
std::vector<std::pair<std::string, type *>> fields;
const std::string identifier;
record_type *is_record() override;
explicit primitive_type(const std::string& identifier);
};
class union_type : public type
{
public:
std::vector<std::pair<std::string, type *>> fields;
using type_field = typename std::pair<std::string, type>;
union_type *is_union() override;
struct record_type
{
std::vector<type_field> fields;
};
struct union_type
{
std::vector<type_field> fields;
};
class declaration_visitor final : public empty_visitor
{
type current_type;
public:
std::unordered_map<std::string, alias_type *> unresolved;
declaration_visitor() = default;
void visit(primitive_type_expression *type_expression) override;
void visit(array_type_expression *type_expression) override;
void visit(pointer_type_expression *type_expression) override;
void visit(program *program) override;
void visit(type_definition *definition) override;
void visit(record_type_expression *type_expression) override;
void visit(union_type_expression *type_expression) override;
void visit(procedure_type_expression *type_expression) override;
};
}
}

View File

@ -28,29 +28,13 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "tree-iterator.h"
#include <unordered_map>
#include <string>
namespace elna
{
namespace gcc
{
class declaration_visitor final : public boot::empty_visitor
{
std::shared_ptr<symbol_table> symbols;
std::unordered_map<std::string, boot::alias_type *> unresolved;
boot::type *build_type(boot::type_expression *type_expression);
boot::record_type *build_record(boot::record_type_expression *type_expression);
boot::union_type *build_union(boot::union_type_expression *type_expression);
tree get_inner_alias(const boot::alias_type& t);
public:
declaration_visitor(std::shared_ptr<symbol_table> symbol_table);
void visit(boot::program *program) override;
void visit(boot::type_definition *definition) override;
};
void do_semantic_analysis(std::shared_ptr<symbol_table> symbols, std::unique_ptr<boot::program>& ast);
class generic_visitor final : public boot::empty_visitor
{