End while and if statements with the end token

This commit is contained in:
Eugen Wissner 2025-01-17 10:11:40 +01:00
parent ef667e3ace
commit a79def50e5
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
10 changed files with 197 additions and 99 deletions

View File

@ -34,7 +34,7 @@ program = [ "type" type_definitions ";" ]
[ constant_part ] [ constant_part ]
{ procedure_definition } { procedure_definition }
[ variable_part ] [ variable_part ]
compound_statement "."; "begin" [ statement_list ] "end" ".";
procedure_definition = "proc" ident formal_parameter_list ";" ( block | "extern" ) ";"; procedure_definition = "proc" ident formal_parameter_list ";" ( block | "extern" ) ";";
@ -45,14 +45,18 @@ block = [ constant_part ]
constant_part = "const" ident "=" integer { "," ident "=" integer } ";"; constant_part = "const" ident "=" integer { "," ident "=" integer } ";";
variable_part = "var" variable_declarations ";"; variable_part = "var" variable_declarations ";";
statement = compound_statement statement = ident ":=" expression
| ident ":=" expression
| ident actual_parameter_list | ident actual_parameter_list
| "while" condition "do" statement | while_do
| "if" expression "then" statement [ else statement ]; | if_then_else;
while_do = "while" condition "do" [ statement_list ] "end";
if_then_else = "if" expression
"then" [ statement_list ]
[ else statement_list ] "end";
statement_list = statement {";" statement }; statement_list = statement {";" statement };
compound_statement = "begin" [ statement_list ] "end";
condition = "odd" expression | condition = "odd" expression |
expression ("="|"#"|"<"|"<="|">"|">=") expression; expression ("="|"#"|"<"|"<="|">"|">=") expression;
@ -86,8 +90,9 @@ variable_declarations = variable_declaration { ";" variable_declaration };
variable_declaration = ident ":" type_expression; variable_declaration = ident ":" type_expression;
type_expression = "array" integer "of" type_expression type_expression = "array" integer "of" type_expression
| "^" type_expression | "pointer" "to" type_expression
| "record" field_list "end" | "record" field_list "end"
| "union" field_list "end"
| ident; | ident;
field_list = field_declaration { ";" field_declaration }; field_list = field_declaration { ";" field_declaration };

View File

@ -3,6 +3,10 @@ type
R = record R = record
x: Int; x: Int;
y: Int y: Int
end,
U = union
a: Int;
b: Int
end; end;
proc test_string(); proc test_string();
@ -25,14 +29,13 @@ begin
x := 0; x := 0;
while x < 2 do while x < 2 do
begin
writei(a[x]); writei(a[x]);
x := x + 1 x := x + 1
end end
end; end;
proc test_pointer(); proc test_pointer();
var x: Int, p: ^Int; var x: Int, p: pointer to Int;
begin begin
x := 5; x := 5;
p := @x; p := @x;
@ -55,6 +58,17 @@ begin
writei(r.y) writei(r.y)
end; end;
proc test_union();
var u: U;
begin
writei("");
writei("Test union:");
u.a := 9;
writei(u.b)
end;
proc test_primitive(); proc test_primitive();
var c: Char, z: Float; var c: Char, z: Float;
begin begin
@ -89,6 +103,7 @@ begin
writei("Test if: True") writei("Test if: True")
else else
writei("Test if: False") writei("Test if: False")
end
end; end;
proc test_not(); proc test_not();
@ -101,6 +116,7 @@ begin
writei("Test not true.") writei("Test not true.")
else else
writei("Test not false") writei("Test not false")
end
end; end;
proc test_param(d: Int, e: Int); proc test_param(d: Int, e: Int);
@ -132,6 +148,7 @@ begin
test_not(); test_not();
test_param(8, 7); test_param(8, 7);
test_const_char(); test_const_char();
test_union();
exit(0) exit(0)
end. end.

View File

