delete for maps

This commit is contained in:
Ginger Bill
2017-02-19 11:50:42 +00:00
parent 758dd9ba16
commit 3cec2550d9
5 changed files with 60 additions and 16 deletions

View File

@@ -8,6 +8,13 @@
#import "halloc.odin";
main :: proc() {
m: map[int]int;
m[123] = 312;
fmt.println(m[123]);
delete(m, 123);
fmt.println(m[123]);
/*
/*
Version 0.1.1

View File

@@ -633,7 +633,7 @@ __dynamic_map_add_entry :: proc(using h: __Map_Header, key: __Map_Key) -> int {
}
__dynamic_map_remove :: proc(using h: __Map_Header, key: __Map_Key) {
__dynamic_map_delete :: proc(using h: __Map_Header, key: __Map_Key) {
fr := __dynamic_map_find(h, key);
if fr.entry_index >= 0 {
__dynamic_map_erase(h, fr);

View File

@@ -2643,7 +2643,6 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
gbString sel_str = expr_to_string(selector);
error_node(op_expr, "`%s` is not exported by `%.*s`", sel_str, LIT(name));
gb_string_free(sel_str);
// NOTE(bill): Not really an error so don't goto error
goto error;
}
@@ -2966,7 +2965,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
} break;
case BuiltinProc_append: {
// append :: proc([dynamic]Type, item: ...Type) {
// append :: proc([dynamic]Type, item: ...Type)
Type *type = operand->type;
type = base_type(type);
if (!is_type_dynamic_array(type)) {
@@ -2996,6 +2995,37 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->type = t_int;
} break;
case BuiltinProc_delete: {
// delete :: proc(map[Key]Value, key: Key)
Type *type = operand->type;
if (!is_type_map(type)) {
gbString str = type_to_string(type);
error_node(operand->expr, "Expected a map, got `%s`", str);
gb_string_free(str);
return false;
}
Type *key = base_type(type)->Map.key;
Operand x = {Addressing_Invalid};
AstNode *key_node = ce->args.e[1];
Operand op = {0};
check_expr(c, &op, key_node);
if (op.mode == Addressing_Invalid) {
return false;
}
if (!check_is_assignable_to(c, &op, key)) {
gbString kt = type_to_string(key);
gbString ot = type_to_string(op.type);
error_node(operand->expr, "Expected a key of type `%s`, got `%s`", key, ot);
gb_string_free(ot);
gb_string_free(kt);
return false;
}
operand->mode = Addressing_NoValue;
} break;
case BuiltinProc_size_of: {
// size_of :: proc(Type) -> untyped int

View File

@@ -30,6 +30,7 @@ typedef enum BuiltinProcId {
BuiltinProc_reserve,
BuiltinProc_clear,
BuiltinProc_append,
BuiltinProc_delete,
BuiltinProc_size_of,
BuiltinProc_size_of_val,
@@ -73,6 +74,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
{STR_LIT("reserve"), 2, false, Expr_Stmt},
{STR_LIT("clear"), 1, false, Expr_Stmt},
{STR_LIT("append"), 1, true, Expr_Expr},
{STR_LIT("delete"), 2, false, Expr_Stmt},
{STR_LIT("size_of"), 1, false, Expr_Expr},
{STR_LIT("size_of_val"), 1, false, Expr_Expr},
@@ -1715,12 +1717,6 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
continue;
}
if (id->is_import) {
// String gpa = str_lit("GetProcAddress");
// if (str_eq(e->token.string, gpa)) {
// Entity *f = scope_lookup_entity(parent_scope, gpa);
// gb_printf_err("%.*s %.*s %td\n", LIT(gpa), LIT(f->token.pos.file), entity_procedure_overload_count(f));
// }
if (is_entity_exported(e)) {
// TODO(bill): Should these entities be imported but cause an error when used?
bool ok = add_entity(c, parent_scope, NULL, e);
@@ -1728,12 +1724,6 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
map_bool_set(&parent_scope->implicit, hash_pointer(e), true);
}
}
// if (str_eq(e->token.string, gpa)) {
// Entity *f = scope_lookup_entity(parent_scope, gpa);
// gb_printf_err("%.*s %.*s %td\n", LIT(gpa), LIT(f->token.pos.file), entity_procedure_overload_count(f));
// }
} else {
add_entity(c, parent_scope, NULL, e);
}

View File

@@ -3244,7 +3244,7 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
args[3] = capacity;
return ir_emit_global_call(proc, "__dynamic_array_reserve", args, 4);
} else if (is_type_dynamic_map(type)) {
irValue **args = gb_alloc_array(a, irValue *, 4);
irValue **args = gb_alloc_array(a, irValue *, 2);
args[0] = ir_gen_map_header(proc, ptr, type);
args[1] = capacity;
return ir_emit_global_call(proc, "__dynamic_map_reserve", args, 2);
@@ -3360,6 +3360,23 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
return ir_emit_global_call(proc, "__dynamic_array_append", daa_args, 5);
} break;
case BuiltinProc_delete: {
ir_emit_comment(proc, str_lit("delete"));
irValue *map = ir_build_expr(proc, ce->args.e[0]);
irValue *key = ir_build_expr(proc, ce->args.e[1]);
Type *map_type = ir_type(map);
GB_ASSERT(is_type_dynamic_map(map_type));
Type *key_type = base_type(map_type)->Map.key;
irValue *addr = ir_address_from_load_or_generate_local(proc, map);
gbAllocator a = proc->module->allocator;
irValue **args = gb_alloc_array(a, irValue *, 2);
args[0] = ir_gen_map_header(proc, addr, map_type);
args[1] = ir_gen_map_key(proc, key, key_type);
return ir_emit_global_call(proc, "__dynamic_map_delete", args, 2);
} break;
case BuiltinProc_assert: {
ir_emit_comment(proc, str_lit("assert"));