mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 22:58:46 +00:00
map string keys and for iterator
This commit is contained in:
+9
-5
@@ -11,14 +11,18 @@
|
|||||||
|
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
m: map[int]u32;
|
m: map[string]u32;
|
||||||
reserve(^m, 16);
|
reserve(^m, 16);
|
||||||
defer free(m);
|
defer free(m);
|
||||||
|
|
||||||
m[123] = 345;
|
m["a"] = 56;
|
||||||
fmt.println(m[123]);
|
m["b"] = 13453;
|
||||||
if x, ok := m[123]; ok {
|
m["c"] = 7654;
|
||||||
fmt.println(x);
|
c, ok := m["c"];
|
||||||
|
assert(ok && c == 7654);
|
||||||
|
|
||||||
|
for val, key in m {
|
||||||
|
fmt.printf("m[\"%s\"] == %v\n", key, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -438,7 +438,10 @@ __dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: in
|
|||||||
|
|
||||||
|
|
||||||
__default_hash :: proc(data: []byte) -> u64 {
|
__default_hash :: proc(data: []byte) -> u64 {
|
||||||
return hash.murmur64(data);
|
return hash.fnv64a(data);
|
||||||
|
}
|
||||||
|
__default_hash_string :: proc(s: string) -> u64 {
|
||||||
|
return __default_hash(cast([]byte)s);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map_Key :: struct #ordered {
|
Map_Key :: struct #ordered {
|
||||||
|
|||||||
+4
-4
@@ -1136,7 +1136,7 @@ void check_map_type(Checker *c, Type *type, AstNode *node) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
struct {
|
struct {
|
||||||
hash: u64,
|
hash: Map_Key,
|
||||||
next: int,
|
next: int,
|
||||||
key: Key_Type,
|
key: Key_Type,
|
||||||
value: Value_Type,
|
value: Value_Type,
|
||||||
@@ -1148,9 +1148,9 @@ void check_map_type(Checker *c, Type *type, AstNode *node) {
|
|||||||
|
|
||||||
isize field_count = 3;
|
isize field_count = 3;
|
||||||
Entity **fields = gb_alloc_array(a, Entity *, field_count);
|
Entity **fields = gb_alloc_array(a, Entity *, field_count);
|
||||||
fields[0] = make_entity_field(a, c->context.scope, make_token_ident(str_lit("key")), t_u64, false, false);
|
fields[0] = make_entity_field(a, c->context.scope, make_token_ident(str_lit("key")), t_map_key, false, false);
|
||||||
fields[1] = make_entity_field(a, c->context.scope, make_token_ident(str_lit("next")), t_int, false, false);
|
fields[1] = make_entity_field(a, c->context.scope, make_token_ident(str_lit("next")), t_int, false, false);
|
||||||
fields[2] = make_entity_field(a, c->context.scope, make_token_ident(str_lit("value")), value, false, false);
|
fields[2] = make_entity_field(a, c->context.scope, make_token_ident(str_lit("value")), value, false, false);
|
||||||
|
|
||||||
check_close_scope(c);
|
check_close_scope(c);
|
||||||
|
|
||||||
|
|||||||
@@ -723,6 +723,11 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
val = t->Vector.elem;
|
val = t->Vector.elem;
|
||||||
idx = t_int;
|
idx = t_int;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Type_Map:
|
||||||
|
val = t->Map.value;
|
||||||
|
idx = t->Map.key;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -975,6 +975,9 @@ irValue *ir_make_const_i32(gbAllocator a, i64 i) {
|
|||||||
irValue *ir_make_const_i64(gbAllocator a, i64 i) {
|
irValue *ir_make_const_i64(gbAllocator a, i64 i) {
|
||||||
return ir_make_value_constant(a, t_i64, make_exact_value_integer(i));
|
return ir_make_value_constant(a, t_i64, make_exact_value_integer(i));
|
||||||
}
|
}
|
||||||
|
irValue *ir_make_const_u64(gbAllocator a, u64 i) {
|
||||||
|
return ir_make_value_constant(a, t_u64, make_exact_value_integer(i));
|
||||||
|
}
|
||||||
irValue *ir_make_const_f32(gbAllocator a, f32 f) {
|
irValue *ir_make_const_f32(gbAllocator a, f32 f) {
|
||||||
return ir_make_value_constant(a, t_f32, make_exact_value_float(f));
|
return ir_make_value_constant(a, t_f32, make_exact_value_float(f));
|
||||||
}
|
}
|
||||||
@@ -1418,15 +1421,28 @@ irValue *ir_gen_map_header(irProcedure *proc, irValue *map_val, Type *map_type)
|
|||||||
|
|
||||||
irValue *ir_gen_map_key(irProcedure *proc, irValue *key) {
|
irValue *ir_gen_map_key(irProcedure *proc, irValue *key) {
|
||||||
irValue *v = ir_add_local_generated(proc, t_map_key);
|
irValue *v = ir_add_local_generated(proc, t_map_key);
|
||||||
irValue *hash = ir_emit_struct_ep(proc, v, 0);
|
|
||||||
Type *t = base_type(ir_type(key));
|
Type *t = base_type(ir_type(key));
|
||||||
if (is_type_integer(t)) {
|
if (is_type_integer(t)) {
|
||||||
ir_emit_store(proc, hash, ir_emit_conv(proc, key, t_u64));
|
ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, key, t_u64));
|
||||||
} else if (is_type_pointer(t)) {
|
} else if (is_type_pointer(t)) {
|
||||||
irValue *p = ir_emit_conv(proc, key, t_uint);
|
irValue *p = ir_emit_conv(proc, key, t_uint);
|
||||||
ir_emit_store(proc, hash, ir_emit_conv(proc, p, t_u64));
|
ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, p, t_u64));
|
||||||
} else {
|
} else {
|
||||||
GB_PANIC("TODO(bill): Map Key type");
|
irValue *str = ir_emit_conv(proc, key, t_string);
|
||||||
|
irValue *hashed_str = NULL;
|
||||||
|
|
||||||
|
if (str->kind == irValue_Constant) {
|
||||||
|
ExactValue ev = str->Constant.value;
|
||||||
|
GB_ASSERT(ev.kind == ExactValue_String);
|
||||||
|
u64 hs = gb_fnv64a(ev.value_string.text, ev.value_string.len);
|
||||||
|
hashed_str = ir_make_const_u64(proc->module->allocator, hs);
|
||||||
|
} else {
|
||||||
|
irValue **args = gb_alloc_array(proc->module->allocator, irValue *, 1);
|
||||||
|
args[0] = str;
|
||||||
|
hashed_str = ir_emit_global_call(proc, "__default_hash_string", args, 1);
|
||||||
|
}
|
||||||
|
ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), hashed_str);
|
||||||
|
ir_emit_store(proc, ir_emit_struct_ep(proc, v, 1), str);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ir_emit_load(proc, v);
|
return ir_emit_load(proc, v);
|
||||||
@@ -4355,6 +4371,7 @@ void ir_emit_increment(irProcedure *proc, irValue *addr) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, irValue *count_ptr,
|
void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, irValue *count_ptr,
|
||||||
irValue **val_, irValue **idx_, irBlock **loop_, irBlock **done_) {
|
irValue **val_, irValue **idx_, irBlock **loop_, irBlock **done_) {
|
||||||
irValue *count = NULL;
|
irValue *count = NULL;
|
||||||
@@ -4374,6 +4391,11 @@ void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, ir
|
|||||||
irBlock *done = NULL;
|
irBlock *done = NULL;
|
||||||
irBlock *body = NULL;
|
irBlock *body = NULL;
|
||||||
|
|
||||||
|
irValue *key = NULL;
|
||||||
|
if (expr_type->kind == Type_Map) {
|
||||||
|
key = ir_add_local_generated(proc, expr_type->Map.key);
|
||||||
|
}
|
||||||
|
|
||||||
irValue *index = ir_add_local_generated(proc, t_int);
|
irValue *index = ir_add_local_generated(proc, t_int);
|
||||||
ir_emit_store(proc, index, ir_make_const_int(proc->module->allocator, -1));
|
ir_emit_store(proc, index, ir_make_const_int(proc->module->allocator, -1));
|
||||||
|
|
||||||
@@ -4410,6 +4432,26 @@ void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, ir
|
|||||||
irValue *elem = ir_emit_struct_ep(proc, expr, 0);
|
irValue *elem = ir_emit_struct_ep(proc, expr, 0);
|
||||||
elem = ir_emit_load(proc, elem);
|
elem = ir_emit_load(proc, elem);
|
||||||
val = ir_emit_load(proc, ir_emit_ptr_offset(proc, elem, idx));
|
val = ir_emit_load(proc, ir_emit_ptr_offset(proc, elem, idx));
|
||||||
|
} break;
|
||||||
|
case Type_Map: {
|
||||||
|
irValue *entries = ir_emit_struct_ep(proc, expr, 1);
|
||||||
|
irValue *elem = ir_emit_struct_ep(proc, entries, 0);
|
||||||
|
elem = ir_emit_load(proc, elem);
|
||||||
|
|
||||||
|
irValue *entry = ir_emit_ptr_offset(proc, elem, idx);
|
||||||
|
val = ir_emit_load(proc, ir_emit_struct_ep(proc, entry, 2));
|
||||||
|
|
||||||
|
irValue *hash = ir_emit_struct_ep(proc, entry, 0);
|
||||||
|
if (is_type_string(expr_type->Map.key)) {
|
||||||
|
irValue *str = ir_emit_struct_ep(proc, hash, 1);
|
||||||
|
ir_emit_store(proc, key, ir_emit_load(proc, str));
|
||||||
|
} else {
|
||||||
|
irValue *hash_ptr = ir_emit_struct_ep(proc, hash, 0);
|
||||||
|
hash_ptr = ir_emit_conv(proc, hash_ptr, ir_type(key));
|
||||||
|
ir_emit_store(proc, key, ir_emit_load(proc, hash_ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
GB_PANIC("Cannot do range_indexed of %s", type_to_string(expr_type));
|
GB_PANIC("Cannot do range_indexed of %s", type_to_string(expr_type));
|
||||||
@@ -4417,6 +4459,10 @@ void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, ir
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key != NULL) {
|
||||||
|
idx = ir_emit_load(proc, key);
|
||||||
|
}
|
||||||
|
|
||||||
if (val_) *val_ = val;
|
if (val_) *val_ = val;
|
||||||
if (idx_) *idx_ = idx;
|
if (idx_) *idx_ = idx;
|
||||||
if (loop_) *loop_ = loop;
|
if (loop_) *loop_ = loop;
|
||||||
@@ -4965,6 +5011,16 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
|
|||||||
Type *expr_type = type_of_expr(proc->module->info, rs->expr);
|
Type *expr_type = type_of_expr(proc->module->info, rs->expr);
|
||||||
Type *et = base_type(type_deref(expr_type));
|
Type *et = base_type(type_deref(expr_type));
|
||||||
switch (et->kind) {
|
switch (et->kind) {
|
||||||
|
case Type_Map: {
|
||||||
|
irAddr addr = ir_build_addr(proc, rs->expr);
|
||||||
|
irValue *map = addr.addr;
|
||||||
|
if (is_type_pointer(type_deref(ir_addr_type(addr)))) {
|
||||||
|
map = ir_addr_load(proc, addr);
|
||||||
|
}
|
||||||
|
irValue *entries_ptr = ir_emit_struct_ep(proc, map, 1);
|
||||||
|
irValue *count_ptr = ir_emit_struct_ep(proc, entries_ptr, 1);
|
||||||
|
ir_build_range_indexed(proc, map, val_type, count_ptr, &val, &index, &loop, &done);
|
||||||
|
} break;
|
||||||
case Type_Array: {
|
case Type_Array: {
|
||||||
irValue *count_ptr = NULL;
|
irValue *count_ptr = NULL;
|
||||||
irValue *array = ir_build_addr(proc, rs->expr).addr;
|
irValue *array = ir_build_addr(proc, rs->expr).addr;
|
||||||
|
|||||||
Reference in New Issue
Block a user