Generate record IR
This commit is contained in:
parent
cf4b6b7ccc
commit
954425f4bd
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user