Ver código fonte

A Value Stack Manipulator

runningwater 2 anos atrás
pai
commit
47c84a77f1
5 arquivos alterados com 129 adições e 2 exclusões
  1. 0 1
      chunk.c
  2. 3 0
      common.h
  3. 5 1
      main.c
  4. 81 0
      vm.c
  5. 40 0
      vm.h

+ 0 - 1
chunk.c

@@ -3,7 +3,6 @@
 //
 #include "chunk.h"
 #include "memory.h"
-#include <stdlib.h>
 
 void initChunk(Chunk *chunk) {
   chunk->count = 0;

+ 3 - 0
common.h

@@ -8,5 +8,8 @@
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
+#include <stdio.h>
+
+#define DEBUG_TRACE_EXECUTION
 
 #endif//CLOX__COMMON_H_

+ 5 - 1
main.c

@@ -1,6 +1,7 @@
-#include "chunk.h"
 #include "common.h"
+#include "chunk.h"
 #include "debug.h"
+#include "vm.h"
 
 /*!
  * @brief 程序主入口
@@ -9,6 +10,7 @@
  * @return
  */
 int main(int argc, char *argv[]) {
+  initVM();
   Chunk chunk;
   initChunk(&chunk);
 
@@ -19,6 +21,8 @@ int main(int argc, char *argv[]) {
   writeChunk(&chunk, OP_RETURN, 123);
 
   disassembleChunk(&chunk, "test chunk");
+  interpret(&chunk);
+  freeVM();
   freeChunk(&chunk);
   return 0;
 }

+ 81 - 0
vm.c

@@ -0,0 +1,81 @@
+/**
+  ******************************************************************************
+  * @file           : vm.c
+  * @author         : simon
+  * @brief          : Interpret the bytecode from chunk
+  * @attention      : None
+  * @date           : 2023/8/17
+  ******************************************************************************
+  */
+#include "common.h"
+#include "vm.h"
+#include "debug.h"
+
+VM vm;
+
+/// \brief 重置栈
+static void resetStack() {
+  vm.stackTop = vm.stack; // 指针指向栈顶
+}
+
+void initVM() {
+  resetStack();
+}
+static InterpretResult run() {
+//! <macro> reads the byte currently pointed at by ip
+//! and then advances the instruction pointer
+#define READ_BYTE() (*vm.ip++)
+//! reads the next byte from the bytecode
+//! treats the resulting number as an index
+#define READ_CONSTANT() (vm.chunk->constants.values[READ_BYTE()])
+
+  for (;;) {
+#ifdef DEBUG_TRACE_EXECUTION
+    //! <Stack tracing> start
+    printf("------------------------\n|");
+    for (Value *slot = vm.stack; slot < vm.stackTop; slot++) {
+      printf("[ ");
+      printValue(*slot);
+      printf(" ]");
+    }
+    printf("\n------------------------");
+    printf("\n");
+    //! <Stack tracing> end
+    disassembleInstruction(vm.chunk, (int) (vm.ip - vm.chunk->code));
+#endif
+    uint8_t instruction;
+    switch (instruction = READ_BYTE()) {
+      case OP_CONSTANT: {
+        Value constant = READ_CONSTANT();
+        push(constant);
+        break;
+      }
+      case OP_RETURN: {
+        printValue(pop());
+        printf("\n");
+        return INTERPRET_OK;
+      }
+    }
+  }
+
+#undef READ_BYTE
+#undef READ_CONSTANT
+}
+void freeVM() {
+
+}
+InterpretResult interpret(Chunk *chunk) {
+  vm.chunk = chunk;
+  vm.ip = vm.chunk->code;
+  return run();
+}
+void push(Value value) {
+  *vm.stackTop = value;
+  vm.stackTop++;
+}
+Value pop() {
+  vm.stackTop--;
+  //! NOTE: 出栈后,里面的值没有清除
+  return *vm.stackTop;
+}
+

+ 40 - 0
vm.h

@@ -0,0 +1,40 @@
+/**
+  ******************************************************************************
+  * @file           : vm.h
+  * @author         : simon
+  * @brief          : hand it a chunk of code—literally a Chunk—and it runs it
+  * @attention      : None
+  * @date           : 2023/8/17
+  ******************************************************************************
+  */
+
+#ifndef CLOX__VM_H_
+#define CLOX__VM_H_
+
+#include "chunk.h"
+#include "value.h"
+
+#define  STACK_MAX 256
+
+typedef struct {
+  Chunk *chunk;
+  uint8_t *ip;
+  Value stack[STACK_MAX];
+  Value *stackTop;  // 栈指针
+} VM;
+typedef enum {
+  INTERPRET_OK,
+  INTERPRET_COMPILE_ERROR,
+  INTERPRET_RUNTIME_ERROR
+} InterpretResult;
+
+void initVM();
+void freeVM();
+/// \brief interpret 执行指令
+/// \param chunk 指令块
+/// \return InterpretResult
+InterpretResult interpret(Chunk *chunk);
+void push(Value value);
+Value pop();
+
+#endif //CLOX__VM_H_