Replace type expression with traits
This commit is contained in:
parent
85b6843ecf
commit
74169d8662
101
boot/ast.cc
101
boot/ast.cc
@ -44,30 +44,25 @@ namespace boot
|
||||
definition->body().accept(this);
|
||||
}
|
||||
|
||||
void empty_visitor::visit(call_expression *expression)
|
||||
void empty_visitor::visit(procedure_call *call)
|
||||
{
|
||||
for (struct expression *const argument : expression->arguments)
|
||||
for (expression *const argument : call->arguments)
|
||||
{
|
||||
argument->accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
void empty_visitor::visit(traits_expression *trait)
|
||||
{
|
||||
trait->type().accept(this);
|
||||
}
|
||||
|
||||
void empty_visitor::visit(cast_expression *expression)
|
||||
{
|
||||
expression->target().accept(this);
|
||||
expression->value().accept(this);
|
||||
}
|
||||
|
||||
void empty_visitor::visit(type_expression *expression)
|
||||
{
|
||||
expression->body().accept(this);
|
||||
}
|
||||
|
||||
void empty_visitor::visit(call_statement *statement)
|
||||
{
|
||||
statement->body().accept(this);
|
||||
}
|
||||
|
||||
void empty_visitor::visit(assign_statement *statement)
|
||||
{
|
||||
statement->rvalue().accept(this);
|
||||
@ -249,13 +244,11 @@ namespace boot
|
||||
return this->source_position;
|
||||
}
|
||||
|
||||
statement::statement(const struct position position)
|
||||
: node(position)
|
||||
statement::statement()
|
||||
{
|
||||
}
|
||||
|
||||
expression::expression(const struct position position)
|
||||
: node(position)
|
||||
expression::expression()
|
||||
{
|
||||
}
|
||||
|
||||
@ -539,13 +532,12 @@ namespace boot
|
||||
}
|
||||
}
|
||||
|
||||
literal::literal(const struct position position)
|
||||
: expression(position)
|
||||
literal::literal()
|
||||
{
|
||||
}
|
||||
|
||||
defer_statement::defer_statement(const struct position position)
|
||||
: statement(position)
|
||||
: node(position)
|
||||
{
|
||||
}
|
||||
|
||||
@ -562,13 +554,12 @@ namespace boot
|
||||
}
|
||||
}
|
||||
|
||||
designator_expression::designator_expression(const struct position position)
|
||||
: expression(position)
|
||||
designator_expression::designator_expression()
|
||||
{
|
||||
}
|
||||
|
||||
variable_expression::variable_expression(const struct position position, const std::string& name)
|
||||
: designator_expression(position), m_name(name)
|
||||
: node(position), name(name)
|
||||
{
|
||||
}
|
||||
|
||||
@ -577,11 +568,6 @@ namespace boot
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
const std::string& variable_expression::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
variable_expression *variable_expression::is_variable()
|
||||
{
|
||||
return this;
|
||||
@ -589,7 +575,7 @@ namespace boot
|
||||
|
||||
array_access_expression::array_access_expression(const struct position position,
|
||||
expression *base, expression *index)
|
||||
: designator_expression(position), m_base(base), m_index(index)
|
||||
: node(position), m_base(base), m_index(index)
|
||||
{
|
||||
}
|
||||
|
||||
@ -621,7 +607,7 @@ namespace boot
|
||||
|
||||
field_access_expression::field_access_expression(const struct position position,
|
||||
expression *base, const std::string& field)
|
||||
: designator_expression(position), m_base(base), m_field(field)
|
||||
: node(position), m_base(base), m_field(field)
|
||||
{
|
||||
}
|
||||
|
||||
@ -652,7 +638,7 @@ namespace boot
|
||||
|
||||
dereference_expression::dereference_expression(const struct position position,
|
||||
expression *base)
|
||||
: designator_expression(position), m_base(base)
|
||||
: node(position), m_base(base)
|
||||
{
|
||||
}
|
||||
|
||||
@ -678,7 +664,7 @@ namespace boot
|
||||
|
||||
binary_expression::binary_expression(const struct position position, expression *lhs,
|
||||
expression *rhs, const binary_operator operation)
|
||||
: expression(position), m_lhs(lhs), m_rhs(rhs), m_operator(operation)
|
||||
: node(position), m_lhs(lhs), m_rhs(rhs), m_operator(operation)
|
||||
{
|
||||
}
|
||||
|
||||
@ -710,7 +696,7 @@ namespace boot
|
||||
|
||||
unary_expression::unary_expression(const struct position position, expression *operand,
|
||||
const unary_operator operation)
|
||||
: expression(position), m_operand(std::move(operand)), m_operator(operation)
|
||||
: node(position), m_operand(std::move(operand)), m_operator(operation)
|
||||
{
|
||||
}
|
||||
|
||||
@ -734,22 +720,22 @@ namespace boot
|
||||
delete m_operand;
|
||||
}
|
||||
|
||||
call_expression::call_expression(const struct position position, designator_expression *callable)
|
||||
: expression(position), m_callable(callable)
|
||||
procedure_call::procedure_call(const struct position position, designator_expression *callable)
|
||||
: node(position), m_callable(callable)
|
||||
{
|
||||
}
|
||||
|
||||
void call_expression::accept(parser_visitor *visitor)
|
||||
void procedure_call::accept(parser_visitor *visitor)
|
||||
{
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
designator_expression& call_expression::callable()
|
||||
designator_expression& procedure_call::callable()
|
||||
{
|
||||
return *m_callable;
|
||||
}
|
||||
|
||||
call_expression::~call_expression()
|
||||
procedure_call::~procedure_call()
|
||||
{
|
||||
for (expression *const argument : arguments)
|
||||
{
|
||||
@ -760,7 +746,7 @@ namespace boot
|
||||
|
||||
cast_expression::cast_expression(const struct position position,
|
||||
std::shared_ptr<top_type> target, expression *value)
|
||||
: expression(position), m_target(target), m_value(value)
|
||||
: node(position), m_target(target), m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
@ -784,39 +770,20 @@ namespace boot
|
||||
delete m_value;
|
||||
}
|
||||
|
||||
type_expression::type_expression(const struct position position, std::shared_ptr<top_type> body)
|
||||
: expression(position), m_body(body)
|
||||
traits_expression::traits_expression(const struct position position,
|
||||
const std::string& name, std::shared_ptr<top_type> type)
|
||||
: node(position), m_type(type), name(name)
|
||||
{
|
||||
}
|
||||
|
||||
void type_expression::accept(parser_visitor *visitor)
|
||||
void traits_expression::accept(parser_visitor *visitor)
|
||||
{
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
top_type& type_expression::body()
|
||||
top_type& traits_expression::type()
|
||||
{
|
||||
return *m_body;
|
||||
}
|
||||
|
||||
call_statement::call_statement(const struct position position, call_expression *body)
|
||||
: statement(position), m_body(body)
|
||||
{
|
||||
}
|
||||
|
||||
void call_statement::accept(parser_visitor *visitor)
|
||||
{
|
||||
visitor->visit(this);
|
||||
}
|
||||
|
||||
call_expression& call_statement::body()
|
||||
{
|
||||
return *m_body;
|
||||
}
|
||||
|
||||
call_statement::~call_statement()
|
||||
{
|
||||
delete m_body;
|
||||
return *m_type;
|
||||
}
|
||||
|
||||
conditional_statements::conditional_statements(expression *prerequisite)
|
||||
@ -839,7 +806,7 @@ namespace boot
|
||||
}
|
||||
|
||||
return_statement::return_statement(const struct position position, expression *return_expression)
|
||||
: statement(position), m_return_expression(return_expression)
|
||||
: node(position), m_return_expression(return_expression)
|
||||
{
|
||||
}
|
||||
|
||||
@ -865,7 +832,7 @@ namespace boot
|
||||
|
||||
assign_statement::assign_statement(const struct position position, designator_expression *lvalue,
|
||||
expression *rvalue)
|
||||
: statement(position), m_lvalue(lvalue), m_rvalue(rvalue)
|
||||
: node(position), m_lvalue(lvalue), m_rvalue(rvalue)
|
||||
{
|
||||
}
|
||||
|
||||
@ -906,7 +873,7 @@ namespace boot
|
||||
|
||||
if_statement::if_statement(const struct position position, conditional_statements *body,
|
||||
std::vector<statement *> *alternative)
|
||||
: statement(position), m_body(body), m_alternative(alternative)
|
||||
: node(position), m_body(body), m_alternative(alternative)
|
||||
{
|
||||
}
|
||||
|
||||
@ -936,7 +903,7 @@ namespace boot
|
||||
}
|
||||
|
||||
while_statement::while_statement(const struct position position, conditional_statements *body)
|
||||
: statement(position), m_body(body)
|
||||
: node(position), m_body(body)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -131,6 +131,9 @@ defer {
|
||||
[A-Za-z_][A-Za-z0-9_]* {
|
||||
return yy::parser::make_IDENTIFIER(yytext, this->location);
|
||||
}
|
||||
#[A-Za-z_][A-Za-z0-9_]* {
|
||||
return yy::parser::make_TRAIT(yytext + 1, this->location);
|
||||
}
|
||||
[0-9]+u {
|
||||
return yy::parser::make_WORD(strtoul(yytext, NULL, 10), this->location);
|
||||
}
|
||||
|
@ -75,6 +75,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
%start program;
|
||||
|
||||
%token <std::string> IDENTIFIER
|
||||
%token <std::string> TRAIT
|
||||
%token <std::int32_t> INTEGER
|
||||
%token <std::uint32_t> WORD
|
||||
%token <float> FLOAT
|
||||
@ -125,11 +126,12 @@ along with GCC; see the file COPYING3. If not see
|
||||
formal_parameters formal_parameter_list;
|
||||
%type <elna::boot::variable_declaration *> formal_parameter
|
||||
%type <std::shared_ptr<elna::boot::top_type>> type_expression;
|
||||
%type <elna::boot::traits_expression *> traits_expression;
|
||||
%type <elna::boot::expression *> expression operand unary;
|
||||
%type <std::vector<elna::boot::expression *>> expressions actual_parameter_list;
|
||||
%type <elna::boot::designator_expression *> designator_expression;
|
||||
%type <elna::boot::assign_statement *> assign_statement;
|
||||
%type <elna::boot::call_expression *> call_expression;
|
||||
%type <elna::boot::procedure_call*> call_expression;
|
||||
%type <elna::boot::while_statement *> while_statement;
|
||||
%type <elna::boot::if_statement *> if_statement;
|
||||
%type <elna::boot::return_statement *> return_statement;
|
||||
@ -227,7 +229,7 @@ assign_statement: designator_expression ":=" expression
|
||||
}
|
||||
call_expression: designator_expression actual_parameter_list
|
||||
{
|
||||
$$ = new elna::boot::call_expression(elna::boot::make_position(@1), $1);
|
||||
$$ = new elna::boot::procedure_call(elna::boot::make_position(@1), $1);
|
||||
std::swap($$->arguments, $2);
|
||||
}
|
||||
cast_expression: "cast" "(" expression ":" type_expression ")"
|
||||
@ -313,10 +315,15 @@ literal:
|
||||
{
|
||||
$$ = new elna::boot::number_literal<std::string>(elna::boot::make_position(@1), $1);
|
||||
}
|
||||
traits_expression:
|
||||
TRAIT "(" type_expression ")"
|
||||
{
|
||||
$$ = new elna::boot::traits_expression(elna::boot::make_position(@1), $1, $3);
|
||||
}
|
||||
operand:
|
||||
literal { $$ = $1; }
|
||||
| designator_expression { $$ = $1; }
|
||||
| "(" type_expression ")" { $$ = new elna::boot::type_expression(elna::boot::make_position(@1), $2); }
|
||||
| traits_expression { $$ = $1; }
|
||||
| cast_expression { $$ = $1; }
|
||||
| call_expression { $$ = $1; }
|
||||
| "(" expression ")" { $$ = $2; }
|
||||
@ -448,10 +455,7 @@ statement:
|
||||
| while_statement { $$ = $1; }
|
||||
| if_statement { $$ = $1; }
|
||||
| return_statement { $$ = $1; }
|
||||
| call_expression
|
||||
{
|
||||
$$ = new elna::boot::call_statement(elna::boot::make_position(@1), $1);
|
||||
}
|
||||
| call_expression { $$ = $1; }
|
||||
| defer_statement { $$ = $1; }
|
||||
statements:
|
||||
statement statements
|
||||
|
@ -84,11 +84,6 @@ namespace gcc
|
||||
list_length(TYPE_ARG_TYPES(symbol_type)) - 1, arguments.size());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
else if (TREE_TYPE(symbol_type) == void_type_node)
|
||||
{
|
||||
append_statement(stmt);
|
||||
this->current_expression = NULL_TREE;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->current_expression = stmt;
|
||||
@ -136,10 +131,10 @@ namespace gcc
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::call_expression *expression)
|
||||
void generic_visitor::visit(boot::procedure_call *call)
|
||||
{
|
||||
location_t call_location = get_location(&expression->position());
|
||||
expression->callable().accept(this);
|
||||
location_t call_location = get_location(&call->position());
|
||||
call->callable().accept(this);
|
||||
|
||||
tree expression_type = TYPE_P(this->current_expression)
|
||||
? this->current_expression
|
||||
@ -147,17 +142,17 @@ namespace gcc
|
||||
|
||||
if (TYPE_P(this->current_expression) && TREE_CODE(expression_type) == RECORD_TYPE)
|
||||
{
|
||||
build_record_call(call_location, this->current_expression, expression->arguments);
|
||||
build_record_call(call_location, this->current_expression, call->arguments);
|
||||
}
|
||||
else if (TREE_CODE(expression_type) == FUNCTION_TYPE)
|
||||
{
|
||||
this->current_expression = build1(ADDR_EXPR,
|
||||
build_pointer_type_for_mode(expression_type, VOIDmode, true), this->current_expression);
|
||||
build_procedure_call(call_location, this->current_expression, expression->arguments);
|
||||
build_procedure_call(call_location, this->current_expression, call->arguments);
|
||||
}
|
||||
else if (is_pointer_type(expression_type) && TREE_CODE(TREE_TYPE(expression_type)) == FUNCTION_TYPE)
|
||||
{
|
||||
build_procedure_call(call_location, this->current_expression, expression->arguments);
|
||||
build_procedure_call(call_location, this->current_expression, call->arguments);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -178,11 +173,6 @@ namespace gcc
|
||||
cast_target, this->current_expression);
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::type_expression *expression)
|
||||
{
|
||||
this->current_expression = build_type(expression->body());
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::program *program)
|
||||
{
|
||||
for (boot::constant_definition *const constant : program->constants)
|
||||
@ -226,10 +216,7 @@ namespace gcc
|
||||
DECL_ARGUMENTS(fndecl) = chainon(DECL_ARGUMENTS(fndecl), declaration_tree);
|
||||
parameter_type = TREE_CHAIN(parameter_type);
|
||||
}
|
||||
for (boot::statement *const body_statement : program->body)
|
||||
{
|
||||
body_statement->accept(this);
|
||||
}
|
||||
visit_statements(program->body);
|
||||
tree set_result = build2(INIT_EXPR, void_type_node, DECL_RESULT(fndecl),
|
||||
build_int_cst_type(integer_type_node, 0));
|
||||
tree return_stmt = build1(RETURN_EXPR, void_type_node, set_result);
|
||||
@ -248,6 +235,19 @@ namespace gcc
|
||||
cgraph_node::finalize_function(fndecl, true);
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::block *block)
|
||||
{
|
||||
for (boot::constant_definition *const constant : block->constants)
|
||||
{
|
||||
constant->accept(this);
|
||||
}
|
||||
for (boot::variable_declaration *const variable : block->variables)
|
||||
{
|
||||
variable->accept(this);
|
||||
}
|
||||
visit_statements(block->body);
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::procedure_definition *definition)
|
||||
{
|
||||
tree declaration_type = build_procedure_type(definition->heading());
|
||||
@ -903,13 +903,13 @@ namespace gcc
|
||||
|
||||
void generic_visitor::visit(boot::variable_expression *expression)
|
||||
{
|
||||
auto symbol = this->lookup(expression->name());
|
||||
auto symbol = this->lookup(expression->name);
|
||||
|
||||
if (symbol == NULL_TREE)
|
||||
{
|
||||
error_at(get_location(&expression->position()),
|
||||
"symbol '%s' not declared in the current scope",
|
||||
expression->name().c_str());
|
||||
expression->name.c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
else
|
||||
@ -964,40 +964,40 @@ namespace gcc
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::traits_expression *trait)
|
||||
{
|
||||
tree type_expression = build_type(trait->type());
|
||||
|
||||
if (trait->name == "size")
|
||||
{
|
||||
this->current_expression = build1(CONVERT_EXPR, elna_word_type_node, size_in_bytes(type_expression));
|
||||
}
|
||||
else if (trait->name == "alignment")
|
||||
{
|
||||
this->current_expression = build_int_cstu(elna_word_type_node, TYPE_ALIGN_UNIT(type_expression));
|
||||
}
|
||||
else if (trait->name == "min" && is_integral_type(type_expression))
|
||||
{
|
||||
this->current_expression = TYPE_MIN_VALUE(type_expression);
|
||||
}
|
||||
else if (trait->name == "max" && is_integral_type(type_expression))
|
||||
{
|
||||
this->current_expression = TYPE_MAX_VALUE(type_expression);
|
||||
}
|
||||
else
|
||||
{
|
||||
error_at(get_location(&trait->position()), "type '%s' does not have property '%s'",
|
||||
print_type(type_expression).c_str(), trait->name.c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::field_access_expression *expression)
|
||||
{
|
||||
expression->base().accept(this);
|
||||
location_t expression_location = get_location(&expression->position());
|
||||
|
||||
if (TYPE_P(this->current_expression))
|
||||
{
|
||||
if (expression->field() == "size")
|
||||
{
|
||||
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 if (expression->field() == "min" && is_integral_type(this->current_expression))
|
||||
{
|
||||
this->current_expression = TYPE_MIN_VALUE(this->current_expression);
|
||||
}
|
||||
else if (expression->field() == "max" && is_integral_type(this->current_expression))
|
||||
{
|
||||
this->current_expression = TYPE_MAX_VALUE(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;
|
||||
}
|
||||
|
||||
}
|
||||
else if (is_aggregate_type(TREE_TYPE(this->current_expression)))
|
||||
if (is_aggregate_type(TREE_TYPE(this->current_expression)))
|
||||
{
|
||||
tree field_declaration = TYPE_FIELDS(TREE_TYPE(this->current_expression));
|
||||
|
||||
@ -1026,6 +1026,12 @@ namespace gcc
|
||||
field_declaration, NULL_TREE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_at(expression_location, "type '%s' does not have a field named '%s'",
|
||||
print_type(TREE_TYPE(this->current_expression)).c_str(), expression->field().c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::dereference_expression *expression)
|
||||
@ -1049,7 +1055,7 @@ namespace gcc
|
||||
if (TREE_CODE(lvalue) == CONST_DECL)
|
||||
{
|
||||
error_at(statement_location, "cannot modify constant '%s'",
|
||||
statement->lvalue().is_variable()->name().c_str());
|
||||
statement->lvalue().is_variable()->name.c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
else if (is_assignable_from(TREE_TYPE(lvalue), rvalue))
|
||||
@ -1083,10 +1089,7 @@ namespace gcc
|
||||
if (statement->alternative() != nullptr)
|
||||
{
|
||||
enter_scope();
|
||||
for (const auto body_statement : *statement->alternative())
|
||||
{
|
||||
body_statement->accept(this);
|
||||
}
|
||||
visit_statements(*statement->alternative());
|
||||
tree mapping = leave_scope();
|
||||
append_statement(mapping);
|
||||
}
|
||||
@ -1120,10 +1123,7 @@ namespace gcc
|
||||
append_statement(then_label_expr);
|
||||
enter_scope();
|
||||
|
||||
for (const auto body_statement : branch.statements)
|
||||
{
|
||||
body_statement->accept(this);
|
||||
}
|
||||
visit_statements(branch.statements);
|
||||
tree mapping = leave_scope();
|
||||
append_statement(mapping);
|
||||
append_statement(goto_endif);
|
||||
@ -1160,12 +1160,19 @@ namespace gcc
|
||||
this->current_expression = NULL_TREE;
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::call_statement *statement)
|
||||
void generic_visitor::visit_statements(const std::vector<boot::statement *>& statements)
|
||||
{
|
||||
for (boot::statement *const statement : statements)
|
||||
{
|
||||
statement->accept(this);
|
||||
|
||||
if (this->current_expression != NULL_TREE && this->current_expression != error_mark_node)
|
||||
{
|
||||
statement->body().accept(this);
|
||||
append_statement(this->current_expression);
|
||||
this->current_expression = NULL_TREE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::return_statement *statement)
|
||||
{
|
||||
@ -1181,15 +1188,14 @@ namespace gcc
|
||||
this->current_expression);
|
||||
tree return_stmt = build1(RETURN_EXPR, void_type_node, set_result);
|
||||
append_statement(return_stmt);
|
||||
|
||||
this->current_expression = NULL_TREE;
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::defer_statement *statement)
|
||||
{
|
||||
enter_scope();
|
||||
for (boot::statement *const body_statement : statement->statements)
|
||||
{
|
||||
body_statement->accept(this);
|
||||
}
|
||||
visit_statements(statement->statements);
|
||||
defer(leave_scope());
|
||||
}
|
||||
}
|
||||
|
@ -58,14 +58,13 @@ namespace boot
|
||||
class constant_definition;
|
||||
class procedure_definition;
|
||||
class type_definition;
|
||||
class call_expression;
|
||||
class procedure_call;
|
||||
class cast_expression;
|
||||
class type_expression;
|
||||
class assign_statement;
|
||||
class if_statement;
|
||||
class while_statement;
|
||||
class return_statement;
|
||||
class call_statement;
|
||||
class traits_expression;
|
||||
class block;
|
||||
class program;
|
||||
class binary_expression;
|
||||
@ -93,10 +92,9 @@ namespace boot
|
||||
virtual void visit(constant_definition *) = 0;
|
||||
virtual void visit(procedure_definition *) = 0;
|
||||
virtual void visit(type_definition *) = 0;
|
||||
virtual void visit(call_expression *) = 0;
|
||||
virtual void visit(procedure_call *) = 0;
|
||||
virtual void visit(cast_expression *) = 0;
|
||||
virtual void visit(type_expression *) = 0;
|
||||
virtual void visit(call_statement *) = 0;
|
||||
virtual void visit(traits_expression *) = 0;
|
||||
virtual void visit(assign_statement *) = 0;
|
||||
virtual void visit(if_statement *) = 0;
|
||||
virtual void visit(while_statement *) = 0;
|
||||
@ -134,10 +132,9 @@ namespace boot
|
||||
virtual void visit(constant_definition *definition) override;
|
||||
virtual void visit(procedure_definition *definition) override;
|
||||
virtual void visit(type_definition *definition) override;
|
||||
virtual void visit(call_expression *expression) override;
|
||||
virtual void visit(traits_expression *trait) override;
|
||||
virtual void visit(procedure_call *call) override;
|
||||
virtual void visit(cast_expression *expression) override;
|
||||
virtual void visit(type_expression *expression) override;
|
||||
virtual void visit(call_statement *statement) override;
|
||||
virtual void visit(assign_statement *statement) override;
|
||||
virtual void visit(if_statement *) override;
|
||||
virtual void visit(while_statement *) override;
|
||||
@ -189,22 +186,16 @@ namespace boot
|
||||
const struct position& position() const;
|
||||
};
|
||||
|
||||
class statement : public node
|
||||
class statement : public virtual node
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* \param position Source code position.
|
||||
*/
|
||||
explicit statement(const struct position position);
|
||||
statement();
|
||||
};
|
||||
|
||||
class expression : public node
|
||||
class expression : public virtual node
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* \param position Source code position.
|
||||
*/
|
||||
explicit expression(const struct position position);
|
||||
expression();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -331,7 +322,7 @@ namespace boot
|
||||
class literal : public expression
|
||||
{
|
||||
protected:
|
||||
explicit literal(const struct position position);
|
||||
literal();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -435,31 +426,17 @@ namespace boot
|
||||
virtual ~cast_expression() override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Type inside an expression.
|
||||
*/
|
||||
class type_expression : public expression
|
||||
class traits_expression : public expression
|
||||
{
|
||||
std::shared_ptr<top_type> m_body;
|
||||
std::shared_ptr<top_type> m_type;
|
||||
|
||||
public:
|
||||
type_expression(const struct position position, std::shared_ptr<top_type> body);
|
||||
const std::string name;
|
||||
|
||||
traits_expression(const struct position position, const std::string& name, std::shared_ptr<top_type> type);
|
||||
virtual void accept(parser_visitor *visitor) override;
|
||||
|
||||
top_type& body();
|
||||
};
|
||||
|
||||
class call_statement : public statement
|
||||
{
|
||||
call_expression *m_body;
|
||||
|
||||
public:
|
||||
call_statement(const struct position position, call_expression *body);
|
||||
virtual void accept(parser_visitor *visitor) override;
|
||||
|
||||
call_expression& body();
|
||||
|
||||
virtual ~call_statement() override;
|
||||
top_type& type();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -501,19 +478,17 @@ namespace boot
|
||||
virtual dereference_expression *is_dereference();
|
||||
|
||||
protected:
|
||||
designator_expression(const struct position position);
|
||||
designator_expression();
|
||||
};
|
||||
|
||||
class variable_expression : public designator_expression
|
||||
{
|
||||
std::string m_name;
|
||||
|
||||
public:
|
||||
const std::string name;
|
||||
|
||||
variable_expression(const struct position position, const std::string& name);
|
||||
virtual void accept(parser_visitor *visitor) override;
|
||||
|
||||
const std::string& name() const;
|
||||
|
||||
variable_expression *is_variable() override;
|
||||
};
|
||||
|
||||
@ -570,19 +545,19 @@ namespace boot
|
||||
/**
|
||||
* Procedure call expression.
|
||||
*/
|
||||
class call_expression : public expression
|
||||
class procedure_call : public expression, public statement
|
||||
{
|
||||
designator_expression *m_callable;
|
||||
|
||||
public:
|
||||
std::vector<expression *> arguments;
|
||||
|
||||
call_expression(const struct position position, designator_expression *callable);
|
||||
procedure_call(const struct position position, designator_expression *callable);
|
||||
virtual void accept(parser_visitor *visitor) override;
|
||||
|
||||
designator_expression& callable();
|
||||
|
||||
virtual ~call_expression() override;
|
||||
virtual ~procedure_call() override;
|
||||
};
|
||||
|
||||
class assign_statement : public statement
|
||||
@ -676,7 +651,7 @@ namespace boot
|
||||
T value;
|
||||
|
||||
number_literal(const struct position position, const T& value)
|
||||
: literal(position), value(value)
|
||||
: node(position), value(value)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -60,15 +60,16 @@ namespace gcc
|
||||
tree procedure_address, const std::vector<boot::expression *>& arguments);
|
||||
void build_record_call(location_t call_location,
|
||||
tree symbol, const std::vector<boot::expression *>& arguments);
|
||||
void visit_statements(const std::vector<boot::statement *>& statements);
|
||||
|
||||
public:
|
||||
generic_visitor(std::shared_ptr<symbol_table> symbol_table);
|
||||
|
||||
void visit(boot::program *program) override;
|
||||
void visit(boot::procedure_definition *definition) override;
|
||||
void visit(boot::call_expression *expression) override;
|
||||
void visit(boot::procedure_call *call) override;
|
||||
void visit(boot::cast_expression *expression) override;
|
||||
void visit(boot::type_expression *expression) override;
|
||||
void visit(boot::traits_expression *trait) 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<double> *literal) override;
|
||||
@ -85,10 +86,10 @@ namespace gcc
|
||||
void visit(boot::array_access_expression *expression) override;
|
||||
void visit(boot::field_access_expression *expression) override;
|
||||
void visit(boot::dereference_expression *expression) override;
|
||||
void visit(boot::block *block) override;
|
||||
void visit(boot::assign_statement *statement) override;
|
||||
void visit(boot::if_statement *statement) override;
|
||||
void visit(boot::while_statement *statement) override;
|
||||
void visit(boot::call_statement *statement) override;
|
||||
void visit(boot::return_statement *statement) override;
|
||||
void visit(boot::defer_statement *statement) override;
|
||||
};
|
||||
|
@ -658,7 +658,7 @@ begin
|
||||
source_code := skip_spaces(source_code)
|
||||
|
||||
while source_code.text.length <> 0u do
|
||||
tokens := cast(reallocarray(cast(tokens: ^Byte), tokens_size^ + 1u, Token.size): ^Token)
|
||||
tokens := cast(reallocarray(cast(tokens: ^Byte), tokens_size^ + 1u, #size(Token)): ^Token)
|
||||
current_token := tokens + tokens_size^
|
||||
first_char := source_code.text[1u]
|
||||
|
||||
@ -832,7 +832,7 @@ var
|
||||
result: ^CommandLine
|
||||
begin
|
||||
i := 1
|
||||
result := cast(malloc(CommandLine.size): ^CommandLine)
|
||||
result := cast(malloc(#size(CommandLine)): ^CommandLine)
|
||||
result^.tokenize := false
|
||||
result^.syntax_tree := false
|
||||
result^.input := nil
|
||||
|
Loading…
x
Reference in New Issue
Block a user