113 lines
2.2 KiB
Go
113 lines
2.2 KiB
Go
package types
|
|
|
|
type ValueType byte
|
|
|
|
const (
|
|
TypeNull ValueType = iota
|
|
TypeNumber
|
|
TypeString
|
|
TypeBoolean
|
|
TypeTable // New type for tables
|
|
)
|
|
|
|
type Value struct {
|
|
Type ValueType
|
|
Data any
|
|
}
|
|
|
|
func NewNull() Value {
|
|
return Value{Type: TypeNull, Data: nil}
|
|
}
|
|
|
|
func NewString(s string) Value {
|
|
return Value{Type: TypeString, Data: s}
|
|
}
|
|
|
|
func NewNumber(n float64) Value {
|
|
return Value{Type: TypeNumber, Data: n}
|
|
}
|
|
|
|
// TableEntry maintains insertion order
|
|
type TableEntry struct {
|
|
Key Value
|
|
Value Value
|
|
}
|
|
|
|
// Table with ordered entries
|
|
type Table struct {
|
|
Entries []TableEntry // Preserves insertion order
|
|
HashMap map[string]int // Fast lookups for string keys
|
|
NumMap map[float64]int // Fast lookups for number keys
|
|
BoolMap map[bool]int // Fast lookups for boolean keys
|
|
}
|
|
|
|
func NewTable() *Table {
|
|
return &Table{
|
|
Entries: []TableEntry{},
|
|
HashMap: make(map[string]int),
|
|
NumMap: make(map[float64]int),
|
|
BoolMap: make(map[bool]int),
|
|
}
|
|
}
|
|
|
|
func NewTableValue() Value {
|
|
return Value{Type: TypeTable, Data: NewTable()}
|
|
}
|
|
|
|
// TableSet preserves insertion order
|
|
func (t *Table) Set(key, value Value) {
|
|
idx := -1
|
|
|
|
switch key.Type {
|
|
case TypeString:
|
|
if i, ok := t.HashMap[key.Data.(string)]; ok {
|
|
idx = i
|
|
}
|
|
case TypeNumber:
|
|
if i, ok := t.NumMap[key.Data.(float64)]; ok {
|
|
idx = i
|
|
}
|
|
case TypeBoolean:
|
|
if i, ok := t.BoolMap[key.Data.(bool)]; ok {
|
|
idx = i
|
|
}
|
|
}
|
|
|
|
if idx >= 0 {
|
|
// Update existing entry
|
|
t.Entries[idx].Value = value
|
|
} else {
|
|
// Add new entry
|
|
t.Entries = append(t.Entries, TableEntry{Key: key, Value: value})
|
|
idx = len(t.Entries) - 1
|
|
|
|
// Update lookup maps
|
|
switch key.Type {
|
|
case TypeString:
|
|
t.HashMap[key.Data.(string)] = idx
|
|
case TypeNumber:
|
|
t.NumMap[key.Data.(float64)] = idx
|
|
case TypeBoolean:
|
|
t.BoolMap[key.Data.(bool)] = idx
|
|
}
|
|
}
|
|
}
|
|
|
|
func (t *Table) Get(key Value) Value {
|
|
switch key.Type {
|
|
case TypeString:
|
|
if i, ok := t.HashMap[key.Data.(string)]; ok {
|
|
return t.Entries[i].Value
|
|
}
|
|
case TypeNumber:
|
|
if i, ok := t.NumMap[key.Data.(float64)]; ok {
|
|
return t.Entries[i].Value
|
|
}
|
|
case TypeBoolean:
|
|
if i, ok := t.BoolMap[key.Data.(bool)]; ok {
|
|
return t.Entries[i].Value
|
|
}
|
|
}
|
|
return NewNull()
|
|
}
|