Browse Source

refactoring

Kajetan Johannes Hammerle 3 years ago
parent
commit
2f17cd404f
5 changed files with 101 additions and 172 deletions
  1. 84 167
      Compiler.c
  2. 5 3
      tests/arrays/types
  3. 2 2
      tests/struct/struct_access
  4. 8 0
      tokenizer/Tokenizer.c
  5. 2 0
      tokenizer/Tokenizer.h

+ 84 - 167
Compiler.c

@@ -26,6 +26,7 @@ static char error[ERROR_LENGTH] = {'\0'};
 static ByteCode* code;
 
 static int16 line = 1;
+static bool onLine = false;
 
 static Variables vars;
 static Functions functions;
@@ -262,100 +263,30 @@ static DataType cCallFunction(const char* name) {
     return found->returnType;
 }
 
-static void cWalkStruct(Variable* v) {
-    int offset = 0;
-    while(true) {
-        if(cConsumeTokenIf(T_OPEN_SQUARE_BRACKET)) {
-            if(!dtIsPointer(v->type)) {
-                cError("[] need a pointer");
-            }
-            cAddOperation(OP_REFERENCE);
-            DataType index = cUnpackedExpression();
-            if(!dtCompare(index, dtInt())) {
-                cError("array index must be an int");
-            }
-            cConsumeToken(T_CLOSE_SQUARE_BRACKET);
-            cAddOperation(OP_ADD_REFERENCE);
-            v->type = dtReference(v->type);
-        }
-        int pointers;
-        if(cConsumeTokenIf(T_ARROW)) {
-            pointers = 1;
-            cAddOperation(OP_REFERENCE);
-        } else if(cConsumeTokenIf(T_POINT)) {
-            pointers = 0;
-        } else {
-            break;
-        }
-        Struct* st = dtGetStruct(&structs, v->type);
-        if(st == NULL || v->type.pointers != pointers) {
-            cError("%s is not a %s but %s", v->name,
-                   pointers ? "struct*" : "struct", cGetName(v->type));
-        }
-        cConsumeToken(T_LITERAL);
-        const char* name = cReadString();
-        Variable inner;
-        if(vSearchStruct(&inner, &structs, st, name)) {
-            cError("%s has no member %s", v->name, name);
-        }
-        v->type = inner.type;
-        v->name = inner.name;
-        offset += inner.address;
-    }
-    if(offset > 0) {
-        cAddIntOperation(OP_PUSH_INT, offset);
-        cAddOperation(OP_ADD_REFERENCE);
-    }
-}
-
-static void cReference(Variable* v, int dimension) {
-    cAddIntOperation(OP_DEREFERENCE_VAR, v->address);
-    while(dimension > 0) {
-        if(!dtIsPointer(v->type)) {
-            cError("too many *");
-        }
-        v->type = dtReference(v->type);
-        dimension--;
-        cAddOperation(OP_REFERENCE);
+static void cStore(DataType left, DataType right, const char* name) {
+    if(!dtCompare(left, right)) {
+        cInvalidOperation(left, right, name);
     }
-    cWalkStruct(v);
-}
-
-static void cStore(Variable* v, DataType dt, const char* name) {
-    if(!dtCompare(v->type, dt)) {
-        cInvalidOperation(v->type, dt, name);
-    }
-    if(dtIsPointer(v->type)) {
+    if(dtIsPointer(left)) {
         cAddOperation(OP_STORE_POINTER);
         return;
     }
-    switch(v->type.type) {
+    switch(left.type) {
         DT_OPERATION(STORE);
-        default: cError("cannot store type %s", cGetName(v->type));
+        default: cError("cannot store type %s", cGetName(left));
     }
 }
 
 static DataType cLiteral() {
     const char* literal = cReadString();
     if(cConsumeTokenIf(T_OPEN_BRACKET)) {
-        DataType dt = cCallFunction(literal);
-        if(dtCompare(dt, dtVoid())) {
-            cError("function returns void");
-        }
-        return dt;
+        return cCallFunction(literal);
     }
     Variable v;
     if(vsSearch(&vars, &v, literal)) {
         cNotDeclared(literal);
     }
     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, "--");
-    }*/
     return dtToVariable(v.type);
 }
 
@@ -433,8 +364,12 @@ static DataType cPrimary() {
 static void cPostChange(DataType* dt, int change, const char* name) {
     if(!dtRemoveVariable(dt) || !dtCompare(*dt, dtInt())) {
         cError("%s needs an int reference", name);
+    } else if(onLine) {
+        cAddByteOperation(OP_INT_CHANGE, change);
+        *dt = dtVoid();
+    } else {
+        cAddByteOperation(OP_PUSH_POST_INT_CHANGE, change);
     }
-    cAddByteOperation(OP_PUSH_POST_INT_CHANGE, change);
 }
 
 static DataType cStructAccess(DataType dt, int pointers) {
@@ -492,6 +427,10 @@ static DataType cPreChange(DataType dt, int change, const char* name) {
     if(!dtRemoveVariable(&dt) || !dtCompare(dt, dtInt())) {
         cError("%s needs an int reference", name);
     }
+    if(onLine) {
+        cAddByteOperation(OP_INT_CHANGE, change);
+        return dtVoid();
+    }
     cAddByteOperation(OP_PUSH_PRE_INT_CHANGE, change);
     return dt;
 }
@@ -722,16 +661,16 @@ static DataType cExpression() {
     return cOr();
 }
 
-static void cOperationSet(Variable* v, const TypedOp* op) {
+static void cOperationSet(DataType left, const TypedOp* op) {
     cAddOperation(OP_DUPLICATE_REFERENCE);
-    cLoadRef(v->type);
-    DataType dt = cUnpackedExpression();
-    cAddTypeOperation(v->type, dt, op);
-    cStore(v, dt, "=");
+    cLoadRef(left);
+    DataType right = cUnpackedExpression();
+    cAddTypeOperation(left, right, op);
+    cStore(left, right, "=");
 }
 
-static void cAddPostLineChange(Variable* v, int change, const char* name) {
-    if(!dtCompare(v->type, dtInt())) {
+static void cAddPostLineChange(DataType dt, int change, const char* name) {
+    if(!dtCompare(dt, dtInt())) {
         cError("%s needs an int", name);
     }
     cAddByteOperation(OP_INT_CHANGE, change);
@@ -744,67 +683,24 @@ static void cDeclareStruct(Struct* st) {
     if(vsInScope(&vars, var)) {
         cDeclared(var);
     }
-    Variable* vp = vsAdd(&vars, var, dt, &structs);
+    Variable* v = vsAdd(&vars, var, dt, &structs);
     if(dtIsPointer(dt)) {
         cConsumeToken(T_SET);
-        cReference(vp, 0);
-        cStore(vp, cUnpackedExpression(), "=");
-    }
-}
-
-static void cLineVariable(const char* name, int dimension) {
-    Variable v;
-    if(vsSearch(&vars, &v, name)) {
-        cNotDeclared(name);
+        cAddIntOperation(OP_DEREFERENCE_VAR, v->address);
+        cStore(v->type, cUnpackedExpression(), "=");
     }
-    cReference(&v, dimension);
-    Token t = cReadTokenAndLine();
-    switch(t) {
-        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;
-        case T_DIV_SET: cOperationSet(&v, &TYPED_DIV); break;
-        case T_MOD_SET: cOperationSet(&v, &TYPED_MOD); break;
-        case T_BIT_AND_SET: cOperationSet(&v, &TYPED_BIT_AND); break;
-        case T_BIT_OR_SET: cOperationSet(&v, &TYPED_BIT_OR); break;
-        case T_BIT_XOR_SET: cOperationSet(&v, &TYPED_BIT_XOR); break;
-        case T_LEFT_SHIFT_SET: cOperationSet(&v, &TYPED_LEFT_SHIFT); break;
-        case T_RIGHT_SHIFT_SET: cOperationSet(&v, &TYPED_RIGHT_SHIFT); break;
-        case T_INCREMENT: cAddPostLineChange(&v, 1, "++"); break;
-        case T_DECREMENT: cAddPostLineChange(&v, -1, "--"); break;
-        default: cUnexpectedToken(t);
-    }
-}
-
-static void cLineLiteral() {
-    const char* literal = cReadString();
-    if(cConsumeTokenIf(T_OPEN_BRACKET)) {
-        DataType dt = cCallFunction(literal);
-        if(!dtCompare(dt, dtVoid())) {
-            cError("function returns %s not void", cGetName(dt));
-        }
-        return;
-    }
-    Struct* st = stsSearch(&structs, literal);
-    if(st != NULL) {
-        cDeclareStruct(st);
-        return;
-    }
-    cLineVariable(literal, 0);
 }
 
-static void cLine(Token t);
+static void cLine();
 
 static void cConsumeBody() {
     int oldLine = line;
     while(!cConsumeTokenIf(T_CLOSE_CURVED_BRACKET)) {
-        Token t = cReadTokenAndLine();
-        if(t == T_END) {
+        if(tPeekToken() == T_END) {
             line = oldLine;
             cError("unexpected end of file: non closed curved bracket");
         }
-        cLine(t);
+        cLine();
     }
 }
 
@@ -924,21 +820,10 @@ static void cDeclare(DataType dt) {
     if(vsInScope(&vars, var)) {
         cDeclared(var);
     }
-    Variable* vp = vsAdd(&vars, var, dt, &structs);
+    Variable* v = vsAdd(&vars, var, dt, &structs);
     cConsumeToken(T_SET);
-    cReference(vp, 0);
-    cStore(vp, cUnpackedExpression(), "=");
-}
-
-static void cAddPreLineChange(int change, const char* name) {
-    cConsumeToken(T_LITERAL);
-    const char* literal = cReadString();
-    Variable v;
-    if(vsSearch(&vars, &v, literal)) {
-        cNotDeclared(literal);
-    }
-    cReference(&v, 0);
-    cAddPostLineChange(&v, change, name);
+    cAddIntOperation(OP_DEREFERENCE_VAR, v->address);
+    cStore(v->type, cUnpackedExpression(), "=");
 }
 
 static void cDelete() {
@@ -949,26 +834,52 @@ static void cDelete() {
     cAddOperation(OP_DELETE);
 }
 
-static void cLineExpression(Token t) {
+static void cSetVariable() {
+    onLine = true;
+    DataType dt = cPreUnary();
+    onLine = false;
+    if(dtCompare(dt, dtVoid())) {
+        return;
+    }
+    if(!dtRemoveVariable(&dt)) {
+        cError("reference or void expected: %s", cGetName(dt));
+    }
+    Token t = cReadTokenAndLine();
+    switch(t) {
+        case T_SET: cStore(dt, cUnpackedExpression(), "="); break;
+        case T_ADD_SET: cOperationSet(dt, &TYPED_ADD); break;
+        case T_SUB_SET: cOperationSet(dt, &TYPED_SUB); break;
+        case T_MUL_SET: cOperationSet(dt, &TYPED_MUL); break;
+        case T_DIV_SET: cOperationSet(dt, &TYPED_DIV); break;
+        case T_MOD_SET: cOperationSet(dt, &TYPED_MOD); break;
+        case T_BIT_AND_SET: cOperationSet(dt, &TYPED_BIT_AND); break;
+        case T_BIT_OR_SET: cOperationSet(dt, &TYPED_BIT_OR); break;
+        case T_BIT_XOR_SET: cOperationSet(dt, &TYPED_BIT_XOR); break;
+        case T_LEFT_SHIFT_SET: cOperationSet(dt, &TYPED_LEFT_SHIFT); break;
+        case T_RIGHT_SHIFT_SET: cOperationSet(dt, &TYPED_RIGHT_SHIFT); break;
+        case T_INCREMENT: cAddPostLineChange(dt, 1, "++"); break;
+        case T_DECREMENT: cAddPostLineChange(dt, -1, "--"); break;
+        default: cUnexpectedToken(t);
+    }
+}
+
+static void cLineExpression() {
+    int marker = tGetMarker();
+    Token t = cReadTokenAndLine();
+    if(t == T_LITERAL) {
+        const char* literal = cReadString();
+        Struct* st = stsSearch(&structs, literal);
+        if(st != NULL) {
+            cDeclareStruct(st);
+            return;
+        }
+    }
     switch(t) {
-        case T_LITERAL: cLineLiteral(); break;
         case T_INT: cDeclare(dtInt()); break;
         case T_BOOL: cDeclare(dtBool()); break;
         case T_FLOAT: cDeclare(dtFloat()); break;
-        case T_INCREMENT: cAddPreLineChange(1, "++"); break;
-        case T_DECREMENT: cAddPreLineChange(-1, "--"); break;
-        case T_MUL:
-            {
-                int c = 1;
-                while(cConsumeTokenIf(T_MUL)) {
-                    c++;
-                }
-                cConsumeToken(T_LITERAL);
-                cLineVariable(cReadString(), c);
-                break;
-            }
         case T_DELETE: cDelete(); break;
-        default: cUnexpectedToken(t);
+        default: tReset(marker); cSetVariable();
     }
 }
 
@@ -977,7 +888,7 @@ static void cFor() {
     vsEnterScope(&vars, &scope);
 
     cConsumeToken(T_OPEN_BRACKET);
-    cLineExpression(cReadTokenAndLine());
+    cLineExpression();
     cConsumeToken(T_SEMICOLON);
     int startCheck = code->length;
     DataType dt = cUnpackedExpression();
@@ -990,7 +901,7 @@ static void cFor() {
     cAddOperation(OP_GOTO);
     int beginBody = cReserveInt();
     int startPerLoop = code->length;
-    cLineExpression(cReadTokenAndLine());
+    cLineExpression();
     cAddIntOperation(OP_GOTO, startCheck);
     cConsumeToken(T_CLOSE_BRACKET);
     cSetInt(beginBody, code->length);
@@ -1028,7 +939,9 @@ static void cContinue() {
     cConsumeToken(T_SEMICOLON);
 }
 
-static void cLine(Token t) {
+static void cLine() {
+    int marker = tGetMarker();
+    Token t = cReadTokenAndLine();
     hasReturn = false;
     cAddOperation(OP_LINE);
     cAddInt16(line);
@@ -1041,7 +954,10 @@ static void cLine(Token t) {
         case T_FOR: cFor(); break;
         case T_BREAK: cBreak(); break;
         case T_CONTINUE: cContinue(); break;
-        default: cLineExpression(t); cConsumeToken(T_SEMICOLON);
+        default:
+            tReset(marker);
+            cLineExpression();
+            cConsumeToken(T_SEMICOLON);
     }
 }
 
@@ -1245,6 +1161,7 @@ static void cAllocAndCompile() {
     forWhileStack = 0;
     breakIndex = 0;
     returnType = dtVoid();
+    onLine = false;
     vsInit(&vars);
     fsInit(&functions);
     fsInit(&functionQueue);

+ 5 - 3
tests/arrays/types

@@ -12,16 +12,18 @@ void main() {
     bool** g = new bool*[4];
     A** h = new A*[4];
     
-    int test = -243;
-    a[2] = -test;
+    a[2] = 243;
     b[2] = 23.5;
     c[2] = true;
-    d[2].a = 64564;
+    d[2].a = 64560;
     e[2] = &a[2];
     f[2] = &b[2];
     g[2] = &c[2];
     h[2] = &d[2];
     
+    h[2]->a += 2;
+    (*h[2]).a += 2;
+    
     print a[2];
     print b[2];
     print c[2];

+ 2 - 2
tests/struct/struct_access

@@ -15,9 +15,9 @@ void main() {
     *ref = 6;
     **refa = 6;
     ***refb = 4;
-    ***refb++;
+    (***refb)++;
     
-    *apa->w++;
+    (*apa)->w++;
     
     a.w++;
     ++a.w;

+ 8 - 0
tokenizer/Tokenizer.c

@@ -299,4 +299,12 @@ const char* tReadString(int* length) {
         }
     }
     return NULL;
+}
+
+int tGetMarker() {
+    return readIndex;
+}
+
+void tReset(int marker) {
+    readIndex = marker;
 }

+ 2 - 0
tokenizer/Tokenizer.h

@@ -18,5 +18,7 @@ bool tReadInt(int* i);
 bool tReadInt16(int16* i);
 bool tReadFloat(float* f);
 const char* tReadString(int* length);
+int tGetMarker();
+void tReset(int marker);
 
 #endif