package compiler // Opcode represents a single bytecode instruction type Opcode uint8 const ( // Stack Operations OpLoadConst Opcode = iota // Load constant onto stack [idx] OpLoadLocal // Load local variable [slot] OpStoreLocal // Store top of stack to local [slot] OpLoadGlobal // Load global variable [idx] OpStoreGlobal // Store top of stack to global [idx] OpPop // Pop top value from stack OpDup // Duplicate top value on stack // Arithmetic Operations OpAdd // a + b OpSub // a - b OpMul // a * b OpDiv // a / b OpNeg // -a OpMod // a % b // Comparison Operations OpEq // a == b OpNeq // a != b OpLt // a < b OpLte // a <= b OpGt // a > b OpGte // a >= b // Logical Operations OpNot // not a OpAnd // a and b OpOr // a or b // Control Flow OpJump // Unconditional jump [offset] OpJumpIfTrue // Jump if top of stack is true [offset] OpJumpIfFalse // Jump if top of stack is false [offset] OpCall // Call function [argCount] OpReturn // Return from function OpReturnNil // Return nil from function // Table Operations OpNewTable // Create new empty table OpGetIndex // table[key] -> value OpSetIndex // table[key] = value OpGetField // table.field -> value [fieldIdx] OpSetField // table.field = value [fieldIdx] OpTableInsert // Insert value into table at next index // Struct Operations OpNewStruct // Create new struct instance [structId] OpGetProperty // struct.field -> value [fieldIdx] OpSetProperty // struct.field = value [fieldIdx] OpCallMethod // Call method on struct [methodIdx, argCount] // Function Operations OpClosure // Create closure from function [funcIdx, upvalueCount] OpGetUpvalue // Get upvalue [idx] OpSetUpvalue // Set upvalue [idx] OpCloseUpvalue // Close upvalue (move to heap) // Array Operations OpNewArray // Create new array with size [size] OpArrayAppend // Append value to array // Type Operations OpGetType // Get type of value on stack OpCast // Cast value to type [typeId] // I/O Operations OpEcho // Echo value to output OpExit // Exit with code // Special Operations OpNoop // No operation OpBreak // Break from loop OpContinue // Continue loop iteration // Debug Operations OpDebugPrint // Debug print stack top OpDebugStack // Debug print entire stack ) // Instruction represents a single bytecode instruction with operands type Instruction struct { Op Opcode Operands []uint16 // Variable length operands } // Chunk represents a compiled chunk of bytecode type Chunk struct { Code []uint8 // Raw bytecode stream Constants []Value // Constant pool Lines []int // Line numbers for debugging Functions []Function // Function definitions Structs []Struct // Struct definitions } // Value represents a runtime value in the VM type Value struct { Type ValueType Data any // Actual value data } // ValueType represents the type of a runtime value type ValueType uint8 const ( ValueNil ValueType = iota ValueBool ValueNumber ValueString ValueTable ValueFunction ValueStruct ValueArray ValueUpvalue ) // Function represents a compiled function type Function struct { Name string // Function name (empty for anonymous) Arity int // Number of parameters Variadic bool // Whether function accepts variable args LocalCount int // Number of local variable slots UpvalCount int // Number of upvalues Chunk Chunk // Function bytecode Defaults []Value // Default parameter values } // Struct represents a compiled struct definition type Struct struct { Name string // Struct name Fields []StructField // Field definitions Methods map[string]uint16 // Method name -> function index ID uint16 // Unique struct identifier } // StructField represents a field in a struct type StructField struct { Name string // Field name Type ValueType // Field type Offset uint16 // Offset in struct layout } // Table represents a key-value table/map type Table struct { Array map[int]Value // Array part (integer keys) Hash map[string]Value // Hash part (string keys) Meta *Table // Metatable for operations } // Array represents a dynamic array type Array struct { Elements []Value // Array elements Count int // Current element count Capacity int // Current capacity } // StructInstance represents an instance of a struct type StructInstance struct { StructID uint16 // Reference to struct definition Fields map[string]Value // Field values } // Upvalue represents a captured variable type Upvalue struct { Location *Value // Pointer to actual value location Closed Value // Closed-over value (when moved to heap) IsClosed bool // Whether upvalue has been closed } // Instruction encoding helpers // EncodeInstruction encodes an instruction into bytecode func EncodeInstruction(op Opcode, operands ...uint16) []uint8 { bytes := []uint8{uint8(op)} for _, operand := range operands { bytes = append(bytes, uint8(operand&0xFF), uint8(operand>>8)) } return bytes } // DecodeInstruction decodes bytecode into instruction func DecodeInstruction(code []uint8, offset int) (Opcode, []uint16, int) { if offset >= len(code) { return OpNoop, nil, offset } op := Opcode(code[offset]) operands := []uint16{} nextOffset := offset + 1 // Decode operands based on instruction type operandCount := GetOperandCount(op) for range operandCount { if nextOffset+1 >= len(code) { break } operand := uint16(code[nextOffset]) | (uint16(code[nextOffset+1]) << 8) operands = append(operands, operand) nextOffset += 2 } return op, operands, nextOffset } // GetOperandCount returns the number of operands for an instruction func GetOperandCount(op Opcode) int { switch op { case OpLoadConst, OpLoadLocal, OpStoreLocal, OpLoadGlobal, OpStoreGlobal: return 1 case OpJump, OpJumpIfTrue, OpJumpIfFalse: return 1 case OpCall, OpNewStruct, OpGetField, OpSetField, OpGetProperty, OpSetProperty: return 1 case OpCallMethod: return 2 case OpClosure: return 2 case OpNewArray, OpCast: return 1 default: return 0 } } // Instruction size calculation func InstructionSize(op Opcode) int { return 1 + (GetOperandCount(op) * 2) // 1 byte opcode + 2 bytes per operand } var opcodeNames = map[Opcode]string{ OpLoadConst: "OP_LOAD_CONST", OpLoadLocal: "OP_LOAD_LOCAL", OpStoreLocal: "OP_STORE_LOCAL", OpAdd: "OP_ADD", OpSub: "OP_SUB", OpMul: "OP_MUL", OpDiv: "OP_DIV", OpJump: "OP_JUMP", OpJumpIfTrue: "OP_JUMP_TRUE", OpJumpIfFalse: "OP_JUMP_FALSE", OpReturn: "OP_RETURN", OpEcho: "OP_ECHO", }