Explorar o código

Arithmetic calculator

runningwater %!s(int64=2) %!d(string=hai) anos
pai
achega
1bba9e54da
Modificáronse 4 ficheiros con 45 adicións e 5 borrados
  1. 5 0
      chunk.h
  2. 10 5
      debug.c
  3. 13 0
      main.c
  4. 17 0
      vm.c

+ 5 - 0
chunk.h

@@ -17,6 +17,11 @@
 
 
 typedef enum {
 typedef enum {
   OP_CONSTANT,///<OP_CONSTANT (index)+>
   OP_CONSTANT,///<OP_CONSTANT (index)+>
+  OP_NEGATE,  /// \brief prefix -
+  OP_ADD, /// \brief +
+  OP_SUBTRACT, /// \brief -
+  OP_MULTIPLY, /// \brief *
+  OP_DIVIDE, /// \brief /
   OP_RETURN,  ///<OP_RETURN>
   OP_RETURN,  ///<OP_RETURN>
 } OpCode;
 } OpCode;
 
 

+ 10 - 5
debug.c

@@ -9,17 +9,17 @@ static int constantInstruction(const char *, Chunk *, int);
 static int simpleInstruction(const char *name, int offset);
 static int simpleInstruction(const char *name, int offset);
 
 
 void disassembleChunk(Chunk *chunk, const char *name) {
 void disassembleChunk(Chunk *chunk, const char *name) {
-  printf("== %s ==\n", name);
+  printf("== %s STARTING ==\n", name);
 
 
   for (int offset = 0; offset < chunk->count;) {
   for (int offset = 0; offset < chunk->count;) {
     offset = disassembleInstruction(chunk, offset);
     offset = disassembleInstruction(chunk, offset);
   }
   }
+  printf("== %s END ==\n", name);
 }
 }
 int disassembleInstruction(Chunk *chunk, int offset) {
 int disassembleInstruction(Chunk *chunk, int offset) {
   printf("%04d ", offset);
   printf("%04d ", offset);
 
 
-  if (offset > 0 &&
-      chunk->lines[offset] == chunk->lines[offset - 1]) {
+  if (offset > 0 && chunk->lines[offset] == chunk->lines[offset - 1]) {
     printf("   | ");
     printf("   | ");
   } else {
   } else {
     printf("%4d ", chunk->lines[offset]);
     printf("%4d ", chunk->lines[offset]);
@@ -27,8 +27,13 @@ int disassembleInstruction(Chunk *chunk, int offset) {
 
 
   uint8_t instruction = chunk->code[offset];
   uint8_t instruction = chunk->code[offset];
   switch (instruction) {
   switch (instruction) {
-    case OP_CONSTANT:return constantInstruction("OP_CONSTANT", chunk, offset);
-    case OP_RETURN:return simpleInstruction("OP_RETURN", offset);
+    case OP_CONSTANT: return constantInstruction("OP_CONSTANT", chunk, offset);
+    case OP_ADD: return simpleInstruction("OP_ADD", offset);
+    case OP_SUBTRACT: return simpleInstruction("OP_SUBTRACT", offset);
+    case OP_MULTIPLY: return simpleInstruction("OP_MULTIPLY", offset);
+    case OP_DIVIDE: return simpleInstruction("OP_DIVIDE", offset);
+    case OP_NEGATE: return simpleInstruction("OP_NEGATE", offset);
+    case OP_RETURN: return simpleInstruction("OP_RETURN", offset);
     default:printf("Unknown opcode %d\n", instruction);
     default:printf("Unknown opcode %d\n", instruction);
       return offset + 1;
       return offset + 1;
   }
   }

+ 13 - 0
main.c

@@ -18,6 +18,19 @@ int main(int argc, char *argv[]) {
   writeChunk(&chunk, OP_CONSTANT, 123);
   writeChunk(&chunk, OP_CONSTANT, 123);
   writeChunk(&chunk, constant, 123);
   writeChunk(&chunk, constant, 123);
 
 
+  constant = addConstant(&chunk, 3.4);
+  writeChunk(&chunk, OP_CONSTANT, 123);
+  writeChunk(&chunk, constant, 123);
+
+  writeChunk(&chunk, OP_ADD, 123);
+
+  constant = addConstant(&chunk, 5.6);
+  writeChunk(&chunk, OP_CONSTANT, 123);
+  writeChunk(&chunk, constant, 123);
+
+  writeChunk(&chunk, OP_DIVIDE, 123);
+  writeChunk(&chunk, OP_NEGATE, 123);
+
   writeChunk(&chunk, OP_RETURN, 123);
   writeChunk(&chunk, OP_RETURN, 123);
 
 
   disassembleChunk(&chunk, "test chunk");
   disassembleChunk(&chunk, "test chunk");

+ 17 - 0
vm.c

@@ -28,6 +28,12 @@ static InterpretResult run() {
 //! reads the next byte from the bytecode
 //! reads the next byte from the bytecode
 //! treats the resulting number as an index
 //! treats the resulting number as an index
 #define READ_CONSTANT() (vm.chunk->constants.values[READ_BYTE()])
 #define READ_CONSTANT() (vm.chunk->constants.values[READ_BYTE()])
+#define BINARY_OP(op) \
+   do { \
+     double b = pop(); \
+     double a = pop(); \
+     push(a op b); \
+   } while(false)
 
 
   for (;;) {
   for (;;) {
 #ifdef DEBUG_TRACE_EXECUTION
 #ifdef DEBUG_TRACE_EXECUTION
@@ -50,6 +56,16 @@ static InterpretResult run() {
         push(constant);
         push(constant);
         break;
         break;
       }
       }
+      case OP_ADD: BINARY_OP(+);
+        break;
+      case OP_SUBTRACT: BINARY_OP(-);
+        break;
+      case OP_MULTIPLY: BINARY_OP(*);
+        break;
+      case OP_DIVIDE: BINARY_OP(/);
+        break;
+      case OP_NEGATE: push(-pop());
+        break;
       case OP_RETURN: {
       case OP_RETURN: {
         printValue(pop());
         printValue(pop());
         printf("\n");
         printf("\n");
@@ -60,6 +76,7 @@ static InterpretResult run() {
 
 
 #undef READ_BYTE
 #undef READ_BYTE
 #undef READ_CONSTANT
 #undef READ_CONSTANT
+#undef BINARY_OP
 }
 }
 void freeVM() {
 void freeVM() {