@ -15,9 +15,9 @@ namespace elna
{ {
namespace gcc namespace gcc
{ {
generic_visitor::generic_visitor() generic_visitor::generic_visitor(std::shared_ptr<source::symbol_table<tree>> symbol_table)
{ {
this->symbol_map = std::make_shared<source::symbol_table<tree>>(); this->symbol_map = symbol_table;
} }
void generic_visitor::visit(source::call_statement *statement) void generic_visitor::visit(source::call_statement *statement)
@ -270,7 +270,7 @@ namespace gcc
this->current_expression = build_string_literal(string->string().size() + 1, string->string().c_str()); this->current_expression = build_string_literal(string->string().size() + 1, string->string().c_str());
} }
void generic_visitor::build_binarary_operation(bool condition, source::binary_expression *expression, void generic_visitor::build_binary_operation(bool condition, source::binary_expression *expression,
tree_code operator_code, tree left, tree right, tree target_type) tree_code operator_code, tree left, tree right, tree target_type)
{ {
auto expression_location = get_location(&expression->position()); auto expression_location = get_location(&expression->position());
@ -354,7 +354,7 @@ namespace gcc
} }
if (operator_code != ERROR_MARK) // An arithmetic operation. if (operator_code != ERROR_MARK) // An arithmetic operation.
{ {
build_binarary_operation(left_type == integer_type_node || left_type == double_type_node, build_binary_operation(left_type == integer_type_node || left_type == double_type_node,
expression, operator_code, left, right, target_type); expression, operator_code, left, right, target_type);
return; return;
} }
@ -373,7 +373,7 @@ namespace gcc
} }
if (operator_code != ERROR_MARK) // A logical operation. if (operator_code != ERROR_MARK) // A logical operation.
{ {
build_binarary_operation(left_type == boolean_type_node, build_binary_operation(left_type == boolean_type_node,
expression, operator_code, left, right, target_type); expression, operator_code, left, right, target_type);
return; return;
} }
@ -538,7 +538,7 @@ namespace gcc
tree record_type_node = make_node(RECORD_TYPE); tree record_type_node = make_node(RECORD_TYPE);
tree_chain record_chain; tree_chain record_chain;
for (auto& field : record_type->fields()) for (auto& field : record_type->fields)
{ {
if (field_names.find(field.first) != field_names.cend()) if (field_names.find(field.first) != field_names.cend())
{ {
@ -564,6 +564,38 @@ namespace gcc
return record_type_node; return record_type_node;
} }
else if (source::union_type_expression *union_type = type.is_union())
{
std::set<std::string> field_names;
tree union_type_node = make_node(UNION_TYPE);
tree_chain union_chain;
for (auto& field : union_type->fields)
{
if (field_names.find(field.first) != field_names.cend())
{
error_at(get_location(&field.second->position()), "repeated field name");
return error_mark_node;
}
field_names.insert(field.first);
tree field_type = build_type(*field.second);
if (field_type == NULL_TREE || field_type == error_mark_node)
{
return field_type;
}
tree field_declaration = build_decl(get_location(&field.second->position()),
FIELD_DECL, get_identifier(field.first.c_str()), field_type);
TREE_ADDRESSABLE(field_declaration) = 1;
DECL_CONTEXT(field_declaration) = union_type_node;
union_chain.append(field_declaration);
}
TYPE_FIELDS(union_type_node) = union_chain.head();
layout_type(union_type_node);
return union_type_node;
}
return NULL_TREE; return NULL_TREE;
} }

View File

@ -34,12 +34,6 @@ namespace gcc
return TREE_CODE(type) == ARRAY_TYPE; return TREE_CODE(type) == ARRAY_TYPE;
} }
bool is_record_type(tree type)
{
gcc_assert(TYPE_P(type));
return TREE_CODE(type) == RECORD_TYPE;
}
tree tree_chain_base::head() tree tree_chain_base::head()
{ {
return first; return first;
@ -79,5 +73,10 @@ namespace gcc
{ {
return m_block; return m_block;
} }
std::shared_ptr<elna::source::symbol_table<tree>> builtin_symbol_table()
{
return std::make_shared<elna::source::symbol_table<tree>>();
}
} }
} }

View File

@ -31,11 +31,11 @@ namespace gcc
void enter_scope(); void enter_scope();
tree_symbol_mapping leave_scope(); tree_symbol_mapping leave_scope();
void build_binarary_operation(bool condition, source::binary_expression *expression, void build_binary_operation(bool condition, source::binary_expression *expression,
tree_code operator_code, tree left, tree right, tree target_type); tree_code operator_code, tree left, tree right, tree target_type);
public: public:
generic_visitor(); generic_visitor(std::shared_ptr<source::symbol_table<tree>> symbol_table);
void visit(source::program *program) override; void visit(source::program *program) override;
void visit(source::procedure_definition *definition) override; void visit(source::procedure_definition *definition) override;

View File

