opcodes.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package parser
  2. // Opcode represents a single byte operation code.
  3. type Opcode = byte
  4. // List of opcodes
  5. const (
  6. OpConstant Opcode = iota // Load constant
  7. OpBComplement // bitwise complement
  8. OpPop // Pop
  9. OpTrue // Push true
  10. OpFalse // Push false
  11. OpEqual // Equal ==
  12. OpNotEqual // Not equal !=
  13. OpMinus // Minus -
  14. OpLNot // Logical not !
  15. OpJumpFalsy // Jump if falsy
  16. OpAndJump // Logical AND jump
  17. OpOrJump // Logical OR jump
  18. OpJump // Jump
  19. OpNull // Push null
  20. OpArray // Array object
  21. OpMap // Map object
  22. OpError // Error object
  23. OpImmutable // Immutable object
  24. OpIndex // Index operation
  25. OpSliceIndex // Slice operation
  26. OpCall // Call function
  27. OpReturn // Return
  28. OpGetGlobal // Get global variable
  29. OpSetGlobal // Set global variable
  30. OpSetSelGlobal // Set global variable using selectors
  31. OpGetLocal // Get local variable
  32. OpSetLocal // Set local variable
  33. OpDefineLocal // Define local variable
  34. OpSetSelLocal // Set local variable using selectors
  35. OpGetFreePtr // Get free variable pointer object
  36. OpGetFree // Get free variables
  37. OpSetFree // Set free variables
  38. OpGetLocalPtr // Get local variable as a pointer
  39. OpSetSelFree // Set free variables using selectors
  40. OpGetBuiltin // Get builtin function
  41. OpClosure // Push closure
  42. OpIteratorInit // Iterator init
  43. OpIteratorNext // Iterator next
  44. OpIteratorKey // Iterator key
  45. OpIteratorValue // Iterator value
  46. OpBinaryOp // Binary operation
  47. OpSuspend // Suspend VM
  48. )
  49. // OpcodeNames are string representation of opcodes.
  50. var OpcodeNames = [...]string{
  51. OpConstant: "CONST",
  52. OpPop: "POP",
  53. OpTrue: "TRUE",
  54. OpFalse: "FALSE",
  55. OpBComplement: "NEG",
  56. OpEqual: "EQL",
  57. OpNotEqual: "NEQ",
  58. OpMinus: "NEG",
  59. OpLNot: "NOT",
  60. OpJumpFalsy: "JMPF",
  61. OpAndJump: "ANDJMP",
  62. OpOrJump: "ORJMP",
  63. OpJump: "JMP",
  64. OpNull: "NULL",
  65. OpGetGlobal: "GETG",
  66. OpSetGlobal: "SETG",
  67. OpSetSelGlobal: "SETSG",
  68. OpArray: "ARR",
  69. OpMap: "MAP",
  70. OpError: "ERROR",
  71. OpImmutable: "IMMUT",
  72. OpIndex: "INDEX",
  73. OpSliceIndex: "SLICE",
  74. OpCall: "CALL",
  75. OpReturn: "RET",
  76. OpGetLocal: "GETL",
  77. OpSetLocal: "SETL",
  78. OpDefineLocal: "DEFL",
  79. OpSetSelLocal: "SETSL",
  80. OpGetBuiltin: "BUILTIN",
  81. OpClosure: "CLOSURE",
  82. OpGetFreePtr: "GETFP",
  83. OpGetFree: "GETF",
  84. OpSetFree: "SETF",
  85. OpGetLocalPtr: "GETLP",
  86. OpSetSelFree: "SETSF",
  87. OpIteratorInit: "ITER",
  88. OpIteratorNext: "ITNXT",
  89. OpIteratorKey: "ITKEY",
  90. OpIteratorValue: "ITVAL",
  91. OpBinaryOp: "BINARYOP",
  92. OpSuspend: "SUSPEND",
  93. }
  94. // OpcodeOperands is the number of operands.
  95. var OpcodeOperands = [...][]int{
  96. OpConstant: {2},
  97. OpPop: {},
  98. OpTrue: {},
  99. OpFalse: {},
  100. OpBComplement: {},
  101. OpEqual: {},
  102. OpNotEqual: {},
  103. OpMinus: {},
  104. OpLNot: {},
  105. OpJumpFalsy: {4},
  106. OpAndJump: {4},
  107. OpOrJump: {4},
  108. OpJump: {4},
  109. OpNull: {},
  110. OpGetGlobal: {2},
  111. OpSetGlobal: {2},
  112. OpSetSelGlobal: {2, 1},
  113. OpArray: {2},
  114. OpMap: {2},
  115. OpError: {},
  116. OpImmutable: {},
  117. OpIndex: {},
  118. OpSliceIndex: {},
  119. OpCall: {1, 1},
  120. OpReturn: {1},
  121. OpGetLocal: {1},
  122. OpSetLocal: {1},
  123. OpDefineLocal: {1},
  124. OpSetSelLocal: {1, 1},
  125. OpGetBuiltin: {1},
  126. OpClosure: {2, 1},
  127. OpGetFreePtr: {1},
  128. OpGetFree: {1},
  129. OpSetFree: {1},
  130. OpGetLocalPtr: {1},
  131. OpSetSelFree: {1, 1},
  132. OpIteratorInit: {},
  133. OpIteratorNext: {},
  134. OpIteratorKey: {},
  135. OpIteratorValue: {},
  136. OpBinaryOp: {1},
  137. OpSuspend: {},
  138. }
  139. // ReadOperands reads operands from the bytecode.
  140. func ReadOperands(numOperands []int, ins []byte) (operands []int, offset int) {
  141. for _, width := range numOperands {
  142. switch width {
  143. case 1:
  144. operands = append(operands, int(ins[offset]))
  145. case 2:
  146. operands = append(operands, int(ins[offset+1])|int(ins[offset])<<8)
  147. case 4:
  148. operands = append(operands, int(ins[offset+3])|int(ins[offset+2])<<8|int(ins[offset+1])<<16|int(ins[offset])<<24)
  149. }
  150. offset += width
  151. }
  152. return
  153. }