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;
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);
--- /dev/null
+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
#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"
#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"
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);
}
array_free(^s.b);
}
-main2 :: proc (args: [] cstring) {
+main :: proc (args: [] cstring) {
s : SOA;
soa_init(^s);
defer soa_deinit(^s);
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;
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);
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;
}
}
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;
}
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;
}
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));
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;
}
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);
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,