Index strings
This commit is contained in:
@ -46,36 +46,44 @@ namespace gcc
|
||||
void generic_visitor::visit(boot::call_expression *expression)
|
||||
{
|
||||
tree symbol = this->lookup(expression->name());
|
||||
location_t call_location = get_location(&expression->position());
|
||||
|
||||
if (symbol == NULL_TREE)
|
||||
{
|
||||
error_at(get_location(&expression->position()),
|
||||
"procedure '%s' not declared",
|
||||
error_at(call_location, "procedure '%s' not declared",
|
||||
expression->name().c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
return;
|
||||
}
|
||||
tree return_type = TREE_TYPE(TREE_TYPE(symbol));
|
||||
tree fndecl_type = build_function_type(return_type, TYPE_ARG_TYPES(symbol));
|
||||
tree printf_fn = build1(ADDR_EXPR, build_pointer_type(fndecl_type), symbol);
|
||||
|
||||
std::vector<tree> arguments(expression->arguments().size());
|
||||
for (std::size_t i = 0; i < expression->arguments().size(); ++i)
|
||||
else if (DECL_P(symbol) && is_procedure_type(TREE_TYPE(symbol)))
|
||||
{
|
||||
expression->arguments().at(i)->accept(this);
|
||||
arguments[i] = this->current_expression;
|
||||
}
|
||||
tree stmt = build_call_array_loc(get_location(&expression->position()),
|
||||
return_type, printf_fn, arguments.size(), arguments.data());
|
||||
tree return_type = TREE_TYPE(TREE_TYPE(symbol));
|
||||
tree fndecl_type = build_function_type(return_type, TYPE_ARG_TYPES(symbol));
|
||||
tree printf_fn = build1(ADDR_EXPR, build_pointer_type(fndecl_type), symbol);
|
||||
|
||||
if (return_type == void_type_node)
|
||||
{
|
||||
append_statement(stmt);
|
||||
this->current_expression = NULL_TREE;
|
||||
std::vector<tree> arguments(expression->arguments().size());
|
||||
for (std::size_t i = 0; i < expression->arguments().size(); ++i)
|
||||
{
|
||||
expression->arguments().at(i)->accept(this);
|
||||
arguments[i] = this->current_expression;
|
||||
}
|
||||
tree stmt = build_call_array_loc(get_location(&expression->position()),
|
||||
return_type, printf_fn, arguments.size(), arguments.data());
|
||||
|
||||
if (return_type == void_type_node)
|
||||
{
|
||||
append_statement(stmt);
|
||||
this->current_expression = NULL_TREE;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->current_expression = stmt;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->current_expression = stmt;
|
||||
error_at(call_location, "'%s' cannot be called, it is neither a procedure nor record",
|
||||
print_type(TYPE_P(symbol) ? symbol : TREE_TYPE(symbol)).c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
@ -347,14 +355,14 @@ namespace gcc
|
||||
TREE_READONLY(string_literal) = 1;
|
||||
TREE_STATIC(string_literal) = 1;
|
||||
|
||||
string_type = TREE_TYPE(TREE_CHAIN(TYPE_FIELDS(elna_string_type_node)));
|
||||
string_type = TREE_TYPE(elna_string_ptr_field_node);
|
||||
string_literal = build4(ARRAY_REF, elna_char_type_node,
|
||||
string_literal, integer_zero_node, NULL_TREE, NULL_TREE);
|
||||
string_literal = build1(ADDR_EXPR, string_type, string_literal);
|
||||
|
||||
vec<constructor_elt, va_gc> *elms = NULL;
|
||||
CONSTRUCTOR_APPEND_ELT(elms, TYPE_FIELDS(elna_string_type_node), index_constant);
|
||||
CONSTRUCTOR_APPEND_ELT(elms, TREE_CHAIN(TYPE_FIELDS(elna_string_type_node)), string_literal);
|
||||
CONSTRUCTOR_APPEND_ELT(elms, elna_string_ptr_field_node, string_literal);
|
||||
CONSTRUCTOR_APPEND_ELT(elms, elna_string_length_field_node, index_constant);
|
||||
|
||||
this->current_expression = build_constructor(elna_string_type_node, elms);
|
||||
}
|
||||
@ -401,14 +409,15 @@ namespace gcc
|
||||
}
|
||||
if (TREE_TYPE(left) == elna_string_type_node)
|
||||
{
|
||||
tree length_field = TYPE_FIELDS(elna_string_type_node);
|
||||
tree ptr_field = TREE_CHAIN(length_field);
|
||||
tree lhs_length = build3(COMPONENT_REF, TREE_TYPE(elna_string_length_field_node),
|
||||
left, elna_string_length_field_node, NULL_TREE);
|
||||
tree lhs_ptr = build3(COMPONENT_REF, TREE_TYPE(elna_string_ptr_field_node),
|
||||
left, elna_string_ptr_field_node, NULL_TREE);
|
||||
|
||||
tree lhs_length = build3(COMPONENT_REF, TREE_TYPE(length_field), left, length_field, NULL_TREE);
|
||||
tree lhs_ptr = build3(COMPONENT_REF, TREE_TYPE(ptr_field), left, ptr_field, NULL_TREE);
|
||||
|
||||
tree rhs_length = build3(COMPONENT_REF, TREE_TYPE(length_field), right, length_field, NULL_TREE);
|
||||
tree rhs_ptr = build3(COMPONENT_REF, TREE_TYPE(ptr_field), right, ptr_field, NULL_TREE);
|
||||
tree rhs_length = build3(COMPONENT_REF, TREE_TYPE(elna_string_length_field_node),
|
||||
right, elna_string_length_field_node, NULL_TREE);
|
||||
tree rhs_ptr = build3(COMPONENT_REF, TREE_TYPE(elna_string_ptr_field_node),
|
||||
right, elna_string_ptr_field_node, NULL_TREE);
|
||||
|
||||
tree length_equality = build2(equality_code, elna_bool_type_node, lhs_length, rhs_length);
|
||||
tree *memcmp = elna_global_decls->get("__builtin_memcmp");
|
||||
@ -732,14 +741,46 @@ namespace gcc
|
||||
{
|
||||
expression->base().accept(this);
|
||||
tree designator = this->current_expression;
|
||||
location_t location = get_location(&expression->position());
|
||||
|
||||
expression->index().accept(this);
|
||||
tree index = this->current_expression;
|
||||
if (!is_integral_type(TREE_TYPE(this->current_expression)))
|
||||
{
|
||||
error_at(location, "type '%s' cannot be used as index",
|
||||
print_type(TREE_TYPE(this->current_expression)).c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
return;
|
||||
}
|
||||
if (this->current_expression != elna_word_type_node)
|
||||
{
|
||||
this->current_expression = fold_convert(elna_word_type_node, this->current_expression);
|
||||
}
|
||||
tree offset = build2(MINUS_EXPR, elna_word_type_node,
|
||||
this->current_expression, size_one_node);
|
||||
|
||||
tree element_type = TREE_TYPE(TREE_TYPE(designator));
|
||||
if (is_array_type(TREE_TYPE(designator)))
|
||||
{
|
||||
tree element_type = TREE_TYPE(TREE_TYPE(designator));
|
||||
|
||||
this->current_expression = build4_loc(get_location(&expression->position()),
|
||||
ARRAY_REF, element_type, designator, index, NULL_TREE, NULL_TREE);
|
||||
this->current_expression = build4_loc(location,
|
||||
ARRAY_REF, element_type, designator, offset, NULL_TREE, NULL_TREE);
|
||||
}
|
||||
else if (TREE_TYPE(designator) == elna_string_type_node)
|
||||
{
|
||||
tree string_ptr = build3_loc(location, COMPONENT_REF, TREE_TYPE(elna_string_ptr_field_node),
|
||||
designator, elna_string_ptr_field_node, NULL_TREE);
|
||||
|
||||
tree target_pointer = do_pointer_arithmetic(boot::binary_operator::sum, string_ptr, offset);
|
||||
|
||||
this->current_expression = build1_loc(location, INDIRECT_REF,
|
||||
elna_char_type_node, target_pointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
error_at(location, "indexing is not allowed on type '%s'",
|
||||
print_type(TREE_TYPE(designator)).c_str());
|
||||
this->current_expression = error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
void generic_visitor::visit(boot::field_access_expression *expression)
|
||||
|
Reference in New Issue
Block a user