package types type ValueType byte const ( TypeNull ValueType = iota TypeNumber TypeString TypeBoolean TypeTable ) type Opcode byte const ( OpConstant Opcode = iota OpSetLocal OpGetLocal OpSetGlobal OpGetGlobal OpEcho OpNewTable OpSetIndex OpGetIndex OpDup OpPop OpEnterScope OpExitScope OpAdd OpSubtract OpMultiply OpDivide OpNegate OpJumpIfFalse OpJump OpEqual OpNotEqual OpLessThan OpGreaterThan OpLessEqual OpGreaterEqual ) type Instruction struct { Opcode Opcode Operand int } type Bytecode struct { Constants []any Instructions []Instruction } 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} } func NewBoolean(b bool) Value { return Value{Type: TypeBoolean, Data: b} } // 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() }