diff --git a/source/compiler/compiler/compiler.cpp b/source/compiler/compiler/compiler.cpp index 0b05afe..62afd09 100644 --- a/source/compiler/compiler/compiler.cpp +++ b/source/compiler/compiler/compiler.cpp @@ -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 diff --git a/source/compiler/compiler/type_system/data_type.cpp b/source/compiler/compiler/type_system/data_type.cpp index 38ddff0..948bc97 100644 --- a/source/compiler/compiler/type_system/data_type.cpp +++ b/source/compiler/compiler/type_system/data_type.cpp @@ -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()); diff --git a/source/compiler/compiler/type_system/data_type.h b/source/compiler/compiler/type_system/data_type.h index f61f715..52287ac 100644 --- a/source/compiler/compiler/type_system/data_type.h +++ b/source/compiler/compiler/type_system/data_type.h @@ -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 members; diff --git a/source/compiler/compiler/type_system/semantic_context.cpp b/source/compiler/compiler/type_system/semantic_context.cpp index 0b1c8b9..d733aaa 100644 --- a/source/compiler/compiler/type_system/semantic_context.cpp +++ b/source/compiler/compiler/type_system/semantic_context.cpp @@ -231,12 +231,14 @@ namespace sigma { return SUCCESS; // nothing else needed } - if(const handle resolved = m_current_scope->find_type(type.identifier_key)) { - type = *resolved; + if(const handle 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); } diff --git a/source/compiler/test/main.s b/source/compiler/test/main.s index 48b2a83..cedacfa 100644 --- a/source/compiler/test/main.s +++ b/source/compiler/test/main.s @@ -14,17 +14,20 @@ // - add more test cases i32 main() { - i32*** memory = cast(malloc(100)); + struct key { + i32* value; + }; - memory[0] = cast(malloc(100)); - memory[1] = cast(malloc(100)); + struct user { + key k; + }; - memory[0][0] = cast(malloc(100)); - memory[1][0] = cast(malloc(100)); + user my_user; - memory[0][0][0] = 1; - memory[1][0][0] = 2; + my_user.k.value = cast(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; } diff --git a/source/type_checker/type_checker.cpp b/source/type_checker/type_checker.cpp index 8c035df..b88a7f6 100644 --- a/source/type_checker/type_checker.cpp +++ b/source/type_checker/type_checker.cpp @@ -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(); + auto& expression = declaration->get(); // 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) { @@ -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 } diff --git a/tests/structs/multiple_access.s b/tests/structs/multiple_access.s new file mode 100644 index 0000000..94adfa9 --- /dev/null +++ b/tests/structs/multiple_access.s @@ -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; +} diff --git a/tests/structs/multiple_access_expected.txt b/tests/structs/multiple_access_expected.txt new file mode 100644 index 0000000..b2b1f77 --- /dev/null +++ b/tests/structs/multiple_access_expected.txt @@ -0,0 +1 @@ +key: 100 diff --git a/tests/structs/multiple_access_ptr.s b/tests/structs/multiple_access_ptr.s new file mode 100644 index 0000000..730d2bc --- /dev/null +++ b/tests/structs/multiple_access_ptr.s @@ -0,0 +1,18 @@ +i32 main() { + struct key { + i32* value; + }; + + struct user { + key k; + }; + + user my_user; + + my_user.k.value = cast(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; +} diff --git a/tests/structs/multiple_access_ptr_expected.txt b/tests/structs/multiple_access_ptr_expected.txt new file mode 100644 index 0000000..e3f6719 --- /dev/null +++ b/tests/structs/multiple_access_ptr_expected.txt @@ -0,0 +1 @@ +key: 123 321