Skip to content

Commit

Permalink
simpler solution?
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli committed Dec 14, 2023
1 parent 10c17ec commit bcf3728
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 31 deletions.
17 changes: 1 addition & 16 deletions self_hosted/create_llvm_ir.jou
Original file line number Diff line number Diff line change
Expand Up @@ -383,21 +383,6 @@ class AstToIR:
LLVMBuildStore(self->builder, new_value, pointer)
return [old_value, new_value]

# LLVM always interprets indexes as signed numbers.
# For example, "200 as byte" would get interpreted as -56.
# This function fixes that.
# https://github.com/Akuli/jou/issues/48
def index_to_llvm(self, ast: AstExpression*) -> LLVMValue*:
types = self->function_or_method_types->get_expression_types(ast)
assert types != NULL
type = types->get_type_after_implicit_cast()

result = self->do_expression(ast)
if type->kind == TypeKind::UnsignedInteger:
return LLVMBuildZExt(self->builder, result, LLVMInt64Type(), "ptr_indexing_implicit_cast")
else:
return result

def do_address_of_expression(self, ast: AstExpression*) -> LLVMValue*:
if ast->kind == AstExpressionKind::GetVariable:
local_var = self->get_local_var_pointer(ast->varname)
Expand Down Expand Up @@ -444,7 +429,7 @@ class AstToIR:
if ast->kind == AstExpressionKind::Indexing:
# &pointer[index] = pointer + some offset
pointer = self->do_expression(&ast->operands[0])
index = self->index_to_llvm(&ast->operands[1])
index = self->do_expression(&ast->operands[1])
return LLVMBuildGEP(self->builder, pointer, &index, 1, "indexing_ptr")

if ast->kind == AstExpressionKind::Dereference:
Expand Down
12 changes: 9 additions & 3 deletions self_hosted/typecheck.jou
Original file line number Diff line number Diff line change
Expand Up @@ -1041,11 +1041,17 @@ class Stage3TypeChecker:
snprintf(message, sizeof message[0], "value of type %s cannot be indexed", types->original_type->name)
fail(pointer->location, message)

index_type = self->do_expression(index)->original_type
if not index_type->is_integer_type():
snprintf(message, sizeof message[0], "the index inside [...] must be an integer, not %s", index_type->name)
index_types = self->do_expression(index)
assert index_types != NULL

if not index_types->original_type->is_integer_type():
snprintf(message, sizeof message[0], "the index inside [...] must be an integer, not %s", index_types->original_type->name)
fail(index->location, message)

# LLVM assumes that indexes smaller than 64 bits are signed.
# https://github.com/Akuli/jou/issues/48
index_types->do_implicit_cast(long_type, Location{}, NULL)

return pointer_type->value_type

def do_expression_maybe_void(self, expression: AstExpression*) -> ExpressionTypes*:
Expand Down
10 changes: 1 addition & 9 deletions src/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,15 +336,7 @@ static void codegen_instruction(const struct State *st, const CfInstruction *ins
}
break;
case CF_PTR_ADD_INT:
{
LLVMValueRef index = getop(1);
if (ins->operands[1]->type->kind == TYPE_UNSIGNED_INTEGER) {
// https://github.com/Akuli/jou/issues/48
// Apparently the default is to interpret indexes as signed.
index = LLVMBuildZExt(st->builder, index, LLVMInt64Type(), "ptr_add_int_implicit_cast");
}
setdest(LLVMBuildGEP(st->builder, getop(0), &index, 1, "ptr_add_int"));
}
setdest(LLVMBuildGEP(st->builder, getop(0), (LLVMValueRef[]){getop(1)}, 1, "ptr_add_int"));
break;
case CF_NUM_CAST:
{
Expand Down
10 changes: 7 additions & 3 deletions src/typecheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -756,14 +756,18 @@ static const Type *typecheck_indexing(
}
assert(ptrtype->kind == TYPE_POINTER);

const Type *indextype = typecheck_expression_not_void(ft, indexexpr)->type;
if (!is_integer_type(indextype)) {
ExpressionTypes *indextypes = typecheck_expression_not_void(ft, indexexpr);
if (!is_integer_type(indextypes->type)) {
fail_with_error(
indexexpr->location,
"the index inside [...] must be an integer, not %s",
indextype->name);
indextypes->type->name);
}

// LLVM assumes that indexes smaller than 64 bits are signed.
// https://github.com/Akuli/jou/issues/48
do_implicit_cast(indextypes, longType, (Location){0}, NULL);

return ptrtype->data.valuetype;
}

Expand Down

0 comments on commit bcf3728

Please sign in to comment.