Compare commits

..

1 Commits

Author SHA1 Message Date
ec0b4be1f7 Use colon instead of as to cast 2025-02-14 19:56:46 +01:00
9 changed files with 202 additions and 256 deletions

View File

@ -61,7 +61,7 @@ namespace boot
expression->value().accept(this); expression->value().accept(this);
} }
void empty_visitor::visit(type_expression *expression) void empty_visitor::visit(size_of_expression *expression)
{ {
expression->body().accept(this); expression->body().accept(this);
} }
@ -152,21 +152,21 @@ namespace boot
expression->operand().accept(this); expression->operand().accept(this);
} }
void empty_visitor::visit(basic_type *) void empty_visitor::visit(basic_type_expression *)
{ {
} }
void empty_visitor::visit(array_type *expression) void empty_visitor::visit(array_type_expression *expression)
{ {
expression->base().accept(this); expression->base().accept(this);
} }
void empty_visitor::visit(pointer_type *expression) void empty_visitor::visit(pointer_type_expression *expression)
{ {
expression->base().accept(this); expression->base().accept(this);
} }
void empty_visitor::visit(record_type *expression) void empty_visitor::visit(record_type_expression *expression)
{ {
for (auto& field : expression->fields) for (auto& field : expression->fields)
{ {
@ -174,7 +174,7 @@ namespace boot
} }
} }
void empty_visitor::visit(union_type *expression) void empty_visitor::visit(union_type_expression *expression)
{ {
for (auto& field : expression->fields) for (auto& field : expression->fields)
{ {
@ -250,113 +250,115 @@ namespace boot
{ {
} }
top_type::top_type(const struct position position) type_expression::type_expression(const struct position position)
: node(position) : node(position)
{ {
} }
basic_type *top_type::is_basic() basic_type_expression *type_expression::is_basic()
{ {
return nullptr; return nullptr;
} }
array_type *top_type::is_array() array_type_expression *type_expression::is_array()
{ {
return nullptr; return nullptr;
} }
record_type *top_type::is_record() record_type_expression *type_expression::is_record()
{ {
return nullptr; return nullptr;
} }
union_type *top_type::is_union() union_type_expression *type_expression::is_union()
{ {
return nullptr; return nullptr;
} }
pointer_type *top_type::is_pointer() pointer_type_expression *type_expression::is_pointer()
{ {
return nullptr; return nullptr;
} }
basic_type::basic_type(const struct position position, const std::string& name) basic_type_expression::basic_type_expression(
: top_type(position), m_name(name) const struct position position, const std::string& name)
: type_expression(position), m_name(name)
{ {
} }
void basic_type::accept(parser_visitor *visitor) void basic_type_expression::accept(parser_visitor *visitor)
{ {
visitor->visit(this); visitor->visit(this);
} }
const std::string& basic_type::base_name() const std::string& basic_type_expression::base_name()
{ {
return m_name; return m_name;
} }
basic_type *basic_type::is_basic() basic_type_expression *basic_type_expression::is_basic()
{ {
return this; return this;
} }
array_type::array_type(const struct position position, top_type *base, array_type_expression::array_type_expression(const struct position position, type_expression *base,
const std::uint32_t size) const std::uint32_t size)
: top_type(position), m_base(base), size(size) : type_expression(position), m_base(base), size(size)
{ {
} }
void array_type::accept(parser_visitor *visitor) void array_type_expression::accept(parser_visitor *visitor)
{ {
visitor->visit(this); visitor->visit(this);
} }
top_type& array_type::base() type_expression& array_type_expression::base()
{ {
return *m_base; return *m_base;
} }
array_type*array_type::is_array() array_type_expression *array_type_expression::is_array()
{ {
return this; return this;
} }
array_type::~array_type() array_type_expression::~array_type_expression()
{ {
delete m_base; delete m_base;
} }
pointer_type::pointer_type(const struct position position, top_type *base) pointer_type_expression::pointer_type_expression(const struct position position, type_expression *base)
: top_type(position), m_base(base) : type_expression(position), m_base(base)
{ {
} }
void pointer_type::accept(parser_visitor *visitor) void pointer_type_expression::accept(parser_visitor *visitor)
{ {
visitor->visit(this); visitor->visit(this);
} }
top_type& pointer_type::base() type_expression& pointer_type_expression::base()
{ {
return *m_base; return *m_base;
} }
pointer_type *pointer_type::is_pointer() pointer_type_expression *pointer_type_expression::is_pointer()
{ {
return this; return this;
} }
pointer_type::~pointer_type() pointer_type_expression::~pointer_type_expression()
{ {
delete m_base; delete m_base;
} }
composite_type::composite_type(const struct position position, fields_t&& fields) composite_type_expression::composite_type_expression(const struct position position,
: top_type(position), fields(std::move(fields)) fields_t&& fields)
: type_expression(position), fields(std::move(fields))
{ {
} }
composite_type::~composite_type() composite_type_expression::~composite_type_expression()
{ {
for (auto& field_declaration : fields) for (auto& field_declaration : fields)
{ {
@ -364,38 +366,40 @@ namespace boot
} }
} }
record_type::record_type(const struct position position, fields_t&& fields) record_type_expression::record_type_expression(const struct position position,
: composite_type(position, std::move(fields)) fields_t&& fields)
: composite_type_expression(position, std::move(fields))
{ {
} }
void record_type::accept(parser_visitor *visitor) void record_type_expression::accept(parser_visitor *visitor)
{ {
visitor->visit(this); visitor->visit(this);
} }
record_type *record_type::is_record() record_type_expression *record_type_expression::is_record()
{ {
return this; return this;
} }
union_type::union_type(const struct position position, fields_t&& fields) union_type_expression::union_type_expression(const struct position position,
: composite_type(position, std::move(fields)) fields_t&& fields)
: composite_type_expression(position, std::move(fields))
{ {
} }
union_type *union_type::is_union() union_type_expression *union_type_expression::is_union()
{ {
return this; return this;
} }
void union_type::accept(parser_visitor *visitor) void union_type_expression::accept(parser_visitor *visitor)
{ {
visitor->visit(this); 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,
const bool exported, top_type *type) const bool exported, type_expression *type)
: definition(position, identifier, exported), m_type(type) : definition(position, identifier, exported), m_type(type)
{ {
} }
@ -410,7 +414,7 @@ namespace boot
visitor->visit(this); visitor->visit(this);
} }
top_type& variable_declaration::variable_type() type_expression& variable_declaration::type()
{ {
return *m_type; return *m_type;
} }
@ -442,7 +446,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, type_expression *return_type)
: definition(position, identifier, exported), m_return_type(return_type) : definition(position, identifier, exported), m_return_type(return_type)
{ {
} }
@ -463,7 +467,7 @@ namespace boot
return this; return this;
} }
top_type *procedure_definition::return_type() type_expression *procedure_definition::return_type()
{ {
return m_return_type; return m_return_type;
} }
@ -481,7 +485,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, type_expression *body)
: definition(position, identifier, exported), m_body(body) : definition(position, identifier, exported), m_body(body)
{ {
} }
@ -491,7 +495,7 @@ namespace boot
visitor->visit(this); visitor->visit(this);
} }
top_type& type_definition::body() type_expression& type_definition::body()
{ {
return *m_body; return *m_body;
} }
@ -772,7 +776,7 @@ namespace boot
} }
} }
cast_expression::cast_expression(const struct position position, top_type *target, expression *value) cast_expression::cast_expression(const struct position position, type_expression *target, expression *value)
: expression(position), m_target(target), m_value(value) : expression(position), m_target(target), m_value(value)
{ {
} }
@ -782,7 +786,7 @@ namespace boot
visitor->visit(this); visitor->visit(this);
} }
top_type& cast_expression::target() type_expression& cast_expression::target()
{ {
return *m_target; return *m_target;
} }
@ -798,22 +802,22 @@ namespace boot
delete m_value; delete m_value;
} }
type_expression::type_expression(const struct position position, top_type *body) size_of_expression::size_of_expression(const struct position position, type_expression *body)
: expression(position), m_body(body) : expression(position), m_body(body)
{ {
} }
void type_expression::accept(parser_visitor *visitor) void size_of_expression::accept(parser_visitor *visitor)
{ {
visitor->visit(this); visitor->visit(this);
} }
top_type& type_expression::body() type_expression& size_of_expression::body()
{ {
return *m_body; return *m_body;
} }
type_expression::~type_expression() size_of_expression::~size_of_expression()
{ {
delete m_body; delete m_body;
} }
@ -1012,10 +1016,6 @@ namespace boot
return "or"; return "or";
case binary_operator::exclusive_disjunction: case binary_operator::exclusive_disjunction:
return "xor"; return "xor";
case binary_operator::shift_left:
return "<<";
case binary_operator::shift_right:
return ">>";
} }
__builtin_unreachable(); __builtin_unreachable();
}; };

