Unify the build_type function
This commit is contained in:
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
Reference in New Issue
Block a user