Implement enumeration type
This commit is contained in:
@ -62,17 +62,19 @@ namespace elna::boot
|
||||
class if_statement;
|
||||
class while_statement;
|
||||
class return_statement;
|
||||
class case_statement;
|
||||
class traits_expression;
|
||||
class block;
|
||||
class program;
|
||||
class binary_expression;
|
||||
class unary_expression;
|
||||
class primitive_type_expression;
|
||||
class named_type_expression;
|
||||
class array_type_expression;
|
||||
class pointer_type_expression;
|
||||
class record_type_expression;
|
||||
class union_type_expression;
|
||||
class procedure_type_expression;
|
||||
class enumeration_type_expression;
|
||||
class variable_expression;
|
||||
class array_access_expression;
|
||||
class field_access_expression;
|
||||
@ -100,16 +102,18 @@ namespace elna::boot
|
||||
virtual void visit(while_statement *) = 0;
|
||||
virtual void visit(return_statement *) = 0;
|
||||
virtual void visit(defer_statement *) = 0;
|
||||
virtual void visit(case_statement *) = 0;
|
||||
virtual void visit(block *) = 0;
|
||||
virtual void visit(program *) = 0;
|
||||
virtual void visit(binary_expression *) = 0;
|
||||
virtual void visit(unary_expression *) = 0;
|
||||
virtual void visit(primitive_type_expression *) = 0;
|
||||
virtual void visit(named_type_expression *) = 0;
|
||||
virtual void visit(array_type_expression *) = 0;
|
||||
virtual void visit(pointer_type_expression *) = 0;
|
||||
virtual void visit(record_type_expression *) = 0;
|
||||
virtual void visit(union_type_expression *) = 0;
|
||||
virtual void visit(procedure_type_expression *) = 0;
|
||||
virtual void visit(enumeration_type_expression *) = 0;
|
||||
virtual void visit(variable_expression *) = 0;
|
||||
virtual void visit(array_access_expression *) = 0;
|
||||
virtual void visit(field_access_expression *) = 0;
|
||||
@ -188,28 +192,29 @@ namespace elna::boot
|
||||
class type_expression : public node
|
||||
{
|
||||
public:
|
||||
virtual primitive_type_expression *is_primitive();
|
||||
virtual named_type_expression *is_named();
|
||||
virtual array_type_expression *is_array();
|
||||
virtual pointer_type_expression *is_pointer();
|
||||
virtual record_type_expression *is_record();
|
||||
virtual union_type_expression *is_union();
|
||||
virtual procedure_type_expression *is_procedure();
|
||||
virtual enumeration_type_expression *is_enumeration();
|
||||
|
||||
protected:
|
||||
type_expression(const struct position position);
|
||||
};
|
||||
|
||||
/**
|
||||
* Expression defining a basic type.
|
||||
* Expression refering to a type by its name.
|
||||
*/
|
||||
class primitive_type_expression : public type_expression
|
||||
class named_type_expression : public type_expression
|
||||
{
|
||||
public:
|
||||
const std::string name;
|
||||
|
||||
primitive_type_expression(const struct position position, const std::string& name);
|
||||
named_type_expression(const struct position position, const std::string& name);
|
||||
void accept(parser_visitor *visitor) override;
|
||||
primitive_type_expression *is_primitive() override;
|
||||
named_type_expression *is_named() override;
|
||||
};
|
||||
|
||||
class array_type_expression : public type_expression
|
||||
@ -269,6 +274,20 @@ namespace elna::boot
|
||||
union_type_expression *is_union() override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enumeration type.
|
||||
*/
|
||||
class enumeration_type_expression : public type_expression
|
||||
{
|
||||
public:
|
||||
const std::vector<std::string> members;
|
||||
|
||||
enumeration_type_expression(const struct position, std::vector<std::string>&& members);
|
||||
|
||||
void accept(parser_visitor *visitor) override;
|
||||
enumeration_type_expression *is_enumeration() override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable declaration.
|
||||
*/
|
||||
@ -291,14 +310,6 @@ namespace elna::boot
|
||||
class literal_expression : public expression
|
||||
{
|
||||
public:
|
||||
virtual literal<std::int32_t> *is_int() = 0;
|
||||
virtual literal<std::uint32_t> *is_word() = 0;
|
||||
virtual literal<double> *is_float() = 0;
|
||||
virtual literal<bool> *is_bool() = 0;
|
||||
virtual literal<unsigned char> *is_char() = 0;
|
||||
virtual literal<std::nullptr_t> *is_nil() = 0;
|
||||
virtual literal<std::string> *is_string() = 0;
|
||||
|
||||
literal_expression *is_literal() override;
|
||||
|
||||
protected:
|
||||
@ -428,18 +439,34 @@ namespace elna::boot
|
||||
|
||||
class return_statement : public statement
|
||||
{
|
||||
expression *m_return_expression{ nullptr };
|
||||
|
||||
public:
|
||||
expression *const return_expression{ nullptr };
|
||||
|
||||
return_statement(const struct position position, expression *return_expression = nullptr);
|
||||
void accept(parser_visitor *visitor) override;
|
||||
virtual return_statement *is_return() override;
|
||||
|
||||
expression *return_expression();
|
||||
|
||||
virtual ~return_statement() override;
|
||||
};
|
||||
|
||||
struct switch_case
|
||||
{
|
||||
std::vector<literal_expression *> labels;
|
||||
std::vector<statement *> statements;
|
||||
};
|
||||
|
||||
class case_statement : public statement
|
||||
{
|
||||
expression *m_condition;
|
||||
|
||||
public:
|
||||
const std::vector<switch_case> cases;
|
||||
|
||||
case_statement(const struct position position, expression *condition, std::vector<switch_case>&& cases);
|
||||
void accept(parser_visitor *visitor) override;
|
||||
expression& condition();
|
||||
};
|
||||
|
||||
class designator_expression : public expression
|
||||
{
|
||||
public:
|
||||
@ -635,90 +662,6 @@ namespace elna::boot
|
||||
{
|
||||
}
|
||||
|
||||
literal<std::int32_t> *is_int() override
|
||||
{
|
||||
if (std::is_same<T, std::int32_t>::value)
|
||||
{
|
||||
return reinterpret_cast<literal<std::int32_t> *>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
literal<std::uint32_t> *is_word() override
|
||||
{
|
||||
if (std::is_same<T, std::uint32_t>::value)
|
||||
{
|
||||
return reinterpret_cast<literal<std::uint32_t> *>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
literal<double> *is_float() override
|
||||
{
|
||||
if (std::is_same<T, double>::value)
|
||||
{
|
||||
return reinterpret_cast<literal<double> *>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
literal<bool> *is_bool() override
|
||||
{
|
||||
if (std::is_same<T, bool>::value)
|
||||
{
|
||||
return reinterpret_cast<literal<bool> *>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
literal<unsigned char> *is_char() override
|
||||
{
|
||||
if (std::is_same<T, unsigned char>::value)
|
||||
{
|
||||
return reinterpret_cast<literal<unsigned char> *>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
literal<std::nullptr_t> *is_nil() override
|
||||
{
|
||||
if (std::is_same<T, std::nullptr_t>::value)
|
||||
{
|
||||
return reinterpret_cast<literal<std::nullptr_t> *>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
literal<std::string> *is_string() override
|
||||
{
|
||||
if (std::is_same<T, std::string>::value)
|
||||
{
|
||||
return reinterpret_cast<literal<std::string> *>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void accept(parser_visitor *visitor) override
|
||||
{
|
||||
visitor->visit(this);
|
||||
@ -728,9 +671,9 @@ namespace elna::boot
|
||||
class defer_statement : public statement
|
||||
{
|
||||
public:
|
||||
std::vector<statement *> statements;
|
||||
const std::vector<statement *> statements;
|
||||
|
||||
defer_statement(const struct position position);
|
||||
defer_statement(const struct position position, std::vector<statement *>&& statements);
|
||||
void accept(parser_visitor *visitor) override;
|
||||
defer_statement *is_defer() override;
|
||||
|
||||
|
@ -49,6 +49,8 @@ namespace elna::boot
|
||||
class declaration_visitor final : public parser_visitor, public error_container
|
||||
{
|
||||
type current_type;
|
||||
constant_info::variant current_literal;
|
||||
|
||||
std::shared_ptr<symbol_table> symbols;
|
||||
|
||||
procedure_type build_procedure(procedure_type_expression& type_expression);
|
||||
@ -58,7 +60,7 @@ namespace elna::boot
|
||||
|
||||
explicit declaration_visitor(const char *path, std::shared_ptr<symbol_table> symbols);
|
||||
|
||||
void visit(primitive_type_expression *type_expression) override;
|
||||
void visit(named_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;
|
||||
@ -66,15 +68,17 @@ namespace elna::boot
|
||||
void visit(record_type_expression *type_expression) override;
|
||||
void visit(union_type_expression *type_expression) override;
|
||||
void visit(procedure_type_expression *type_expression) override;
|
||||
void visit(enumeration_type_expression *type_expression) override;
|
||||
|
||||
void visit(variable_declaration *declaration) override;
|
||||
void visit(constant_definition *) override;
|
||||
void visit(constant_definition *definition) override;
|
||||
void visit(procedure_definition *definition) override;
|
||||
void visit(assign_statement *statement) override;
|
||||
void visit(if_statement *statement) override;
|
||||
void visit(while_statement *statement) override;
|
||||
void visit(return_statement *statement) override;
|
||||
void visit(defer_statement *statement) override;
|
||||
void visit(case_statement *statement) override;
|
||||
void visit(procedure_call *call) override;
|
||||
void visit(block *block) override;
|
||||
void visit(cast_expression *expression) override;
|
||||
@ -85,12 +89,12 @@ namespace elna::boot
|
||||
void visit(array_access_expression *expression) override;
|
||||
void visit(field_access_expression *expression) override;
|
||||
void visit(dereference_expression *expression) override;
|
||||
void visit(literal<std::int32_t> *) override;
|
||||
void visit(literal<std::uint32_t> *) override;
|
||||
void visit(literal<double> *) override;
|
||||
void visit(literal<bool> *) override;
|
||||
void visit(literal<unsigned char> *) override;
|
||||
void visit(literal<std::nullptr_t> *) override;
|
||||
void visit(literal<std::string> *) override;
|
||||
void visit(literal<std::int32_t> *literal) override;
|
||||
void visit(literal<std::uint32_t> *literal) override;
|
||||
void visit(literal<double> *literal) override;
|
||||
void visit(literal<bool> *literal) override;
|
||||
void visit(literal<unsigned char> *literal) override;
|
||||
void visit(literal<std::nullptr_t> *literal) override;
|
||||
void visit(literal<std::string> *literal) override;
|
||||
};
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ namespace elna::boot
|
||||
class pointer_type;
|
||||
class array_type;
|
||||
class procedure_type;
|
||||
class enumeration_type;
|
||||
|
||||
class type
|
||||
{
|
||||
@ -46,7 +47,8 @@ namespace elna::boot
|
||||
_union,
|
||||
pointer,
|
||||
array,
|
||||
procedure
|
||||
procedure,
|
||||
enumeration
|
||||
};
|
||||
type_tag tag{ type_tag::empty };
|
||||
union
|
||||
@ -58,6 +60,7 @@ namespace elna::boot
|
||||
std::shared_ptr<pointer_type> pointer;
|
||||
std::shared_ptr<array_type> array;
|
||||
std::shared_ptr<procedure_type> procedure;
|
||||
std::shared_ptr<enumeration_type> enumeration;
|
||||
};
|
||||
|
||||
void copy(const type& other);
|
||||
@ -72,6 +75,7 @@ namespace elna::boot
|
||||
explicit type(std::shared_ptr<pointer_type> pointer);
|
||||
explicit type(std::shared_ptr<array_type> array);
|
||||
explicit type(std::shared_ptr<procedure_type> procedure);
|
||||
explicit type(std::shared_ptr<enumeration_type> enumeration);
|
||||
|
||||
type(const type& other);
|
||||
type& operator=(const type& other);
|
||||
@ -141,8 +145,16 @@ namespace elna::boot
|
||||
procedure_type(return_t return_type = return_t());
|
||||
};
|
||||
|
||||
struct enumeration_type
|
||||
{
|
||||
std::vector<std::string> members;
|
||||
|
||||
explicit enumeration_type(const std::vector<std::string>& members);
|
||||
};
|
||||
|
||||
class type_info;
|
||||
class procedure_info;
|
||||
class constant_info;
|
||||
|
||||
class info : public std::enable_shared_from_this<info>
|
||||
{
|
||||
@ -174,6 +186,17 @@ namespace elna::boot
|
||||
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);
|
||||
};
|
||||
|
||||
/**
|
||||
* Symbol table.
|
||||
*/
|
||||
|
@ -47,7 +47,6 @@ namespace elna::gcc
|
||||
std::unordered_map<std::string, tree> unresolved;
|
||||
|
||||
void declare_procedure(boot::procedure_definition *const definition);
|
||||
tree build_label_decl(const char *name, location_t loc);
|
||||
tree build_procedure_type(boot::procedure_type_expression& type);
|
||||
void build_composite_type(const std::vector<boot::field_declaration>& fields,
|
||||
tree composite_type_node);
|
||||
@ -101,13 +100,15 @@ namespace elna::gcc
|
||||
void visit(boot::assign_statement *statement) override;
|
||||
void visit(boot::if_statement *statement) override;
|
||||
void visit(boot::while_statement *statement) override;
|
||||
void visit(boot::primitive_type_expression *type) override;
|
||||
void visit(boot::named_type_expression *type) override;
|
||||
void visit(boot::array_type_expression *type) 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::return_statement *statement) override;
|
||||
void visit(boot::defer_statement *statement) override;
|
||||
void visit(boot::case_statement *statement) override;
|
||||
};
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ namespace elna::gcc
|
||||
{
|
||||
using symbol_table = boot::symbol_map<tree, tree, NULL_TREE>;
|
||||
|
||||
bool is_pointer_type(tree type);
|
||||
bool is_integral_type(tree type);
|
||||
bool is_numeric_type(tree type);
|
||||
bool is_primitive_type(tree type);
|
||||
@ -42,9 +41,9 @@ namespace elna::gcc
|
||||
|
||||
/**
|
||||
* \param type The type to evaluate.
|
||||
* \return Whether the given type is record or union.
|
||||
* \return Whether this type can be converted to another type.
|
||||
*/
|
||||
bool is_aggregate_type(tree type);
|
||||
bool is_castable_type(tree type);
|
||||
|
||||
/**
|
||||
* \param lhs Left hand value.
|
||||
@ -82,4 +81,5 @@ 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_label_decl(const char *name, location_t loc);
|
||||
}
|
||||
|
Reference in New Issue
Block a user