Skip to content

Commit

Permalink
Added support for nested structs.
Browse files Browse the repository at this point in the history
  • Loading branch information
Goubermouche committed Feb 8, 2024
1 parent 4391d49 commit dd3c2cd
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 16 deletions.
4 changes: 2 additions & 2 deletions source/compiler/compiler/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ namespace sigma {
TRY(tokenizer::tokenize(file, &m_description.source_path, frontend));
TRY(parser::parse(frontend));

frontend.syntax.print_ast();

// backend
// at this point we want to merge all frontend contexts into the backend context
backend_context backend(frontend.syntax, m_description.target);

// run analysis on the generated AST
TRY(type_checker::type_check(backend));
backend.syntax.print_ast();

TRY(ir_translator::translate(backend));

// compile the generated IR module
Expand Down
2 changes: 1 addition & 1 deletion source/compiler/compiler/type_system/data_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace sigma {
case token_type::IDENTIFIER: {
// custom types, resolved in the type checker
base_type = UNRESOLVED;
identifier_key = token.symbol_key;
unresolved_key = token.symbol_key;
break;
}
default: PANIC("undefined token -> type conversion for token '{}'", token.tok.to_string());
Expand Down
1 change: 1 addition & 0 deletions source/compiler/compiler/type_system/data_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ namespace sigma {
auto get_alignment() const -> u16;
auto get_size() const -> u16;

utility::string_table_key unresolved_key;
utility::string_table_key identifier_key;
utility::slice<data_type> members;

Expand Down
8 changes: 5 additions & 3 deletions source/compiler/compiler/type_system/semantic_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,14 @@ namespace sigma {
return SUCCESS; // nothing else needed
}

if(const handle<data_type> resolved = m_current_scope->find_type(type.identifier_key)) {
type = *resolved;
if(const handle<data_type> resolved = m_current_scope->find_type(type.unresolved_key)) {
type.members = resolved->members;
type.base_type = resolved->base_type;
type.pointer_level = resolved->pointer_level;
return SUCCESS;
}

const std::string& identifier = m_context.syntax.strings.get(type.identifier_key);
const std::string& identifier = m_context.syntax.strings.get(type.unresolved_key);
return error::emit(error::code::UNKNOWN_TYPE, location, identifier);
}

Expand Down
19 changes: 11 additions & 8 deletions source/compiler/test/main.s
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,20 @@
// - add more test cases

i32 main() {
i32*** memory = cast<i32***>(malloc(100));
struct key {
i32* value;
};

memory[0] = cast<i32**>(malloc(100));
memory[1] = cast<i32**>(malloc(100));
struct user {
key k;
};

memory[0][0] = cast<i32*>(malloc(100));
memory[1][0] = cast<i32*>(malloc(100));
user my_user;

memory[0][0][0] = 1;
memory[1][0][0] = 2;
my_user.k.value = cast<i32*>(malloc(sizeof(i32) * 2));
my_user.k.value[0] = 123;
my_user.k.value[1] = 321;

printf("%d %d\n", memory[0][0][0], memory[1][0][0]);
printf("key: %d %d\n", my_user.k.value[0], my_user.k.value[1]);
ret 0;
}
9 changes: 7 additions & 2 deletions source/type_checker/type_checker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,10 +412,10 @@ namespace sigma {
}

auto type_checker::type_check_struct_declaration(ast_node declaration) const -> type_check_result {
const auto& expression = declaration->get<ast::named_type_expression>();
auto& expression = declaration->get<ast::named_type_expression>();

// verify that no two members of the struct have the same identifier
const auto& members = expression.type.members;
auto& members = expression.type.members;

for (u64 i = 0; i < members.get_size(); ++i) {
for (u64 j = i + 1; j < members.get_size(); ++j) {
Expand All @@ -426,6 +426,11 @@ namespace sigma {
}
}

// resolve inner types
for(auto& member : members) {
TRY(m_context.semantics.resolve_type(member, declaration->location));
}

TRY(m_context.semantics.declare_struct(declaration));
return data_type::create_unknown(); // not used
}
Expand Down
16 changes: 16 additions & 0 deletions tests/structs/multiple_access.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
i32 main() {
struct key {
i32 value;
};

struct user {
key k;
};

user my_user;

my_user.k.value = 100;

printf("key: %d\n", my_user.k.value);
ret 0;
}
1 change: 1 addition & 0 deletions tests/structs/multiple_access_expected.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
key: 100
18 changes: 18 additions & 0 deletions tests/structs/multiple_access_ptr.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
i32 main() {
struct key {
i32* value;
};

struct user {
key k;
};

user my_user;

my_user.k.value = cast<i32*>(malloc(sizeof(i32) * 2));
my_user.k.value[0] = 123;
my_user.k.value[1] = 321;

printf("key: %d %d\n", my_user.k.value[0], my_user.k.value[1]);
ret 0;
}
1 change: 1 addition & 0 deletions tests/structs/multiple_access_ptr_expected.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
key: 123 321

0 comments on commit dd3c2cd

Please sign in to comment.