Fix some indexing problems
This commit is contained in:
parent
668e18e8ba
commit
226118bcbb
@ -256,8 +256,18 @@ namespace AST {
|
|||||||
|
|
||||||
|
|
||||||
codegen::StackValue IndexAccessExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
codegen::StackValue IndexAccessExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
||||||
auto value = this->m_expr->codegen(builder, scope);
|
auto intended_ty = this->m_expr->get_codegen_type(scope);
|
||||||
std::shared_ptr<types::Type> inner_ty{};
|
|
||||||
|
codegen::StackValue value;
|
||||||
|
if (intended_ty->m_kind != types::TypeKind::Pointer) {
|
||||||
|
auto lvalued = scope.with_lvalue();
|
||||||
|
value = this->m_expr->codegen(builder, lvalued);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
value = this->m_expr->codegen(builder, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << intended_ty->formatted() << std::endl;
|
||||||
|
|
||||||
std::vector<llvm::Value*> idx_list{ };
|
std::vector<llvm::Value*> idx_list{ };
|
||||||
idx_list.push_back(llvm::ConstantInt::get(builder.builder->getInt32Ty(), this->m_num));
|
idx_list.push_back(llvm::ConstantInt::get(builder.builder->getInt32Ty(), this->m_num));
|
||||||
@ -265,30 +275,12 @@ namespace AST {
|
|||||||
if (value.ty->m_kind == types::TypeKind::Pointer) {
|
if (value.ty->m_kind == types::TypeKind::Pointer) {
|
||||||
auto ptr_ty = dynamic_cast<types::PointerType*>(value.ty.get());
|
auto ptr_ty = dynamic_cast<types::PointerType*>(value.ty.get());
|
||||||
|
|
||||||
auto gep_value = builder.builder->CreateGEP(ptr_ty->m_inner->codegen(builder, scope.structs), value.value, idx_list, "GEP");
|
auto gep_value = builder.builder->CreateGEP(ptr_ty->m_inner->codegen(builder, scope.structs), value.value, idx_list, "ptr_gep");
|
||||||
|
|
||||||
auto loaded = value.ty->load(builder, gep_value, scope.structs);
|
|
||||||
return codegen::StackValue{
|
|
||||||
loaded.first,
|
|
||||||
loaded.second
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (value.ty->m_kind == types::TypeKind::Array) {
|
|
||||||
auto array_ty = dynamic_cast<types::ArrayType*>(value.ty.get());
|
|
||||||
if (array_ty->m_raw) {
|
|
||||||
throw CompileError("Tried indexing a raw array", this->m_meta);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto gep_value = builder.builder->CreateGEP(array_ty->m_inner->codegen(builder, scope.structs), value.value, idx_list, "GEP");
|
|
||||||
|
|
||||||
auto ptr_ty = std::shared_ptr<types::Type>{
|
|
||||||
new types::PointerType { array_ty->m_inner->m_const, array_ty->m_inner}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (scope.is_lvalue) {
|
if (scope.is_lvalue) {
|
||||||
return codegen::StackValue{
|
return codegen::StackValue{
|
||||||
gep_value,
|
gep_value,
|
||||||
ptr_ty,
|
value.ty,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -299,6 +291,31 @@ namespace AST {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (value.ty->m_kind == types::TypeKind::Array) {
|
||||||
|
auto array_ty = dynamic_cast<types::ArrayType*>(value.ty.get());
|
||||||
|
// if (array_ty->m_raw) {
|
||||||
|
// throw CompileError("Tried indexing a raw array", this->m_meta);
|
||||||
|
// }
|
||||||
|
|
||||||
|
auto gep_value = builder.builder->CreateGEP(array_ty->m_inner->codegen(builder, scope.structs), value.value, idx_list, "array_gep");
|
||||||
|
|
||||||
|
if (scope.is_lvalue) {
|
||||||
|
return codegen::StackValue{
|
||||||
|
gep_value,
|
||||||
|
array_ty->m_inner,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto ptr_ty = std::shared_ptr<types::Type>{
|
||||||
|
new types::PointerType { array_ty->m_inner->m_const, array_ty->m_inner}
|
||||||
|
};
|
||||||
|
auto loaded = ptr_ty->load(builder, gep_value, scope.structs);
|
||||||
|
return codegen::StackValue{
|
||||||
|
loaded.first,
|
||||||
|
loaded.second
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
throw CompileError("Tried indexing a non-pointer", this->m_meta);
|
throw CompileError("Tried indexing a non-pointer", this->m_meta);
|
||||||
}
|
}
|
||||||
@ -345,17 +362,17 @@ namespace AST {
|
|||||||
auto gep = builder.builder->CreateStructGEP(
|
auto gep = builder.builder->CreateStructGEP(
|
||||||
ptr_ty->m_inner->codegen(builder, scope.structs), struct_ptr.value, idx);
|
ptr_ty->m_inner->codegen(builder, scope.structs), struct_ptr.value, idx);
|
||||||
|
|
||||||
auto ptr_ty = std::shared_ptr<types::Type>{
|
|
||||||
new types::PointerType { field_ty->m_const, field_ty }
|
|
||||||
};
|
|
||||||
|
|
||||||
if (scope.is_lvalue) {
|
if (scope.is_lvalue) {
|
||||||
return codegen::StackValue{
|
return codegen::StackValue{
|
||||||
gep,
|
gep,
|
||||||
ptr_ty
|
field_ty
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
auto ptr_ty = std::shared_ptr<types::Type>{
|
||||||
|
new types::PointerType { field_ty->m_const, field_ty }
|
||||||
|
};
|
||||||
auto loaded = ptr_ty->load(builder, gep, scope.structs);
|
auto loaded = ptr_ty->load(builder, gep, scope.structs);
|
||||||
return codegen::StackValue{ loaded.first, loaded.second };
|
return codegen::StackValue{ loaded.first, loaded.second };
|
||||||
}
|
}
|
||||||
@ -458,19 +475,15 @@ namespace AST {
|
|||||||
builder.builder->SetInsertPoint(builder.block);
|
builder.builder->SetInsertPoint(builder.block);
|
||||||
|
|
||||||
if (this->m_type->m_kind == types::TypeKind::Array) {
|
if (this->m_type->m_kind == types::TypeKind::Array) {
|
||||||
auto array_ty = dynamic_cast<types::ArrayType*>(this->m_type.get());
|
auto raw_llvm_ty = this->m_type->codegen(builder, scope.structs);
|
||||||
if (!array_ty->m_raw) {
|
auto ptr = builder.builder->CreateAlloca(raw_llvm_ty);
|
||||||
auto raw_ty = types::ArrayType{ array_ty->m_inner, array_ty->m_size, true };
|
if (this->m_expr.has_value()) {
|
||||||
auto raw_llvm_ty = raw_ty.codegen(builder, scope.structs);
|
auto value = this->m_expr->get()->codegen(builder, scope);
|
||||||
auto ptr = builder.builder->CreateAlloca(raw_llvm_ty);
|
builder.builder->CreateStore(value.value, ptr, false);
|
||||||
if (this->m_expr.has_value()) {
|
|
||||||
auto value = this->m_expr->get()->codegen(builder, scope);
|
|
||||||
builder.builder->CreateStore(value.value, ptr, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.values[this->m_name] = codegen::StackValue{ ptr, this->m_type };
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope.values[this->m_name] = codegen::StackValue{ ptr, this->m_type };
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ty = this->m_type->codegen(builder, scope.structs);
|
auto ty = this->m_type->codegen(builder, scope.structs);
|
||||||
|
|||||||
@ -176,7 +176,7 @@ std::optional<CompileOutput> compile(std::string_view in_filename) {
|
|||||||
builder.mod->print(llvm_ir_dest, nullptr);
|
builder.mod->print(llvm_ir_dest, nullptr);
|
||||||
llvm_ir_dest.flush();
|
llvm_ir_dest.flush();
|
||||||
|
|
||||||
// std::cout << llvm_ir_string << std::endl;
|
std::cout << llvm_ir_string << std::endl;
|
||||||
|
|
||||||
// Print output to obj-file
|
// Print output to obj-file
|
||||||
std::error_code EC;
|
std::error_code EC;
|
||||||
|
|||||||
@ -8,6 +8,7 @@ namespace parsing {
|
|||||||
static uint32_t struct_id_counter = 0;
|
static uint32_t struct_id_counter = 0;
|
||||||
|
|
||||||
Result<std::unique_ptr<AST::Expression>, std::string> parse_expression(token::TokenStream& stream, Scope& scope);
|
Result<std::unique_ptr<AST::Expression>, std::string> parse_expression(token::TokenStream& stream, Scope& scope);
|
||||||
|
Result<std::optional<uint32_t>, std::string> parse_array_postfix(token::TokenStream& stream, bool allow_empty, Scope&);
|
||||||
|
|
||||||
Result<std::shared_ptr<types::Type>, std::string> parse_type(token::TokenStream& stream, Scope& scope) {
|
Result<std::shared_ptr<types::Type>, std::string> parse_type(token::TokenStream& stream, Scope& scope) {
|
||||||
token::TokenStream inner{ stream };
|
token::TokenStream inner{ stream };
|
||||||
@ -41,12 +42,23 @@ namespace parsing {
|
|||||||
if (counter++ > 0)
|
if (counter++ > 0)
|
||||||
inner.expect(token::Type::Symbol, ";");
|
inner.expect(token::Type::Symbol, ";");
|
||||||
|
|
||||||
auto ty = parse_type(inner, scope);
|
auto ty_res = parse_type(inner, scope);
|
||||||
if (!ty.ok())
|
if (!ty_res.ok())
|
||||||
break;
|
break;
|
||||||
|
auto ty = ty_res.unwrap();
|
||||||
|
|
||||||
auto field_name = inner.expect(token::Type::Ident);
|
auto field_name = inner.expect(token::Type::Ident);
|
||||||
fields.push_back(types::StructField{ field_name.content, ty.unwrap() });
|
|
||||||
|
auto array_postfix = parse_array_postfix(inner, false, scope);
|
||||||
|
while (array_postfix.ok()) {
|
||||||
|
auto postfix = array_postfix.unwrap();
|
||||||
|
ty = std::shared_ptr<types::Type>{
|
||||||
|
new types::ArrayType(ty, *postfix, true)
|
||||||
|
};
|
||||||
|
array_postfix = parse_array_postfix(inner, false, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
fields.push_back(types::StructField{ field_name.content, ty });
|
||||||
}
|
}
|
||||||
|
|
||||||
inner.expect(token::Type::Symbol, "}");
|
inner.expect(token::Type::Symbol, "}");
|
||||||
@ -430,7 +442,7 @@ namespace parsing {
|
|||||||
while (array_postfix.ok()) {
|
while (array_postfix.ok()) {
|
||||||
auto postfix = array_postfix.unwrap();
|
auto postfix = array_postfix.unwrap();
|
||||||
ty = std::shared_ptr<types::Type>{
|
ty = std::shared_ptr<types::Type>{
|
||||||
new types::ArrayType(ty, *postfix, false)
|
new types::ArrayType(ty, *postfix, true)
|
||||||
};
|
};
|
||||||
array_postfix = parse_array_postfix(inner, false, scope);
|
array_postfix = parse_array_postfix(inner, false, scope);
|
||||||
}
|
}
|
||||||
|
|||||||
8
test.c
8
test.c
@ -15,6 +15,7 @@ struct Otus;
|
|||||||
|
|
||||||
struct Otus {
|
struct Otus {
|
||||||
int field;
|
int field;
|
||||||
|
int second[2];
|
||||||
};
|
};
|
||||||
void update(struct Otus potus) {
|
void update(struct Otus potus) {
|
||||||
potus.field = 20;
|
potus.field = 20;
|
||||||
@ -36,14 +37,19 @@ int main() {
|
|||||||
printf("first element: %d!\n", somelist[0]);
|
printf("first element: %d!\n", somelist[0]);
|
||||||
printf("first element via ptr: %d!\n", somelist_ptr[0]);
|
printf("first element via ptr: %d!\n", somelist_ptr[0]);
|
||||||
|
|
||||||
struct Otus otus = { 5 };
|
struct Otus otus = { 5, { 7, 3 } };
|
||||||
update(otus);
|
update(otus);
|
||||||
|
|
||||||
printf("first field: %d!\n", otus.field);
|
printf("first field: %d!\n", otus.field);
|
||||||
|
printf("second field's second element: %d!\n", otus.second[1]);
|
||||||
|
|
||||||
char hello = 10;
|
char hello = 10;
|
||||||
update_ptr(&hello);
|
update_ptr(&hello);
|
||||||
printf("hello: %d!\n", hello);
|
printf("hello: %d!\n", hello);
|
||||||
|
|
||||||
|
char twod_array[5][5];
|
||||||
|
twod_array[0][0] = 50;
|
||||||
|
printf("2d array: %d!\n", twod_array[0][0]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user