Browse Source

refactoring and more specific operations

Kajetan Johannes Hammerle 3 năm trước cách đây
mục cha
commit
32b80921a2
4 tập tin đã thay đổi với 57 bổ sung55 xóa
  1. 20 29
      Compiler.c
  2. 6 3
      utils/ByteCodePrinter.c
  3. 5 2
      vm/Operation.h
  4. 26 21
      vm/Script.c

+ 20 - 29
Compiler.c

@@ -55,32 +55,26 @@ typedef struct {
     const char* name;
 } TypedOp;
 
-#define TYPE_OP(NAME, INT, LONG, FLOAT, BOOL, POINTER, text)                   \
-    static const TypedOp TYPED_##NAME = {OP_##INT,  OP_##LONG,    OP_##FLOAT,  \
-                                         OP_##BOOL, OP_##POINTER, text};
-TYPE_OP(MUL, MUL_INT32, MUL_INT64, MUL_FLOAT, NOTHING, NOTHING, "*")
-TYPE_OP(DIV, DIV_INT32, DIV_INT64, DIV_FLOAT, NOTHING, NOTHING, "/")
-TYPE_OP(MOD, MOD_INT32, MOD_INT64, NOTHING, NOTHING, NOTHING, "%")
-TYPE_OP(ADD, ADD_INT32, ADD_INT64, ADD_FLOAT, NOTHING, NOTHING, "+")
-TYPE_OP(SUB, SUB_INT32, SUB_INT64, SUB_FLOAT, NOTHING, NOTHING, "-")
-TYPE_OP(LESS, LESS_INT32, LESS_INT64, LESS_FLOAT, NOTHING, NOTHING, "<")
-TYPE_OP(LESS_EQUAL, GREATER_INT32, GREATER_INT64, GREATER_FLOAT, NOTHING,
-        NOTHING, "<=")
-TYPE_OP(GREATER, GREATER_INT32, GREATER_INT64, GREATER_FLOAT, NOTHING, NOTHING,
-        ">")
-TYPE_OP(GREATER_EQUAL, LESS_INT32, LESS_INT64, LESS_FLOAT, NOTHING, NOTHING,
-        ">=")
-TYPE_OP(EQUAL, EQUAL_INT32, EQUAL_INT64, EQUAL_FLOAT, EQUAL_BOOL, EQUAL_POINTER,
-        "==")
-TYPE_OP(NOT_EQUAL, EQUAL_INT32, EQUAL_INT64, EQUAL_FLOAT, EQUAL_BOOL,
-        EQUAL_POINTER, "!=")
-TYPE_OP(BIT_OR, BIT_OR_INT32, BIT_OR_INT64, NOTHING, NOTHING, NOTHING, "|")
-TYPE_OP(BIT_XOR, BIT_XOR_INT32, BIT_XOR_INT64, NOTHING, NOTHING, NOTHING, "^")
-TYPE_OP(BIT_AND, BIT_AND_INT32, BIT_AND_INT64, NOTHING, NOTHING, NOTHING, "&")
-TYPE_OP(LEFT_SHIFT, LEFT_SHIFT_INT32, LEFT_SHIFT_INT64, NOTHING, NOTHING,
-        NOTHING, "<<")
-TYPE_OP(RIGHT_SHIFT, RIGHT_SHIFT_INT32, RIGHT_SHIFT_INT64, NOTHING, NOTHING,
-        NOTHING, ">>")
+#define TYPE_OP(NAME, FLOAT, BOOL, POINTER, text)                              \
+    static const TypedOp TYPED_##NAME = {OP_##NAME##_INT32, OP_##NAME##_INT64, \
+                                         OP_##FLOAT,        OP_##BOOL,         \
+                                         OP_##POINTER,      text};
+TYPE_OP(MUL, MUL_FLOAT, NOTHING, NOTHING, "*")
+TYPE_OP(DIV, DIV_FLOAT, NOTHING, NOTHING, "/")
+TYPE_OP(MOD, NOTHING, NOTHING, NOTHING, "%")
+TYPE_OP(ADD, ADD_FLOAT, NOTHING, NOTHING, "+")
+TYPE_OP(SUB, SUB_FLOAT, NOTHING, NOTHING, "-")
+TYPE_OP(LESS, LESS_FLOAT, NOTHING, NOTHING, "<")
+TYPE_OP(LESS_EQUAL, LESS_EQUAL_FLOAT, NOTHING, NOTHING, "<=")
+TYPE_OP(GREATER, GREATER_FLOAT, NOTHING, NOTHING, ">")
+TYPE_OP(GREATER_EQUAL, GREATER_EQUAL_FLOAT, NOTHING, NOTHING, ">=")
+TYPE_OP(EQUAL, EQUAL_FLOAT, EQUAL_BOOL, EQUAL_POINTER, "==")
+TYPE_OP(NOT_EQUAL, NOT_EQUAL_FLOAT, NOT_EQUAL_BOOL, NOT_EQUAL_POINTER, "!=")
+TYPE_OP(BIT_OR, NOTHING, NOTHING, NOTHING, "|")
+TYPE_OP(BIT_XOR, NOTHING, NOTHING, NOTHING, "^")
+TYPE_OP(BIT_AND, NOTHING, NOTHING, NOTHING, "&")
+TYPE_OP(LEFT_SHIFT, NOTHING, NOTHING, NOTHING, "<<")
+TYPE_OP(RIGHT_SHIFT, NOTHING, NOTHING, NOTHING, ">>")
 
 static void cError(const char* format, ...) {
     va_list args;
@@ -628,14 +622,12 @@ static DataType cComparison() {
             a = dtBool();
         } else if(cConsumeTokenIf(T_LESS_EQUAL)) {
             cAddTypeOperation(&a, cShift, &TYPED_LESS_EQUAL);
-            cAddOperation(OP_NOT);
             a = dtBool();
         } else if(cConsumeTokenIf(T_GREATER)) {
             cAddTypeOperation(&a, cShift, &TYPED_GREATER);
             a = dtBool();
         } else if(cConsumeTokenIf(T_GREATER_EQUAL)) {
             cAddTypeOperation(&a, cShift, &TYPED_GREATER_EQUAL);
-            cAddOperation(OP_NOT);
             a = dtBool();
         } else {
             return a;
@@ -651,7 +643,6 @@ static DataType cEqual() {
             a = dtBool();
         } else if(cConsumeTokenIf(T_NOT_EQUAL)) {
             cAddTypeOperation(&a, cComparison, &TYPED_NOT_EQUAL);
-            cAddOperation(OP_NOT);
             a = dtBool();
         } else {
             return a;

+ 6 - 3
utils/ByteCodePrinter.c

@@ -144,7 +144,8 @@ static void btPrintFloat(const char* op) {
     PRINT_OP(OP_STORE_##TYPE);                                                 \
     PRINT_OP(OP_LOAD_##TYPE);                                                  \
     PRINT_OP_INT32(OP_RETURN_##TYPE);                                          \
-    PRINT_OP(OP_EQUAL_##TYPE);
+    PRINT_OP(OP_EQUAL_##TYPE);                                                 \
+    PRINT_OP(OP_NOT_EQUAL_##TYPE);
 
 static void btConsumeOperation() {
     Operation op = code->code[readIndex++];
@@ -164,11 +165,12 @@ static void btConsumeOperation() {
         PRINT_NUMBER_OP(SUB);
         PRINT_NUMBER_OP(MUL);
         PRINT_NUMBER_OP(DIV);
-        PRINT_OP(OP_MOD_INT32);
-        PRINT_OP(OP_MOD_INT64);
+        PRINT_INTEGRAL_OP(MOD);
         PRINT_NUMBER_OP(INVERT_SIGN);
         PRINT_NUMBER_OP(LESS);
+        PRINT_NUMBER_OP(LESS_EQUAL);
         PRINT_NUMBER_OP(GREATER);
+        PRINT_NUMBER_OP(GREATER_EQUAL);
         PRINT_OP(OP_NOT);
         PRINT_OP(OP_AND);
         PRINT_OP(OP_OR);
@@ -196,6 +198,7 @@ static void btConsumeOperation() {
         PRINT_OP_INT32(OP_LOAD);
         PRINT_OP(OP_STORE_POINTER);
         PRINT_OP(OP_EQUAL_POINTER);
+        PRINT_OP(OP_NOT_EQUAL_POINTER);
         PRINT_OP_INT8(OP_PUSH_PRE_CHANGE_INT32);
         PRINT_OP_INT8(OP_PUSH_POST_CHANGE_INT32);
         PRINT_OP_INT8(OP_CHANGE_INT32);

+ 5 - 2
vm/Operation.h

@@ -22,10 +22,13 @@ typedef enum Operation {
     OP_MOD_INT64,
     OP_NUMBER(INVERT_SIGN),
     OP_NUMBER(LESS),
+    OP_NUMBER(LESS_EQUAL),
     OP_NUMBER(GREATER),
-    OP_NUMBER(EQUAL),
-    OP_EQUAL_BOOL,
+    OP_NUMBER(GREATER_EQUAL),
+    OP_TYPE(EQUAL),
+    OP_TYPE(NOT_EQUAL),
     OP_EQUAL_POINTER,
+    OP_NOT_EQUAL_POINTER,
     OP_NOT,
     OP_AND,
     OP_OR,

+ 26 - 21
vm/Script.c

@@ -390,11 +390,11 @@ static void sStore(Script* sc, int length) {
     }
 }
 
-static void sEqualPointer(Script* sc) {
+static void sEqualPointer(Script* sc, bool wanted) {
     Pointer a;
     Pointer b;
     if(sPopPointer(sc, &a) && sPopPointer(sc, &b)) {
-        sPushBool(sc, a.array == b.array && a.offset == b.offset);
+        sPushBool(sc, (a.array == b.array && a.offset == b.offset) == wanted);
     }
 }
 
@@ -433,15 +433,24 @@ static void sCall(Script* sc) {
             sPush##To(sc, value);                                              \
         }                                                                      \
     }
+#define CASE_CAST(TYPE1, Type1, type1, TYPE2, Type2, type2)                    \
+    case OP_##TYPE1##_TO_##TYPE2: CAST(Type1, type1, Type2); break;            \
+    case OP_##TYPE2##_TO_##TYPE1:                                              \
+        CAST(Type2, type2, Type1);                                             \
+        break;
 #define CASE_CHANGE(TYPE, Type, type)                                          \
     case OP_PUSH_PRE_CHANGE_##TYPE: PUSH_PRE_CHANGE(Type, type); break;        \
     case OP_PUSH_POST_CHANGE_##TYPE: PUSH_POST_CHANGE(Type, type); break;      \
     case OP_CHANGE_##TYPE:                                                     \
         CHANGE(type);                                                          \
         break;
-#define CASE_NUMBER_OP(name, op)                                               \
+#define CASE_INTEGRAL_OP(name, op)                                             \
     case OP_##name##_INT32: NUMBER_OP(int32, Int32, op); break;                \
-    case OP_##name##_INT64: NUMBER_OP(int64, Int64, op); break;                \
+    case OP_##name##_INT64:                                                    \
+        NUMBER_OP(int64, Int64, op);                                           \
+        break;
+#define CASE_NUMBER_OP(name, op)                                               \
+    CASE_INTEGRAL_OP(name, op)                                                 \
     case OP_##name##_FLOAT:                                                    \
         NUMBER_OP(float, Float, op);                                           \
         break;
@@ -455,6 +464,7 @@ static void sCall(Script* sc) {
     case OP_STORE_##TYPE: sStore(sc, sizeof(type)); break;                     \
     case OP_RETURN_##TYPE: RETURN(type, Type); break;                          \
     case OP_EQUAL_##TYPE: BOOL_OP(type, Type, ==); break;                      \
+    case OP_NOT_EQUAL_##TYPE: BOOL_OP(type, Type, !=); break;                  \
     case OP_LOAD_##TYPE: sLoad(sc, sizeof(type)); break;
 
 static void sConsumeInstruction(Script* sc) {
@@ -463,13 +473,23 @@ static void sConsumeInstruction(Script* sc) {
         CASE_NUMBER_OP(SUB, -);
         CASE_NUMBER_OP(MUL, *);
         CASE_BOOL_OP(LESS, <);
+        CASE_BOOL_OP(LESS_EQUAL, <=);
         CASE_BOOL_OP(GREATER, >);
+        CASE_BOOL_OP(GREATER_EQUAL, >=);
         CASE_TYPE(INT32, Int32, int32);
         CASE_TYPE(INT64, Int64, int64);
         CASE_TYPE(BOOL, Bool, bool);
         CASE_TYPE(FLOAT, Float, float);
         CASE_CHANGE(INT32, Int32, int32);
         CASE_CHANGE(INT64, Int64, int64);
+        CASE_INTEGRAL_OP(BIT_AND, &);
+        CASE_INTEGRAL_OP(BIT_OR, |);
+        CASE_INTEGRAL_OP(BIT_XOR, ^);
+        CASE_INTEGRAL_OP(LEFT_SHIFT, <<);
+        CASE_INTEGRAL_OP(RIGHT_SHIFT, >>);
+        CASE_CAST(INT32, Int32, int32, FLOAT, Float, float);
+        CASE_CAST(INT32, Int32, int32, INT64, Int64, int64);
+        CASE_CAST(INT64, Int64, int64, FLOAT, Float, float);
         case OP_NOTHING: break;
         case OP_PUSH_INT32: PUSH_CONSTANT(int32, Int32); break;
         case OP_PUSH_INT64: PUSH_CONSTANT(int64, Int64); break;
@@ -489,17 +509,7 @@ static void sConsumeInstruction(Script* sc) {
         case OP_AND: BOOL_OP(bool, Bool, &&); break;
         case OP_OR: BOOL_OP(bool, Bool, ||); break;
         case OP_BIT_NOT_INT32: sBitNotInt32(sc); break;
-        case OP_BIT_AND_INT32: NUMBER_OP(int32, Int32, &); break;
-        case OP_BIT_OR_INT32: NUMBER_OP(int32, Int32, |); break;
-        case OP_BIT_XOR_INT32: NUMBER_OP(int32, Int32, ^); break;
-        case OP_LEFT_SHIFT_INT32: NUMBER_OP(int32, Int32, <<); break;
-        case OP_RIGHT_SHIFT_INT32: NUMBER_OP(int32, Int32, >>); break;
         case OP_BIT_NOT_INT64: sBitNotInt64(sc); break;
-        case OP_BIT_AND_INT64: NUMBER_OP(int64, Int64, &); break;
-        case OP_BIT_OR_INT64: NUMBER_OP(int64, Int64, |); break;
-        case OP_BIT_XOR_INT64: NUMBER_OP(int64, Int64, ^); break;
-        case OP_LEFT_SHIFT_INT64: NUMBER_OP(int64, Int64, <<); break;
-        case OP_RIGHT_SHIFT_INT64: NUMBER_OP(int64, Int64, >>); break;
         case OP_LINE: sLine(sc); break;
         case OP_GOTO: sGoTo(sc); break;
         case OP_IF_GOTO: sIfGoTo(sc); break;
@@ -518,13 +528,8 @@ static void sConsumeInstruction(Script* sc) {
         case OP_DELETE: sDeleteArray(sc); break;
         case OP_LENGTH: sLength(sc); break;
         case OP_STORE_POINTER: sStore(sc, sizeof(Pointer)); break;
-        case OP_EQUAL_POINTER: sEqualPointer(sc); break;
-        case OP_INT32_TO_FLOAT: CAST(Int32, int32, Float); break;
-        case OP_FLOAT_TO_INT32: CAST(Float, float, Int32); break;
-        case OP_INT32_TO_INT64: CAST(Int32, int32, Int64); break;
-        case OP_INT64_TO_INT32: CAST(Int64, int64, Int32); break;
-        case OP_FLOAT_TO_INT64: CAST(Float, float, Int64); break;
-        case OP_INT64_TO_FLOAT: CAST(Int64, int64, Float); break;
+        case OP_EQUAL_POINTER: sEqualPointer(sc, true); break;
+        case OP_NOT_EQUAL_POINTER: sEqualPointer(sc, false); break;
         case OP_CALL: sCall(sc); break;
     }
 }