HashMap is now Printable. Fix access inlining for enums. #1958

This commit is contained in:
Christoffer Lerno
2025-02-12 23:11:46 +01:00
parent c9ecb09cd7
commit 1f856cacf5
6 changed files with 55 additions and 6 deletions

View File

@@ -6,8 +6,9 @@
*>
module std::collections::map(<Key, Value>);
import std::math;
import std::io @norecurse;
struct HashMap
struct HashMap (Printable)
{
Entry*[] table;
Allocator allocator;
@@ -446,6 +447,18 @@ fn void HashMap.resize(&map, uint new_capacity) @private
map.threshold = (uint)(new_capacity * map.load_factor);
}
fn usz! HashMap.to_format(&self, Formatter* f) @dynamic
{
usz len;
len += f.print("{ ")!;
self.@each_entry(; Entry* entry)
{
if (len > 2) len += f.print(", ")!;
len += f.printf("%s: %s", entry.key, entry.value)!;
};
return len + f.print(" }");
}
fn void HashMap.transfer(&map, Entry*[] new_table) @private
{
Entry*[] src = map.table;

View File

@@ -76,6 +76,7 @@
- New unit test default runner.
- Added weakly linked `fmodf`.
- Add `@select` to perform the equivalent of `a ? x : y` at compile time.
- `HashMap` is now `Printable`.
## 0.6.6 Change list

View File

@@ -1089,7 +1089,7 @@ const char *llvm_codegen(void *context)
void llvm_add_global_decl(GenContext *c, Decl *decl)
{
ASSERT(decl->var.kind == VARDECL_GLOBAL || decl->var.kind == VARDECL_CONST);
ASSERT_SPAN(decl, decl->var.kind == VARDECL_GLOBAL || decl->var.kind == VARDECL_CONST);
bool same_module = decl->unit->module == c->code_module;
LLVMTypeRef type = llvm_get_type(c, decl->type);
@@ -1282,7 +1282,7 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl)
{
return decl->backend_ref = llvm_get_ref(c, decl->var.alias);
}
ASSERT(decl->var.kind == VARDECL_GLOBAL || decl->var.kind == VARDECL_CONST);
ASSERT_SPAN(decl, decl->var.kind == VARDECL_GLOBAL || decl->var.kind == VARDECL_CONST);
llvm_add_global_decl(c, decl);
return decl->backend_ref;
case DECL_FUNC:

View File

@@ -1767,7 +1767,6 @@ static void cast_enum_to_value(Expr* expr, Type *to_type)
cast_int_to_int(expr, to_type);
return;
}
if (expr_is_const_enum(expr))
{
expr_replace(expr, copy_expr_single(expr->const_expr.enum_err_val->enum_constant.args[decl->enums.inline_index]));

View File

@@ -277,14 +277,27 @@ Expr *sema_enter_inline_member(Expr *parent, CanonicalType *type)
{
Decl *decl = type->decl;
if (!decl->is_substruct) return NULL;
if (parent->expr_kind == EXPR_CONST)
{
return copy_expr_single(parent->const_expr.enum_err_val->enum_constant.args[0]);
if (decl->enums.inline_value)
{
Expr *expr = expr_new_expr(EXPR_CONST, parent);
expr_rewrite_const_int(expr, decl->enums.type_info->type, parent->const_expr.enum_err_val->enum_constant.ordinal);
return expr;
}
return copy_expr_single(parent->const_expr.enum_err_val->enum_constant.args[decl->enums.inline_index]);
}
if (decl->enums.inline_value)
{
Expr *expr = copy_expr_single(parent);
expr->type = decl->enums.type_info->type;
return expr;
}
Expr *property = expr_new(EXPR_ACCESS_RESOLVED, parent->span);
property->resolve_status = RESOLVE_DONE;
property->access_resolved_expr.parent = parent;
property->access_resolved_expr.ref = decl->enums.parameters[0];
property->access_resolved_expr.ref = decl->enums.parameters[decl->enums.inline_value];
property->type = property->access_resolved_expr.ref->type;
return property;
}

View File

@@ -56,6 +56,29 @@ fn void map()
}
}
def FooMap = HashMap(<char, Foobar>);
enum Foobar : inline char
{
FOO,
BAR,
BAZ
}
enum Foobar2 : int (inline char y)
{
ABC = 3,
DEF = 5,
}
fn void map_inline_enum()
{
FooMap x;
x[Foobar.BAZ] = FOO;
x[Foobar2.ABC] = BAR;
test::eq(string::tformat("%s", x), "{ 2: FOO, 3: BAR }");
x.free();
}
fn void map_remove()
{
TestHashMap m;