From 626d156302ab508d84bd4f81e9d31773fb946040 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Sat, 2 Nov 2024 01:38:26 +0800 Subject: [PATCH] :bug: fix ptr_call_field resolve bug --- bootstrap/sema/semantic.cpp | 26 +++++++------------------- src/main.colgm | 10 +++++----- src/std/hashmap.colgm | 10 +++++----- test/generic.colgm | 5 ++++- test/test_lib/data.colgm | 18 ++++++++++++++++-- 5 files changed, 37 insertions(+), 32 deletions(-) diff --git a/bootstrap/sema/semantic.cpp b/bootstrap/sema/semantic.cpp index 41f2791..87bd213 100644 --- a/bootstrap/sema/semantic.cpp +++ b/bootstrap/sema/semantic.cpp @@ -304,18 +304,16 @@ type semantic::resolve_type_convert(type_convert* node) { ); } - // normal struct to pointer is not allowed + // normal struct to any type is not allowed if (ctx.search_symbol_kind(res)==sym_kind::struct_kind && - !res.is_pointer() && - type_res.is_pointer()) { + !res.is_pointer()) { rp.report(node->get_target(), "cannot convert \"" + res.to_string() + "\" to \"" + type_res.to_string() + "\"." ); } - // pointer to normal struct is also not allowed - if (res.is_pointer() && - ctx.search_symbol_kind(type_res)==sym_kind::struct_kind && + // any type to normal struct is also not allowed + if (ctx.search_symbol_kind(type_res)==sym_kind::struct_kind && !type_res.is_pointer()) { rp.report(node->get_target(), "cannot convert \"" + res.to_string() + @@ -844,19 +842,9 @@ type semantic::resolve_ptr_get_field(const type& prev, ptr_get_field* node) { } if (struct_self.method.count(node->get_name())) { check_pub_method(node, node->get_name(), struct_self); - auto infer = type({ - prev.name, - prev.loc_file, - prev.pointer_depth, - false - }); - infer.stm_info = { - .flag_is_static = false, - .flag_is_normal = true, - .method_name = node->get_name() - }; - node->set_resolve_type(infer); - return infer; + const auto res = struct_method_infer(prev, node->get_name()); + node->set_resolve_type(res); + return res; } if (struct_self.static_method.count(node->get_name())) { rp.report(node, diff --git a/src/main.colgm b/src/main.colgm index 49904b6..29f31ad 100644 --- a/src/main.colgm +++ b/src/main.colgm @@ -90,11 +90,11 @@ func report_invalid_argument(arg: i8*) { } // FIXME: make it run -// func test_hashmap() { -// var map = hashmap::new(); -// map->delete(); -// free(map => i8*); -// } +func test_hashmap() { + var map = hashmap::new(); + map->delete(); + free(map => i8*); +} func main(argc: i32, argv: i8**) -> i32 { if (argc==(1 => i32)) { diff --git a/src/std/hashmap.colgm b/src/std/hashmap.colgm index 7898dce..c5e0f65 100644 --- a/src/std/hashmap.colgm +++ b/src/std/hashmap.colgm @@ -1,5 +1,5 @@ use std::str::{ str }; -use std::libc::{ malloc, free }; +use std::libc::{ malloc, free, streq }; pub struct pair { key: str*, @@ -35,13 +35,13 @@ impl hashmap { impl hashmap { pub func insert(self, key: str*, value: T*) { var hash = 0 => u64; - for (var i = 0; i < key->size; i+=1) { - hash = hash * 31 + (key[i] => u64); + for (var i = 0 => u64; i < key->size; i += 1 => u64) { + hash = hash * (31 => u64) + (key->c_str[i] => u64); } hash = hash % 1024 => u64; var bucket_list = self->data[hash] => bucket*; - while (bucket_list != nil) { - if (bucket_list->pair.key == key) { + while (bucket_list => i8* != nil) { + if (streq(bucket_list->pair.key->c_str, key->c_str)) { bucket_list->pair.value = value; return; } diff --git a/test/generic.colgm b/test/generic.colgm index bb5ddef..0751b1a 100644 --- a/test/generic.colgm +++ b/test/generic.colgm @@ -1,4 +1,4 @@ -use data::{ A, B, Test, EmbedTest, PublicStruct, test_i32 }; +use data::{ A, B, Test, EmbedTest, PublicStruct, EmbedPubStct, test_i32 }; use libc::{ puts, malloc, free }; struct Vec { @@ -107,6 +107,9 @@ func main() -> i64 { var pub_stct = PublicStruct::instance(); pub_stct.get_field(); + var embed_pub_stct = EmbedPubStct::instance(); + embed_pub_stct.get_field(); + test_i32(); add_test('a', '\0'); diff --git a/test/test_lib/data.colgm b/test/test_lib/data.colgm index 5ee2582..c460d29 100644 --- a/test/test_lib/data.colgm +++ b/test/test_lib/data.colgm @@ -16,7 +16,7 @@ pub struct Test { impl Test { pub func get_test(self) -> T { - puts("[test_lib/data.colgm] get_test called"); + puts("[test_lib/data.colgm] Test::get_test called"); return self->test; } } @@ -44,7 +44,21 @@ impl PublicStruct { return PublicStruct { field: PrivateStruct { field: 42 => T } }; } pub func get_field(self) -> T { - puts("[test_lib/data.colgm] get_field called"); + puts("[test_lib/data.colgm] PublicStruct::get_field called"); return self->field.field; } +} + +pub struct EmbedPubStct { + embed: PublicStruct +} + +impl EmbedPubStct { + pub func instance() -> EmbedPubStct { + return EmbedPubStct { embed: PublicStruct::instance() }; + } + pub func get_field(self) -> T { + puts("[test_lib/data.colgm] EmbedPubStct::get_field called"); + return self->embed.get_field(); + } } \ No newline at end of file