🐛 fix ptr_call_field resolve bug

This commit is contained in:
ValKmjolnir 2024-11-02 01:38:26 +08:00
parent ace758db97
commit 626d156302
5 changed files with 37 additions and 32 deletions

View File

@ -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 && if (ctx.search_symbol_kind(res)==sym_kind::struct_kind &&
!res.is_pointer() && !res.is_pointer()) {
type_res.is_pointer()) {
rp.report(node->get_target(), rp.report(node->get_target(),
"cannot convert \"" + res.to_string() + "cannot convert \"" + res.to_string() +
"\" to \"" + type_res.to_string() + "\"." "\" to \"" + type_res.to_string() + "\"."
); );
} }
// pointer to normal struct is also not allowed // any type to normal struct is also not allowed
if (res.is_pointer() && if (ctx.search_symbol_kind(type_res)==sym_kind::struct_kind &&
ctx.search_symbol_kind(type_res)==sym_kind::struct_kind &&
!type_res.is_pointer()) { !type_res.is_pointer()) {
rp.report(node->get_target(), rp.report(node->get_target(),
"cannot convert \"" + res.to_string() + "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())) { if (struct_self.method.count(node->get_name())) {
check_pub_method(node, node->get_name(), struct_self); check_pub_method(node, node->get_name(), struct_self);
auto infer = type({ const auto res = struct_method_infer(prev, node->get_name());
prev.name, node->set_resolve_type(res);
prev.loc_file, return res;
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;
} }
if (struct_self.static_method.count(node->get_name())) { if (struct_self.static_method.count(node->get_name())) {
rp.report(node, rp.report(node,

View File

@ -90,11 +90,11 @@ func report_invalid_argument(arg: i8*) {
} }
// FIXME: make it run // FIXME: make it run
// func test_hashmap() { func test_hashmap() {
// var map = hashmap<i64>::new(); var map = hashmap<i64>::new();
// map->delete(); map->delete();
// free(map => i8*); free(map => i8*);
// } }
func main(argc: i32, argv: i8**) -> i32 { func main(argc: i32, argv: i8**) -> i32 {
if (argc==(1 => i32)) { if (argc==(1 => i32)) {

View File

@ -1,5 +1,5 @@
use std::str::{ str }; use std::str::{ str };
use std::libc::{ malloc, free }; use std::libc::{ malloc, free, streq };
pub struct pair<T> { pub struct pair<T> {
key: str*, key: str*,
@ -35,13 +35,13 @@ impl hashmap<T> {
impl hashmap<T> { impl hashmap<T> {
pub func insert(self, key: str*, value: T*) { pub func insert(self, key: str*, value: T*) {
var hash = 0 => u64; var hash = 0 => u64;
for (var i = 0; i < key->size; i+=1) { for (var i = 0 => u64; i < key->size; i += 1 => u64) {
hash = hash * 31 + (key[i] => u64); hash = hash * (31 => u64) + (key->c_str[i] => u64);
} }
hash = hash % 1024 => u64; hash = hash % 1024 => u64;
var bucket_list = self->data[hash] => bucket<T>*; var bucket_list = self->data[hash] => bucket<T>*;
while (bucket_list != nil) { while (bucket_list => i8* != nil) {
if (bucket_list->pair.key == key) { if (streq(bucket_list->pair.key->c_str, key->c_str)) {
bucket_list->pair.value = value; bucket_list->pair.value = value;
return; return;
} }

View File

@ -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 }; use libc::{ puts, malloc, free };
struct Vec<T> { struct Vec<T> {
@ -107,6 +107,9 @@ func main() -> i64 {
var pub_stct = PublicStruct<i32>::instance(); var pub_stct = PublicStruct<i32>::instance();
pub_stct.get_field(); pub_stct.get_field();
var embed_pub_stct = EmbedPubStct<i32>::instance();
embed_pub_stct.get_field();
test_i32(); test_i32();
add_test<i8>('a', '\0'); add_test<i8>('a', '\0');

View File

@ -16,7 +16,7 @@ pub struct Test<T> {
impl Test<T> { impl Test<T> {
pub func get_test(self) -> T { 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; return self->test;
} }
} }
@ -44,7 +44,21 @@ impl PublicStruct<T> {
return PublicStruct<T> { field: PrivateStruct<T> { field: 42 => T } }; return PublicStruct<T> { field: PrivateStruct<T> { field: 42 => T } };
} }
pub func get_field(self) -> 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; return self->field.field;
} }
}
pub struct EmbedPubStct<T> {
embed: PublicStruct<T>
}
impl EmbedPubStct<T> {
pub func instance() -> EmbedPubStct<T> {
return EmbedPubStct<T> { embed: PublicStruct<T>::instance() };
}
pub func get_field(self) -> T {
puts("[test_lib/data.colgm] EmbedPubStct::get_field called");
return self->embed.get_field();
}
} }