Przeglądaj źródła

imprived parsing of [], . and ->

Kajetan Johannes Hammerle 3 lat temu
rodzic
commit
b8baeb3b46
10 zmienionych plików z 272 dodań i 179 usunięć
  1. 210 153
      Compiler.c
  2. 13 5
      DataType.c
  3. 2 1
      DataType.h
  4. 33 0
      tests/arrays/types
  5. 8 0
      tests/arrays/types.out
  6. 1 1
      tests/bits/invert
  7. 1 1
      tests/struct/int_reference
  8. 0 1
      utils/ByteCodePrinter.c
  9. 0 1
      vm/Operation.h
  10. 4 16
      vm/Script.c

+ 210 - 153
Compiler.c

@@ -198,9 +198,40 @@ static const char* cReadString() {
 
 static DataType cExpression();
 
+static void cLoadRef(DataType type) {
+    if(dtIsPointer(type)) {
+        cAddOperation(OP_REFERENCE);
+        return;
+    }
+    switch(type.type) {
+        DT_OPERATION(LOAD);
+        case DT_STRUCT:
+            {
+                Struct* st = dtGetStruct(&structs, type);
+                if(st == NULL) {
+                    cError("compiler struct error");
+                }
+                cAddIntOperation(OP_LOAD, dtGetSize(type, &structs));
+                break;
+            }
+        default: cError("cannot load type %s", cGetName(type));
+    }
+}
+
+static DataType cUnpack(DataType dt) {
+    if(dtRemoveVariable(&dt)) {
+        cLoadRef(dt);
+    }
+    return dt;
+}
+
+static DataType cUnpackedExpression() {
+    return cUnpack(cExpression());
+}
+
 static void cCallFunctionArguments(Function* f) {
     while(!cConsumeTokenIf(T_CLOSE_BRACKET)) {
-        DataType dt = cExpression();
+        DataType dt = cUnpackedExpression();
         if(fAddArgument(f, dt, &structs)) {
             cTooMuchArguments();
         }
@@ -239,7 +270,7 @@ static void cWalkStruct(Variable* v) {
                 cError("[] need a pointer");
             }
             cAddOperation(OP_REFERENCE);
-            DataType index = cExpression();
+            DataType index = cUnpackedExpression();
             if(!dtCompare(index, dtInt())) {
                 cError("array index must be an int");
             }
@@ -290,26 +321,6 @@ static void cReference(Variable* v, int dimension) {
     cWalkStruct(v);
 }
 
-static void cLoadRef(Variable* v) {
-    if(dtIsPointer(v->type)) {
-        cAddOperation(OP_LOAD_POINTER);
-        return;
-    }
-    switch(v->type.type) {
-        DT_OPERATION(LOAD);
-        case DT_STRUCT:
-            {
-                Struct* st = dtGetStruct(&structs, v->type);
-                if(st == NULL) {
-                    cError("compiler struct error");
-                }
-                cAddIntOperation(OP_LOAD, dtGetSize(v->type, &structs));
-                break;
-            }
-        default: cError("cannot load type %s", cGetName(v->type));
-    }
-}
-
 static void cStore(Variable* v, DataType dt, const char* name) {
     if(!dtCompare(v->type, dt)) {
         cInvalidOperation(v->type, dt, name);
@@ -324,14 +335,6 @@ static void cStore(Variable* v, DataType dt, const char* name) {
     }
 }
 
-static DataType cPostChange(Variable* v, int change, const char* name) {
-    if(!dtCompare(v->type, dtInt())) {
-        cError("%s needs an int", name);
-    }
-    cAddByteOperation(OP_PUSH_POST_INT_CHANGE, change);
-    return dtInt();
-}
-
 static DataType cLiteral() {
     const char* literal = cReadString();
     if(cConsumeTokenIf(T_OPEN_BRACKET)) {
@@ -345,14 +348,15 @@ static DataType cLiteral() {
     if(vsSearch(&vars, &v, literal)) {
         cNotDeclared(literal);
     }
-    cReference(&v, 0);
+    cAddIntOperation(OP_DEREFERENCE_VAR, v.address);
+    /*cWalkStruct(&v);
+
     if(cConsumeTokenIf(T_INCREMENT)) {
         return cPostChange(&v, 1, "++");
     } else if(cConsumeTokenIf(T_DECREMENT)) {
         return cPostChange(&v, -1, "--");
-    }
-    cLoadRef(&v);
-    return v.type;
+    }*/
+    return dtToVariable(v.type);
 }
 
 static DataType cBracketPrimary() {
@@ -361,20 +365,49 @@ static DataType cBracketPrimary() {
     return result;
 }
 
+static DataType cExtendType(DataType dt) {
+    while(cConsumeTokenIf(T_MUL)) {
+        dt = dtDereference(dt);
+    }
+    return dt;
+}
+
+static DataType cReadType() {
+    DataType dt = dtVoid();
+    Token t = cReadTokenAndLine();
+    switch(t) {
+        case T_INT: dt = dtInt(); break;
+        case T_BOOL: dt = dtBool(); break;
+        case T_FLOAT: dt = dtFloat(); break;
+        case T_LITERAL:
+            {
+                const char* name = cReadString();
+                Struct* st = stsSearch(&structs, name);
+                if(st == NULL) {
+                    cError("struct %s does not exist");
+                }
+                dt = dtStruct(st);
+                break;
+            }
+        default: cUnexpectedToken(t);
+    }
+    return cExtendType(dt);
+}
+
 static DataType cAllocArray() {
-    cConsumeToken(T_INT);
+    DataType dt = cReadType();
     cConsumeToken(T_OPEN_SQUARE_BRACKET);
-    DataType index = cExpression();
+    DataType index = cUnpackedExpression();
     if(!dtCompare(index, dtInt())) {
         cError("array size must be an int");
     }
     cConsumeToken(T_CLOSE_SQUARE_BRACKET);
-    cAddIntOperation(OP_NEW, dtGetSize(dtInt(), &structs));
-    return dtToArray(dtInt(), 1);
+    cAddIntOperation(OP_NEW, dtGetSize(dt, &structs));
+    return dtDereference(dt);
 }
 
 static DataType cLength() {
-    DataType pointer = cExpression();
+    DataType pointer = cUnpackedExpression();
     if(!dtIsPointer(pointer)) {
         cError("length expects a pointer");
     }
@@ -397,83 +430,117 @@ static DataType cPrimary() {
     }
 }
 
-static DataType cPreChange(int change, const char* name) {
+static void cPostChange(DataType* dt, int change, const char* name) {
+    if(!dtRemoveVariable(dt) || !dtCompare(*dt, dtInt())) {
+        cError("%s needs an int reference", name);
+    }
+    cAddByteOperation(OP_PUSH_POST_INT_CHANGE, change);
+}
+
+static DataType cStructAccess(DataType dt, int pointers) {
+    Struct* st = dtGetStruct(&structs, dt);
+    if(st == NULL || dt.pointers != pointers) {
+        cError(pointers == 0 ? ". expects a struct" : "-> expects a struct*");
+    }
     cConsumeToken(T_LITERAL);
-    const char* literal = cReadString();
-    Variable v;
-    if(vsSearch(&vars, &v, literal)) {
-        cNotDeclared(literal);
+    const char* name = cReadString();
+    Variable inner;
+    if(vSearchStruct(&inner, &structs, st, name)) {
+        cError("%s has no member %s", st->name, name);
     }
-    cReference(&v, 0);
-    if(!dtCompare(v.type, dtInt())) {
-        cError("%s needs an int", name);
+    if(inner.address > 0) {
+        cAddIntOperation(OP_PUSH_INT, inner.address);
+        cAddOperation(OP_ADD_REFERENCE);
+    }
+    return dtToVariable(inner.type);
+}
+
+static DataType cAccess() {
+    DataType dt = cPrimary();
+    while(true) {
+        if(cConsumeTokenIf(T_INCREMENT)) {
+            cPostChange(&dt, 1, "++");
+        } else if(cConsumeTokenIf(T_DECREMENT)) {
+            cPostChange(&dt, -1, "--");
+        } else if(cConsumeTokenIf(T_POINT)) {
+            if(!dtRemoveVariable(&dt)) {
+                cError(". expects a reference");
+            }
+            dt = cStructAccess(dt, 0);
+        } else if(cConsumeTokenIf(T_ARROW)) {
+            dt = cStructAccess(cUnpack(dt), 1);
+        } else if(cConsumeTokenIf(T_OPEN_SQUARE_BRACKET)) {
+            dt = cUnpack(dt);
+            if(!dtIsPointer(dt)) {
+                cError("[] needs a pointer");
+            }
+            DataType index = cUnpackedExpression();
+            if(!dtCompare(index, dtInt())) {
+                cError("array index must be an int");
+            }
+            cConsumeToken(T_CLOSE_SQUARE_BRACKET);
+            cAddOperation(OP_ADD_REFERENCE);
+            dt = dtToVariable(dtReference(dt));
+        } else {
+            break;
+        }
+    }
+    return dt;
+}
+
+static DataType cPreChange(DataType dt, int change, const char* name) {
+    if(!dtRemoveVariable(&dt) || !dtCompare(dt, dtInt())) {
+        cError("%s needs an int reference", name);
     }
     cAddByteOperation(OP_PUSH_PRE_INT_CHANGE, change);
-    return dtInt();
+    return dt;
 }
 
 static DataType cPreUnary() {
-    if(cConsumeTokenIf(T_SUB)) {
-        DataType result = cPrimary();
-        if(dtCompare(result, dtInt())) {
+    if(cConsumeTokenIf(T_INCREMENT)) {
+        return cPreChange(cPreUnary(), 1, "++");
+    } else if(cConsumeTokenIf(T_DECREMENT)) {
+        return cPreChange(cPreUnary(), -1, "--");
+    } else if(cConsumeTokenIf(T_SUB)) {
+        DataType dt = cUnpack(cPreUnary());
+        if(dtCompare(dt, dtInt())) {
             cAddOperation(OP_INVERT_SIGN_INT);
-        } else if(dtCompare(result, dtFloat())) {
+        } else if(dtCompare(dt, dtFloat())) {
             cAddOperation(OP_INVERT_SIGN_FLOAT);
         } else {
-            cError("cannot invert sign of %s", cGetName(result));
+            cError("cannot invert sign of %s", cGetName(dt));
         }
-        return result;
-    } else if(cConsumeTokenIf(T_INCREMENT)) {
-        return cPreChange(1, "++");
-    } else if(cConsumeTokenIf(T_DECREMENT)) {
-        return cPreChange(-1, "--");
+        return dt;
     } else if(cConsumeTokenIf(T_NOT)) {
-        int counter = 1;
-        while(cConsumeTokenIf(T_NOT)) {
-            counter++;
-        }
-        DataType result = cPrimary();
-        if(!dtCompare(result, dtBool())) {
-            cError("! needs a bool not %s", cGetName(result));
+        DataType dt = cPreUnary();
+        if(!dtCompare(dt, dtBool())) {
+            cError("! needs a bool not %s", cGetName(dt));
         }
         cAddOperation(OP_NOT);
-        if((counter & 1) == 0) {
-            cAddOperation(OP_NOT);
-        }
-        return dtBool();
+        return dt;
     } else if(cConsumeTokenIf(T_BIT_NOT)) {
-        DataType result = cPrimary();
-        if(dtCompare(result, dtInt())) {
-            cAddOperation(OP_BIT_NOT);
-        } else {
-            cError("~ needs an int not %s", cGetName(result));
+        DataType dt = cPreUnary();
+        if(!dtCompare(dt, dtInt())) {
+            cError("~ needs an int not %s", cGetName(dt));
         }
-        return result;
+        cAddOperation(OP_BIT_NOT);
+        return dt;
     } else if(cConsumeTokenIf(T_BIT_AND)) {
-        cConsumeToken(T_LITERAL);
-        const char* literal = cReadString();
-        Variable v;
-        if(vsSearch(&vars, &v, literal)) {
-            cNotDeclared(literal);
+        DataType dt = cPreUnary();
+        if(!dtRemoveVariable(&dt)) {
+            cError("& needs a reference");
         }
-        cReference(&v, 0);
-        return dtDereference(v.type);
+        return dtDereference(dt);
     } else if(cConsumeTokenIf(T_MUL)) {
-        int c = 1;
-        while(cConsumeTokenIf(T_MUL)) {
-            c++;
-        }
-        cConsumeToken(T_LITERAL);
-        const char* literal = cReadString();
-        Variable v;
-        if(vsSearch(&vars, &v, literal)) {
-            cNotDeclared(literal);
+        DataType dt = cPreUnary();
+        if(!dtIsPointer(dt)) {
+            cError("* expects a pointer");
         }
-        cReference(&v, c);
-        cLoadRef(&v);
-        return v.type;
+        dt = dtReference(dt);
+        cAddOperation(OP_REFERENCE);
+        return dt;
     }
-    return cPrimary();
+    return cAccess();
 }
 
 static void cAddTypeOperation(DataType a, DataType b, const TypedOp* op) {
@@ -498,11 +565,14 @@ static DataType cMul() {
     DataType a = cPreUnary();
     while(true) {
         if(cConsumeTokenIf(T_MUL)) {
-            cAddTypeOperation(a, cPreUnary(), &TYPED_MUL);
+            a = cUnpack(a);
+            cAddTypeOperation(a, cUnpack(cPreUnary()), &TYPED_MUL);
         } else if(cConsumeTokenIf(T_DIV)) {
-            cAddTypeOperation(a, cPreUnary(), &TYPED_DIV);
+            a = cUnpack(a);
+            cAddTypeOperation(a, cUnpack(cPreUnary()), &TYPED_DIV);
         } else if(cConsumeTokenIf(T_MOD)) {
-            cAddTypeOperation(a, cPreUnary(), &TYPED_MOD);
+            a = cUnpack(a);
+            cAddTypeOperation(a, cUnpack(cPreUnary()), &TYPED_MOD);
         } else {
             break;
         }
@@ -514,9 +584,11 @@ static DataType cAdd() {
     DataType a = cMul();
     while(true) {
         if(cConsumeTokenIf(T_ADD)) {
-            cAddTypeOperation(a, cMul(), &TYPED_ADD);
+            a = cUnpack(a);
+            cAddTypeOperation(a, cUnpack(cMul()), &TYPED_ADD);
         } else if(cConsumeTokenIf(T_SUB)) {
-            cAddTypeOperation(a, cMul(), &TYPED_SUB);
+            a = cUnpack(a);
+            cAddTypeOperation(a, cUnpack(cMul()), &TYPED_SUB);
         } else {
             break;
         }
@@ -528,9 +600,11 @@ static DataType cShift() {
     DataType a = cAdd();
     while(true) {
         if(cConsumeTokenIf(T_LEFT_SHIFT)) {
-            cAddTypeOperation(a, cAdd(), &TYPED_LEFT_SHIFT);
+            a = cUnpack(a);
+            cAddTypeOperation(a, cUnpack(cAdd()), &TYPED_LEFT_SHIFT);
         } else if(cConsumeTokenIf(T_RIGHT_SHIFT)) {
-            cAddTypeOperation(a, cAdd(), &TYPED_RIGHT_SHIFT);
+            a = cUnpack(a);
+            cAddTypeOperation(a, cUnpack(cAdd()), &TYPED_RIGHT_SHIFT);
         } else {
             break;
         }
@@ -542,17 +616,21 @@ static DataType cComparison() {
     DataType a = cShift();
     while(true) {
         if(cConsumeTokenIf(T_LESS)) {
-            cAddTypeOperation(a, cShift(), &TYPED_LESS);
+            a = cUnpack(a);
+            cAddTypeOperation(a, cUnpack(cShift()), &TYPED_LESS);
             a = dtBool();
         } else if(cConsumeTokenIf(T_LESS_EQUAL)) {
-            cAddTypeOperation(a, cShift(), &TYPED_LESS_EQUAL);
+            a = cUnpack(a);
+            cAddTypeOperation(a, cUnpack(cShift()), &TYPED_LESS_EQUAL);
             cAddOperation(OP_NOT);
             a = dtBool();
         } else if(cConsumeTokenIf(T_GREATER)) {
-            cAddTypeOperation(a, cShift(), &TYPED_GREATER);
+            a = cUnpack(a);
+            cAddTypeOperation(a, cUnpack(cShift()), &TYPED_GREATER);
             a = dtBool();
         } else if(cConsumeTokenIf(T_GREATER_EQUAL)) {
-            cAddTypeOperation(a, cShift(), &TYPED_GREATER_EQUAL);
+            a = cUnpack(a);
+            cAddTypeOperation(a, cUnpack(cShift()), &TYPED_GREATER_EQUAL);
             cAddOperation(OP_NOT);
             a = dtBool();
         } else {
@@ -566,10 +644,12 @@ static DataType cEqual() {
     DataType a = cComparison();
     while(true) {
         if(cConsumeTokenIf(T_EQUAL)) {
-            cAddTypeOperation(a, cComparison(), &TYPED_EQUAL);
+            a = cUnpack(a);
+            cAddTypeOperation(a, cUnpack(cComparison()), &TYPED_EQUAL);
             a = dtBool();
         } else if(cConsumeTokenIf(T_NOT_EQUAL)) {
-            cAddTypeOperation(a, cComparison(), &TYPED_NOT_EQUAL);
+            a = cUnpack(a);
+            cAddTypeOperation(a, cUnpack(cComparison()), &TYPED_NOT_EQUAL);
             cAddOperation(OP_NOT);
             a = dtBool();
         } else {
@@ -582,8 +662,8 @@ static DataType cEqual() {
 static DataType cBitAnd() {
     DataType a = cEqual();
     while(cConsumeTokenIf(T_BIT_AND)) {
-        DataType b = cEqual();
-        cAddTypeOperation(a, b, &TYPED_BIT_AND);
+        a = cUnpack(a);
+        cAddTypeOperation(a, cUnpack(cEqual()), &TYPED_BIT_AND);
     }
     return a;
 }
@@ -591,8 +671,8 @@ static DataType cBitAnd() {
 static DataType cBitXor() {
     DataType a = cBitAnd();
     while(cConsumeTokenIf(T_BIT_XOR)) {
-        DataType b = cBitAnd();
-        cAddTypeOperation(a, b, &TYPED_BIT_XOR);
+        a = cUnpack(a);
+        cAddTypeOperation(a, cUnpack(cBitAnd()), &TYPED_BIT_XOR);
     }
     return a;
 }
@@ -600,8 +680,8 @@ static DataType cBitXor() {
 static DataType cBitOr() {
     DataType a = cBitXor();
     while(cConsumeTokenIf(T_BIT_OR)) {
-        DataType b = cBitXor();
-        cAddTypeOperation(a, b, &TYPED_BIT_OR);
+        a = cUnpack(a);
+        cAddTypeOperation(a, cUnpack(cBitXor()), &TYPED_BIT_OR);
     }
     return a;
 }
@@ -609,9 +689,10 @@ static DataType cBitOr() {
 static DataType cAnd() {
     DataType a = cBitOr();
     while(cConsumeTokenIf(T_AND)) {
+        a = cUnpack(a);
         cAddOperation(OP_PEEK_FALSE_GOTO);
         int p = cReserveInt();
-        DataType b = cBitOr();
+        DataType b = cUnpack(cBitOr());
         if(!dtCompare(a, dtBool()) || !dtCompare(b, dtBool())) {
             cInvalidOperation(a, b, "&&");
         }
@@ -624,9 +705,10 @@ static DataType cAnd() {
 static DataType cOr() {
     DataType a = cAnd();
     while(cConsumeTokenIf(T_OR)) {
+        a = cUnpack(a);
         cAddOperation(OP_PEEK_TRUE_GOTO);
         int p = cReserveInt();
-        DataType b = cAnd();
+        DataType b = cUnpack(cAnd());
         if(!dtCompare(a, dtBool()) || !dtCompare(b, dtBool())) {
             cInvalidOperation(a, b, "||");
         }
@@ -642,8 +724,8 @@ static DataType cExpression() {
 
 static void cOperationSet(Variable* v, const TypedOp* op) {
     cAddOperation(OP_DUPLICATE_REFERENCE);
-    cLoadRef(v);
-    DataType dt = cExpression();
+    cLoadRef(v->type);
+    DataType dt = cUnpackedExpression();
     cAddTypeOperation(v->type, dt, op);
     cStore(v, dt, "=");
 }
@@ -655,13 +737,6 @@ static void cAddPostLineChange(Variable* v, int change, const char* name) {
     cAddByteOperation(OP_INT_CHANGE, change);
 }
 
-static DataType cExtendType(DataType dt) {
-    while(cConsumeTokenIf(T_MUL)) {
-        dt = dtDereference(dt);
-    }
-    return dt;
-}
-
 static void cDeclareStruct(Struct* st) {
     DataType dt = cExtendType(dtStruct(st));
     cConsumeToken(T_LITERAL);
@@ -673,7 +748,7 @@ static void cDeclareStruct(Struct* st) {
     if(dtIsPointer(dt)) {
         cConsumeToken(T_SET);
         cReference(vp, 0);
-        cStore(vp, cExpression(), "=");
+        cStore(vp, cUnpackedExpression(), "=");
     }
 }
 
@@ -685,7 +760,7 @@ static void cLineVariable(const char* name, int dimension) {
     cReference(&v, dimension);
     Token t = cReadTokenAndLine();
     switch(t) {
-        case T_SET: cStore(&v, cExpression(), "="); break;
+        case T_SET: cStore(&v, cUnpackedExpression(), "="); break;
         case T_ADD_SET: cOperationSet(&v, &TYPED_ADD); break;
         case T_SUB_SET: cOperationSet(&v, &TYPED_SUB); break;
         case T_MUL_SET: cOperationSet(&v, &TYPED_MUL); break;
@@ -755,7 +830,7 @@ static void cReturn() {
         cAddReturn(OP_RETURN);
         return;
     }
-    DataType dt = cExpression();
+    DataType dt = cUnpackedExpression();
     if(!dtCompare(dt, returnType)) {
         cError("wrong return type, should be %s", cGetName(returnType));
     }
@@ -772,7 +847,7 @@ static void cReturn() {
 }
 
 static void cPrint() {
-    DataType dt = cExpression();
+    DataType dt = cUnpackedExpression();
     if(dtIsPointer(dt)) {
         cAddOperation(OP_PRINT_POINTER);
         cConsumeToken(T_SEMICOLON);
@@ -787,7 +862,7 @@ static void cPrint() {
 
 static void cIf() {
     cConsumeToken(T_OPEN_BRACKET);
-    DataType dt = cExpression();
+    DataType dt = cUnpackedExpression();
     if(!dtCompare(dt, dtBool())) {
         cError("if expects a bool not %s", cGetName(dt));
     }
@@ -822,7 +897,7 @@ static void cConsumeBreaks(int start, int address) {
 static void cWhile() {
     int start = code->length;
     cConsumeToken(T_OPEN_BRACKET);
-    DataType dt = cExpression();
+    DataType dt = cUnpackedExpression();
     if(!dtCompare(dt, dtBool())) {
         cError("while expects a bool not %s", cGetName(dt));
     }
@@ -852,7 +927,7 @@ static void cDeclare(DataType dt) {
     Variable* vp = vsAdd(&vars, var, dt, &structs);
     cConsumeToken(T_SET);
     cReference(vp, 0);
-    cStore(vp, cExpression(), "=");
+    cStore(vp, cUnpackedExpression(), "=");
 }
 
 static void cAddPreLineChange(int change, const char* name) {
@@ -867,7 +942,7 @@ static void cAddPreLineChange(int change, const char* name) {
 }
 
 static void cDelete() {
-    DataType pointer = cExpression();
+    DataType pointer = cUnpackedExpression();
     if(!dtIsPointer(pointer)) {
         cError("delete expects a pointer");
     }
@@ -905,7 +980,7 @@ static void cFor() {
     cLineExpression(cReadTokenAndLine());
     cConsumeToken(T_SEMICOLON);
     int startCheck = code->length;
-    DataType dt = cExpression();
+    DataType dt = cUnpackedExpression();
     if(!dtCompare(dt, dtBool())) {
         cError("for expects a bool not %s", cGetName(dt));
     }
@@ -1108,25 +1183,7 @@ static void cStruct() {
     DataType self = dtStruct(st);
     cConsumeToken(T_OPEN_CURVED_BRACKET);
     while(!cConsumeTokenIf(T_CLOSE_CURVED_BRACKET)) {
-        Token t = cReadTokenAndLine();
-        DataType dt = dtVoid();
-        switch(t) {
-            case T_INT: dt = dtInt(); break;
-            case T_BOOL: dt = dtBool(); break;
-            case T_FLOAT: dt = dtFloat(); break;
-            case T_LITERAL:
-                {
-                    const char* name = cReadString();
-                    Struct* st = stsSearch(&structs, name);
-                    if(st == NULL) {
-                        cError("struct %s does not exist");
-                    }
-                    dt = dtStruct(st);
-                    break;
-                }
-            default: cUnexpectedToken(t);
-        }
-        dt = cExtendType(dt);
+        DataType dt = cReadType();
         if(dtCompare(dt, self)) {
             cError("struct %s contains itself", name);
         }

+ 13 - 5
DataType.c

@@ -93,11 +93,6 @@ DataType dtDereference(DataType dt) {
     return dt;
 }
 
-DataType dtToArray(DataType dt, int dimension) {
-    dt.pointers = dimension;
-    return dt;
-}
-
 bool dtCompare(DataType a, DataType b) {
     return a.pointers == b.pointers && a.structId == b.structId &&
            a.type == b.type;
@@ -118,6 +113,19 @@ Struct* dtGetStruct(Structs* sts, DataType dt) {
     return sts->data + dt.structId;
 }
 
+DataType dtToVariable(DataType dt) {
+    dt.type |= 8;
+    return dt;
+}
+
+bool dtRemoveVariable(DataType* dt) {
+    if(dt->type & 8) {
+        dt->type &= 7;
+        return true;
+    }
+    return false;
+}
+
 void stAddVariable(Struct* st, const char* name, DataType type) {
     int index = st->amount;
     st->amount++;

+ 2 - 1
DataType.h

@@ -48,9 +48,10 @@ DataType dtStruct(Struct* st);
 
 DataType dtReference(DataType dt);
 DataType dtDereference(DataType dt);
-DataType dtToArray(DataType dt, int dimension);
 bool dtIsPointer(DataType dt);
 Struct* dtGetStruct(Structs* sts, DataType dt);
+DataType dtToVariable(DataType dt);
+bool dtRemoveVariable(DataType* dt);
 
 bool dtCompare(DataType a, DataType b);
 int dtMaxDimensions();

+ 33 - 0
tests/arrays/types

@@ -0,0 +1,33 @@
+struct A {
+    int a;
+};
+
+void main() {
+    int* a = new int[4];
+    float* b = new float[4];
+    bool* c = new bool[4];
+    A* d = new A[4];
+    int** e = new int*[4];
+    float** f = new float*[4];
+    bool** g = new bool*[4];
+    A** h = new A*[4];
+    
+    int test = -243;
+    a[2] = -test;
+    b[2] = 23.5;
+    c[2] = true;
+    d[2].a = 64564;
+    e[2] = &a[2];
+    f[2] = &b[2];
+    g[2] = &c[2];
+    h[2] = &d[2];
+    
+    print a[2];
+    print b[2];
+    print c[2];
+    print d[2].a;
+    print *e[2];
+    print *f[2];
+    print *g[2];
+    print (*h[2]).a;
+}

+ 8 - 0
tests/arrays/types.out

@@ -0,0 +1,8 @@
+243
+23.50
+true
+64564
+243
+23.50
+true
+64564

+ 1 - 1
tests/bits/invert

@@ -1,4 +1,4 @@
 void main() {
     print ~0;
-    print ~(~7);
+    print ~~~(~7);
 }

+ 1 - 1
tests/struct/int_reference

@@ -8,7 +8,7 @@ void main() {
     int* b = &a;
     a = 6;
     print a;
-    print *b;
+    print *(b);
     test(&a);
     test(b);
     print a;

+ 0 - 1
utils/ByteCodePrinter.c

@@ -174,7 +174,6 @@ static void btConsumeOperation() {
         PRINT_OP(OP_DELETE);
         PRINT_OP(OP_LENGTH);
         PRINT_OP_INT(OP_LOAD);
-        PRINT_OP(OP_LOAD_POINTER);
         PRINT_OP(OP_STORE_POINTER);
         PRINT_OP(OP_EQUAL_POINTER);
         PRINT_OP_BYTE(OP_PUSH_PRE_INT_CHANGE);

+ 0 - 1
vm/Operation.h

@@ -51,7 +51,6 @@ typedef enum Operation {
     OP_NEW,
     OP_DELETE,
     OP_LENGTH,
-    OP_LOAD_POINTER,
     OP_STORE_POINTER,
     OP_PUSH_PRE_INT_CHANGE,
     OP_PUSH_POST_INT_CHANGE,

+ 4 - 16
vm/Script.c

@@ -352,13 +352,12 @@ static void sDereference(Script* sc) {
     }
 }
 
-static void sReference(Script* sc) {
+static void sLoad(Script* sc, int length) {
     Pointer p;
     if(sPopPointer(sc, &p)) {
-        void* src = sCheckAddress(sc, &p, sizeof(Pointer));
+        void* src = sCheckAddress(sc, &p, length);
         if(src != NULL) {
-            memcpy(&p, src, sizeof(Pointer));
-            sPushPointer(sc, &p);
+            sPush(sc, src, length);
         }
     }
 }
@@ -405,16 +404,6 @@ static void sStore(Script* sc, int length) {
     }
 }
 
-static void sLoad(Script* sc, int length) {
-    Pointer p;
-    if(sPopPointer(sc, &p)) {
-        void* src = sCheckAddress(sc, &p, length);
-        if(src != NULL) {
-            sPush(sc, src, length);
-        }
-    }
-}
-
 static void sEqualPointer(Script* sc) {
     Pointer a;
     Pointer b;
@@ -522,14 +511,13 @@ static void sConsumeInstruction(Script* sc) {
         case OP_RETURN: sReturn(sc); break;
         case OP_RESERVE: sReserveBytes(sc); break;
         case OP_DEREFERENCE_VAR: sDereference(sc); break;
-        case OP_REFERENCE: sReference(sc); break;
+        case OP_REFERENCE: sLoad(sc, sizeof(Pointer)); break;
         case OP_DUPLICATE_REFERENCE: sDuplicateReference(sc); break;
         case OP_ADD_REFERENCE: sAddReference(sc); break;
         case OP_LOAD: sLoadSize(sc); break;
         case OP_NEW: sNewArray(sc); break;
         case OP_DELETE: sDeleteArray(sc); break;
         case OP_LENGTH: sLength(sc); break;
-        case OP_LOAD_POINTER: sLoad(sc, sizeof(Pointer)); break;
         case OP_STORE_POINTER: sStore(sc, sizeof(Pointer)); break;
         case OP_PRINT_POINTER: sPrintPointer(sc); break;
         case OP_EQUAL_POINTER: sEqualPointer(sc); break;