Allow multiple variable declarations with a single type

This commit is contained in:
2025-02-15 10:26:04 +01:00
parent 82b3806fd2
commit b358f8ba27
7 changed files with 117 additions and 138 deletions

View File

@ -300,8 +300,7 @@ namespace boot
return this;
}
array_type::array_type(const struct position position, top_type *base,
const std::uint32_t size)
array_type::array_type(const struct position position, std::shared_ptr<top_type> base, const std::uint32_t size)
: top_type(position), m_base(base), size(size)
{
}
@ -321,12 +320,7 @@ namespace boot
return this;
}
array_type::~array_type()
{
delete m_base;
}
pointer_type::pointer_type(const struct position position, top_type *base)
pointer_type::pointer_type(const struct position position, std::shared_ptr<top_type> base)
: top_type(position), m_base(base)
{
}
@ -346,24 +340,11 @@ namespace boot
return this;
}
pointer_type::~pointer_type()
{
delete m_base;
}
composite_type::composite_type(const struct position position, fields_t&& fields)
: top_type(position), fields(std::move(fields))
{
}
composite_type::~composite_type()
{
for (auto& field_declaration : fields)
{
delete field_declaration.second;
}
}
record_type::record_type(const struct position position, fields_t&& fields)
: composite_type(position, std::move(fields))
{
@ -395,16 +376,11 @@ namespace boot
}
variable_declaration::variable_declaration(const struct position position, const std::string& identifier,
const bool exported, top_type *type)
std::shared_ptr<top_type> type, const bool exported)
: definition(position, identifier, exported), m_type(type)
{
}
variable_declaration::~variable_declaration()
{
delete m_type;
}
void variable_declaration::accept(parser_visitor *visitor)
{
visitor->visit(this);
@ -442,7 +418,7 @@ namespace boot
}
procedure_definition::procedure_definition(const struct position position, const std::string& identifier,
const bool exported, top_type *return_type)
const bool exported, std::shared_ptr<top_type> return_type)
: definition(position, identifier, exported), m_return_type(return_type)
{
}
@ -463,7 +439,7 @@ namespace boot
return this;
}
top_type *procedure_definition::return_type()
std::shared_ptr<top_type> procedure_definition::return_type()
{
return m_return_type;
}
@ -481,7 +457,7 @@ namespace boot
}
type_definition::type_definition(const struct position position, const std::string& identifier,
const bool exported, top_type *body)
const bool exported, std::shared_ptr<top_type> body)
: definition(position, identifier, exported), m_body(body)
{
}
@ -496,11 +472,6 @@ namespace boot
return *m_body;
}
type_definition::~type_definition()
{
delete m_body;
}
block::block(const struct position position)
: node(position)
{
@ -772,7 +743,8 @@ namespace boot
}
}
cast_expression::cast_expression(const struct position position, top_type *target, expression *value)
cast_expression::cast_expression(const struct position position,
std::shared_ptr<top_type> target, expression *value)
: expression(position), m_target(target), m_value(value)
{
}
@ -794,11 +766,10 @@ namespace boot
cast_expression::~cast_expression()
{
delete m_target;
delete m_value;
}
type_expression::type_expression(const struct position position, top_type *body)
type_expression::type_expression(const struct position position, std::shared_ptr<top_type> body)
: expression(position), m_body(body)
{
}
@ -813,11 +784,6 @@ namespace boot
return *m_body;
}
type_expression::~type_expression()
{
delete m_body;
}
call_statement::call_statement(const struct position position, call_expression *body)
: statement(position), m_body(body)
{

View File

@ -98,10 +98,10 @@ along with GCC; see the file COPYING3. If not see
%type <elna::boot::literal *> literal;
%type <elna::boot::constant_definition *> constant_definition;
%type <std::vector<elna::boot::constant_definition *>> constant_part constant_definitions;
%type <elna::boot::variable_declaration *> variable_declaration;
%type <std::vector<elna::boot::variable_declaration *>> variable_declarations variable_part
formal_parameter_list;
%type <elna::boot::top_type *> type_expression;
%type <std::vector<elna::boot::variable_declaration *>> variable_declarations variable_part variable_declaration
formal_parameters formal_parameter_list;
%type <elna::boot::variable_declaration *> formal_parameter
%type <std::shared_ptr<elna::boot::top_type>> type_expression;
%type <elna::boot::expression *> expression operand unary;
%type <std::vector<elna::boot::expression *>> expressions actual_parameter_list;
%type <elna::boot::designator_expression *> designator_expression;
@ -117,12 +117,13 @@ along with GCC; see the file COPYING3. If not see
%type <elna::boot::type_definition *> type_definition;
%type <std::vector<elna::boot::type_definition *>> type_definitions type_part;
%type <elna::boot::block *> block;
%type <std::pair<std::string, elna::boot::top_type *>> field_declaration;
%type <std::vector<std::pair<std::string, elna::boot::top_type *>>> field_list;
%type <elna::boot::field_t> field_declaration;
%type <std::vector<std::pair<std::string, std::shared_ptr<elna::boot::top_type>>>> field_list;
%type <std::vector<elna::boot::conditional_statements *>> elsif_statement_list;
%type <elna::boot::cast_expression *> cast_expression;
%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;
%%
program:
constant_part type_part variable_part procedure_part BEGIN_BLOCK optional_statements END_BLOCK DOT
@ -154,6 +155,13 @@ identifier_definition:
{
$$ = std::make_pair($1, false);
}
identifier_definitions:
identifier_definition COMMA identifier_definitions
{
std::swap($$, $3);
$$.emplace($$.cbegin(), $1);
}
| identifier_definition { $$.emplace_back(std::move($1)); }
procedure_heading:
PROCEDURE identifier_definition formal_parameter_list SEMICOLON
{
@ -427,35 +435,41 @@ field_list:
type_expression:
ARRAY INTEGER OF type_expression
{
$$ = new elna::boot::array_type(elna::boot::make_position(@1), $4, $2);
$$ = std::make_shared<elna::boot::array_type>(elna::boot::make_position(@1), $4, $2);
}
| POINTER TO type_expression
{
$$ = new elna::boot::pointer_type(elna::boot::make_position(@1), $3);
$$ = std::make_shared<elna::boot::pointer_type>(elna::boot::make_position(@1), $3);
}
| RECORD field_list END_BLOCK
{
$$ = new elna::boot::record_type(elna::boot::make_position(@1), std::move($2));
$$ = std::make_shared<elna::boot::record_type>(elna::boot::make_position(@1), std::move($2));
}
| UNION field_list END_BLOCK
{
$$ = new elna::boot::union_type(elna::boot::make_position(@1), std::move($2));
$$ = std::make_shared<elna::boot::union_type>(elna::boot::make_position(@1), std::move($2));
}
| IDENTIFIER
{
$$ = new elna::boot::basic_type(elna::boot::make_position(@1), $1);
$$ = std::make_shared<elna::boot::basic_type>(elna::boot::make_position(@1), $1);
}
variable_declaration: identifier_definition COLON type_expression
variable_declaration: identifier_definitions COLON type_expression
{
$$ = new elna::boot::variable_declaration(elna::boot::make_position(@2), $1.first, $1.second, $3);
for (const std::pair<std::string, bool>& identifier : $1)
{
elna::boot::variable_declaration *declaration = new elna::boot::variable_declaration(
elna::boot::make_position(@2), identifier.first, $3, identifier.second);
$$.push_back(declaration);
}
}
variable_declarations:
variable_declaration COMMA variable_declarations
variable_declaration variable_declarations
{
std::swap($$, $3);
$$.emplace($$.cbegin(), $1);
std::swap($$, $1);
$$.reserve($$.size() + $2.size());
$$.insert(std::end($$), std::begin($2), std::end($2));
}
| variable_declaration { $$.emplace_back(std::move($1)); }
| variable_declaration { std::swap($$, $1); }
variable_part:
/* no variable declarations */ {}
| VAR variable_declarations { std::swap($$, $2); }
@ -489,9 +503,20 @@ type_part:
/* no type definitions */ {}
| TYPE {}
| TYPE type_definitions { std::swap($$, $2); }
formal_parameter: IDENTIFIER COLON type_expression
{
$$ = new elna::boot::variable_declaration(elna::boot::make_position(@2), $1, $3);
}
formal_parameters:
formal_parameter COMMA formal_parameters
{
std::swap($$, $3);
$$.emplace($$.cbegin(), $1);
}
| formal_parameter { $$.emplace_back(std::move($1)); }
formal_parameter_list:
LEFT_PAREN RIGHT_PAREN {}
| LEFT_PAREN variable_declarations RIGHT_PAREN { std::swap($$, $2); }
| LEFT_PAREN formal_parameters RIGHT_PAREN { std::swap($$, $2); }
actual_parameter_list:
LEFT_PAREN RIGHT_PAREN {}
| LEFT_PAREN expressions RIGHT_PAREN { std::swap($$, $2); }