View File

@ -137,6 +137,9 @@ return {
cast { cast {
return yy::parser::make_CAST(this->location); return yy::parser::make_CAST(this->location);
} }
sizeof {
return yy::parser::make_SIZEOF(this->location);
}
defer { defer {
return yy::parser::make_DEFER(this->location); return yy::parser::make_DEFER(this->location);
} }
@ -229,12 +232,6 @@ defer {
\] { \] {
return yy::parser::make_RIGHT_SQUARE(this->location); return yy::parser::make_RIGHT_SQUARE(this->location);
} }
\<\< {
return yy::parser::make_SHIFT_LEFT(this->location);
}
\>\> {
return yy::parser::make_SHIFT_RIGHT(this->location);
}
\>= { \>= {
return yy::parser::make_GREATER_EQUAL(this->location); return yy::parser::make_GREATER_EQUAL(this->location);
} }

View File

@ -85,7 +85,7 @@ along with GCC; see the file COPYING3. If not see
%token CONST VAR PROCEDURE ARRAY OF TYPE RECORD POINTER TO UNION %token CONST VAR PROCEDURE ARRAY OF TYPE RECORD POINTER TO UNION
%token BEGIN_BLOCK END_BLOCK EXTERN DEFER %token BEGIN_BLOCK END_BLOCK EXTERN DEFER
%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 CAST SHIFT_LEFT SHIFT_RIGHT %token AND OR NOT CAST SIZEOF
%token GREATER_EQUAL LESS_EQUAL LESS_THAN GREATER_THAN NOT_EQUAL EQUALS %token GREATER_EQUAL LESS_EQUAL LESS_THAN GREATER_THAN NOT_EQUAL EQUALS
%token PLUS MINUS MULTIPLICATION DIVISION REMAINDER %token PLUS MINUS MULTIPLICATION DIVISION REMAINDER
%token ASSIGNMENT COLON HAT AT NIL ARROW %token ASSIGNMENT COLON HAT AT NIL ARROW
@ -101,7 +101,7 @@ along with GCC; see the file COPYING3. If not see
%type <elna::boot::variable_declaration *> variable_declaration; %type <elna::boot::variable_declaration *> variable_declaration;
%type <std::vector<elna::boot::variable_declaration *>> variable_declarations variable_part %type <std::vector<elna::boot::variable_declaration *>> variable_declarations variable_part
formal_parameter_list; formal_parameter_list;
%type <elna::boot::top_type *> type_expression; %type <elna::boot::type_expression *> 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,8 +117,8 @@ 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 <std::pair<std::string, elna::boot::type_expression *>> field_declaration;
%type <std::vector<std::pair<std::string, elna::boot::top_type *>>> field_list; %type <std::vector<std::pair<std::string, elna::boot::type_expression *>>> 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;
@ -265,9 +265,9 @@ literal:
operand: operand:
literal { $$ = $1; } literal { $$ = $1; }
| designator_expression { $$ = $1; } | designator_expression { $$ = $1; }
| LEFT_PAREN type_expression RIGHT_PAREN | SIZEOF LEFT_PAREN type_expression RIGHT_PAREN
{ {
$$ = new elna::boot::type_expression(elna::boot::make_position(@1), $2); $$ = new elna::boot::size_of_expression(elna::boot::make_position(@1), $3);
} }
| cast_expression { $$ = $1; } | cast_expression { $$ = $1; }
| call_expression { $$ = $1; } | call_expression { $$ = $1; }
@ -344,16 +344,6 @@ expression:
$$ = new elna::boot::binary_expression(elna::boot::make_position(@2), $1, $3, $$ = new elna::boot::binary_expression(elna::boot::make_position(@2), $1, $3,
elna::boot::binary_operator::exclusive_disjunction); elna::boot::binary_operator::exclusive_disjunction);
} }
| expression SHIFT_LEFT expression
{
$$ = new elna::boot::binary_expression(elna::boot::make_position(@2), $1, $3,
elna::boot::binary_operator::shift_left);
}
| expression SHIFT_RIGHT expression
{
$$ = new elna::boot::binary_expression(elna::boot::make_position(@2), $1, $3,
elna::boot::binary_operator::shift_right);
}
unary: unary:
AT operand AT operand
{ {
@ -427,23 +417,23 @@ 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); $$ = new elna::boot::array_type_expression(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); $$ = new elna::boot::pointer_type_expression(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)); $$ = new elna::boot::record_type_expression(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)); $$ = new elna::boot::union_type_expression(elna::boot::make_position(@1), std::move($2));
} }
| IDENTIFIER | IDENTIFIER
{ {
$$ = new elna::boot::basic_type(elna::boot::make_position(@1), $1); $$ = new elna::boot::basic_type_expression(elna::boot::make_position(@1), $1);
} }
variable_declaration: identifier_definition COLON type_expression variable_declaration: identifier_definition COLON type_expression
{ {
@ -458,7 +448,7 @@ variable_declarations:
| variable_declaration { $$.emplace_back(std::move($1)); } | variable_declaration { $$.emplace_back(std::move($1)); }
variable_part: variable_part:
/* no variable declarations */ {} /* no variable declarations */ {}
| VAR variable_declarations { std::swap($$, $2); } | VAR variable_declarations SEMICOLON { std::swap($$, $2); }
constant_definition: identifier_definition EQUALS literal constant_definition: identifier_definition EQUALS literal
{ {
$$ = new elna::boot::constant_definition(elna::boot::make_position(@1), $1.first, $1.second, $3); $$ = new elna::boot::constant_definition(elna::boot::make_position(@1), $1.first, $1.second, $3);

View File

@ -146,7 +146,7 @@ namespace gcc
{ {
build_procedure_call(call_location, symbol, expression->arguments()); build_procedure_call(call_location, symbol, expression->arguments());
} }
else if (TYPE_P(symbol) && TREE_CODE(symbol) == RECORD_TYPE) else if (TYPE_P(symbol) && is_record_type(symbol))
{ {
build_record_call(call_location, symbol, expression->arguments()); build_record_call(call_location, symbol, expression->arguments());
} }
@ -169,9 +169,11 @@ namespace gcc
cast_target, this->current_expression); cast_target, this->current_expression);
} }
void generic_visitor::visit(boot::type_expression *expression) void generic_visitor::visit(boot::size_of_expression *expression)
{ {
this->current_expression = build_type(expression->body()); auto body_type = build_type(expression->body());
this->current_expression = build1(CONVERT_EXPR, elna_word_type_node, size_in_bytes(body_type));
} }
void generic_visitor::visit(boot::program *program) void generic_visitor::visit(boot::program *program)
@ -245,7 +247,7 @@ namespace gcc
for (std::size_t i = 0; i < definition->parameters.size(); ++i) for (std::size_t i = 0; i < definition->parameters.size(); ++i)
{ {
parameter_types[i] = build_type(definition->parameters.at(i)->variable_type()); parameter_types[i] = build_type(definition->parameters.at(i)->type());
} }
tree return_type = definition->return_type() == nullptr tree return_type = definition->return_type() == nullptr
? void_type_node ? void_type_node
@ -575,11 +577,10 @@ namespace gcc
} }
if (left_type != right_type if (left_type != right_type
&& !are_compatible_pointers(left_type, right) && !are_compatible_pointers(left_type, right)
&& !are_compatible_pointers(right_type, left) && !are_compatible_pointers(right_type, left))
&& !(is_integral_type(left_type) && right_type == elna_word_type_node))
{ {
error_at(expression_location, error_at(expression_location,
"invalid operands of type '%s' and '%s' for operator %s", "invalid operands of type %s and %s for operator %s",
print_type(left_type).c_str(), print_type(right_type).c_str(), print_type(left_type).c_str(), print_type(right_type).c_str(),
boot::print_binary_operator(expression->operation())); boot::print_binary_operator(expression->operation()));
this->current_expression = error_mark_node; this->current_expression = error_mark_node;
@ -629,16 +630,6 @@ namespace gcc
case boot::binary_operator::not_equals: case boot::binary_operator::not_equals:
this->current_expression = build_equality_operation(expression, left, right); this->current_expression = build_equality_operation(expression, left, right);
break; break;
case boot::binary_operator::shift_left:
this->current_expression = build_binary_operation(
is_numeric_type(left_type) && right_type == elna_word_type_node,
expression, LSHIFT_EXPR, left, right, left_type);
break;
case boot::binary_operator::shift_right:
this->current_expression = build_binary_operation(
is_numeric_type(left_type) && right_type == elna_word_type_node,
expression, RSHIFT_EXPR, left, right, left_type);
break;
} }
} }
@ -741,9 +732,9 @@ namespace gcc
} }
} }
tree generic_visitor::build_type(boot::top_type& type) tree generic_visitor::build_type(boot::type_expression& type)
{ {
if (boot::basic_type *basic_type = type.is_basic()) if (boot::basic_type_expression *basic_type = type.is_basic())
{ {
tree symbol = this->lookup(basic_type->base_name()); tree symbol = this->lookup(basic_type->base_name());
@ -756,7 +747,7 @@ namespace gcc
return error_mark_node; return error_mark_node;
} }
else if (boot::array_type *array_type = type.is_array()) else if (boot::array_type_expression *array_type = type.is_array())
{ {
tree lower_bound = build_int_cst_type(integer_type_node, 0); tree lower_bound = build_int_cst_type(integer_type_node, 0);
tree upper_bound = build_int_cst_type(integer_type_node, array_type->size); tree upper_bound = build_int_cst_type(integer_type_node, array_type->size);
@ -770,7 +761,7 @@ namespace gcc
return build_array_type(base_type, range_type); return build_array_type(base_type, range_type);
} }
else if (boot::pointer_type *pointer_type = type.is_pointer()) else if (boot::pointer_type_expression *pointer_type = type.is_pointer())
{ {
tree base_type = build_type(pointer_type->base()); tree base_type = build_type(pointer_type->base());
@ -780,7 +771,7 @@ namespace gcc
} }
return build_pointer_type_for_mode(base_type, VOIDmode, true); return build_pointer_type_for_mode(base_type, VOIDmode, true);
} }
else if (boot::record_type *record_type = type.is_record()) else if (boot::record_type_expression *record_type = type.is_record())
{ {
std::set<std::string> field_names; std::set<std::string> field_names;
tree record_type_node = make_node(RECORD_TYPE); tree record_type_node = make_node(RECORD_TYPE);
@ -807,7 +798,7 @@ namespace gcc
return record_type_node; return record_type_node;
} }
else if (boot::union_type *union_type = type.is_union()) else if (boot::union_type_expression *union_type = type.is_union())
{ {
std::set<std::string> field_names; std::set<std::string> field_names;
tree union_type_node = make_node(UNION_TYPE); tree union_type_node = make_node(UNION_TYPE);
@ -839,7 +830,7 @@ namespace gcc
void generic_visitor::visit(boot::variable_declaration *declaration) void generic_visitor::visit(boot::variable_declaration *declaration)
{ {
tree declaration_type = build_type(declaration->variable_type()); tree declaration_type = build_type(declaration->type());
gcc_assert(declaration_type != NULL_TREE); gcc_assert(declaration_type != NULL_TREE);
location_t declaration_location = get_location(&declaration->position()); location_t declaration_location = get_location(&declaration->position());
@ -937,56 +928,32 @@ namespace gcc
void generic_visitor::visit(boot::field_access_expression *expression) void generic_visitor::visit(boot::field_access_expression *expression)
{ {
expression->base().accept(this); expression->base().accept(this);
location_t expression_location = get_location(&expression->position()); tree field_declaration = TYPE_FIELDS(TREE_TYPE(this->current_expression));
if (TYPE_P(this->current_expression)) while (field_declaration != NULL_TREE)
{ {
if (expression->field() == "size") tree declaration_name = DECL_NAME(field_declaration);
{ const char *identifier_pointer = IDENTIFIER_POINTER(declaration_name);
this->current_expression = build1(CONVERT_EXPR, elna_word_type_node,
size_in_bytes(this->current_expression));
}
else if (expression->field() == "alignment")
{
this->current_expression = build_int_cstu(elna_word_type_node,
TYPE_ALIGN_UNIT(this->current_expression));
}
else
{
error_at(expression_location, "type '%s' does not have property '%s'",
print_type(this->current_expression).c_str(), expression->field().c_str());
this->current_expression = error_mark_node;
}
if (expression->field() == identifier_pointer)
{
break;
}
field_declaration = TREE_CHAIN(field_declaration);
} }
else if (is_aggregate_type(TREE_TYPE(this->current_expression))) location_t expression_location = get_location(&expression->position());
if (field_declaration == NULL_TREE)
{ {
tree field_declaration = TYPE_FIELDS(TREE_TYPE(this->current_expression)); error_at(expression_location,
"record type does not have a field named '%s'",
while (field_declaration != NULL_TREE) expression->field().c_str());
{ this->current_expression = error_mark_node;
tree declaration_name = DECL_NAME(field_declaration); }
const char *identifier_pointer = IDENTIFIER_POINTER(declaration_name); else
{
if (expression->field() == identifier_pointer) this->current_expression = build3_loc(expression_location, COMPONENT_REF,
{ TREE_TYPE(field_declaration), this->current_expression,
break; field_declaration, NULL_TREE);
}
field_declaration = TREE_CHAIN(field_declaration);
}
if (field_declaration == NULL_TREE)
{
error_at(expression_location,
"record type does not have a field named '%s'",
expression->field().c_str());
this->current_expression = error_mark_node;
}
else
{
this->current_expression = build3_loc(expression_location, COMPONENT_REF,
TREE_TYPE(field_declaration), this->current_expression,
field_declaration, NULL_TREE);
}
} }
} }

View File

@ -62,10 +62,9 @@ namespace gcc
return type == NULL_TREE || type == void_type_node; return type == NULL_TREE || type == void_type_node;
} }
bool is_aggregate_type(tree type) bool is_record_type(tree type)
{ {
gcc_assert(TYPE_P(type)); return TREE_CODE(type) == RECORD_TYPE;
return TREE_CODE(type) == RECORD_TYPE || TREE_CODE(type) == UNION_TYPE;
} }
bool are_compatible_pointers(tree lhs_type, tree rhs) bool are_compatible_pointers(tree lhs_type, tree rhs)
@ -195,7 +194,7 @@ namespace gcc
else else
{ {
error_at(expression_location, error_at(expression_location,
"invalid operands of type '%s' and '%s' for operator %s", "invalid operands of type %s and %s for operator %s",
print_type(left_type).c_str(), print_type(right_type).c_str(), print_type(left_type).c_str(), print_type(right_type).c_str(),
elna::boot::print_binary_operator(expression->operation())); elna::boot::print_binary_operator(expression->operation()));
return error_mark_node; return error_mark_node;

View File

@ -42,9 +42,7 @@ namespace boot
greater_equal, greater_equal,
disjunction, disjunction,
conjunction, conjunction,
exclusive_disjunction, exclusive_disjunction
shift_left,
shift_right
}; };
enum class unary_operator enum class unary_operator
@ -60,7 +58,7 @@ namespace boot
class type_definition; class type_definition;
class call_expression; class call_expression;
class cast_expression; class cast_expression;
class type_expression; class size_of_expression;
class assign_statement; class assign_statement;
class if_statement; class if_statement;
class while_statement; class while_statement;
@ -70,11 +68,11 @@ namespace boot
class program; class program;
class binary_expression; class binary_expression;
class unary_expression; class unary_expression;
class basic_type; class basic_type_expression;
class array_type; class array_type_expression;
class pointer_type; class pointer_type_expression;
class record_type; class record_type_expression;
class union_type; 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;
@ -94,7 +92,7 @@ namespace boot
virtual void visit(type_definition *) = 0; virtual void visit(type_definition *) = 0;
virtual void visit(call_expression *) = 0; virtual void visit(call_expression *) = 0;
virtual void visit(cast_expression *) = 0; virtual void visit(cast_expression *) = 0;
virtual void visit(type_expression *) = 0; virtual void visit(size_of_expression *) = 0;
virtual void visit(call_statement *) = 0; virtual void visit(call_statement *) = 0;
virtual void visit(assign_statement *) = 0; virtual void visit(assign_statement *) = 0;
virtual void visit(if_statement *) = 0; virtual void visit(if_statement *) = 0;
@ -105,11 +103,11 @@ namespace boot
virtual void visit(program *) = 0; virtual void visit(program *) = 0;
virtual void visit(binary_expression *) = 0; virtual void visit(binary_expression *) = 0;
virtual void visit(unary_expression *) = 0; virtual void visit(unary_expression *) = 0;
virtual void visit(basic_type *) = 0; virtual void visit(basic_type_expression *) = 0;
virtual void visit(array_type *) = 0; virtual void visit(array_type_expression *) = 0;
virtual void visit(pointer_type *) = 0; virtual void visit(pointer_type_expression *) = 0;
virtual void visit(record_type *) = 0; virtual void visit(record_type_expression *) = 0;
virtual void visit(union_type *) = 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;
@ -134,7 +132,7 @@ namespace boot
virtual void visit(type_definition *definition) override; virtual void visit(type_definition *definition) override;
virtual void visit(call_expression *expression) override; virtual void visit(call_expression *expression) override;
virtual void visit(cast_expression *expression) override; virtual void visit(cast_expression *expression) override;
virtual void visit(type_expression *expression) override; virtual void visit(size_of_expression *expression) override;
virtual void visit(call_statement *statement) override; virtual void visit(call_statement *statement) override;
virtual void visit(assign_statement *statement) override; virtual void visit(assign_statement *statement) override;
virtual void visit(if_statement *) override; virtual void visit(if_statement *) override;
@ -145,11 +143,11 @@ namespace boot
virtual void visit(program *program) override; virtual void visit(program *program) override;
virtual void visit(binary_expression *expression) override; virtual void visit(binary_expression *expression) override;
virtual void visit(unary_expression *expression) override; virtual void visit(unary_expression *expression) override;
virtual void visit(basic_type *) override; virtual void visit(basic_type_expression *) override;
virtual void visit(array_type *expression) override; virtual void visit(array_type_expression *expression) override;
virtual void visit(pointer_type *) override; virtual void visit(pointer_type_expression *) override;
virtual void visit(record_type *expression) override; virtual void visit(record_type_expression *expression) override;
virtual void visit(union_type *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;
@ -220,23 +218,23 @@ namespace boot
/** /**
* Some type expression. * Some type expression.
*/ */
class top_type : public node class type_expression : public node
{ {
public: public:
virtual basic_type *is_basic(); virtual basic_type_expression *is_basic();
virtual array_type *is_array(); virtual array_type_expression *is_array();
virtual pointer_type *is_pointer(); virtual pointer_type_expression *is_pointer();
virtual record_type *is_record(); virtual record_type_expression *is_record();
virtual union_type *is_union(); virtual union_type_expression *is_union();
protected: protected:
top_type(const struct position position); type_expression(const struct position position);
}; };
/** /**
* Expression defining a basic type. * Expression defining a basic type.
*/ */
class basic_type : public top_type class basic_type_expression final : public type_expression
{ {
const std::string m_name; const std::string m_name;
@ -245,76 +243,76 @@ namespace boot
* \param position Source code position. * \param position Source code position.
* \param name Type name. * \param name Type name.
*/ */
basic_type(const struct position position, const std::string& name); basic_type_expression(const struct position position, const std::string& name);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
const std::string& base_name(); const std::string& base_name();
basic_type *is_basic() override; basic_type_expression *is_basic() override;
}; };
class array_type : public top_type class array_type_expression final : public type_expression
{ {
top_type *m_base; type_expression *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_expression(const struct position position, type_expression *base, const std::uint32_t size);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
top_type& base(); type_expression& base();
array_type *is_array() override; array_type_expression *is_array() override;
virtual ~array_type() override; virtual ~array_type_expression() override;
}; };
class pointer_type : public top_type class pointer_type_expression final : public type_expression
{ {
top_type *m_base; type_expression *m_base;
public: public:
pointer_type(const struct position position, top_type *base); pointer_type_expression(const struct position position, type_expression *base);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
top_type& base(); type_expression& base();
pointer_type *is_pointer() override; pointer_type_expression *is_pointer() override;
virtual ~pointer_type() override; virtual ~pointer_type_expression() override;
}; };
using field_t = std::pair<std::string, top_type *>; using field_t = std::pair<std::string, type_expression *>;
using fields_t = std::vector<field_t>; using fields_t = std::vector<field_t>;
class composite_type : public top_type class composite_type_expression : public type_expression
{ {
protected: protected:
composite_type(const struct position position, fields_t&& fields); composite_type_expression(const struct position position, fields_t&& fields);
public: public:
fields_t fields; fields_t fields;
virtual ~composite_type() override; virtual ~composite_type_expression() override;
}; };
class record_type : public composite_type class record_type_expression final : public composite_type_expression
{ {
public: public:
record_type(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;
record_type *is_record() override; record_type_expression *is_record() override;
}; };
class union_type : public composite_type class union_type_expression final : public composite_type_expression
{ {
public: public:
union_type(const struct position position, fields_t&& fields); union_type_expression(const struct position position, fields_t&& fields);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
union_type *is_union() override; union_type_expression *is_union() override;
}; };
/** /**
@ -322,14 +320,14 @@ namespace boot
*/ */
class variable_declaration : public definition class variable_declaration : public definition
{ {
top_type *m_type; type_expression *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); const bool exported, type_expression *type);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
top_type& variable_type(); type_expression& type();
virtual ~variable_declaration() override; virtual ~variable_declaration() override;
}; };
@ -370,17 +368,17 @@ namespace boot
*/ */
class procedure_definition : public definition class procedure_definition : public definition
{ {
top_type *m_return_type{ nullptr }; type_expression *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, type_expression *return_type = nullptr);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
top_type *return_type(); type_expression *return_type();
block *body(); block *body();
procedure_definition *add_body(block *procedure_body); procedure_definition *add_body(block *procedure_body);
@ -393,14 +391,14 @@ namespace boot
*/ */
class type_definition : public definition class type_definition : public definition
{ {
top_type *m_body; type_expression *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, type_expression *expression);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
top_type& body(); type_expression& body();
virtual ~type_definition() override; virtual ~type_definition() override;
}; };
@ -432,33 +430,33 @@ namespace boot
*/ */
class cast_expression : public expression class cast_expression : public expression
{ {
top_type *m_target; type_expression *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, type_expression *target, expression *value);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
top_type& target(); type_expression& target();
expression& value(); expression& value();
virtual ~cast_expression() override; virtual ~cast_expression() override;
}; };
/** /**
* Type inside an expression. * sizeOf operator.
*/ */
class type_expression : public expression class size_of_expression : public expression
{ {
top_type *m_body; type_expression *m_body;
public: public:
type_expression(const struct position position, top_type *body); size_of_expression(const struct position position, type_expression *body);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
top_type& body(); type_expression& body();
virtual ~type_expression() override; virtual ~size_of_expression() override;
}; };
class call_statement : public statement class call_statement : public statement

View File

@ -40,7 +40,7 @@ namespace gcc
std::shared_ptr<boot::symbol_table<tree>> symbol_map; std::shared_ptr<boot::symbol_table<tree>> symbol_map;
tree build_label_decl(const char *name, location_t loc); tree build_label_decl(const char *name, location_t loc);
tree build_type(boot::top_type& type); tree build_type(boot::type_expression& type);
void enter_scope(); void enter_scope();
tree leave_scope(); tree leave_scope();
@ -67,7 +67,7 @@ namespace gcc
void visit(boot::procedure_definition *definition) override; void visit(boot::procedure_definition *definition) override;
void visit(boot::call_expression *expression) override; void visit(boot::call_expression *expression) override;
void visit(boot::cast_expression *expression) override; void visit(boot::cast_expression *expression) override;
void visit(boot::type_expression *expression) override; void visit(boot::size_of_expression *expression) override;
void visit(boot::number_literal<std::int32_t> *literal) override; void visit(boot::number_literal<std::int32_t> *literal) override;
void visit(boot::number_literal<std::uint32_t> *literal) override; void visit(boot::number_literal<std::uint32_t> *literal) override;
void visit(boot::number_literal<double> *literal) override; void visit(boot::number_literal<double> *literal) override;

View File

@ -39,12 +39,7 @@ namespace gcc
bool is_array_type(tree type); bool is_array_type(tree type);
bool is_procedure_type(tree type); bool is_procedure_type(tree type);
bool is_void_type(tree type); bool is_void_type(tree type);
bool is_record_type(tree type);
/**
* \param type The type to evaluate.
* \return Whether the given type is record or union.
*/
bool is_aggregate_type(tree type);
/** /**
* \param lhs Left hand value. * \param lhs Left hand value.

View File

@ -173,7 +173,7 @@ 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;
@ -230,7 +230,7 @@ end
proc string_dup(origin: String) -> String; proc string_dup(origin: String) -> String;
var var
copy: pointer to Char copy: pointer to Char;
begin begin
copy := cast(malloc(origin.length): pointer to Char); copy := cast(malloc(origin.length): pointer to Char);
strncpy(copy, origin.ptr, origin.length); strncpy(copy, origin.ptr, origin.length);
@ -244,7 +244,7 @@ end
proc make_position() -> Position; proc make_position() -> Position;
var var
result: Position result: Position;
begin begin
return Position(1u, 1u) return Position(1u, 1u)
end end
@ -253,7 +253,7 @@ 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);
@ -349,7 +349,7 @@ end
proc lex_identifier(source_code: pointer to SourceCode, token_content: pointer to String); proc lex_identifier(source_code: pointer to SourceCode, token_content: pointer to String);
var var
content_length: Word content_length: Word;
begin begin
content_length := 0u; content_length := 0u;
token_content^ := source_code^.text; token_content^ := source_code^.text;
@ -363,7 +363,7 @@ end
proc lex_comment(source_code: pointer to SourceCode, token_content: pointer to String) -> Bool; proc lex_comment(source_code: pointer to SourceCode, token_content: pointer to String) -> Bool;
var var
content_length: Word content_length: Word;
begin begin
content_length := 0u; content_length := 0u;
token_content^ := source_code^.text; token_content^ := source_code^.text;
@ -401,7 +401,7 @@ var
token_end: pointer to Char, token_end: pointer to Char,
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;
@ -439,7 +439,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;
while i < tokens_size do while i < tokens_size do
@ -583,7 +583,7 @@ end
proc categorize_identifier(token_content: String) -> Token; proc categorize_identifier(token_content: String) -> Token;
var var
current_token: Token current_token: Token;
begin begin
if "if" = token_content then if "if" = token_content then
current_token.kind := TOKEN_IF current_token.kind := TOKEN_IF
@ -662,14 +662,14 @@ var
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;
tokens := nil; tokens := nil;
source_code := skip_spaces(source_code); source_code := skip_spaces(source_code);
while source_code.text.length <> 0u do while source_code.text.length <> 0u do
tokens := cast(reallocarray(cast(tokens: pointer to Byte), tokens_size^ + 1u, Token.size): pointer to Token); tokens := cast(reallocarray(cast(tokens: pointer to Byte), tokens_size^ + 1u, sizeof(Token)): pointer to Token);
current_token := tokens + tokens_size^; current_token := tokens + tokens_size^;
first_char := source_code.text[1u]; first_char := source_code.text[1u];
@ -821,15 +821,15 @@ end
proc parse_literal(tokens: pointer to pointer to Token, tokens_size: pointer to Word) -> pointer to Literal; proc parse_literal(tokens: pointer to pointer to Token, tokens_size: pointer to Word) -> pointer to Literal;
begin begin
return cast(calloc(1u, Literal.size): pointer to Literal) return cast(calloc(1u, sizeof(Literal)): pointer to Literal)
end end
proc parse_constant_definition(tokens: pointer to pointer to Token, proc parse_constant_definition(tokens: pointer to pointer to Token,
tokens_size: pointer to Word) -> pointer to ConstantDefinition; tokens_size: pointer to Word) -> pointer to ConstantDefinition;
var var
result: pointer to ConstantDefinition result: pointer to ConstantDefinition;
begin begin
result := cast(calloc(1u, ConstantDefinition.size): pointer to ConstantDefinition); result := cast(calloc(1u, sizeof(ConstantDefinition)): pointer to ConstantDefinition);
result^.name := cast(malloc(strlen(tokens^^.value.string_value)): pointer to Char); result^.name := cast(malloc(strlen(tokens^^.value.string_value)): pointer to Char);
strcpy(result^.name, tokens^^.value.string_value); strcpy(result^.name, tokens^^.value.string_value);
@ -851,9 +851,9 @@ 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, sizeof(Program)): pointer to Program);
result^.constants.elements := nil; result^.constants.elements := nil;
result^.constants.count := 0u; result^.constants.count := 0u;
@ -867,7 +867,7 @@ begin
reallocarray( reallocarray(
cast(result^.constants.elements: pointer to Byte), cast(result^.constants.elements: pointer to Byte),
result^.constants.count + 1u, result^.constants.count + 1u,
(pointer to ConstantDefinition).size sizeof(pointer to ConstantDefinition)
) : pointer to pointer to ConstantDefinition); ) : pointer to pointer to ConstantDefinition);
current_constant := result^.constants.elements + result^.constants.count; current_constant := result^.constants.elements + result^.constants.count;
@ -885,10 +885,10 @@ proc parse_command_line*(argc: Int, argv: pointer to pointer to Char) -> pointer
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;
result := cast(malloc(CommandLine.size): pointer to CommandLine); result := cast(malloc(sizeof(CommandLine)): pointer to CommandLine);
result^.tokenize := false; result^.tokenize := false;
result^.syntax_tree := false; result^.syntax_tree := false;
result^.input := nil; result^.input := nil;
@ -927,7 +927,7 @@ 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);
if command_line = nil then if command_line = nil then