Implement enumeration type
This commit is contained in:
38
boot/ast.cc
38
boot/ast.cc
@ -103,7 +103,7 @@ namespace elna::boot
|
||||
{
|
||||
}
|
||||
|
||||
primitive_type_expression *type_expression::is_primitive()
|
||||
named_type_expression *type_expression::is_named()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
@ -133,17 +133,22 @@ namespace elna::boot
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
primitive_type_expression::primitive_type_expression(const struct position position, const std::string& name)
|
||||
enumeration_type_expression *type_expression::is_enumeration()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
named_type_expression::named_type_expression(const struct position position, const std::string& name)
|
||||
: type_expression(position), name(name)
|
||||
{
|
||||
}
|
||||
|
||||
void primitive_type_expression::accept(parser_visitor *visitor)
|
||||
void named_type_expression::accept(parser_visitor *visitor)
|
||||
{
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
primitive_type_expression *primitive_type_expression::is_primitive()
|
||||
named_type_expression *named_type_expression::is_named()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
@ -312,6 +317,26 @@ namespace elna::boot
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
procedure_type_expression *procedure_type_expression::is_procedure()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
enumeration_type_expression::enumeration_type_expression(const struct position position, std::vector<std::string>&& members)
|
||||
: type_expression(position), members(members)
|
||||
{
|
||||
}
|
||||
|
||||
void enumeration_type_expression::accept(parser_visitor *visitor)
|
||||
{
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
enumeration_type_expression *enumeration_type_expression::is_enumeration()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
procedure_definition::procedure_definition(const struct position position, const std::string& identifier,
|
||||
const bool exported, procedure_type_expression *heading, block *body)
|
||||
: definition(position, identifier, exported), m_heading(heading), body(body)
|
||||
@ -323,11 +348,6 @@ namespace elna::boot
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
procedure_type_expression *procedure_type_expression::is_procedure()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
procedure_type_expression& procedure_definition::heading()
|
||||
{
|
||||
return *m_heading;
|
||||
|
@ -157,6 +157,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
%type <elna::boot::defer_statement *> defer_statement;
|
||||
%type <std::pair<std::string, bool>> identifier_definition;
|
||||
%type <std::vector<std::pair<std::string, bool>>> identifier_definitions;
|
||||
%type <std::vector<std::string>> identifiers;
|
||||
%%
|
||||
program:
|
||||
constant_part type_part variable_part procedure_part "begin" statements "end" "."
|
||||
@ -507,10 +508,21 @@ type_expression:
|
||||
std::swap(result->parameters, $3);
|
||||
$$ = result;
|
||||
}
|
||||
| "(" identifiers ")"
|
||||
{
|
||||
$$ = new boot::enumeration_type_expression(boot::make_position(@1), std::move($2));
|
||||
}
|
||||
| IDENTIFIER
|
||||
{
|
||||
$$ = new boot::primitive_type_expression(boot::make_position(@1), $1);
|
||||
$$ = new boot::named_type_expression(boot::make_position(@1), $1);
|
||||
}
|
||||
identifiers:
|
||||
IDENTIFIER "," identifiers
|
||||
{
|
||||
std::swap($$, $3);
|
||||
$$.emplace($$.cbegin(), std::move($1));
|
||||
}
|
||||
| IDENTIFIER { $$.emplace_back(std::move($1)); }
|
||||
variable_declaration: identifier_definitions ":" type_expression
|
||||
{
|
||||
std::shared_ptr<boot::type_expression> shared_type{ $3 };
|
||||
@ -561,16 +573,14 @@ type_definitions:
|
||||
type_part:
|
||||
/* no type definitions */ {}
|
||||
| "type" type_definitions { std::swap($$, $2); }
|
||||
formal_parameter: IDENTIFIER ":" type_expression
|
||||
{
|
||||
$$ = std::make_pair($1, $3);
|
||||
}
|
||||
formal_parameter:
|
||||
IDENTIFIER ":" type_expression { $$ = std::make_pair($1, $3); }
|
||||
formal_parameters:
|
||||
/* no formal parameters */ {}
|
||||
| formal_parameter "," formal_parameters
|
||||
{
|
||||
std::swap($$, $3);
|
||||
$$.emplace($$.cbegin(), $1);
|
||||
$$.emplace($$.cbegin(), std::move($1));
|
||||
}
|
||||
| formal_parameter { $$.emplace_back(std::move($1)); }
|
||||
actual_parameter_list:
|
||||
|
@ -114,7 +114,7 @@ namespace elna::boot
|
||||
unresolved_declaration->reference = this->current_type;
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(primitive_type_expression *type_expression)
|
||||
void declaration_visitor::visit(named_type_expression *type_expression)
|
||||
{
|
||||
auto unresolved_alias = this->unresolved.find(type_expression->name);
|
||||
|
||||
@ -177,6 +177,13 @@ namespace elna::boot
|
||||
this->current_type = type(result_type);
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(enumeration_type_expression *type_expression)
|
||||
{
|
||||
std::shared_ptr<enumeration_type> result_type = std::make_shared<enumeration_type>(type_expression->members);
|
||||
|
||||
this->current_type = type(result_type);
|
||||
}
|
||||
|
||||
void declaration_visitor::visit(variable_declaration *declaration)
|
||||
{
|
||||
declaration->variable_type().accept(this);
|
||||
|
@ -58,6 +58,11 @@ namespace elna::boot
|
||||
{
|
||||
}
|
||||
|
||||
type::type(std::shared_ptr<enumeration_type> enumeration)
|
||||
: tag(type_tag::enumeration), enumeration(enumeration)
|
||||
{
|
||||
}
|
||||
|
||||
void type::copy(const type& other)
|
||||
{
|
||||
switch (other.tag)
|
||||
@ -85,6 +90,9 @@ namespace elna::boot
|
||||
case type_tag::procedure:
|
||||
new (&procedure) std::shared_ptr<procedure_type>(other.procedure);
|
||||
break;
|
||||
case type_tag::enumeration:
|
||||
new (&enumeration) std::shared_ptr<enumeration_type>(other.enumeration);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,6 +129,9 @@ namespace elna::boot
|
||||
case type_tag::procedure:
|
||||
new (&procedure) std::shared_ptr<procedure_type>(std::move(other.procedure));
|
||||
break;
|
||||
case type_tag::enumeration:
|
||||
new (&enumeration) std::shared_ptr<enumeration_type>(std::move(other.enumeration));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,6 +189,9 @@ namespace elna::boot
|
||||
case type_tag::procedure:
|
||||
this->procedure.~shared_ptr<procedure_type>();
|
||||
break;
|
||||
case type_tag::enumeration:
|
||||
this->enumeration.~shared_ptr<enumeration_type>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,6 +237,12 @@ namespace elna::boot
|
||||
return tag == type_tag::procedure ? this->procedure : nullptr;
|
||||
}
|
||||
|
||||
template<>
|
||||
std::shared_ptr<enumeration_type> type::get<enumeration_type>() const
|
||||
{
|
||||
return tag == type_tag::enumeration ? this->enumeration : nullptr;
|
||||
}
|
||||
|
||||
bool type::empty() const
|
||||
{
|
||||
return tag == type_tag::empty;
|
||||
@ -253,6 +273,11 @@ namespace elna::boot
|
||||
{
|
||||
}
|
||||
|
||||
enumeration_type::enumeration_type(const std::vector<std::string>& members)
|
||||
: members(members)
|
||||
{
|
||||
}
|
||||
|
||||
info::~info()
|
||||
{
|
||||
}
|
||||
|
Reference in New Issue
Block a user