Przeglądaj źródła

improved byte code printer

Kajetan Johannes Hammerle 3 lat temu
rodzic
commit
2d8b00be28
7 zmienionych plików z 195 dodań i 103 usunięć
  1. 183 0
      ByteCodePrinter.c
  2. 8 0
      ByteCodePrinter.h
  3. 0 97
      Script.c
  4. 0 2
      Script.h
  5. 3 2
      Test.c
  6. 1 0
      meson.build
  7. 0 2
      tests/mix

+ 183 - 0
ByteCodePrinter.c

@@ -0,0 +1,183 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "ByteCodePrinter.h"
+
+#define LINE_LENGTH 80
+
+static ByteCode* code;
+static int readIndex;
+static int line;
+static char buffer[LINE_LENGTH];
+static int bIndex;
+
+static void btPrintHeading() {
+    puts("|  Index |  Line |            Operation | Argument 1 | Argument 2 |");
+    puts("|--------|-------|----------------------|------------|------------|");
+}
+
+static void btAdd(const char* format, ...) {
+    va_list args;
+    va_start(args, format);
+    bIndex += vsnprintf(buffer + bIndex, LINE_LENGTH - bIndex, format, args);
+    va_end(args);
+}
+
+static void btFillBase() {
+    buffer[0] = '\0';
+    bIndex = 0;
+    btAdd("| %6d | %5d |", readIndex, line);
+}
+
+static void btRead(void* buffer, int length) {
+    if(readIndex + length > code->length) {
+        return;
+    }
+    memcpy(buffer, code->code + readIndex, length);
+    readIndex += length;
+}
+
+static void btAddOperation(const char* s) {
+    if(s[0] != '\0' && s[1] != '\0' && s[2] != '\0' && s[3] != '\0') {
+        s += 3;
+    }
+    btAdd(" %20s |", s);
+}
+
+static void btAddInt() {
+    int value = 0;
+    btRead(&value, sizeof(int));
+    btAdd(" %10d |", value);
+}
+
+static void btAddFloat() {
+    float value = 0;
+    btRead(&value, sizeof(float));
+    btAdd(" %10.2f |", value);
+}
+
+static void btAddFiller() {
+    btAdd("            |");
+}
+
+static void sPrintLine() {
+    btRead(&line, 2);
+    printf("| %6d |-------|----------------------|------------|------------|\n",
+           readIndex);
+}
+
+static void btPrintOp(const char* op) {
+    btFillBase();
+    btAddOperation(op);
+    btAddFiller();
+    btAddFiller();
+    puts(buffer);
+}
+
+static void btPrintInt(const char* op) {
+    btFillBase();
+    btAddOperation(op);
+    btAddInt();
+    btAddFiller();
+    puts(buffer);
+}
+
+static void btPrintInt2(const char* op) {
+    btFillBase();
+    btAddOperation(op);
+    btAddInt();
+    btAddInt();
+    puts(buffer);
+}
+
+static void btPrintFloat(const char* op) {
+    btFillBase();
+    btAddOperation(op);
+    btAddFloat();
+    btAddFiller();
+    puts(buffer);
+}
+
+static void btPrintString(const char* msg) {
+    int length = 0;
+    btRead(&length, sizeof(int));
+    char* s = (char*)(code->code + readIndex);
+    readIndex += length;
+    btFillBase();
+    btAddOperation(msg);
+    btAdd(" %10s |", s);
+    btAddFiller();
+    puts(buffer);
+}
+
+#define PRINT_OP_BASE(op, name)                                                \
+    case op:                                                                   \
+        btPrint##name(#op);                                                    \
+        break;
+#define PRINT_OP(op) PRINT_OP_BASE(op, Op)
+#define PRINT_OP_INT(op) PRINT_OP_BASE(op, Int)
+#define PRINT_OP_INT2(op) PRINT_OP_BASE(op, Int2)
+
+static void btConsumeOperation() {
+    int op = code->code[readIndex++];
+    switch(op) {
+        PRINT_OP(OP_NOTHING);
+        PRINT_OP_INT(OP_PUSH_INT);
+        PRINT_OP_BASE(OP_PUSH_FLOAT, Float);
+        PRINT_OP(OP_PUSH_NULL);
+        PRINT_OP(OP_PUSH_TRUE);
+        PRINT_OP(OP_PUSH_FALSE);
+        PRINT_OP_INT2(OP_PUSH_VARS);
+        PRINT_OP_INT(OP_POP_VARS);
+        PRINT_OP(OP_POP);
+        PRINT_OP(OP_SET);
+        PRINT_OP(OP_PRE_INCREMENT);
+        PRINT_OP(OP_POST_INCREMENT);
+        PRINT_OP(OP_PRE_DECREMENT);
+        PRINT_OP(OP_POST_DECREMENT);
+        PRINT_OP(OP_ADD);
+        PRINT_OP(OP_SUB);
+        PRINT_OP(OP_MUL);
+        PRINT_OP(OP_DIV);
+        PRINT_OP(OP_MOD);
+        PRINT_OP(OP_INVERT_SIGN);
+        PRINT_OP(OP_LESS);
+        PRINT_OP(OP_GREATER);
+        PRINT_OP(OP_EQUAL);
+        PRINT_OP(OP_NOT);
+        PRINT_OP(OP_AND);
+        PRINT_OP(OP_OR);
+        PRINT_OP(OP_BIT_NOT);
+        PRINT_OP(OP_BIT_AND);
+        PRINT_OP(OP_BIT_OR);
+        PRINT_OP(OP_BIT_XOR);
+        PRINT_OP(OP_LEFT_SHIFT);
+        PRINT_OP(OP_RIGHT_SHIFT);
+        PRINT_OP(OP_PRINT);
+        PRINT_OP_INT(OP_GOTO);
+        PRINT_OP_INT2(OP_GOSUB);
+        PRINT_OP_INT(OP_IF_GOTO);
+        PRINT_OP(OP_SET_RETURN);
+        PRINT_OP(OP_RETURN);
+        PRINT_OP(OP_DUPLICATE);
+        PRINT_OP(OP_ALLOCATE_ARRAY);
+        PRINT_OP(OP_ARRAY_LENGTH);
+        PRINT_OP_INT(OP_REFERENCE_FROM_VAR);
+        PRINT_OP_INT(OP_REFERENCE_FROM_ARRAY);
+        PRINT_OP(OP_DEREFERENCE);
+        PRINT_OP_BASE(OP_PUSH_CONST_STRING, String);
+        case OP_LINE: sPrintLine(); break;
+        default: printf("Unknown: %d\n", op);
+    }
+}
+
+void btPrint(ByteCode* bt) {
+    code = bt;
+    readIndex = 0;
+    line = 0;
+    btPrintHeading();
+    while(readIndex < code->length) {
+        btConsumeOperation();
+    }
+}

