intern identifiers

This commit is contained in:
2026-06-10 21:27:00 +02:00
parent d6e03b6f08
commit cdbe4fbc99
16 changed files with 497 additions and 182 deletions
+58
View File
@@ -0,0 +1,58 @@
package symbol
import "core:mem"
import "core:strings"
Id :: distinct u32
INVALID :: Id(0)
Table :: struct {
items: [dynamic]string,
lookup: map[string]Id,
stored_bytes: int,
allocator: mem.Allocator,
}
init_table :: proc(allocator := context.allocator) -> Table {
table: Table
table.items.allocator = allocator
table.lookup.allocator = allocator
table.allocator = allocator
return table
}
destroy_table :: proc(table: ^Table) {
delete(table.lookup)
for item in table.items {
delete(item, table.allocator)
}
delete(table.items)
}
intern :: proc(table: ^Table, text: string) -> Id {
if len(text) == 0 {
return INVALID
}
if id, ok := table.lookup[text]; ok {
return id
}
cloned := strings.clone(text, table.allocator)
id := Id(len(table.items) + 1)
append(&table.items, cloned)
table.lookup[cloned] = id
table.stored_bytes += len(cloned)
return id
}
resolve :: proc(table: ^Table, id: Id) -> string {
index := int(id) - 1
if index < 0 || index >= len(table.items) {
return ""
}
return table.items[index]
}
is_valid :: proc(id: Id) -> bool {
return id != INVALID
}