package compiler
// Opcode represents a single byte operation code.
type Opcode = byte
// List of opcodes
const (
OpConstant Opcode = iota // Load constant
OpAdd // Add
OpSub // Sub
OpMul // Multiply
OpDiv // Divide
OpRem // Remainder
OpBAnd // bitwise AND
OpBOr // bitwise OR
OpBXor // bitwise XOR
OpBShiftLeft // bitwise shift left
OpBShiftRight // bitwise shift right
OpBAndNot // bitwise AND NOT
OpBComplement // bitwise complement
OpPop // Pop
OpTrue // Push true
OpFalse // Push false
OpEqual // Equal ==
OpNotEqual // Not equal !=
OpGreaterThan // Greater than >=
OpGreaterThanEqual // Greater than or equal to >=
OpMinus // Minus -
OpLNot // Logical not !
OpJumpFalsy // Jump if falsy
OpAndJump // Logical AND jump
OpOrJump // Logical OR jump
OpJump // Jump
OpNull // Push null
OpArray // Array object
OpMap // Map object
OpError // Error object
OpImmutable // Immutable object
OpIndex // Index operation
OpSliceIndex // Slice operation
OpCall // Call function
OpReturn // Return
OpReturnValue // Return value
OpGetGlobal // Get global variable
OpSetGlobal // Set global variable
OpSetSelGlobal // Set global variable using selectors
OpGetLocal // Get local variable
OpSetLocal // Set local variable
OpDefineLocal // Define local variable
OpSetSelLocal // Set local variable using selectors
OpGetFree // Get free variables
OpSetFree // Set free variables
OpSetSelFree // Set free variables using selectors
OpGetBuiltin // Get builtin function
OpGetBuiltinModule // Get builtin module
OpClosure // Push closure
OpIteratorInit // Iterator init
OpIteratorNext // Iterator next
OpIteratorKey // Iterator key
OpIteratorValue // Iterator value
)
// OpcodeNames is opcode names.
var OpcodeNames = [...]string{
OpConstant: "CONST",
OpPop: "POP",
OpTrue: "TRUE",
OpFalse: "FALSE",
OpAdd: "ADD",
OpSub: "SUB",
OpMul: "MUL",
OpDiv: "DIV",
OpRem: "REM",
OpBAnd: "AND",
OpBOr: "OR",
OpBXor: "XOR",
OpBAndNot: "ANDN",
OpBShiftLeft: "SHL",
OpBShiftRight: "SHR",
OpBComplement: "NEG",
OpEqual: "EQL",
OpNotEqual: "NEQ",
OpGreaterThan: "GTR",
OpGreaterThanEqual: "GEQ",
OpMinus: "NEG",
OpLNot: "NOT",
OpJumpFalsy: "JMPF",
OpAndJump: "ANDJMP",
OpOrJump: "ORJMP",
OpJump: "JMP",
OpNull: "NULL",
OpGetGlobal: "GETG",
OpSetGlobal: "SETG",
OpSetSelGlobal: "SETSG",
OpArray: "ARR",
OpMap: "MAP",
OpError: "ERROR",
OpImmutable: "IMMUT",
OpIndex: "INDEX",
OpSliceIndex: "SLICE",
OpCall: "CALL",
OpReturn: "RET",
OpReturnValue: "RETVAL",
OpGetLocal: "GETL",
OpSetLocal: "SETL",
OpDefineLocal: "DEFL",
OpSetSelLocal: "SETSL",
OpGetBuiltin: "BUILTIN",
OpGetBuiltinModule: "BLTMOD",
OpClosure: "CLOSURE",
OpGetFree: "GETF",
OpSetFree: "SETF",
OpSetSelFree: "SETSF",
OpIteratorInit: "ITER",
OpIteratorNext: "ITNXT",
OpIteratorKey: "ITKEY",
OpIteratorValue: "ITVAL",
}
// OpcodeOperands is the number of operands.
var OpcodeOperands = [...][]int{
OpConstant: {2},
OpPop: {},
OpTrue: {},
OpFalse: {},
OpAdd: {},
OpSub: {},
OpMul: {},
OpDiv: {},
OpRem: {},
OpBAnd: {},
OpBOr: {},
OpBXor: {},
OpBAndNot: {},
OpBShiftLeft: {},
OpBShiftRight: {},
OpBComplement: {},
OpEqual: {},
OpNotEqual: {},
OpGreaterThan: {},
OpGreaterThanEqual: {},
OpMinus: {},
OpLNot: {},
OpJumpFalsy: {2},
OpAndJump: {2},
OpOrJump: {2},
OpJump: {2},
OpNull: {},
OpGetGlobal: {2},
OpSetGlobal: {2},
OpSetSelGlobal: {2, 1},
OpArray: {2},
OpMap: {2},
OpError: {},
OpImmutable: {},
OpIndex: {},
OpSliceIndex: {},
OpCall: {1},
OpReturn: {},
OpReturnValue: {},
OpGetLocal: {1},
OpSetLocal: {1},
OpDefineLocal: {1},
OpSetSelLocal: {1, 1},
OpGetBuiltin: {1},
OpGetBuiltinModule: {},
OpClosure: {2, 1},
OpGetFree: {1},
OpSetFree: {1},
OpSetSelFree: {1, 1},
OpIteratorInit: {},
OpIteratorNext: {},
OpIteratorKey: {},
OpIteratorValue: {},
}
// ReadOperands reads operands from the bytecode.
func ReadOperands(numOperands []int, ins []byte) (operands []int, offset int) {
for _, width := range numOperands {
switch width {
case 1:
operands = append(operands, int(ins[offset]))
case 2:
operands = append(operands, int(ins[offset+1])|int(ins[offset])<<8)
}
offset += width
}
return
}