+ 8 - 0
ByteCodePrinter.h

@@ -0,0 +1,8 @@
+#ifndef BYTECODEPRINTER_H
+#define BYTECODEPRINTER_H
+
+#include "ByteCode.h"
+
+void btPrint(ByteCode* bt);
+
+#endif

+ 0 - 97
Script.c

@@ -576,101 +576,4 @@ void sCollectGarbage(Script* sc) {
         sMark(sc, sc->stack + i);
     }
     aRemoveUnmarked(&sc->allocator);
-}
-
-static void sPrintInt(Script* sc, const char* msg) {
-    int value = 0;
-    sReadInt(sc, &value);
-    printf("%s %d\n", msg, value);
-}
-
-static void sPrint2Int(Script* sc, const char* msg) {
-    int a = 0;
-    sReadInt(sc, &a);
-    int b = 0;
-    sReadInt(sc, &b);
-    printf("%s %d %d\n", msg, a, b);
-}
-
-static void sPrintInt16(Script* sc, const char* msg) {
-    int value = 0;
-    sRead(sc, &value, 2);
-    printf("%s %d\n", msg, value);
-}
-
-static void sPrintFloat(Script* sc, const char* msg) {
-    float value = 0;
-    sRead(sc, &value, sizeof(float));
-    printf("%s %.2f\n", msg, value);
-}
-
-static void sPrintString(Script* sc, const char* msg) {
-    int length = 0;
-    sReadInt(sc, &length);
-    char* s = (char*)(sc->code->code + sc->readIndex);
-    sc->readIndex += length;
-    printf("%s %d \"%s\"\n", msg, length, s);
-}
-
-void sPrintCode(Script* sc) {
-    int oldRead = sc->readIndex;
-    sc->readIndex = 0;
-    while(sHasData(sc)) {
-        printf(" %3d | ", sc->readIndex);
-        switch(sReadOperation(sc)) {
-            case OP_NOTHING: puts("Nothing"); break;
-            case OP_PUSH_INT: sPrintInt(sc, "Push Int"); break;
-            case OP_PUSH_FLOAT: sPrintFloat(sc, "Push Float"); break;
-            case OP_PUSH_CONST_STRING:
-                sPrintString(sc, "Push Const String");
-                break;
-            case OP_PUSH_NULL: puts("Push null"); break;
-            case OP_PUSH_TRUE: puts("Push true"); break;
-            case OP_PUSH_FALSE: puts("Push false"); break;
-            case OP_PUSH_VARS: sPrint2Int(sc, "Push Vars"); break;
-            case OP_POP_VARS: sPrintInt(sc, "Pop Vars"); break;
-            case OP_POP: puts("Pop"); break;
-            case OP_SET: puts("Set"); break;
-            case OP_PRE_INCREMENT: puts("Pre Increment"); break;
-            case OP_POST_INCREMENT: puts("Post Increment"); break;
-            case OP_PRE_DECREMENT: puts("Pre Decrement"); break;
-            case OP_POST_DECREMENT: puts("Post Decrement"); break;
-            case OP_ADD: puts("Add"); break;
-            case OP_SUB: puts("Sub"); break;
-            case OP_MUL: puts("Mul"); break;
-            case OP_DIV: puts("Div"); break;
-            case OP_MOD: puts("Mod"); break;
-            case OP_INVERT_SIGN: puts("Invert Sign"); break;
-            case OP_LESS: puts("Less"); break;
-            case OP_GREATER: puts("Greater"); break;
-            case OP_EQUAL: puts("Equal"); break;
-            case OP_NOT: puts("Not"); break;
-            case OP_AND: puts("And"); break;
-            case OP_OR: puts("Or"); break;
-            case OP_BIT_NOT: puts("Bit Not"); break;
-            case OP_BIT_AND: puts("Bit And"); break;
-            case OP_BIT_OR: puts("Bit Or"); break;
-            case OP_BIT_XOR: puts("Bit Xor"); break;
-            case OP_LEFT_SHIFT: puts("Left Shift"); break;
-            case OP_RIGHT_SHIFT: puts("Right Shift"); break;
-            case OP_PRINT: puts("Print"); break;
-            case OP_LINE: sPrintInt16(sc, "------------ Line"); break;
-            case OP_GOTO: sPrintInt(sc, "GoTo"); break;
-            case OP_GOSUB: sPrint2Int(sc, "GoSub"); break;
-            case OP_IF_GOTO: sPrintInt(sc, "If GoTo"); break;
-            case OP_SET_RETURN: puts("Set Return"); break;
-            case OP_RETURN: puts("Return"); break;
-            case OP_DUPLICATE: puts("Duplicate"); break;
-            case OP_ALLOCATE_ARRAY: puts("Allocate Array"); break;
-            case OP_ARRAY_LENGTH: puts("Array Length"); break;
-            case OP_REFERENCE_FROM_VAR:
-                sPrintInt(sc, "Reference From Var");
-                break;
-            case OP_REFERENCE_FROM_ARRAY:
-                sPrintInt(sc, "Reference From Array");
-                break;
-            case OP_DEREFERENCE: puts("Dereference"); break;
-        }
-    }
-    sc->readIndex = oldRead;
 }