@ -26,7 +26,6 @@ namespace gcc
bool is_pointer_type(tree type); bool is_pointer_type(tree type);
bool is_string_type(tree type); bool is_string_type(tree type);
bool is_array_type(tree type); bool is_array_type(tree type);
bool is_record_type(tree type);
class tree_chain_base class tree_chain_base
{ {
@ -58,5 +57,7 @@ namespace gcc
tree bind_expression(); tree bind_expression();
tree block(); tree block();
}; };
std::shared_ptr<elna::source::symbol_table<tree>> builtin_symbol_table();
} }
} }

View File

@ -52,6 +52,7 @@ namespace source
class array_type_expression; class array_type_expression;
class pointer_type_expression; class pointer_type_expression;
class record_type_expression; class record_type_expression;
class union_type_expression;
class variable_expression; class variable_expression;
class array_access_expression; class array_access_expression;
class field_access_expression; class field_access_expression;
@ -83,6 +84,7 @@ namespace source
virtual void visit(array_type_expression *) = 0; virtual void visit(array_type_expression *) = 0;
virtual void visit(pointer_type_expression *) = 0; virtual void visit(pointer_type_expression *) = 0;
virtual void visit(record_type_expression *) = 0; virtual void visit(record_type_expression *) = 0;
virtual void visit(union_type_expression *) = 0;
virtual void visit(variable_expression *) = 0; virtual void visit(variable_expression *) = 0;
virtual void visit(array_access_expression *) = 0; virtual void visit(array_access_expression *) = 0;
virtual void visit(field_access_expression *is_field_access) = 0; virtual void visit(field_access_expression *is_field_access) = 0;
@ -116,6 +118,7 @@ namespace source
virtual void visit(array_type_expression *expression) override; virtual void visit(array_type_expression *expression) override;
virtual void visit(pointer_type_expression *) override; virtual void visit(pointer_type_expression *) override;
virtual void visit(record_type_expression *expression) override; virtual void visit(record_type_expression *expression) override;
virtual void visit(union_type_expression *expression) override;
virtual void visit(variable_expression *) override; virtual void visit(variable_expression *) override;
virtual void visit(array_access_expression *expression) override; virtual void visit(array_access_expression *expression) override;
virtual void visit(field_access_expression *expression) override; virtual void visit(field_access_expression *expression) override;
@ -253,6 +256,7 @@ namespace source
virtual array_type_expression *is_array(); virtual array_type_expression *is_array();
virtual pointer_type_expression *is_pointer(); virtual pointer_type_expression *is_pointer();
virtual record_type_expression *is_record(); virtual record_type_expression *is_record();
virtual union_type_expression *is_union();
protected: protected:
type_expression(const struct position position); type_expression(const struct position position);
@ -310,23 +314,36 @@ namespace source
virtual ~pointer_type_expression() override; virtual ~pointer_type_expression() override;
}; };
class record_type_expression final : public type_expression using field_t = std::pair<std::string, type_expression *>;
using fields_t = std::vector<field_t>;
class composite_type_expression : public type_expression
{
protected:
composite_type_expression(const struct position position, fields_t&& fields);
public:
fields_t fields;
virtual ~composite_type_expression() override;
};
class record_type_expression final : public composite_type_expression
{ {
public: public:
using field_t = std::pair<std::string, type_expression *>;
using fields_t = std::vector<field_t>;
record_type_expression(const struct position position, fields_t&& fields); record_type_expression(const struct position position, fields_t&& fields);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
fields_t& fields();
record_type_expression *is_record() override; record_type_expression *is_record() override;
};
virtual ~record_type_expression() override; class union_type_expression final : public composite_type_expression
{
public:
union_type_expression(const struct position position, fields_t&& fields);
private: virtual void accept(parser_visitor *visitor) override;
fields_t m_fields; union_type_expression *is_union() override;
}; };
/** /**
@ -443,13 +460,11 @@ namespace source
class compound_statement : public statement class compound_statement : public statement
{ {
std::vector<statement *> m_statements;
public: public:
explicit compound_statement(const struct position position); std::vector<statement *> statements;
virtual void accept(parser_visitor *visitor) override;
std::vector<statement *>& statements(); compound_statement(const struct position position, std::vector<statement *>&& statements);
virtual void accept(parser_visitor *visitor) override;
virtual ~compound_statement() override; virtual ~compound_statement() override;
}; };
@ -556,8 +571,8 @@ namespace source
class if_statement : public statement class if_statement : public statement
{ {
expression *m_prerequisite; expression *m_prerequisite;
statement *m_body; compound_statement *m_body;
statement *m_alternative; compound_statement *m_alternative;
public: public:
/** /**
@ -567,12 +582,12 @@ namespace source
* \param alternative Statement executed if the condition is not met. * \param alternative Statement executed if the condition is not met.
*/ */
if_statement(const struct position position, expression *prerequisite, if_statement(const struct position position, expression *prerequisite,
statement *body, statement *alternative = nullptr); compound_statement *body, compound_statement *alternative = nullptr);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
expression& prerequisite(); expression& prerequisite();
statement& body(); compound_statement& body();
statement *alternative(); compound_statement *alternative();
virtual ~if_statement() override; virtual ~if_statement() override;
}; };
@ -583,7 +598,7 @@ namespace source
class while_statement : public statement class while_statement : public statement
{ {
expression *m_prerequisite; expression *m_prerequisite;
statement *m_body; compound_statement *m_body;
public: public:
/** /**
@ -592,11 +607,11 @@ namespace source
* \param body Statement executed while the condition is met. * \param body Statement executed while the condition is met.
*/ */
while_statement(const struct position position, expression *prerequisite, while_statement(const struct position position, expression *prerequisite,
statement *body); compound_statement *body);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
expression& prerequisite(); expression& prerequisite();
statement& body(); compound_statement& body();
virtual ~while_statement() override; virtual ~while_statement() override;
}; };

