Implement pointers
This commit is contained in:
@ -51,6 +51,10 @@ namespace gcc
|
||||
{
|
||||
format_number = "%s\n";
|
||||
}
|
||||
else if (is_pointer_type(argument_type))
|
||||
{
|
||||
format_number = "%p\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
error_at(get_location(&argument->position()),
|
||||
@ -256,6 +260,20 @@ namespace gcc
|
||||
operator_code, target_type, left, right);
|
||||
}
|
||||
|
||||
void generic_visitor::visit(source::unary_expression *expression)
|
||||
{
|
||||
switch (expression->operation())
|
||||
{
|
||||
case source::unary_operator::reference:
|
||||
expression->operand().accept(this);
|
||||
|
||||
this->current_expression = build1_loc(get_location(&expression->position()), ADDR_EXPR,
|
||||
build_pointer_type_for_mode(TREE_TYPE(this->current_expression), VOIDmode, true),
|
||||
this->current_expression);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::visit(source::constant_definition *definition)
|
||||
{
|
||||
location_t definition_location = get_location(&definition->position());
|
||||
@ -344,6 +362,10 @@ namespace gcc
|
||||
{
|
||||
return TREE_TYPE(symbol->second);
|
||||
}
|
||||
error_at(get_location(&basic_type->position()),
|
||||
"type '%s' not declared", basic_type->base_name().c_str());
|
||||
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (source::array_type_expression *array_type = type.is_array())
|
||||
{
|
||||
@ -351,14 +373,24 @@ namespace gcc
|
||||
tree upper_bound = build_int_cst_type(integer_type_node, array_type->size);
|
||||
tree base_type = build_type(array_type->base());
|
||||
|
||||
if (base_type == NULL_TREE)
|
||||
if (base_type == NULL_TREE || base_type == error_mark_node)
|
||||
{
|
||||
return NULL_TREE;
|
||||
return base_type;
|
||||
}
|
||||
tree range_type = build_range_type(integer_type_node, lower_bound, upper_bound);
|
||||
|
||||
return build_array_type(base_type, range_type);
|
||||
}
|
||||
else if (source::pointer_type_expression *pointer_type = type.is_pointer())
|
||||
{
|
||||
tree base_type = build_type(pointer_type->base());
|
||||
|
||||
if (base_type == NULL_TREE || base_type == error_mark_node)
|
||||
{
|
||||
return base_type;
|
||||
}
|
||||
return build_pointer_type_for_mode(base_type, VOIDmode, true);
|
||||
}
|
||||
else if (source::record_type_expression *record_type = type.is_record())
|
||||
{
|
||||
std::set<std::string> field_names;
|
||||
@ -397,13 +429,8 @@ namespace gcc
|
||||
void generic_visitor::visit(source::declaration *declaration)
|
||||
{
|
||||
tree declaration_type = build_type(declaration->type());
|
||||
gcc_assert(declaration_type != NULL_TREE);
|
||||
|
||||
if (declaration_type == NULL_TREE)
|
||||
{
|
||||
error_at(get_location(&declaration->type().position()),
|
||||
"type '%s' not declared", declaration->type().base_name().c_str());
|
||||
return;
|
||||
}
|
||||
auto declaration_location = get_location(&declaration->position());
|
||||
tree declaration_tree = build_decl(declaration_location, VAR_DECL,
|
||||
get_identifier(declaration->identifier().c_str()), declaration_type);
|
||||
@ -455,6 +482,46 @@ namespace gcc
|
||||
ARRAY_REF, element_type, designator, index, NULL_TREE, NULL_TREE);
|
||||
}
|
||||
|
||||
void generic_visitor::visit(source::field_access_expression *expression)
|
||||
{
|
||||
expression->base().accept(this);
|
||||
tree field_declaration = TYPE_FIELDS(TREE_TYPE(this->current_expression));
|
||||
|
||||
while (field_declaration != NULL_TREE)
|
||||
{
|
||||
tree declaration_name = DECL_NAME(field_declaration);
|
||||
const char *identifier_pointer = IDENTIFIER_POINTER(declaration_name);
|
||||
|
||||
if (expression->field() == identifier_pointer)
|
||||
{
|
||||
break;
|
||||
}
|
||||
field_declaration = TREE_CHAIN(field_declaration);
|
||||
}
|
||||
location_t expression_location = get_location(&expression->position());
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::visit(source::dereference_expression *expression)
|
||||
{
|
||||
expression->base().accept(this);
|
||||
|
||||
this->current_expression = build1_loc(get_location(&expression->position()), INDIRECT_REF,
|
||||
TREE_TYPE(TREE_TYPE(this->current_expression)), this->current_expression);
|
||||
}
|
||||
|
||||
void generic_visitor::visit(source::assign_statement *statement)
|
||||
{
|
||||
statement->lvalue().accept(this);
|
||||
|
Reference in New Issue
Block a user