From: Brendan Hansen Date: Tue, 1 Sep 2020 16:00:16 +0000 (-0500) Subject: added ptrmap.onyx; small bugfixes; changed rules about auto pointer conversions X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=e5821d9db1966d3b6612516957d277fd7dfda325;p=onyx.git added ptrmap.onyx; small bugfixes; changed rules about auto pointer conversions --- diff --git a/core/array.onyx b/core/array.onyx index 2498d4a4..7717c058 100644 --- a/core/array.onyx +++ b/core/array.onyx @@ -67,6 +67,13 @@ array_delete :: proc (arr: ^[..] $T, idx: u32) { arr.count -= 1; } +array_fast_delete :: proc (arr: ^[..] $T, idx: u32) { + if idx >= arr.count do return; + + arr.data[idx] = arr.data[arr.count - 1]; + arr.count -= 1; +} + array_contains :: proc (arr: ^[..] $T, x: T) -> bool { for i: 0, arr.count do if arr.data[i] == x do return true; return false; diff --git a/core/file.onyx b/core/file.onyx index 70ac2683..83ca7188 100644 --- a/core/file.onyx +++ b/core/file.onyx @@ -100,7 +100,7 @@ file_get_contents_from_file :: proc (file: File) -> string { fd_seek(file.fd, 0l, Whence.Set, ^dummy); dummy2: u32; - buf := IOVec.{ cast(rawptr) data, size }; + buf := IOVec.{ data, size }; fd_pread(file.fd, IOVecArray.{ ^buf, 1 }, 0l, ^dummy2); fd_seek(file.fd, prev_loc, Whence.Set, ^dummy); diff --git a/core/ptrmap.onyx b/core/ptrmap.onyx new file mode 100644 index 00000000..e828771b --- /dev/null +++ b/core/ptrmap.onyx @@ -0,0 +1,111 @@ +package core + + +PtrMap :: struct { + hashes : [..] i32; + entries : [..] PtrMapEntry; +} + +PtrMapEntry :: struct { + key : rawptr; + value : rawptr; + + next : i32; +} + +ptrmap_init :: proc (use pmap: ^PtrMap, hash_count: i32 = 16) { + array_init(^hashes, hash_count); + array_init(^entries, 4); + + for i: 0, hash_count do array_push(^hashes, -1); +} + +ptrmap_free :: proc (use pmap: ^PtrMap) { + array_free(^hashes); + array_free(^entries); +} + + +ptrmap_put :: proc (use pmap: ^PtrMap, key: rawptr, value: rawptr) { + lr := ptrmap_lookup(pmap, key); + + if lr.entry_index >= 0 { + entries[lr.entry_index].value = value; + return; + } + + array_push(^entries, PtrMapEntry.{ + key = key, + value = value, + next = hashes[lr.hash_index], + }); + + hashes[lr.hash_index] = entries.count - 1; +} + +ptrmap_has :: proc (use pmap: ^PtrMap, key: rawptr) -> bool { + lr := ptrmap_lookup(pmap, key); + return lr.entry_index >= 0; +} + +ptrmap_get :: proc (use pmap: ^PtrMap, key: rawptr) -> rawptr { + lr := ptrmap_lookup(pmap, key); + if lr.entry_index >= 0 do return entries[lr.entry_index].value; + + return null; +} + +ptrmap_delete :: proc (use pmap: ^PtrMap, key: rawptr) { + lr := ptrmap_lookup(pmap, key); + if lr.entry_index < 0 do return; + + if lr.entry_prev < 0 do hashes[lr.hash_index] = entries[lr.entry_index].next; + else do hashes[lr.entry_prev] = entries[lr.entry_index].next; + + if lr.entry_index == entries.count - 1 { + array_pop(^entries); + return; + } + + array_fast_delete(^entries, lr.entry_index); + last := ptrmap_lookup(pmap, entries[lr.entry_index].key); + if last.entry_prev >= 0 do entries[last.entry_prev].next = lr.entry_index; + else do hashes[last.hash_index] = lr.entry_index; +} + +ptrmap_clear :: proc (use pmap: ^PtrMap) { + for i: 0, hashes.count do hashes.data[i] = -1; + entries.count = 0; +} + + + +// +// Private symbols +// + +#private +PtrMapLookupResult :: struct { + hash_index : i32 = -1; + entry_index : i32 = -1; + entry_prev : i32 = -1; +} + +#private +ptrmap_lookup :: proc (use pmap: ^PtrMap, key: rawptr) -> PtrMapLookupResult { + lr := PtrMapLookupResult.{}; + + hash := cast(u32) 0xcbf29ce4 ^ cast(u32) key; + + lr.hash_index = hash % hashes.count; + lr.entry_index = hashes[lr.hash_index]; + + while lr.entry_index >= 0 { + if entries[lr.entry_index].key == key do return lr; + + lr.entry_prev = lr.entry_index; + lr.entry_index = entries[lr.entry_index].next; + } + + return lr; +} \ No newline at end of file diff --git a/core/std/js.onyx b/core/std/js.onyx index 8650a2a4..69b0473b 100644 --- a/core/std/js.onyx +++ b/core/std/js.onyx @@ -7,6 +7,7 @@ use package builtin #include_file "core/intrinsics" #include_file "core/math" #include_file "core/memory" +#include_file "core/ptrmap" #include_file "core/random" #include_file "core/stdio" #include_file "core/string" diff --git a/core/std/wasi.onyx b/core/std/wasi.onyx index 518befb8..0c8d9495 100644 --- a/core/std/wasi.onyx +++ b/core/std/wasi.onyx @@ -8,6 +8,7 @@ use package builtin #include_file "core/intrinsics" #include_file "core/math" #include_file "core/memory" +#include_file "core/ptrmap" #include_file "core/random" #include_file "core/stdio" #include_file "core/string" diff --git a/core/string.onyx b/core/string.onyx index b81b6227..3804ea35 100644 --- a/core/string.onyx +++ b/core/string.onyx @@ -222,7 +222,7 @@ i64_to_string :: proc (n_: i64, base: u64, buf: Buffer) -> string { string_builder_add_i64 :: proc (use sb: ^StringBuilder, n: i64, base := 10l) -> ^StringBuilder { buf : [256] u8; - s := i64_to_string(n, base, Buffer.{ cast(rawptr) buf, 256 }); + s := i64_to_string(n, base, Buffer.{ cast(^void) buf, 256 }); return string_builder_add_string(sb, s); } diff --git a/onyx b/onyx index 8f0b8937..708fe456 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/poly_test.onyx b/progs/poly_test.onyx index de6a34f6..4d0dbafe 100644 --- a/progs/poly_test.onyx +++ b/progs/poly_test.onyx @@ -63,7 +63,7 @@ soa_deinit :: proc (s: ^SOA) { array_free(^s.b); } -main2 :: proc (args: [] cstring) { +main :: proc (args: [] cstring) { s : SOA; soa_init(^s); defer soa_deinit(^s); @@ -85,9 +85,37 @@ main2 :: proc (args: [] cstring) { print("After adding...\n"); print_arr_details(^s.a); print_arr_details(^s.b); -} -main :: proc (args: [] cstring) { + + map : PtrMap; + ptrmap_init(^map); + defer ptrmap_free(^map); + + for i: 0, 100 do ptrmap_put(^map, ^s.a[i], ^s.b[i]); + + print("Has ^a[20]? "); + print(ptrmap_has(^map, ^s.a[20])); + print("\n"); + + print("Has null? "); + print(ptrmap_has(^map, null)); + print("\n"); + + print("Value at ^a[50]: "); + print(ptrmap_get(^map, ^s.a[50])); + print(" == "); + print(^s.b[50]); + print("\n"); + + print("Deleteing ^a[20]\n"); + ptrmap_delete(^map, ^s.a[20]); + + print("Has ^a[20]? "); + print(ptrmap_has(^map, ^s.a[20])); + print("\n"); +} + +main2 :: proc (args: [] cstring) { print(cast(u32) __heap_start, 16); iarr_backing : [32] i32; @@ -163,7 +191,7 @@ main :: proc (args: [] cstring) { print_array(varr, "\n"); - dummy := Dummy.{ data = calloc(sizeof [5] i32) }; + dummy := Dummy.{ data = cast(^u32) calloc(sizeof [5] i32) }; for i: 0, dummy.count do dummy.data[i] = i * 5; print_array(dummy); diff --git a/src/onyxchecker.c b/src/onyxchecker.c index b80a4728..0d0dfe16 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -48,13 +48,15 @@ b32 check_return(AstReturn* retnode) { if (!types_are_compatible(retnode->expr->type, semstate.expected_return_type)) { onyx_report_error(retnode->expr->token->pos, "Expected to return a value of type '%s', returning value of type '%s'.", - type_get_name(retnode->expr->type), - type_get_name(semstate.expected_return_type)); + type_get_name(semstate.expected_return_type), + type_get_name(retnode->expr->type)); return 1; } } else { if (semstate.expected_return_type->Basic.size > 0) { - onyx_report_error(retnode->token->pos, "returning from non-void function without value"); + onyx_report_error(retnode->token->pos, + "Returning from non-void function without value. Expected a value of type '%s'.", + type_get_name(semstate.expected_return_type)); return 1; } } @@ -524,11 +526,11 @@ b32 check_binop_assignment(AstBinaryOp* binop, b32 assignment_is_ok) { if (check_binaryop(&binop_node, 0)) return 1; } - if (!types_are_compatible(binop->left->type, binop->right->type)) { + if (!types_are_compatible(binop->right->type, binop->right->type)) { onyx_report_error(binop->token->pos, "Cannot assign value of type '%s' to a '%s'.", - type_get_name(binop->left->type), - type_get_name(binop->right->type)); + type_get_name(binop->right->type), + type_get_name(binop->left->type)); return 1; } @@ -564,11 +566,19 @@ b32 check_binaryop_compare(AstBinaryOp** pbinop) { return 1; } - if (!types_are_compatible(binop->left->type, binop->right->type)) { + // HACK: Since ^... to rawptr is a one way conversion, strip any pointers + // away so they can be compared as expected + Type* ltype = binop->left->type; + Type* rtype = binop->right->type; + + if (ltype->kind == Type_Kind_Pointer) ltype = &basic_types[Basic_Kind_Rawptr]; + if (rtype->kind == Type_Kind_Pointer) rtype = &basic_types[Basic_Kind_Rawptr]; + + if (!types_are_compatible(ltype, rtype)) { onyx_report_error(binop->token->pos, "Cannot compare '%s' to '%s'.", - type_get_name(binop->left->type), - type_get_name(binop->right->type)); + type_get_name(ltype), + type_get_name(rtype)); return 1; } @@ -770,7 +780,7 @@ b32 check_struct_literal(AstStructLiteral* sl) { if (!types_are_compatible(formal, (*actual)->type)) { onyx_report_error(sl->token->pos, - "Mismatched types for %d%s member, expected '%s, got '%s'.", + "Mismatched types for %d%s member, expected '%s', got '%s'.", i, bh_num_suffix(i), type_get_name(formal), type_get_name((*actual)->type)); diff --git a/src/onyxtypes.c b/src/onyxtypes.c index beade717..040d26bd 100644 --- a/src/onyxtypes.c +++ b/src/onyxtypes.c @@ -134,9 +134,6 @@ b32 types_are_compatible(Type* t1, Type* t2) { return types_are_compatible(t1->Pointer.elem, t2->Pointer.elem); } - if (t2->kind == Type_Kind_Basic && t2->Basic.kind == Basic_Kind_Rawptr) - return 1; - break; } diff --git a/src/onyxutils.c b/src/onyxutils.c index 538cb06f..67d91f72 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -445,6 +445,7 @@ AstFunction* polymorphic_proc_lookup(AstPolyProc* pp, PolyProcLookupMethod pp_lo return bh_table_get(AstFunction *, pp->concrete_funcs, key_buf); } + Type* old_return_type = semstate.expected_return_type; semstate.curr_scope = pp->poly_scope; AstFunction* func = (AstFunction *) ast_clone(semstate.node_allocator, pp->base_func); @@ -459,9 +460,11 @@ AstFunction* polymorphic_proc_lookup(AstPolyProc* pp, PolyProcLookupMethod pp_lo has_error: onyx_report_error(pos, "Error in polymorphic procedure generated from this call site."); + semstate.expected_return_type = old_return_type; return NULL; no_errors: + semstate.expected_return_type = old_return_type; bh_arr_push(semstate.other_entities, ((Entity) { .type = Entity_Type_Function_Header,