View File

@ -43,7 +43,7 @@ namespace source
void empty_visitor::visit(compound_statement *statement) void empty_visitor::visit(compound_statement *statement)
{ {
for (auto& nested_statement : statement->statements()) for (const auto nested_statement : statement->statements)
{ {
nested_statement->accept(this); nested_statement->accept(this);
} }
@ -114,7 +114,15 @@ namespace source
void empty_visitor::visit(record_type_expression *expression) void empty_visitor::visit(record_type_expression *expression)
{ {
for (auto& field : expression->fields()) for (auto& field : expression->fields)
{
field.second->accept(this);
}
}
void empty_visitor::visit(union_type_expression *expression)
{
for (auto& field : expression->fields)
{ {
field.second->accept(this); field.second->accept(this);
} }
@ -244,6 +252,11 @@ namespace source
return nullptr; return nullptr;
} }
union_type_expression *type_expression::is_union()
{
return nullptr;
}
pointer_type_expression *type_expression::is_pointer() pointer_type_expression *type_expression::is_pointer()
{ {
return nullptr; return nullptr;
@ -321,9 +334,23 @@ namespace source
delete m_base; delete m_base;
} }
composite_type_expression::composite_type_expression(const struct position position,
fields_t&& fields)
: type_expression(position), fields(std::move(fields))
{
}
composite_type_expression::~composite_type_expression()
{
for (auto& field_declaration : fields)
{
delete field_declaration.second;
}
}
record_type_expression::record_type_expression(const struct position position, record_type_expression::record_type_expression(const struct position position,
record_type_expression::fields_t&& fields) fields_t&& fields)
: type_expression(position), m_fields(std::move(fields)) : composite_type_expression(position, std::move(fields))
{ {
} }
@ -332,22 +359,25 @@ namespace source
visitor->visit(this); visitor->visit(this);
} }
record_type_expression::fields_t& record_type_expression::fields()
{
return m_fields;
}
record_type_expression *record_type_expression::is_record() record_type_expression *record_type_expression::is_record()
{ {
return this; return this;
} }
record_type_expression::~record_type_expression() union_type_expression::union_type_expression(const struct position position,
fields_t&& fields)
: composite_type_expression(position, std::move(fields))
{ {
for (auto& field_declaration : fields()) }
{
delete field_declaration.second; union_type_expression *union_type_expression::is_union()
} {
return this;
}
void union_type_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
} }
variable_declaration::variable_declaration(const struct position position, const std::string& identifier, variable_declaration::variable_declaration(const struct position position, const std::string& identifier,
@ -766,8 +796,8 @@ namespace source
} }
} }
compound_statement::compound_statement(const struct position position) compound_statement::compound_statement(const struct position position, std::vector<statement *>&& statements)
: statement(position) : statement(position), statements(std::move(statements))
{ {
} }
@ -776,14 +806,9 @@ namespace source
visitor->visit(this); visitor->visit(this);
} }
std::vector<statement *>& compound_statement::statements()
{
return m_statements;
}
compound_statement::~compound_statement() compound_statement::~compound_statement()
{ {
for (auto statement : m_statements) for (auto statement : statements)
{ {
delete statement; delete statement;
} }
@ -836,7 +861,7 @@ namespace source
} }
if_statement::if_statement(const struct position position, expression *prerequisite, if_statement::if_statement(const struct position position, expression *prerequisite,
statement *body, statement *alternative) compound_statement *body, compound_statement *alternative)
: statement(position), m_prerequisite(prerequisite), m_body(body), : statement(position), m_prerequisite(prerequisite), m_body(body),
m_alternative(alternative) m_alternative(alternative)
{ {
@ -852,12 +877,12 @@ namespace source
return *m_prerequisite; return *m_prerequisite;
} }
statement& if_statement::body() compound_statement& if_statement::body()
{ {
return *m_body; return *m_body;
} }
statement *if_statement::alternative() compound_statement *if_statement::alternative()
{ {
return m_alternative; return m_alternative;
} }
@ -874,7 +899,7 @@ namespace source
} }
while_statement::while_statement(const struct position position, expression *prerequisite, while_statement::while_statement(const struct position position, expression *prerequisite,
statement *body) compound_statement *body)
: statement(position), m_prerequisite(prerequisite), m_body(body) : statement(position), m_prerequisite(prerequisite), m_body(body)
{ {
} }
@ -889,7 +914,7 @@ namespace source
return *m_prerequisite; return *m_prerequisite;
} }
statement& while_statement::body() compound_statement& while_statement::body()
{ {
return *m_body; return *m_body;
} }