+ 0 - 2
Script.h

@@ -32,6 +32,4 @@ void sSetPrinter(ObjectPrinter p);
 
 void sCollectGarbage(Script* sc);
 
-void sPrintCode(Script* sc);
-
 #endif

+ 3 - 2
Test.c

@@ -6,6 +6,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "ByteCodePrinter.h"
 #include "Compiler.h"
 #include "Script.h"
 #include "tokenizer/Tokenizer.h"
@@ -100,10 +101,10 @@ static void tsCheckScript(Script* sc) {
         return;
     }
     if(tsCompareResults(file)) {
-        sPrintCode(sc);
+        btPrint(sc->code);
     } else if(sc->stackIndex != 0) {
         printf("%s has non empty stack: %d\n", path, sc->stackIndex);
-        sPrintCode(sc);
+        btPrint(sc->code);
     }
     fclose(file);
 }

+ 1 - 0
meson.build

@@ -11,6 +11,7 @@ src = [
     'Test.c', 
     'StringIntMap.c',
     'ByteCode.c',
+    'ByteCodePrinter.c',
     'FunctionMap.c',
     'Object.c',
     'Allocator.c'

+ 0 - 2
tests/mix

@@ -4,5 +4,3 @@ b = 6;
 if(a + b < 20 && a > 3) {
     print 1;
 }
-
-print 1 / 0;