mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
dynamic map insertion and lookup
This commit is contained in:
+4
-3
@@ -11,11 +11,12 @@
|
|||||||
|
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
Value :: type f32;
|
m: map[int]u32;
|
||||||
m: map[int]Value;
|
|
||||||
reserve(^m, 16);
|
reserve(^m, 16);
|
||||||
defer free(m);
|
defer free(m);
|
||||||
// m[123] = 345.0;
|
|
||||||
|
m[123] = 345;
|
||||||
|
fmt.println(m[123]);
|
||||||
if x, ok := m[123]; ok {
|
if x, ok := m[123]; ok {
|
||||||
fmt.println(x);
|
fmt.println(x);
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-6
@@ -511,25 +511,27 @@ __dynamic_map_rehash :: proc(using header: Map_Header, new_count: int) {
|
|||||||
__dynamic_map_grow(new_header);
|
__dynamic_map_grow(new_header);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(header.m);
|
free_ptr_with_allocator(header.m.hashes.allocator, header.m.hashes.data);
|
||||||
|
free_ptr_with_allocator(header.m.entries.allocator, header.m.entries.data);
|
||||||
header.m^ = nm;
|
header.m^ = nm;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__dynamic_map_get :: proc(h: Map_Header, key: Map_Key) -> rawptr {
|
__dynamic_map_get :: proc(h: Map_Header, key: Map_Key) -> rawptr {
|
||||||
index := __dynamic_map_find(h, key).entry_index;
|
index := __dynamic_map_find(h, key).entry_index;
|
||||||
if index >= 0 {
|
if index >= 0 {
|
||||||
data := cast(^byte)__dynamic_map_get_entry(h, index);
|
data := cast(^byte)__dynamic_map_get_entry(h, index);
|
||||||
return data + h.value_offset;
|
val := data + h.value_offset;
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
__dynamic_map_set :: proc(using h: Map_Header, key: Map_Key, value: rawptr) {
|
__dynamic_map_set :: proc(using h: Map_Header, key: Map_Key, value: rawptr) {
|
||||||
|
index: int;
|
||||||
|
|
||||||
if m.hashes.count == 0 {
|
if m.hashes.count == 0 {
|
||||||
__dynamic_map_grow(h);
|
__dynamic_map_grow(h);
|
||||||
}
|
}
|
||||||
index: int;
|
|
||||||
fr := __dynamic_map_find(h, key);
|
fr := __dynamic_map_find(h, key);
|
||||||
if fr.entry_index >= 0 {
|
if fr.entry_index >= 0 {
|
||||||
index = fr.entry_index;
|
index = fr.entry_index;
|
||||||
@@ -544,7 +546,8 @@ __dynamic_map_set :: proc(using h: Map_Header, key: Map_Key, value: rawptr) {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
data := cast(^byte)__dynamic_map_get_entry(h, index);
|
data := cast(^byte)__dynamic_map_get_entry(h, index);
|
||||||
mem.copy(data+value_offset, value, entry_size-value_offset);
|
val := data+value_offset;
|
||||||
|
mem.copy(val, value, entry_size-value_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if __dynamic_map_full(h) {
|
if __dynamic_map_full(h) {
|
||||||
@@ -598,7 +601,7 @@ __dynamic_map_add_entry :: proc(using h: Map_Header, key: Map_Key) -> int {
|
|||||||
end.key = key;
|
end.key = key;
|
||||||
end.next = -1;
|
end.next = -1;
|
||||||
}
|
}
|
||||||
return c;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-7
@@ -3829,12 +3829,6 @@ void check_unpack_arguments(Checker *c, ArrayOperand *operands, AstNodeArray arg
|
|||||||
Operand o = {0};
|
Operand o = {0};
|
||||||
check_multi_expr(c, &o, args.e[i]);
|
check_multi_expr(c, &o, args.e[i]);
|
||||||
|
|
||||||
if (o.mode == Addressing_MapIndex) {
|
|
||||||
Type *tuple_type = make_map_tuple_type(c->allocator, o.type);
|
|
||||||
add_type_and_value(&c->info, o.expr, o.mode, tuple_type, (ExactValue){0});
|
|
||||||
o.type = tuple_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o.type == NULL || o.type->kind != Type_Tuple) {
|
if (o.type == NULL || o.type->kind != Type_Tuple) {
|
||||||
array_add(operands, o);
|
array_add(operands, o);
|
||||||
} else {
|
} else {
|
||||||
@@ -4997,7 +4991,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
o->mode = Addressing_MapIndex;
|
o->mode = Addressing_MapIndex;
|
||||||
o->type = t->Map.value;
|
o->type = make_map_tuple_type(c->allocator, t->Map.value);
|
||||||
o->expr = node;
|
o->expr = node;
|
||||||
return Expr_Expr;
|
return Expr_Expr;
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-3
@@ -256,13 +256,17 @@ Type *check_assignment_variable(Checker *c, Operand *op_a, AstNode *lhs) {
|
|||||||
e->flags |= EntityFlag_Used;
|
e->flags |= EntityFlag_Used;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Type *assignment_type = op_b.type;
|
||||||
switch (op_b.mode) {
|
switch (op_b.mode) {
|
||||||
case Addressing_Invalid:
|
case Addressing_Invalid:
|
||||||
return NULL;
|
return NULL;
|
||||||
case Addressing_Variable:
|
case Addressing_Variable:
|
||||||
break;
|
break;
|
||||||
case Addressing_MapIndex:
|
case Addressing_MapIndex: {
|
||||||
break;
|
Type *t = base_type(assignment_type); GB_ASSERT(is_type_tuple(t));
|
||||||
|
t = t->Tuple.variables[0]->type;
|
||||||
|
assignment_type = t;
|
||||||
|
} break;
|
||||||
default: {
|
default: {
|
||||||
if (op_b.expr->kind == AstNode_SelectorExpr) {
|
if (op_b.expr->kind == AstNode_SelectorExpr) {
|
||||||
// NOTE(bill): Extra error checks
|
// NOTE(bill): Extra error checks
|
||||||
@@ -287,7 +291,7 @@ Type *check_assignment_variable(Checker *c, Operand *op_a, AstNode *lhs) {
|
|||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
check_assignment(c, op_a, op_b.type, str_lit("assignment"));
|
check_assignment(c, op_a, assignment_type, str_lit("assignment"));
|
||||||
if (op_a->mode == Addressing_Invalid) {
|
if (op_a->mode == Addressing_Invalid) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -372,6 +372,7 @@ typedef struct irAddr {
|
|||||||
struct {
|
struct {
|
||||||
irValue *map_key;
|
irValue *map_key;
|
||||||
Type * map_type;
|
Type * map_type;
|
||||||
|
Type * map_result;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
// union {
|
// union {
|
||||||
@@ -384,10 +385,11 @@ irAddr ir_make_addr(irValue *addr) {
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
irAddr ir_make_addr_map(irValue *addr, irValue *map_key, Type *map_type) {
|
irAddr ir_make_addr_map(irValue *addr, irValue *map_key, Type *map_type, Type *map_result) {
|
||||||
irAddr v = {irAddr_Map, addr};
|
irAddr v = {irAddr_Map, addr};
|
||||||
v.map_key = map_key;
|
v.map_key = map_key;
|
||||||
v.map_type = map_type;
|
v.map_type = map_type;
|
||||||
|
v.map_result = map_result;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -589,23 +591,6 @@ Type *ir_type(irValue *value) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type *ir_addr_type(irAddr addr) {
|
|
||||||
if (addr.addr == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addr.kind == irAddr_Map) {
|
|
||||||
Type *t = base_type(addr.map_type);
|
|
||||||
GB_ASSERT(is_type_map(t));
|
|
||||||
return t->Map.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
Type *t = ir_type(addr.addr);
|
|
||||||
GB_ASSERT(is_type_pointer(t));
|
|
||||||
return type_deref(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool ir_is_blank_ident(AstNode *node) {
|
bool ir_is_blank_ident(AstNode *node) {
|
||||||
if (node->kind == AstNode_Ident) {
|
if (node->kind == AstNode_Ident) {
|
||||||
@@ -1461,6 +1446,23 @@ irValue *ir_address_from_load_or_generate_local(irProcedure *proc, irValue *val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Type *ir_addr_type(irAddr addr) {
|
||||||
|
if (addr.addr == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addr.kind == irAddr_Map) {
|
||||||
|
Type *t = base_type(addr.map_type);
|
||||||
|
GB_ASSERT(is_type_map(t));
|
||||||
|
return t->Map.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type *t = ir_type(addr.addr);
|
||||||
|
GB_ASSERT(is_type_pointer(t));
|
||||||
|
return type_deref(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
irValue *ir_addr_store(irProcedure *proc, irAddr addr, irValue *value) {
|
irValue *ir_addr_store(irProcedure *proc, irAddr addr, irValue *value) {
|
||||||
if (addr.addr == NULL) {
|
if (addr.addr == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1469,7 +1471,8 @@ irValue *ir_addr_store(irProcedure *proc, irAddr addr, irValue *value) {
|
|||||||
Type *map_type = base_type(addr.map_type);
|
Type *map_type = base_type(addr.map_type);
|
||||||
irValue *h = ir_gen_map_header(proc, addr.addr, map_type);
|
irValue *h = ir_gen_map_header(proc, addr.addr, map_type);
|
||||||
irValue *key = ir_gen_map_key(proc, addr.map_key);
|
irValue *key = ir_gen_map_key(proc, addr.map_key);
|
||||||
irValue *ptr =ir_address_from_load_or_generate_local(proc, value);
|
irValue *v = ir_emit_conv(proc, value, map_type->Map.value);
|
||||||
|
irValue *ptr = ir_address_from_load_or_generate_local(proc, v);
|
||||||
ptr = ir_emit_conv(proc, ptr, t_rawptr);
|
ptr = ir_emit_conv(proc, ptr, t_rawptr);
|
||||||
|
|
||||||
irValue **args = gb_alloc_array(proc->module->allocator, irValue *, 3);
|
irValue **args = gb_alloc_array(proc->module->allocator, irValue *, 3);
|
||||||
@@ -1487,7 +1490,7 @@ irValue *ir_addr_store(irProcedure *proc, irAddr addr, irValue *value) {
|
|||||||
// irValue *out = ir_emit(proc, ir_make_instr_insert_element(proc, v, elem, addr.Vector.index));
|
// irValue *out = ir_emit(proc, ir_make_instr_insert_element(proc, v, elem, addr.Vector.index));
|
||||||
// return ir_emit_store(proc, addr.addr, out);
|
// return ir_emit_store(proc, addr.addr, out);
|
||||||
// } else {
|
// } else {
|
||||||
irValue *v = ir_emit_conv(proc, value, ir_addr_type(addr));
|
irValue *v = ir_emit_conv(proc, value, ir_addr_type(addr));
|
||||||
return ir_emit_store(proc, addr.addr, v);
|
return ir_emit_store(proc, addr.addr, v);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
@@ -1527,7 +1530,12 @@ irValue *ir_addr_load(irProcedure *proc, irAddr addr) {
|
|||||||
ir_start_block(proc, done);
|
ir_start_block(proc, done);
|
||||||
|
|
||||||
|
|
||||||
return ir_emit_load(proc, v);
|
if (is_type_tuple(addr.map_result)) {
|
||||||
|
return ir_emit_load(proc, v);
|
||||||
|
} else {
|
||||||
|
irValue *single = ir_emit_struct_ep(proc, v, 0);
|
||||||
|
return ir_emit_load(proc, single);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (addr.kind == irAddr_Vector) {
|
// if (addr.kind == irAddr_Vector) {
|
||||||
@@ -3778,7 +3786,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
|||||||
irValue *key = ir_build_expr(proc, ie->index);
|
irValue *key = ir_build_expr(proc, ie->index);
|
||||||
key = ir_emit_conv(proc, key, t->Map.key);
|
key = ir_emit_conv(proc, key, t->Map.key);
|
||||||
|
|
||||||
return ir_make_addr_map(map_val, key, t);
|
Type *result_type = type_of_expr(proc->module->info, expr);
|
||||||
|
return ir_make_addr_map(map_val, key, t, result_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
irValue *using_addr = NULL;
|
irValue *using_addr = NULL;
|
||||||
@@ -4598,8 +4607,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
|||||||
if (lvals.e[i].addr == NULL) {
|
if (lvals.e[i].addr == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
irValue *v = ir_emit_conv(proc, inits.e[i], ir_addr_type(lvals.e[i]));
|
ir_addr_store(proc, lvals.e[i], inits.e[i]);
|
||||||
ir_addr_store(proc, lvals.e[i], v);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user