🐛 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 &&
!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,

View File

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

View File

@ -1,5 +1,5 @@
use std::str::{ str };
use std::libc::{ malloc, free };
use std::libc::{ malloc, free, streq };
pub struct pair<T> {
key: str*,
@ -35,13 +35,13 @@ impl hashmap<T> {
impl hashmap<T> {
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<T>*;
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;
}

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

View File

@ -16,7 +16,7 @@ pub struct Test<T> {
impl Test<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;
}
}
@ -44,7 +44,21 @@ impl PublicStruct<T> {
return PublicStruct<T> { field: PrivateStruct<T> { 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<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();
}
}