Allow multiple variable declarations with a single type

This commit is contained in:
Eugen Wissner 2025-02-15 10:26:04 +01:00
parent 82b3806fd2
commit e66e077824
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
4 changed files with 85 additions and 109 deletions

View File

@ -300,8 +300,7 @@ namespace boot
return this; return this;
} }
array_type::array_type(const struct position position, top_type *base, array_type::array_type(const struct position position, std::shared_ptr<top_type> base, const std::uint32_t size)
const std::uint32_t size)
: top_type(position), m_base(base), size(size) : top_type(position), m_base(base), size(size)
{ {
} }
@ -321,12 +320,7 @@ namespace boot
return this; return this;
} }
array_type::~array_type() pointer_type::pointer_type(const struct position position, std::shared_ptr<top_type> base)
{
delete m_base;
}
pointer_type::pointer_type(const struct position position, top_type *base)
: top_type(position), m_base(base) : top_type(position), m_base(base)
{ {
} }
@ -346,24 +340,11 @@ namespace boot
return this; return this;
} }
pointer_type::~pointer_type()
{
delete m_base;
}
composite_type::composite_type(const struct position position, fields_t&& fields) composite_type::composite_type(const struct position position, fields_t&& fields)
: top_type(position), fields(std::move(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) record_type::record_type(const struct position position, fields_t&& fields)
: composite_type(position, std::move(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, 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) : definition(position, identifier, exported), m_type(type)
{ {
} }
variable_declaration::~variable_declaration()
{
delete m_type;
}
void variable_declaration::accept(parser_visitor *visitor) void variable_declaration::accept(parser_visitor *visitor)
{ {
visitor->visit(this); visitor->visit(this);
@ -442,7 +418,7 @@ namespace boot
} }
procedure_definition::procedure_definition(const struct position position, const std::string& identifier, 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) : definition(position, identifier, exported), m_return_type(return_type)
{ {
} }
@ -463,7 +439,7 @@ namespace boot
return this; return this;
} }
top_type *procedure_definition::return_type() std::shared_ptr<top_type> procedure_definition::return_type()
{ {
return m_return_type; return m_return_type;
} }
@ -481,7 +457,7 @@ namespace boot
} }
type_definition::type_definition(const struct position position, const std::string& identifier, 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) : definition(position, identifier, exported), m_body(body)
{ {
} }
@ -496,11 +472,6 @@ namespace boot
return *m_body; return *m_body;
} }
type_definition::~type_definition()
{
delete m_body;
}
block::block(const struct position position) block::block(const struct position position)
: node(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) : expression(position), m_target(target), m_value(value)
{ {
} }
@ -794,11 +766,10 @@ namespace boot
cast_expression::~cast_expression() cast_expression::~cast_expression()
{ {
delete m_target;
delete m_value; 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) : expression(position), m_body(body)
{ {
} }
@ -813,11 +784,6 @@ namespace boot
return *m_body; return *m_body;
} }
type_expression::~type_expression()
{
delete m_body;
}
call_statement::call_statement(const struct position position, call_expression *body) call_statement::call_statement(const struct position position, call_expression *body)
: statement(position), m_body(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::literal *> literal;
%type <elna::boot::constant_definition *> constant_definition; %type <elna::boot::constant_definition *> constant_definition;
%type <std::vector<elna::boot::constant_definition *>> constant_part constant_definitions; %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 variable_declaration
%type <std::vector<elna::boot::variable_declaration *>> variable_declarations variable_part formal_parameters formal_parameter_list;
formal_parameter_list; %type <elna::boot::variable_declaration *> formal_parameter
%type <elna::boot::top_type *> type_expression; %type <std::shared_ptr<elna::boot::top_type>> type_expression;
%type <elna::boot::expression *> expression operand unary; %type <elna::boot::expression *> expression operand unary;
%type <std::vector<elna::boot::expression *>> expressions actual_parameter_list; %type <std::vector<elna::boot::expression *>> expressions actual_parameter_list;
%type <elna::boot::designator_expression *> designator_expression; %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 <elna::boot::type_definition *> type_definition;
%type <std::vector<elna::boot::type_definition *>> type_definitions type_part; %type <std::vector<elna::boot::type_definition *>> type_definitions type_part;
%type <elna::boot::block *> block; %type <elna::boot::block *> block;
%type <std::pair<std::string, elna::boot::top_type *>> field_declaration; %type <elna::boot::field_t> field_declaration;
%type <std::vector<std::pair<std::string, elna::boot::top_type *>>> field_list; %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 <std::vector<elna::boot::conditional_statements *>> elsif_statement_list;
%type <elna::boot::cast_expression *> cast_expression; %type <elna::boot::cast_expression *> cast_expression;
%type <elna::boot::defer_statement *> defer_statement; %type <elna::boot::defer_statement *> defer_statement;
%type <std::pair<std::string, bool>> identifier_definition; %type <std::pair<std::string, bool>> identifier_definition;
%type <std::vector<std::pair<std::string, bool>>> identifier_definitions;
%% %%
program: program:
constant_part type_part variable_part procedure_part BEGIN_BLOCK optional_statements END_BLOCK DOT 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); $$ = 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_heading:
PROCEDURE identifier_definition formal_parameter_list SEMICOLON PROCEDURE identifier_definition formal_parameter_list SEMICOLON
{ {
@ -427,35 +435,41 @@ field_list:
type_expression: type_expression:
ARRAY INTEGER OF 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 | 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 | 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 | 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 | 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_declarations:
variable_declaration COMMA variable_declarations variable_declaration variable_declarations
{ {
std::swap($$, $3); std::swap($$, $1);
$$.emplace($$.cbegin(), $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: variable_part:
/* no variable declarations */ {} /* no variable declarations */ {}
| VAR variable_declarations { std::swap($$, $2); } | VAR variable_declarations { std::swap($$, $2); }
@ -489,9 +503,20 @@ type_part:
/* no type definitions */ {} /* no type definitions */ {}
| TYPE {} | TYPE {}
| TYPE type_definitions { std::swap($$, $2); } | 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: formal_parameter_list:
LEFT_PAREN RIGHT_PAREN {} 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: actual_parameter_list:
LEFT_PAREN RIGHT_PAREN {} LEFT_PAREN RIGHT_PAREN {}
| LEFT_PAREN expressions RIGHT_PAREN { std::swap($$, $2); } | LEFT_PAREN expressions RIGHT_PAREN { std::swap($$, $2); }

View File

@ -255,37 +255,33 @@ namespace boot
class array_type : public top_type class array_type : public top_type
{ {
top_type *m_base; std::shared_ptr<top_type> m_base;
public: public:
const std::uint32_t size; const std::uint32_t size;
array_type(const struct position position, top_type*base, const std::uint32_t size); array_type(const struct position position, std::shared_ptr<top_type> base, const std::uint32_t size);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
top_type& base(); top_type& base();
array_type *is_array() override; array_type *is_array() override;
virtual ~array_type() override;
}; };
class pointer_type : public top_type class pointer_type : public top_type
{ {
top_type *m_base; std::shared_ptr<top_type> m_base;
public: public:
pointer_type(const struct position position, top_type *base); pointer_type(const struct position position, std::shared_ptr<top_type> base);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
top_type& base(); top_type& base();
pointer_type *is_pointer() override; pointer_type *is_pointer() override;
virtual ~pointer_type() override;
}; };
using field_t = std::pair<std::string, top_type *>; using field_t = std::pair<std::string, std::shared_ptr<top_type>>;
using fields_t = std::vector<field_t>; using fields_t = std::vector<field_t>;
class composite_type : public top_type class composite_type : public top_type
@ -295,8 +291,6 @@ namespace boot
public: public:
fields_t fields; fields_t fields;
virtual ~composite_type() override;
}; };
class record_type : public composite_type class record_type : public composite_type
@ -322,16 +316,14 @@ namespace boot
*/ */
class variable_declaration : public definition class variable_declaration : public definition
{ {
top_type *m_type; std::shared_ptr<top_type> m_type;
public: public:
variable_declaration(const struct position position, const std::string& identifier, 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 = false);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
top_type& variable_type(); top_type& variable_type();
virtual ~variable_declaration() override;
}; };
/** /**
@ -370,17 +362,17 @@ namespace boot
*/ */
class procedure_definition : public definition class procedure_definition : public definition
{ {
top_type *m_return_type{ nullptr }; std::shared_ptr<top_type> m_return_type{ nullptr };
block *m_body{ nullptr }; block *m_body{ nullptr };
public: public:
std::vector<variable_declaration *> parameters; std::vector<variable_declaration *> parameters;
procedure_definition(const struct position position, const std::string& identifier, procedure_definition(const struct position position, const std::string& identifier,
const bool exported, top_type *return_type = nullptr); const bool exported, std::shared_ptr<top_type> return_type = nullptr);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
top_type *return_type(); std::shared_ptr<top_type> return_type();
block *body(); block *body();
procedure_definition *add_body(block *procedure_body); procedure_definition *add_body(block *procedure_body);
@ -393,16 +385,14 @@ namespace boot
*/ */
class type_definition : public definition class type_definition : public definition
{ {
top_type *m_body; std::shared_ptr<top_type> m_body;
public: public:
type_definition(const struct position position, const std::string& identifier, type_definition(const struct position position, const std::string& identifier,
const bool exported, top_type *expression); const bool exported, std::shared_ptr<top_type> expression);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
top_type& body(); top_type& body();
virtual ~type_definition() override;
}; };
/** /**
@ -432,11 +422,11 @@ namespace boot
*/ */
class cast_expression : public expression class cast_expression : public expression
{ {
top_type *m_target; std::shared_ptr<top_type> m_target;
expression *m_value; expression *m_value;
public: public:
cast_expression(const struct position position, top_type *target, expression *value); cast_expression(const struct position position, std::shared_ptr<top_type> target, expression *value);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
top_type& target(); top_type& target();
@ -450,15 +440,13 @@ namespace boot
*/ */
class type_expression : public expression class type_expression : public expression
{ {
top_type *m_body; std::shared_ptr<top_type> m_body;
public: public:
type_expression(const struct position position, top_type *body); type_expression(const struct position position, std::shared_ptr<top_type> body);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
top_type& body(); top_type& body();
virtual ~type_expression() override;
}; };
class call_statement : public statement class call_statement : public statement

View File

@ -172,7 +172,8 @@ end
proc write_i(value: Int); proc write_i(value: Int);
var var
digit: Int, n: Word, digit: Int
n: Word
buffer: array 10 of Char buffer: array 10 of Char
begin begin
n := 10u; n := 10u;
@ -243,16 +244,14 @@ end
*) *)
proc make_position() -> Position; proc make_position() -> Position;
var
result: Position
begin begin
return Position(1u, 1u) return Position(1u, 1u)
end end
proc read_source(filename: pointer to Char, result: pointer to String) -> Bool; proc read_source(filename: pointer to Char, result: pointer to String) -> Bool;
var var
input_file: pointer to FILE, input_file: pointer to FILE
source_size: Int, source_size: Int
input: pointer to Byte input: pointer to Byte
begin begin
input_file := fopen(filename, "rb\0".ptr); input_file := fopen(filename, "rb\0".ptr);
@ -398,9 +397,8 @@ end
proc lex_string(input: pointer to Char, current_token: pointer to Token) -> pointer to Char; proc lex_string(input: pointer to Char, current_token: pointer to Token) -> pointer to Char;
var var
token_end: pointer to Char, token_end, constructed_string: pointer to Char
constructed_string: pointer to Char, token_length: Word
token_length: Word,
is_valid: Bool is_valid: Bool
begin begin
token_end := input; token_end := input;
@ -438,7 +436,7 @@ end
proc print_tokens(tokens: pointer to Token, tokens_size: Word); proc print_tokens(tokens: pointer to Token, tokens_size: Word);
var var
current_token: pointer to Token, current_token: pointer to Token
i: Word i: Word
begin begin
i := 0u; i := 0u;
@ -657,11 +655,10 @@ end
proc tokenize(source_code: SourceCode, tokens_size: pointer to Word) -> pointer to Token; proc tokenize(source_code: SourceCode, tokens_size: pointer to Word) -> pointer to Token;
var var
token_end: pointer to Char, token_end: pointer to Char
tokens: pointer to Token, tokens, current_token: pointer to Token
current_token: pointer to Token, token_length: Word
token_length: Word, first_char: Char
first_char: Char,
token_content: String token_content: String
begin begin
tokens_size^ := 0u; tokens_size^ := 0u;
@ -850,7 +847,7 @@ end
proc parse_program(tokens: pointer to pointer to Token, tokens_size: pointer to Word) -> pointer to Program; proc parse_program(tokens: pointer to pointer to Token, tokens_size: pointer to Word) -> pointer to Program;
var var
result: pointer to Program, result: pointer to Program
current_constant: pointer to pointer to ConstantDefinition current_constant: pointer to pointer to ConstantDefinition
begin begin
result := cast(calloc(1u, Program.size): pointer to Program); result := cast(calloc(1u, Program.size): pointer to Program);
@ -883,8 +880,8 @@ end
proc parse_command_line*(argc: Int, argv: pointer to pointer to Char) -> pointer to CommandLine; proc parse_command_line*(argc: Int, argv: pointer to pointer to Char) -> pointer to CommandLine;
var var
parameter: pointer to pointer to Char, parameter: pointer to pointer to Char
i: Int, i: Int
result: pointer to CommandLine result: pointer to CommandLine
begin begin
i := 1; i := 1;
@ -924,9 +921,9 @@ end
proc process(argc: Int, argv: pointer to pointer to Char) -> Int; proc process(argc: Int, argv: pointer to pointer to Char) -> Int;
var var
tokens: pointer to Token, tokens: pointer to Token
tokens_size: Word, tokens_size: Word
source_code: SourceCode, source_code: SourceCode
command_line: pointer to CommandLine command_line: pointer to CommandLine
begin begin
command_line := parse_command_line(argc, argv); command_line := parse_command_line(argc, argv);