View File

@ -76,6 +76,15 @@ type {
record { record {
return yy::parser::make_RECORD(this->location); return yy::parser::make_RECORD(this->location);
} }
union {
return yy::parser::make_UNION(this->location);
}
pointer {
return yy::parser::make_POINTER(this->location);
}
to {
return yy::parser::make_TO(this->location);
}
true { true {
return yy::parser::make_BOOLEAN(true, this->location); return yy::parser::make_BOOLEAN(true, this->location);
} }

View File

@ -62,8 +62,8 @@
%token <std::string> CHARACTER "character" %token <std::string> CHARACTER "character"
%token <std::string> STRING "string" %token <std::string> STRING "string"
%token <bool> BOOLEAN %token <bool> BOOLEAN
%token IF WHILE DO %token IF WHILE DO THEN ELSE
%token CONST VAR PROCEDURE ARRAY OF TYPE RECORD %token CONST VAR PROCEDURE ARRAY OF TYPE RECORD POINTER TO UNION
%token BEGIN_BLOCK END_BLOCK EXTERN %token BEGIN_BLOCK END_BLOCK EXTERN
%token LEFT_PAREN RIGHT_PAREN LEFT_SQUARE RIGHT_SQUARE SEMICOLON DOT COMMA %token LEFT_PAREN RIGHT_PAREN LEFT_SQUARE RIGHT_SQUARE SEMICOLON DOT COMMA
%token AND OR NOT %token AND OR NOT
@ -71,9 +71,6 @@
%token PLUS MINUS MULTIPLICATION DIVISION %token PLUS MINUS MULTIPLICATION DIVISION
%token ASSIGNMENT COLON HAT AT %token ASSIGNMENT COLON HAT AT
%precedence THEN
%precedence ELSE
%type <elna::source::literal *> literal; %type <elna::source::literal *> literal;
%type <elna::source::constant_definition *> constant_definition; %type <elna::source::constant_definition *> constant_definition;
%type <std::vector<elna::source::constant_definition *>> constant_part constant_definitions; %type <std::vector<elna::source::constant_definition *>> constant_part constant_definitions;
@ -84,7 +81,6 @@
%type <elna::source::expression *> expression pointer summand factor comparand logical_operand; %type <elna::source::expression *> expression pointer summand factor comparand logical_operand;
%type <std::vector<elna::source::expression *>> expressions actual_parameter_list; %type <std::vector<elna::source::expression *>> expressions actual_parameter_list;
%type <elna::source::designator_expression *> designator_expression; %type <elna::source::designator_expression *> designator_expression;
%type <elna::source::compound_statement *> compound_statement;
%type <elna::source::assign_statement *> assign_statement; %type <elna::source::assign_statement *> assign_statement;
%type <elna::source::call_statement *> call_statement; %type <elna::source::call_statement *> call_statement;
%type <elna::source::while_statement *> while_statement; %type <elna::source::while_statement *> while_statement;
@ -167,11 +163,6 @@ procedure_definitions:
procedure_part: procedure_part:
/* no procedure definitions */ {} /* no procedure definitions */ {}
| procedure_definitions { std::swap($$, $1); } | procedure_definitions { std::swap($$, $1); }
compound_statement: BEGIN_BLOCK optional_statements END_BLOCK
{
$$ = new elna::source::compound_statement(elna::source::make_position(@1));
std::swap($$->statements(), $2);
}
assign_statement: designator_expression ASSIGNMENT expression assign_statement: designator_expression ASSIGNMENT expression
{ {
$$ = new elna::source::assign_statement(elna::source::make_position(@1), $1, $3); $$ = new elna::source::assign_statement(elna::source::make_position(@1), $1, $3);
@ -181,21 +172,22 @@ call_statement: IDENTIFIER actual_parameter_list
$$ = new elna::source::call_statement(elna::source::make_position(@1), $1); $$ = new elna::source::call_statement(elna::source::make_position(@1), $1);
std::swap($$->arguments(), $2); std::swap($$->arguments(), $2);
} }
while_statement: WHILE expression DO statement while_statement: WHILE expression DO optional_statements END_BLOCK
{ {
$$ = new elna::source::while_statement(elna::source::make_position(@1), auto body = new elna::source::compound_statement(elna::source::make_position(@3), std::move($4));
$2, $4); $$ = new elna::source::while_statement(elna::source::make_position(@1), $2, body);
} }
if_statement: if_statement:
IF expression THEN statement IF expression THEN optional_statements END_BLOCK
{ {
$$ = new elna::source::if_statement(elna::source::make_position(@1), auto then = new elna::source::compound_statement(elna::source::make_position(@3), std::move($4));
$2, $4); $$ = new elna::source::if_statement(elna::source::make_position(@1), $2, then);
} }
| IF expression THEN statement ELSE statement | IF expression THEN optional_statements ELSE optional_statements END_BLOCK
{ {
$$ = new elna::source::if_statement(elna::source::make_position(@1), auto then = new elna::source::compound_statement(elna::source::make_position(@3), std::move($4));
$2, $4, $6); auto _else = new elna::source::compound_statement(elna::source::make_position(@5), std::move($6));
$$ = new elna::source::if_statement(elna::source::make_position(@1), $2, then, _else);
} }
literal: literal:
INTEGER INTEGER
@ -315,8 +307,7 @@ designator_expression:
$$ = new elna::source::variable_expression(elna::source::make_position(@1), $1); $$ = new elna::source::variable_expression(elna::source::make_position(@1), $1);
} }
statement: statement:
compound_statement { $$ = $1; } assign_statement { $$ = $1; }
| assign_statement { $$ = $1; }
| call_statement { $$ = $1; } | call_statement { $$ = $1; }
| while_statement { $$ = $1; } | while_statement { $$ = $1; }
| if_statement { $$ = $1; } | if_statement { $$ = $1; }
@ -344,14 +335,18 @@ type_expression:
{ {
$$ = new elna::source::array_type_expression(elna::source::make_position(@1), $4, $2); $$ = new elna::source::array_type_expression(elna::source::make_position(@1), $4, $2);
} }
| HAT type_expression | POINTER TO type_expression
{ {
$$ = new elna::source::pointer_type_expression(elna::source::make_position(@1), $2); $$ = new elna::source::pointer_type_expression(elna::source::make_position(@1), $3);
} }
| RECORD field_list END_BLOCK | RECORD field_list END_BLOCK
{ {
$$ = new elna::source::record_type_expression(elna::source::make_position(@1), std::move($2)); $$ = new elna::source::record_type_expression(elna::source::make_position(@1), std::move($2));
} }
| UNION field_list END_BLOCK
{
$$ = new elna::source::union_type_expression(elna::source::make_position(@1), std::move($2));
}
| IDENTIFIER | IDENTIFIER
{ {
$$ = new elna::source::basic_type_expression(elna::source::make_position(@1), $1); $$ = new elna::source::basic_type_expression(elna::source::make_position(@1), $1);
@ -359,7 +354,7 @@ type_expression:
variable_declaration: IDENTIFIER COLON type_expression variable_declaration: IDENTIFIER COLON type_expression
{ {
$$ = new elna::source::variable_declaration(elna::source::make_position(@1), $1, $3); $$ = new elna::source::variable_declaration(elna::source::make_position(@1), $1, $3);
}; }
variable_declarations: variable_declarations:
variable_declaration COMMA variable_declarations variable_declaration COMMA variable_declarations
{ {