vm.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /**
  2. ******************************************************************************
  3. * @file : vm.c
  4. * @author : simon
  5. * @brief : Interpret the bytecode from chunk
  6. * @attention : None
  7. * @date : 2023/8/17
  8. ******************************************************************************
  9. */
  10. #include "common.h"
  11. #include "vm.h"
  12. #include "debug.h"
  13. VM vm;
  14. /// \brief 重置栈
  15. static void resetStack() {
  16. vm.stackTop = vm.stack; // 指针指向栈顶
  17. }
  18. void initVM() {
  19. resetStack();
  20. }
  21. static InterpretResult run() {
  22. //! <macro> reads the byte currently pointed at by ip
  23. //! and then advances the instruction pointer
  24. #define READ_BYTE() (*vm.ip++)
  25. //! reads the next byte from the bytecode
  26. //! treats the resulting number as an index
  27. #define READ_CONSTANT() (vm.chunk->constants.values[READ_BYTE()])
  28. #define BINARY_OP(op) \
  29. do { \
  30. double b = pop(); \
  31. double a = pop(); \
  32. push(a op b); \
  33. } while(false)
  34. for (;;) {
  35. #ifdef DEBUG_TRACE_EXECUTION
  36. //! <Stack tracing> start
  37. printf("------------------------\n|");
  38. for (Value *slot = vm.stack; slot < vm.stackTop; slot++) {
  39. printf("[ ");
  40. printValue(*slot);
  41. printf(" ]");
  42. }
  43. printf("\n------------------------");
  44. printf("\n");
  45. //! <Stack tracing> end
  46. disassembleInstruction(vm.chunk, (int) (vm.ip - vm.chunk->code));
  47. #endif
  48. uint8_t instruction;
  49. switch (instruction = READ_BYTE()) {
  50. case OP_CONSTANT: {
  51. Value constant = READ_CONSTANT();
  52. push(constant);
  53. break;
  54. }
  55. case OP_ADD: BINARY_OP(+);
  56. break;
  57. case OP_SUBTRACT: BINARY_OP(-);
  58. break;
  59. case OP_MULTIPLY: BINARY_OP(*);
  60. break;
  61. case OP_DIVIDE: BINARY_OP(/);
  62. break;
  63. case OP_NEGATE: push(-pop());
  64. break;
  65. case OP_RETURN: {
  66. printValue(pop());
  67. printf("\n");
  68. return INTERPRET_OK;
  69. }
  70. }
  71. }
  72. #undef READ_BYTE
  73. #undef READ_CONSTANT
  74. #undef BINARY_OP
  75. }
  76. void freeVM() {
  77. }
  78. InterpretResult interpret(Chunk *chunk) {
  79. vm.chunk = chunk;
  80. vm.ip = vm.chunk->code;
  81. return run();
  82. }
  83. void push(Value value) {
  84. *vm.stackTop = value;
  85. vm.stackTop++;
  86. }
  87. Value pop() {
  88. vm.stackTop--;
  89. //! NOTE: 出栈后,里面的值没有清除
  90. return *vm.stackTop;
  91. }