Generate record IR

This commit is contained in:
Eugen Wissner 2025-01-09 22:40:39 +01:00
parent cf4b6b7ccc
commit 954425f4bd
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
4 changed files with 68 additions and 25 deletions

View File

@ -7,6 +7,8 @@
#include "stringpool.h" #include "stringpool.h"
#include "diagnostic.h" #include "diagnostic.h"
#include "realmpfr.h" #include "realmpfr.h"
#include "stor-layout.h"
#include <set>
namespace elna namespace elna
{ {
@ -357,6 +359,38 @@ namespace gcc
return build_array_type(base_type, range_type); return build_array_type(base_type, range_type);
} }
else if (source::record_type_expression *record_type = type.is_record())
{
std::set<std::string> field_names;
tree record_type_node = make_node(RECORD_TYPE);
tree_chain record_chain;
for (auto& field : record_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) = record_type_node;
record_chain.append(field_declaration);
}
TYPE_FIELDS(record_type_node) = record_chain.head();
layout_type(record_type_node);
return record_type_node;
}
return NULL_TREE; return NULL_TREE;
} }

View File

@ -29,6 +29,12 @@ 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;

View File

@ -4,6 +4,7 @@
#include "system.h" #include "system.h"
#include "coretypes.h" #include "coretypes.h"
#include "tree.h" #include "tree.h"
#include "tree.h"
enum elna_tree_index enum elna_tree_index
{ {
@ -24,6 +25,7 @@ namespace gcc
void init_ttree(); void init_ttree();
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
{ {

View File

@ -79,14 +79,13 @@
%type <elna::source::char_literal *> character_literal; %type <elna::source::char_literal *> character_literal;
%type <elna::source::string_literal *> string_literal; %type <elna::source::string_literal *> string_literal;
%type <elna::source::constant_definition *> constant_definition; %type <elna::source::constant_definition *> constant_definition;
%type <std::vector<elna::source::constant_definition *>> constant_definition_part constant_definitions; %type <std::vector<elna::source::constant_definition *>> constant_part constant_definitions;
%type <elna::source::declaration *> variable_declaration; %type <elna::source::declaration *> variable_declaration;
%type <std::vector<elna::source::declaration *>> variable_declarations variable_declaration_part %type <std::vector<elna::source::declaration *>> variable_declarations variable_part
formal_parameter_list; formal_parameter_list;
%type <elna::source::type_expression *> type_expression; %type <elna::source::type_expression *> type_expression;
%type <elna::source::expression *> expression pointer summand factor address comparand; %type <elna::source::expression *> expression pointer summand factor comparand;
%type <std::vector<elna::source::expression *>> expressions actual_parameter_list; %type <std::vector<elna::source::expression *>> expressions actual_parameter_list;
%type <elna::source::variable_expression *> variable_expression;
%type <elna::source::designator_expression *> designator_expression; %type <elna::source::designator_expression *> designator_expression;
%type <elna::source::compound_statement *> compound_statement; %type <elna::source::compound_statement *> compound_statement;
%type <elna::source::assign_statement *> assign_statement; %type <elna::source::assign_statement *> assign_statement;
@ -96,13 +95,13 @@
%type <elna::source::statement *> statement; %type <elna::source::statement *> statement;
%type <std::vector<elna::source::statement *>> statements optional_statements; %type <std::vector<elna::source::statement *>> statements optional_statements;
%type <elna::source::procedure_definition *> procedure_definition; %type <elna::source::procedure_definition *> procedure_definition;
%type <std::vector<elna::source::procedure_definition *>> procedure_definitions procedure_definition_part; %type <std::vector<elna::source::procedure_definition *>> procedure_definitions procedure_part;
%type <elna::source::type_definition *> type_definition; %type <elna::source::type_definition *> type_definition;
%type <std::vector<elna::source::type_definition *>> type_definitions type_definition_part; %type <std::vector<elna::source::type_definition *>> type_definitions type_part;
%type <elna::source::block *> block; %type <elna::source::block *> block;
%% %%
program: program:
type_definition_part constant_definition_part procedure_definition_part variable_declaration_part statement DOT type_part constant_part procedure_part variable_part compound_statement DOT
{ {
std::vector<elna::source::definition *> definitions($1.size() + $2.size() + $3.size()); std::vector<elna::source::definition *> definitions($1.size() + $2.size() + $3.size());
std::vector<elna::source::definition *>::iterator definition = definitions.begin(); std::vector<elna::source::definition *>::iterator definition = definitions.begin();
@ -122,7 +121,7 @@ program:
driver.tree = std::make_unique<elna::source::program>(elna::source::position{}, driver.tree = std::make_unique<elna::source::program>(elna::source::position{},
std::move(definitions), std::move($4), std::move($5)); std::move(definitions), std::move($4), std::move($5));
} }
block: constant_definition_part variable_declaration_part statement block: constant_part variable_part statement
{ {
std::vector<elna::source::definition *> definitions($1.size()); std::vector<elna::source::definition *> definitions($1.size());
std::vector<elna::source::definition *>::iterator definition = definitions.begin(); std::vector<elna::source::definition *>::iterator definition = definitions.begin();
@ -148,7 +147,7 @@ procedure_definitions:
$$.emplace($$.cbegin(), std::move($1)); $$.emplace($$.cbegin(), std::move($1));
} }
| procedure_definition { $$.emplace_back(std::move($1)); } | procedure_definition { $$.emplace_back(std::move($1)); }
procedure_definition_part: procedure_part:
/* no procedure definitions */ {} /* no procedure definitions */ {}
| procedure_definitions { std::swap($$, $1); } | procedure_definitions { std::swap($$, $1); }
integer_literal: INTEGER integer_literal: INTEGER
@ -221,20 +220,13 @@ summand:
$$ = new elna::source::binary_expression(elna::source::make_position(@1), $$ = new elna::source::binary_expression(elna::source::make_position(@1),
$1, $3, '/'); $1, $3, '/');
} }
address:
pointer HAT
{
$$ = new elna::source::unary_expression(elna::source::make_position(@1),
$1, '^');
}
| pointer { $$ = $1; }
factor: factor:
AT address AT pointer
{ {
$$ = new elna::source::unary_expression(elna::source::make_position(@1), $$ = new elna::source::unary_expression(elna::source::make_position(@1),
$2, '@'); $2, '@');
} }
| address { $$ = $1; } | pointer { $$ = $1; }
comparand: comparand:
summand PLUS summand summand PLUS summand
{ {
@ -286,14 +278,23 @@ expressions:
$$.emplace($$.cbegin(), $1); $$.emplace($$.cbegin(), $1);
} }
| expression { $$.emplace_back(std::move($1)); } | expression { $$.emplace_back(std::move($1)); }
variable_expression:
IDENTIFIER { $$ = new elna::source::variable_expression(elna::source::make_position(@1), $1); }
designator_expression: designator_expression:
variable_expression LEFT_SQUARE expression RIGHT_SQUARE designator_expression LEFT_SQUARE expression RIGHT_SQUARE
{ {
$$ = new elna::source::array_access_expression(elna::source::make_position(@1), $1, $3); $$ = new elna::source::array_access_expression(elna::source::make_position(@1), $1, $3);
} }
| variable_expression { $$ = $1; } | designator_expression DOT IDENTIFIER
{
$$ = new elna::source::field_access_expression(elna::source::make_position(@1), $1, $3);
}
| designator_expression HAT
{
$$ = new elna::source::dereference_expression(elna::source::make_position(@1), $1);
}
| IDENTIFIER
{
$$ = new elna::source::variable_expression(elna::source::make_position(@1), $1);
}
statement: statement:
compound_statement { $$ = $1; } compound_statement { $$ = $1; }
| assign_statement { $$ = $1; } | assign_statement { $$ = $1; }
@ -334,7 +335,7 @@ variable_declarations:
$$.emplace($$.cbegin(), $1); $$.emplace($$.cbegin(), $1);
} }
| variable_declaration { $$.emplace_back(std::move($1)); } | variable_declaration { $$.emplace_back(std::move($1)); }
variable_declaration_part: variable_part:
/* no variable declarations */ {} /* no variable declarations */ {}
| VAR variable_declarations SEMICOLON { std::swap($$, $2); } | VAR variable_declarations SEMICOLON { std::swap($$, $2); }
constant_definition: IDENTIFIER EQUALS integer_literal constant_definition: IDENTIFIER EQUALS integer_literal
@ -348,7 +349,7 @@ constant_definitions:
$$.emplace($$.cbegin(), std::move($1)); $$.emplace($$.cbegin(), std::move($1));
} }
| constant_definition { $$.emplace_back(std::move($1)); } | constant_definition { $$.emplace_back(std::move($1)); }
constant_definition_part: constant_part:
/* no constant definitions */ {} /* no constant definitions */ {}
| CONST constant_definitions SEMICOLON { std::swap($$, $2); } | CONST constant_definitions SEMICOLON { std::swap($$, $2); }
type_definition: IDENTIFIER EQUALS type_expression type_definition: IDENTIFIER EQUALS type_expression
@ -362,7 +363,7 @@ type_definitions:
$$.emplace($$.cbegin(), std::move($1)); $$.emplace($$.cbegin(), std::move($1));
} }
| type_definition { $$.emplace_back(std::move($1)); } | type_definition { $$.emplace_back(std::move($1)); }
type_definition_part: type_part:
/* no type definitions */ {} /* no type definitions */ {}
| TYPE type_definitions SEMICOLON { std::swap($$, $2); } | TYPE type_definitions SEMICOLON { std::swap($$, $2); }
formal_parameter_list: formal_parameter_list: