Implement enumeration type

This commit is contained in:
2025-04-04 22:48:12 +02:00
parent 50970f3289
commit b2ae486f88
13 changed files with 423 additions and 337 deletions

View File

@ -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;

View File

@ -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:

View File

@ -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,13 +177,23 @@ 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);
}
void declaration_visitor::visit(constant_definition *)
void declaration_visitor::visit(constant_definition *definition)
{
definition->body().accept(this);
this->symbols->enter(definition->identifier, std::make_shared<constant_info>(this->current_literal));
}
void declaration_visitor::visit(procedure_definition *definition)
@ -333,31 +343,38 @@ namespace elna::boot
expression->base().accept(this);
}
void declaration_visitor::visit(literal<std::int32_t> *)
void declaration_visitor::visit(literal<std::int32_t> *literal)
{
this->current_literal = literal->value;
}
void declaration_visitor::visit(literal<std::uint32_t> *)
void declaration_visitor::visit(literal<std::uint32_t> *literal)
{
this->current_literal = literal->value;
}
void declaration_visitor::visit(literal<double> *)
void declaration_visitor::visit(literal<double> *literal)
{
this->current_literal = literal->value;
}
void declaration_visitor::visit(literal<bool> *)
void declaration_visitor::visit(literal<bool> *literal)
{
this->current_literal = literal->value;
}
void declaration_visitor::visit(literal<unsigned char> *)
void declaration_visitor::visit(literal<unsigned char> *literal)
{
this->current_literal = literal->value;
}
void declaration_visitor::visit(literal<std::nullptr_t> *)
void declaration_visitor::visit(literal<std::nullptr_t> *literal)
{
this->current_literal = literal->value;
}
void declaration_visitor::visit(literal<std::string> *)
void declaration_visitor::visit(literal<std::string> *literal)
{
this->current_literal = literal->value;
}
}

View File

@ -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()
{
}
@ -287,6 +312,11 @@ namespace elna::boot
return std::static_pointer_cast<procedure_info>(shared_from_this());
}
constant_info::constant_info(const variant& symbol)
: symbol(symbol)
{
}
std::shared_ptr<symbol_table> builtin_symbol_table()
{
auto result = std::make_shared<symbol_table>();