59 lines
1.1 KiB
Odin
59 lines
1.1 KiB
Odin
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
|
|
}
|