Explorar el Código

type safety mostly done, arrays / strings outstanding

Kajetan Johannes Hammerle hace 3 años
padre
commit
7a5573d024
Se han modificado 100 ficheros con 942 adiciones y 788 borrados
  1. 441 340
      Compiler.c
  2. 1 1
      meson.build
  3. 0 5
      old_tests/bits/and
  4. 0 2
      old_tests/bits/invert
  5. 0 5
      old_tests/bits/or
  6. 0 9
      old_tests/bits/shift
  7. 0 5
      old_tests/bits/xor
  8. 0 22
      old_tests/functions/arguments
  9. 0 10
      old_tests/functions/arguments.out
  10. 0 14
      old_tests/functions/forward
  11. 0 7
      old_tests/functions/function
  12. 0 13
      old_tests/functions/overloading
  13. 0 10
      old_tests/functions/recursion
  14. 0 7
      old_tests/functions/return
  15. 0 11
      old_tests/functions/return_value
  16. 0 18
      old_tests/functions/scope
  17. 0 13
      old_tests/if/and
  18. 0 13
      old_tests/if/else
  19. 0 9
      old_tests/if/if
  20. 0 6
      old_tests/if/invert
  21. 0 13
      old_tests/if/or
  22. 0 19
      old_tests/loops/break
  23. 0 35
      old_tests/loops/continue
  24. 0 9
      old_tests/loops/for
  25. 0 5
      old_tests/loops/while
  26. 0 10
      old_tests/loops/while_post_dec
  27. 0 10
      old_tests/loops/while_post_inc
  28. 0 10
      old_tests/loops/while_pre_dec
  29. 0 10
      old_tests/loops/while_pre_inc
  30. 0 6
      old_tests/mix
  31. 0 3
      old_tests/strings/const_string
  32. 0 3
      old_tests/strings/const_string.out
  33. 0 1
      old_tests/types/null
  34. 0 1
      old_tests/types/null.out
  35. 7 0
      tests/bits/and
  36. 0 0
      tests/bits/and.out
  37. 4 0
      tests/bits/invert
  38. 0 0
      tests/bits/invert.out
  39. 7 0
      tests/bits/or
  40. 0 0
      tests/bits/or.out
  41. 11 0
      tests/bits/shift
  42. 0 0
      tests/bits/shift.out
  43. 7 0
      tests/bits/xor
  44. 0 0
      tests/bits/xor.out
  45. 10 8
      tests/calc/add
  46. 14 12
      tests/calc/div
  47. 7 5
      tests/calc/mod
  48. 10 8
      tests/calc/mul
  49. 6 4
      tests/calc/sub
  50. 8 6
      tests/comments/line
  51. 8 6
      tests/comments/lines
  52. 16 14
      tests/comparison/equal
  53. 12 10
      tests/comparison/greater
  54. 12 10
      tests/comparison/greater_equal
  55. 12 10
      tests/comparison/less
  56. 12 10
      tests/comparison/less_equal
  57. 16 14
      tests/comparison/not_equal
  58. 20 0
      tests/functions/arguments
  59. 6 0
      tests/functions/arguments.out
  60. 19 0
      tests/functions/forward
  61. 0 0
      tests/functions/forward.out
  62. 9 0
      tests/functions/function
  63. 0 0
      tests/functions/function.out
  64. 6 4
      tests/functions/function2
  65. 0 0
      tests/functions/function2.out
  66. 15 0
      tests/functions/overloading
  67. 0 0
      tests/functions/overloading.out
  68. 12 0
      tests/functions/recursion
  69. 0 0
      tests/functions/recursion.out
  70. 9 0
      tests/functions/return
  71. 0 0
      tests/functions/return.out
  72. 15 0
      tests/functions/return_value
  73. 1 0
      tests/functions/return_value.out
  74. 18 0
      tests/functions/scope
  75. 2 2
      tests/functions/scope.out
  76. 15 0
      tests/if/and
  77. 0 0
      tests/if/and.out
  78. 15 0
      tests/if/else
  79. 0 0
      tests/if/else.out
  80. 13 10
      tests/if/elseif
  81. 0 0
      tests/if/elseif.out
  82. 11 0
      tests/if/if
  83. 0 0
      tests/if/if.out
  84. 8 0
      tests/if/invert
  85. 0 0
      tests/if/invert.out
  86. 15 0
      tests/if/or
  87. 0 0
      tests/if/or.out
  88. 21 0
      tests/loops/break
  89. 0 0
      tests/loops/break.out
  90. 37 0
      tests/loops/continue
  91. 0 0
      tests/loops/continue.out
  92. 11 0
      tests/loops/for
  93. 0 0
      tests/loops/for.out
  94. 7 0
      tests/loops/while
  95. 0 0
      tests/loops/while.out
  96. 12 0
      tests/loops/while_post_dec
  97. 0 0
      tests/loops/while_post_dec.out
  98. 12 0
      tests/loops/while_post_inc
  99. 0 0
      tests/loops/while_post_inc.out
  100. 12 0
      tests/loops/while_pre_dec

+ 441 - 340
Compiler.c

@@ -6,13 +6,13 @@
 #include "Compiler.h"
 #include "DataType.h"
 #include "tokenizer/Tokenizer.h"
-#include "utils/FunctionMap.h"
+#include "utils/Functions.h"
 #include "utils/Variables.h"
 #include "vm/Operation.h"
 
 #define ERROR_LENGTH 256
-//#define RETURN_BUFFER 16
-//#define BREAK_BUFFER 32
+#define RETURN_BUFFER 16
+#define BREAK_BUFFER 32
 
 static jmp_buf errorJump;
 static char error[ERROR_LENGTH] = {'\0'};
@@ -22,16 +22,17 @@ static ByteCode* code;
 static int16 line = 1;
 
 static Variables vars;
-// static FunctionMap functions;
+static Functions functions;
+static Functions functionQueue;
 
-/*static int returns[RETURN_BUFFER];
+static int returns[RETURN_BUFFER];
 static int returnIndex = 0;
-static int returnState = 0;
+static DataType returnType = DT_VOID;
 
 static int breaks[BREAK_BUFFER];
 static int breakIndex = 0;
 static int forWhileStack = 0;
-static int continueAt = 0;*/
+static int continueAt = 0;
 
 typedef struct {
     Operation intOp;
@@ -56,6 +57,13 @@ static const TypedOp TYPED_EQUAL = {OP_EQUAL_INT, OP_EQUAL_FLOAT, OP_EQUAL_BOOL,
                                     "=="};
 static const TypedOp TYPED_NOT_EQUAL = {OP_EQUAL_INT, OP_EQUAL_FLOAT,
                                         OP_EQUAL_BOOL, "!="};
+static const TypedOp TYPED_BIT_OR = {OP_BIT_OR, OP_NOTHING, OP_NOTHING, "|"};
+static const TypedOp TYPED_BIT_XOR = {OP_BIT_XOR, OP_NOTHING, OP_NOTHING, "^"};
+static const TypedOp TYPED_BIT_AND = {OP_BIT_AND, OP_NOTHING, OP_NOTHING, "&"};
+static const TypedOp TYPED_LEFT_SHIFT = {OP_LEFT_SHIFT, OP_NOTHING, OP_NOTHING,
+                                         "<<"};
+static const TypedOp TYPED_RIGHT_SHIFT = {OP_RIGHT_SHIFT, OP_NOTHING,
+                                          OP_NOTHING, ">>"};
 
 static void cError(const char* format, ...) {
     va_list args;
@@ -73,15 +81,13 @@ static void cNotDeclared(const char* name) {
     cError("variable %s has not been declared", name);
 }
 
-static void cNotInitialized(const char* name) {
-    cError("variable %s has not been initialized", name);
+static void cDeclared(const char* name) {
+    cError("%s has already been declared", name);
 }
 
-/*static int cAddVar(const char* var) {
-    int index = vars[varIndex].entries;
-    simAdd(vars + varIndex, var, &index);
-    return index;
-}*/
+static void cTooMuchArguments() {
+    cError("too much function arguments");
+}
 
 static void cUnexpectedToken(Token t) {
     cError("unexpected token on line %d: %s", line, tGetName(t));
@@ -92,13 +98,13 @@ static void cAddOperation(Operation token) {
     bcAddBytes(code, &c, 1);
 }
 
-/*static int cReserveInt() {
+static int cReserveInt() {
     return bcReserveBytes(code, sizeof(int));
 }
 
 static void cSetInt(int p, int i) {
     bcSetBytes(code, p, &i, sizeof(int));
-}*/
+}
 
 static void cAddInt(int i) {
     bcAddBytes(code, &i, sizeof(int));
@@ -108,19 +114,6 @@ static void cAddInt16(int16 i) {
     bcAddBytes(code, &i, sizeof(int16));
 }
 
-/*static int cAddPush(int offset) {
-    cAddOperation(OP_PUSH_VARS);
-    int p = cReserveInt();
-    cAddInt(offset);
-    return p;
-}
-
-static void cAddPop(int p, int vars) {
-    cAddOperation(OP_POP_VARS);
-    cAddInt(vars);
-    cSetInt(p, vars);
-}*/
-
 static Token cReadTokenAndLine() {
     Token t = tReadToken();
     if(tReadInt16(&line)) {
@@ -163,17 +156,6 @@ static void cConstantFloat() {
     bcAddBytes(code, &value, sizeof(float));
 }
 
-/*static void cConstantString() {
-    int length;
-    const char* s = tReadString(&length);
-    if(s == NULL) {
-        cError("text without string on line %d", line);
-    }
-    cAddOperation(OP_PUSH_CONST_STRING);
-    cAddInt(length);
-    bcAddBytes(code, s, length);
-}*/
-
 static const char* cReadString() {
     int length;
     const char* literal = tReadString(&length);
@@ -185,93 +167,97 @@ static const char* cReadString() {
 
 static DataType cExpression();
 
-/*static int cCallFunctionArguments() {
-    int arguments = 0;
+static void cCallFunctionArguments(Function* f) {
     while(!cConsumeTokenIf(T_CLOSE_BRACKET)) {
-        arguments++;
-        cExpression();
+        DataType dt = cExpression();
+        if(fAddArgument(f, dt)) {
+            cTooMuchArguments();
+        }
         if(cConsumeTokenIf(T_COMMA) && tPeekToken() == T_CLOSE_BRACKET) {
             cUnexpectedToken(tPeekToken());
         }
     }
-    return arguments;
 }
 
-static void cCallFunction(const char* literal, bool noReturn) {
+static DataType cCallFunction(const char* name) {
     cAddOperation(OP_PUSH_INT);
     cAddInt(0);
-    int arguments = cCallFunctionArguments();
-    Function* f = fmSearch(&functions, literal, arguments);
+    Function f;
+    fInit(&f, name, line);
+    cCallFunctionArguments(&f);
     cAddOperation(OP_GOSUB);
-    if(f == NULL) {
-        fmEnqueue(&functions, literal, arguments, line, cReserveInt(),
-                  noReturn);
-        cAddInt(arguments);
-        cAddOperation(OP_NOTHING);
+    Function* found = fsSearch(&functions, &f);
+    if(found == NULL) {
+        cError("unknown function");
+    }
+    if(found->address == -1) {
+        f.returnType = found->returnType;
+        f.address = cReserveInt();
+        fsAdd(&functionQueue, &f);
     } else {
-        if(!noReturn && !f->returns) {
-            cError("function '%s' needs a return value on line %d", f->name,
-                   line);
-        }
-        cAddInt(f->address);
-        cAddInt(arguments);
-        if(f->returns && noReturn) {
-            cAddOperation(OP_POP);
-        }
+        cAddInt(found->address);
     }
-}*/
+    cAddInt(found->size);
+    return found->returnType;
+}
+
+static DataType cLoadVariable(Variable* v) {
+    switch(v->type) {
+        case DT_INT: cAddOperation(OP_LOAD_INT); break;
+        default: cError("cannot load type %s", dtGetName(v->type));
+    }
+    cAddInt(v->address);
+    return v->type;
+}
+
+static void cStoreVariable(Variable* v, DataType dt, const char* name) {
+    if(v->type != dt) {
+        cInvalidOperation(v->type, dt, name);
+    }
+    switch(v->type) {
+        case DT_INT: cAddOperation(OP_STORE_INT); break;
+        default: cError("cannot store type %s", dtGetName(v->type));
+    }
+    cAddInt(v->address);
+}
 
-static void cAddReference(int address) {
-    // if(cConsumeTokenIf(T_OPEN_SQUARE_BRACKET)) {
-    //    cExpression();
-    //    cAddOperation(OP_REFERENCE_FROM_ARRAY);
-    //    cAddInt(cAddVar(var));
-    //    cConsumeToken(T_CLOSE_SQUARE_BRACKET);
-    //} else {
-    cAddOperation(OP_REFERENCE_FROM_VAR);
-    cAddInt(address);
-    //}
+static DataType cPostChange(Variable* v, int change, const char* name) {
+    if(v->type != DT_INT) {
+        cError("%s needs an int", name);
+    }
+    cAddOperation(OP_LOAD_INT);
+    cAddInt(v->address);
+    cAddOperation(OP_LOAD_INT);
+    cAddInt(v->address);
+    cAddOperation(OP_PUSH_INT);
+    cAddInt(change);
+    cAddOperation(OP_ADD_INT);
+    cAddOperation(OP_STORE_INT);
+    cAddInt(v->address);
+    return DT_INT;
 }
 
 static DataType cLiteral() {
     const char* literal = cReadString();
-    /*if(cConsumeTokenIf(T_OPEN_BRACKET)) {
-        cCallFunction(literal, false);
-        return;
-    }*/
+    if(cConsumeTokenIf(T_OPEN_BRACKET)) {
+        DataType dt = cCallFunction(literal);
+        if(dt == DT_VOID) {
+            cError("function returns void");
+        }
+        return dt;
+    }
     Variable* v = vSearch(&vars, literal);
     if(v == NULL) {
         cNotDeclared(literal);
-    } else if(!v->initialized) {
-        cNotInitialized(literal);
     }
-    cAddReference(v->address);
-    cAddOperation(OP_DEREFERENCE_INT);
-    return v->type;
-    /*if(cConsumeTokenIf(T_INCREMENT)) {
-        cAddOperation(OP_POST_INCREMENT);
+    if(cConsumeTokenIf(T_INCREMENT)) {
+        return cPostChange(v, 1, "++");
     } else if(cConsumeTokenIf(T_DECREMENT)) {
-        cAddOperation(OP_POST_DECREMENT);
-    } else if(cConsumeTokenIf(T_POINT)) {
-        cConsumeToken(T_LITERAL);
-        const char* access = cReadString();
-        if(strcmp(access, "length") == 0) {
-            cAddOperation(OP_ARRAY_LENGTH);
-        } else {
-            cError("'%s' not supported after . on line %d", access, line);
-        }
-    } else {
-        cAddOperation(OP_DEREFERENCE);
-    }*/
+        return cPostChange(v, -1, "--");
+    }
+    return cLoadVariable(v);
 }
 
-/*static void cArray() {
-    cConsumeToken(T_OPEN_SQUARE_BRACKET);
-    cExpression();
-    cConsumeToken(T_CLOSE_SQUARE_BRACKET);
-    cAddOperation(OP_ALLOCATE_ARRAY);
-}*/
-
 static DataType cBracketPrimary() {
     DataType result = cExpression();
     cConsumeToken(T_CLOSE_BRACKET);
@@ -283,22 +269,34 @@ static DataType cPrimary() {
     switch(t) {
         case T_CONST_INT: cConstantInt(); return DT_INT;
         case T_FLOAT: cConstantFloat(); return DT_FLOAT;
-        // case T_TEXT: cConstantString(); break;
-        // case T_NULL: cAddOperation(OP_PUSH_NULL); break;
         case T_TRUE: cAddOperation(OP_PUSH_TRUE); return DT_BOOL;
         case T_FALSE: cAddOperation(OP_PUSH_FALSE); return DT_BOOL;
         case T_OPEN_BRACKET: return cBracketPrimary();
         case T_LITERAL: return cLiteral();
-        // case T_ARRAY: cArray(); break;
         default: cUnexpectedToken(t); return DT_VOID;
     }
 }
 
-/*static void cPreChange(Operation op) {
+static DataType cPreChange(int change, const char* name) {
     cConsumeToken(T_LITERAL);
-    cAddReference(cReadString());
-    cAddOperation(op);
-}*/
+    const char* literal = cReadString();
+    Variable* v = vSearch(&vars, literal);
+    if(v == NULL) {
+        cNotDeclared(literal);
+    } else if(v->type != DT_INT) {
+        cError("%s needs an int", name);
+    }
+    cAddOperation(OP_LOAD_INT);
+    cAddInt(v->address);
+    cAddOperation(OP_PUSH_INT);
+    cAddInt(change);
+    cAddOperation(OP_ADD_INT);
+    cAddOperation(OP_STORE_INT);
+    cAddInt(v->address);
+    cAddOperation(OP_LOAD_INT);
+    cAddInt(v->address);
+    return DT_INT;
+}
 
 static DataType cPreUnary() {
     if(cConsumeTokenIf(T_SUB)) {
@@ -309,26 +307,34 @@ static DataType cPreUnary() {
             default: cError("cannot invert sign of %s", dtGetName(result));
         }
         return result;
-    } /*else if(cConsumeTokenIf(T_INCREMENT)) {
-        cPreChange(OP_PRE_INCREMENT);
+    } else if(cConsumeTokenIf(T_INCREMENT)) {
+        return cPreChange(1, "++");
     } else if(cConsumeTokenIf(T_DECREMENT)) {
-        cPreChange(OP_PRE_DECREMENT);
+        return cPreChange(-1, "--");
     } else if(cConsumeTokenIf(T_NOT)) {
         int counter = 1;
         while(cConsumeTokenIf(T_NOT)) {
             counter++;
         }
-        cPrimary();
+        DataType result = cPrimary();
+        if(result != DT_BOOL) {
+            cError("! needs a bool not %s", dtGetName(result));
+        }
         cAddOperation(OP_NOT);
         if((counter & 1) == 0) {
             cAddOperation(OP_NOT);
         }
+        return DT_BOOL;
     } else if(cConsumeTokenIf(T_BIT_NOT)) {
-        cPrimary();
-        cAddOperation(OP_BIT_NOT);
-    } else {*/
+        DataType result = cPrimary();
+        if(result == DT_INT) {
+            cAddOperation(OP_BIT_NOT);
+        } else {
+            cError("~ needs an int not %s", dtGetName(result));
+        }
+        return result;
+    }
     return cPrimary();
-    //}
 }
 
 static void cAddTypeOperation(DataType a, DataType b, const TypedOp* op) {
@@ -374,18 +380,17 @@ static DataType cAdd() {
 }
 
 static DataType cShift() {
-    return cAdd();
-    /*while(true) {
+    DataType a = cAdd();
+    while(true) {
         if(cConsumeTokenIf(T_LEFT_SHIFT)) {
-            cAdd();
-            cAddOperation(OP_LEFT_SHIFT);
+            cAddTypeOperation(a, cAdd(), &TYPED_LEFT_SHIFT);
         } else if(cConsumeTokenIf(T_RIGHT_SHIFT)) {
-            cAdd();
-            cAddOperation(OP_RIGHT_SHIFT);
+            cAddTypeOperation(a, cAdd(), &TYPED_RIGHT_SHIFT);
         } else {
             break;
         }
-    }*/
+    }
+    return a;
 }
 
 static DataType cComparison() {
@@ -430,216 +435,168 @@ static DataType cEqual() {
 }
 
 static DataType cBitAnd() {
-    return cEqual();
-    /*while(cConsumeTokenIf(T_BIT_AND)) {
-        cEqual();
-        cAddOperation(OP_BIT_AND);
-    }*/
+    DataType a = cEqual();
+    while(cConsumeTokenIf(T_BIT_AND)) {
+        DataType b = cEqual();
+        cAddTypeOperation(a, b, &TYPED_BIT_AND);
+    }
+    return a;
 }
 
 static DataType cBitXor() {
-    return cBitAnd();
-    /*while(cConsumeTokenIf(T_BIT_XOR)) {
-        cBitAnd();
-        cAddOperation(OP_BIT_XOR);
-    }*/
+    DataType a = cBitAnd();
+    while(cConsumeTokenIf(T_BIT_XOR)) {
+        DataType b = cBitAnd();
+        cAddTypeOperation(a, b, &TYPED_BIT_XOR);
+    }
+    return a;
 }
 
 static DataType cBitOr() {
-    return cBitXor();
-    /*while(cConsumeTokenIf(T_BIT_OR)) {
-        cBitXor();
-        cAddOperation(OP_BIT_OR);
-    }*/
+    DataType a = cBitXor();
+    while(cConsumeTokenIf(T_BIT_OR)) {
+        DataType b = cBitXor();
+        cAddTypeOperation(a, b, &TYPED_BIT_OR);
+    }
+    return a;
 }
 
 static DataType cAnd() {
-    return cBitOr();
-    /*while(cConsumeTokenIf(T_AND)) {
-        cAddOperation(OP_DUPLICATE);
-        cAddOperation(OP_IF_GOTO);
+    DataType a = cBitOr();
+    while(cConsumeTokenIf(T_AND)) {
+        cAddOperation(OP_PEEK_FALSE_GOTO);
         int p = cReserveInt();
-        cBitOr();
+        DataType b = cBitOr();
+        if(a != DT_BOOL || b != DT_BOOL) {
+            cInvalidOperation(a, b, "&&");
+        }
         cAddOperation(OP_AND);
         cSetInt(p, code->length);
-    }*/
+    }
+    return a;
 }
 
 static DataType cOr() {
-    return cAnd();
-    /*while(cConsumeTokenIf(T_OR)) {
-        cAddOperation(OP_DUPLICATE);
-        cAddOperation(OP_NOT);
-        cAddOperation(OP_IF_GOTO);
+    DataType a = cAnd();
+    while(cConsumeTokenIf(T_OR)) {
+        cAddOperation(OP_PEEK_TRUE_GOTO);
         int p = cReserveInt();
-        cAnd();
+        DataType b = cAnd();
+        if(a != DT_BOOL || b != DT_BOOL) {
+            cInvalidOperation(a, b, "||");
+        }
         cAddOperation(OP_OR);
         cSetInt(p, code->length);
-    }*/
+    }
+    return a;
 }
 
 static DataType cExpression() {
     return cOr();
 }
 
-/*static void cOperationSet(Operation op) {
-    cAddOperation(OP_DUPLICATE);
-    cAddOperation(OP_DEREFERENCE);
-    cExpression();
-    cAddOperation(op);
-    cAddOperation(OP_SET);
-}*/
+static void cSet(Variable* v) {
+    cStoreVariable(v, cExpression(), "=");
+}
+
+static void cOperationSet(Variable* v, const TypedOp* op) {
+    DataType a = cLoadVariable(v);
+    DataType b = cExpression();
+    cAddTypeOperation(a, b, op);
+    cStoreVariable(v, b, "=");
+}
+
+static void cAddPostLineChange(Variable* v, int change, const char* name) {
+    if(v->type != DT_INT) {
+        cError("%s needs an int", name);
+    }
+    cAddOperation(OP_LOAD_INT);
+    cAddInt(v->address);
+    cAddOperation(OP_PUSH_INT);
+    cAddInt(change);
+    cAddOperation(OP_ADD_INT);
+    cAddOperation(OP_STORE_INT);
+    cAddInt(v->address);
+}
 
 static void cLineLiteral() {
     const char* literal = cReadString();
-    /*if(cConsumeTokenIf(T_OPEN_BRACKET)) {
-        cCallFunction(literal, true);
+    if(cConsumeTokenIf(T_OPEN_BRACKET)) {
+        DataType dt = cCallFunction(literal);
+        if(dt != DT_VOID) {
+            cError("function returns %s not void", dtGetName(dt));
+        }
         return;
-    }*/
+    }
     Variable* v = vSearch(&vars, literal);
     if(v == NULL) {
         cNotDeclared(literal);
     }
-    cAddReference(v->address);
-    cConsumeToken(T_SET);
-    DataType dt = cExpression();
-    if(v->type != dt) {
-        cInvalidOperation(v->type, dt, "=");
-    }
-    if(dt == DT_INT) {
-        cAddOperation(OP_SET_INT);
-    } else {
-        cError("%s cannot be set", dtGetName(dt));
-    }
-    v->initialized = true;
-    /*Token t = cReadTokenAndLine();
+    Token t = cReadTokenAndLine();
     switch(t) {
-        case T_SET:
-            cExpression();
-            cAddOperation(OP_SET);
-            break;
-        case T_ADD_SET: cOperationSet(OP_ADD); break;
-        case T_SUB_SET: cOperationSet(OP_SUB); break;
-        case T_MUL_SET: cOperationSet(OP_MUL); break;
-        case T_DIV_SET: cOperationSet(OP_DIV); break;
-        case T_MOD_SET: cOperationSet(OP_MOD); break;
-        case T_BIT_AND_SET: cOperationSet(OP_BIT_AND); break;
-        case T_BIT_OR_SET: cOperationSet(OP_BIT_OR); break;
-        case T_BIT_XOR_SET: cOperationSet(OP_BIT_XOR); break;
-        case T_LEFT_SHIFT_SET: cOperationSet(OP_LEFT_SHIFT); break;
-        case T_RIGHT_SHIFT_SET: cOperationSet(OP_RIGHT_SHIFT); break;
-        case T_INCREMENT:
-            cAddOperation(OP_POST_INCREMENT);
-            cAddOperation(OP_POP);
-            break;
-        case T_DECREMENT:
-            cAddOperation(OP_POST_DECREMENT);
-            cAddOperation(OP_POP);
-            break;
+        case T_SET: cSet(v); 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 int cFunctionArguments() {
-    int arguments = 0;
-    while(!cConsumeTokenIf(T_CLOSE_BRACKET)) {
-        cConsumeToken(T_LITERAL);
-        arguments++;
-        cAddVar(cReadString());
-        if(cConsumeTokenIf(T_COMMA) && tPeekToken() != T_LITERAL) {
-            cUnexpectedToken(tPeekToken());
-        }
     }
-    return arguments;
 }
 
 static void cLine(Token t);
 
 static void cConsumeBody() {
-    cConsumeToken(T_OPEN_CURVED_BRACKET);
     int oldLine = line;
     while(!cConsumeTokenIf(T_CLOSE_CURVED_BRACKET)) {
         Token t = cReadTokenAndLine();
         if(t == T_END) {
-            cError(
-                "unexpected end of file: non closed curved bracket on line %d",
-                oldLine);
+            line = oldLine;
+            cError("unexpected end of file: non closed curved bracket");
         }
         cLine(t);
     }
 }
 
-static void cLinkReturns() {
-    for(int i = 0; i < returnIndex; i++) {
-        cSetInt(returns[i], vars[1].entries);
-    }
-    returnIndex = 0;
-}
-
-static void cFunctionBody(const char* name, int arguments) {
-    int oldLine = line;
-    cAddOperation(OP_GOTO);
-    int gotoIndex = cReserveInt();
-
-    int address = code->length;
-    returnState = 0;
-
-    int p = cAddPush(arguments);
+static void cConsumeScope() {
+    Scope scope;
+    vEnterScope(&vars, &scope);
     cConsumeBody();
-    cAddPop(p, vars[1].entries);
-
-    cLinkReturns();
-
-    if(!fmAdd(&functions, name, arguments, address, returnState == 2)) {
-        cError("function registered twice on line %d", oldLine);
-    }
-
-    cAddOperation(OP_RETURN);
-    cSetInt(gotoIndex, code->length);
-}
-
-static void cFunction() {
-    if(varIndex == 1) {
-        cError("function inside function on line %d", line);
-    }
-    cConsumeToken(T_LITERAL);
-    const char* name = cReadString();
-    cConsumeToken(T_OPEN_BRACKET);
-    varIndex = 1;
-    vars[1].entries = 0;
-    cFunctionBody(name, cFunctionArguments());
-    varIndex = 0;
+    vLeaveScope(&vars, &scope);
 }
 
-static void cAddReturn() {
-    cAddOperation(OP_POP_VARS);
-    returns[returnIndex++] = cReserveInt(vars);
-    cAddOperation(OP_RETURN);
+static void cAddReturn(Operation op) {
+    cAddOperation(op);
+    returns[returnIndex++] = cReserveInt();
 }
 
 static void cReturn() {
-    if(varIndex == 0) {
-        cError("return without a function on line %d", line);
-    } else if(returnIndex >= RETURN_BUFFER) {
-        cError("too much returns in function around line %d", line);
-    }
-    if(cConsumeTokenIf(T_SEMICOLON)) {
-        if(returnState == 2) {
-            cError("mixed return type on line %d", line);
-        }
-        returnState = 1;
-        cAddReturn();
-    } else {
-        if(returnState == 1) {
-            cError("mixed return type on line %d", line);
-        }
-        returnState = 2;
-        cExpression();
-        cAddOperation(OP_SET_RETURN);
-        cAddReturn();
+    if(returnIndex >= RETURN_BUFFER) {
+        cError("too much returns in function");
+    }
+    if(returnType == DT_VOID) {
         cConsumeToken(T_SEMICOLON);
+        cAddReturn(OP_RETURN);
+        return;
+    }
+    DataType dt = cExpression();
+    if(dt != returnType) {
+        cError("wrong return type, should be %s", dtGetName(returnType));
     }
-}*/
+    switch(dt) {
+        case DT_INT: cAddReturn(OP_RETURN_INT); break;
+        case DT_BOOL: cAddReturn(OP_RETURN_BOOL); break;
+        default: cError("cannot return %s", dtGetName(dt));
+    }
+    cConsumeToken(T_SEMICOLON);
+}
 
 static void cPrint() {
     DataType dt = cExpression();
@@ -647,18 +604,22 @@ static void cPrint() {
         case DT_INT: cAddOperation(OP_PRINT_INT); break;
         case DT_FLOAT: cAddOperation(OP_PRINT_FLOAT); break;
         case DT_BOOL: cAddOperation(OP_PRINT_BOOL); break;
-        default: cError("cannot print data type %s", dtGetName(dt));
+        default: cError("cannot print type %s", dtGetName(dt));
     }
     cConsumeToken(T_SEMICOLON);
 }
 
-/*static void cIf() {
+static void cIf() {
     cConsumeToken(T_OPEN_BRACKET);
-    cExpression();
+    DataType dt = cExpression();
+    if(dt != DT_BOOL) {
+        cError("if expects a bool not %s", dtGetName(dt));
+    }
     cConsumeToken(T_CLOSE_BRACKET);
     cAddOperation(OP_IF_GOTO);
     int ifP = cReserveInt();
-    cConsumeBody();
+    cConsumeToken(T_OPEN_CURVED_BRACKET);
+    cConsumeScope();
     cSetInt(ifP, code->length);
 
     if(cConsumeTokenIf(T_ELSE)) {
@@ -668,7 +629,8 @@ static void cPrint() {
         if(cConsumeTokenIf(T_IF)) {
             cIf();
         } else {
-            cConsumeBody();
+            cConsumeToken(T_OPEN_CURVED_BRACKET);
+            cConsumeScope();
         }
         cSetInt(elseP, code->length);
     }
@@ -684,7 +646,10 @@ static void cConsumeBreaks(int start, int address) {
 static void cWhile() {
     int start = code->length;
     cConsumeToken(T_OPEN_BRACKET);
-    cExpression();
+    DataType dt = cExpression();
+    if(dt != DT_BOOL) {
+        cError("while expects a bool not %s", dtGetName(dt));
+    }
     cConsumeToken(T_CLOSE_BRACKET);
     cAddOperation(OP_IF_GOTO);
     int ifP = cReserveInt();
@@ -692,58 +657,60 @@ static void cWhile() {
     forWhileStack++;
     int oldContinue = continueAt;
     continueAt = start;
-    cConsumeBody();
+    cConsumeToken(T_OPEN_CURVED_BRACKET);
+    cConsumeScope();
     continueAt = oldContinue;
     forWhileStack--;
     cAddOperation(OP_GOTO);
     cAddInt(start);
     cSetInt(ifP, code->length);
     cConsumeBreaks(breakStart, code->length);
-}*/
+}
 
 static void cInt() {
     cConsumeToken(T_LITERAL);
     const char* var = cReadString();
-    Variable* v = vSearch(&vars, var);
+    Variable* v = vSearchScope(&vars, var);
     if(v != NULL) {
-        cError("%s has already been declared", var);
+        cDeclared(var);
     }
     v = vAdd(&vars, var, DT_INT);
-    if(tPeekToken() == T_SEMICOLON) {
-        return;
-    }
     cConsumeToken(T_SET);
-    cAddReference(v->address);
-    DataType dt = cExpression();
-    if(dt != DT_INT) {
-        cInvalidOperation(DT_INT, dt, "=");
+    cSet(v);
+}
+
+static void cAddPreLineChange(int change, const char* name) {
+    cConsumeToken(T_LITERAL);
+    const char* literal = cReadString();
+    Variable* v = vSearch(&vars, literal);
+    if(v == NULL) {
+        cNotDeclared(literal);
     }
-    cAddOperation(OP_SET_INT);
-    v->initialized = true;
+    cAddPostLineChange(v, change, name);
 }
 
 static void cLineExpression(Token t) {
     switch(t) {
         case T_LITERAL: cLineLiteral(); break;
         case T_INT: cInt(); break;
-        /*case T_INCREMENT:
-            cPreChange(OP_PRE_INCREMENT);
-            cAddOperation(OP_POP);
-            break;
-        case T_DECREMENT:
-            cPreChange(OP_PRE_DECREMENT);
-            cAddOperation(OP_POP);
-            break;*/
+        case T_INCREMENT: cAddPreLineChange(1, "++"); break;
+        case T_DECREMENT: cAddPreLineChange(-1, "--"); break;
         default: cUnexpectedToken(t);
     }
 }
 
-/*static void cFor() {
+static void cFor() {
+    Scope scope;
+    vEnterScope(&vars, &scope);
+
     cConsumeToken(T_OPEN_BRACKET);
     cLineExpression(cReadTokenAndLine());
     cConsumeToken(T_SEMICOLON);
     int startCheck = code->length;
-    cExpression();
+    DataType dt = cExpression();
+    if(dt != DT_BOOL) {
+        cError("for expects a bool not %s", dtGetName(dt));
+    }
     cConsumeToken(T_SEMICOLON);
     cAddOperation(OP_IF_GOTO);
     int end = cReserveInt();
@@ -759,6 +726,7 @@ static void cLineExpression(Token t) {
     forWhileStack++;
     int oldContinue = continueAt;
     continueAt = startPerLoop;
+    cConsumeToken(T_OPEN_CURVED_BRACKET);
     cConsumeBody();
     continueAt = oldContinue;
     forWhileStack--;
@@ -766,6 +734,8 @@ static void cLineExpression(Token t) {
     cAddInt(startPerLoop);
     cSetInt(end, code->length);
     cConsumeBreaks(breakStart, code->length);
+
+    vLeaveScope(&vars, &scope);
 }
 
 static void cBreak() {
@@ -786,64 +756,195 @@ static void cContinue() {
     cAddOperation(OP_GOTO);
     cAddInt(continueAt);
     cConsumeToken(T_SEMICOLON);
-}*/
+}
 
 static void cLine(Token t) {
     cAddOperation(OP_LINE);
     cAddInt16(line);
     switch(t) {
+        case T_OPEN_CURVED_BRACKET: cConsumeScope(); break;
         case T_PRINT: cPrint(); break;
-        // case T_FUNCTION: cFunction(); break;
-        // case T_RETURN: cReturn(); break;
-        // case T_IF: cIf(); break;
-        // case T_WHILE: cWhile(); break;
-        // case T_FOR: cFor(); break;
-        // case T_BREAK: cBreak(); break;
-        // case T_CONTINUE: cContinue(); break;
+        case T_RETURN: cReturn(); break;
+        case T_IF: cIf(); break;
+        case T_WHILE: cWhile(); break;
+        case T_FOR: cFor(); break;
+        case T_BREAK: cBreak(); break;
+        case T_CONTINUE: cContinue(); break;
         default: cLineExpression(t); cConsumeToken(T_SEMICOLON);
     }
 }
 
+static void cFunctionArgument(Function* f);
+
+static void cFunctionCommaOrEnd(Function* f) {
+    if(cConsumeTokenIf(T_CLOSE_BRACKET)) {
+        return;
+    }
+    cConsumeToken(T_COMMA);
+    cFunctionArgument(f);
+}
+
+static void cFunctionAddArgument(Function* f, DataType dt) {
+    cConsumeToken(T_LITERAL);
+    const char* name = cReadString();
+    Variable* v = vSearchScope(&vars, name);
+    if(v != NULL) {
+        cDeclared(name);
+    }
+    vAdd(&vars, name, dt);
+    if(fAddArgument(f, dt)) {
+        cTooMuchArguments();
+    }
+    cFunctionCommaOrEnd(f);
+}
+
+static void cFunctionArgument(Function* f) {
+    Token t = cReadTokenAndLine();
+    switch(t) {
+        case T_INT: cFunctionAddArgument(f, DT_INT); break;
+        default: cUnexpectedToken(t);
+    }
+}
+
+static void cFunctionArguments(Function* f) {
+    cConsumeToken(T_OPEN_BRACKET);
+    if(!cConsumeTokenIf(T_CLOSE_BRACKET)) {
+        cFunctionArgument(f);
+    }
+}
+
+static int cReserve(int offset) {
+    cAddOperation(OP_RESERVE);
+    int p = cReserveInt();
+    cAddInt(offset);
+    return p;
+}
+
+static void cFree(int p, int bytes) {
+    cAddOperation(OP_RETURN);
+    cAddInt(bytes);
+    cSetInt(p, bytes);
+}
+
+static void cLinkReturns(int bytes) {
+    for(int i = 0; i < returnIndex; i++) {
+        cSetInt(returns[i], bytes);
+    }
+    returnIndex = 0;
+}
+
+static void cInnerFunction(Function* f) {
+    cConsumeToken(T_OPEN_CURVED_BRACKET);
+    int p = cReserve(f->size);
+    returnIndex = 0;
+    cConsumeScope();
+    cFree(p, vars.maxAddress);
+    cLinkReturns(vars.maxAddress);
+}
+
+static bool cForwardFunction(Function* found, Function* f) {
+    if(!cConsumeTokenIf(T_SEMICOLON)) {
+        return false;
+    } else if(found != NULL) {
+        cError("function registered twice");
+    }
+    f->address = -1;
+    fsAdd(&functions, f);
+    return true;
+}
+
+static void cBuildFunction(Function* f, DataType rType) {
+    cConsumeToken(T_LITERAL);
+    fInit(f, cReadString(), line);
+    f->returnType = rType;
+    vReset(&vars);
+    cFunctionArguments(f);
+}
+
+static void cFunction(DataType rType) {
+    Function f;
+    cBuildFunction(&f, rType);
+    Function* found = fsSearch(&functions, &f);
+    if(cForwardFunction(found, &f)) {
+        return;
+    }
+    cAddOperation(OP_LINE);
+    cAddInt16(line);
+    cAddOperation(OP_GOTO);
+    int end = cReserveInt();
+    f.address = code->length;
+    if(found != NULL) {
+        if(found->address == -1) {
+            found->address = f.address;
+        } else {
+            cError("function registered twice");
+        }
+    } else {
+        fsAdd(&functions, &f);
+    }
+    returnType = rType;
+    cInnerFunction(&f);
+    cSetInt(end, code->length);
+}
+
+static void cGlobalScope(Token t) {
+    switch(t) {
+        case T_VOID: cFunction(DT_VOID); break;
+        case T_INT: cFunction(DT_INT); break;
+        case T_BOOL: cFunction(DT_BOOL); break;
+        default: cUnexpectedToken(t);
+    }
+}
+
+static void cCallMain() {
+    Function f;
+    fInit(&f, "main", line);
+    Function* found = fsSearch(&functions, &f);
+    if(found != NULL && found->returnType == DT_VOID) {
+        cAddOperation(OP_PUSH_INT);
+        cAddInt(0);
+        cAddOperation(OP_GOSUB);
+        cAddInt(found->address);
+        cAddInt(found->size);
+    }
+}
+
 static void cForEachLine() {
     Token t = cReadTokenAndLine();
     while(t != T_END) {
-        cLine(t);
+        cGlobalScope(t);
         t = cReadTokenAndLine();
     }
+    cCallMain();
 }
 
-/*static void cLinkQueuedFunctions() {
-    for(int i = 0; i < functions.queueEntries; i++) {
-        Function* f = fmSearch(&functions, functions.queue[i].name,
-                               functions.queue[i].arguments);
-        if(f == NULL) {
-            cError("unknown function on line %d", functions.queue[i].line);
-        } else if(!functions.queue[i].noReturn && !f->returns) {
-            cError("function '%s' needs a return value on line %d", f->name,
-                   functions.queue[i].line);
-        }
-        cSetInt(functions.queue[i].reserved, f->address);
-        if(functions.queue[i].noReturn && f->returns) {
-            code->code[functions.queue[i].reserved + sizeof(int) * 2] = OP_POP;
+static void cLinkQueuedFunctions() {
+    for(int i = 0; i < functionQueue.entries; i++) {
+        Function* f = functionQueue.data + i;
+        Function* found = fsSearch(&functions, f);
+        if(found == NULL) {
+            line = f->line;
+            cError("unknown function");
+        } else if(f->returnType != found->returnType) {
+            line = f->line;
+            cError("function return type is not %s", dtGetName(f->returnType));
         }
+        cSetInt(f->address, found->address);
     }
-}*/
+}
 
 static void cAllocAndCompile() {
-    // varIndex = 0;
-    // returnIndex = 0;
-    // returnState = 0;
-    // forWhileStack = 0;
-    // breakIndex = 0;
+    forWhileStack = 0;
+    breakIndex = 0;
     vInit(&vars);
-    // fmInit(&functions);
+    fsInit(&functions);
+    fsInit(&functionQueue);
     if(!setjmp(errorJump)) {
-        // int p = cAddPush(0);
         cForEachLine();
-        // cAddPop(p, vars[varIndex].entries);
-        // cLinkQueuedFunctions();
+        cLinkQueuedFunctions();
     }
-    // fmDelete(&functions);
+    fsDelete(&functionQueue);
+    fsDelete(&functions);
     vDelete(&vars);
 }
 

+ 1 - 1
meson.build

@@ -7,7 +7,7 @@ src = [
     'tokenizer/File.c', 
     'utils/Utils.c', 
     'utils/Variables.c',
-    'utils/FunctionMap.c',
+    'utils/Functions.c',
     'utils/ByteCodePrinter.c',
     'Compiler.c', 
     'DataType.c', 

+ 0 - 5
old_tests/bits/and

@@ -1,5 +0,0 @@
-a = 7;
-a = a & 15;
-print a;
-a &= 9;
-print a;

+ 0 - 2
old_tests/bits/invert

@@ -1,2 +0,0 @@
-print ~0;
-print ~(~7);

+ 0 - 5
old_tests/bits/or

@@ -1,5 +0,0 @@
-a = 0;
-a = a | 2;
-print a;
-a |= 5;
-print a;

+ 0 - 9
old_tests/bits/shift

@@ -1,9 +0,0 @@
-a = 1;
-a = a << 2;
-a <<= 3;
-print a;
-
-a = 100;
-a = a >> 2;
-a >>= 3;
-print a;

+ 0 - 5
old_tests/bits/xor

@@ -1,5 +0,0 @@
-a = 0;
-a = a ^ 2;
-print a;
-a ^= 7;
-print a;

+ 0 - 22
old_tests/functions/arguments

@@ -1,22 +0,0 @@
-a = 2;
-b = 3;
-
-function wusi(c, d) {
-    print c;
-    print d;
-}
-
-function test(c, d) {
-    print a;
-    print b;
-    print c;
-    print d;
-    wusi(4, 5 + 6);
-}
-
-test(a, b);
-
-print a;
-print b;
-print c;
-print d;

+ 0 - 10
old_tests/functions/arguments.out

@@ -1,10 +0,0 @@
-null
-null
-2
-3
-4
-11
-2
-3
-null
-null

+ 0 - 14
old_tests/functions/forward

@@ -1,14 +0,0 @@
-test();
-test(1);
-
-function test() {
-    print 4;
-    print 5;
-}
-
-function test(a) {
-    print a;
-    print 6;
-}
-
-test();

+ 0 - 7
old_tests/functions/function

@@ -1,7 +0,0 @@
-function test() {
-    print 4;
-    print 5;
-}
-
-test();
-test();

+ 0 - 13
old_tests/functions/overloading

@@ -1,13 +0,0 @@
-function test(a, b) {
-    print a + 1;
-    print b + 2;
-}
-
-function test(a, b, c) {
-    print a + 3;
-    print b + 4;
-    print c + 100;
-}
-
-test(1, 2);
-test(10, 20, 1);

+ 0 - 10
old_tests/functions/recursion

@@ -1,10 +0,0 @@
-function fac(n) {
-    if(n < 2) {
-        return 1;
-    }
-    return n * fac(n - 1);
-}
-
-print fac(5);
-print fac(7);
-print fac(12);

+ 0 - 7
old_tests/functions/return

@@ -1,7 +0,0 @@
-function test() {
-    print 5;
-    return;
-    print 6;
-}
-
-test();

+ 0 - 11
old_tests/functions/return_value

@@ -1,11 +0,0 @@
-function test() {
-    return 3;
-}
-
-function test(a, b) {
-    print 5;
-    return a + b;
-}
-
-test();
-print test(2, 4);

+ 0 - 18
old_tests/functions/scope

@@ -1,18 +0,0 @@
-a = 2;
-b = 3;
-print a;
-print b;
-
-function test() {
-    print a;
-    print b;
-    a = 4;
-    b = 5;
-    print a;
-    print b;
-}
-
-test();
-
-print a;
-print b;

+ 0 - 13
old_tests/if/and

@@ -1,13 +0,0 @@
-print false && false;
-print true && false;
-print false && true;
-print true && true;
-
-function test() {
-    print 1;
-    return true;
-}
-
-print false && test() && test();
-print true && test() && false && test();
-print true && test() && test();

+ 0 - 13
old_tests/if/else

@@ -1,13 +0,0 @@
-print 5;
-if(true) {
-    print 6;
-} else {
-    print 7;
-}
-print 8;
-if(false) {
-    print 9;
-} else {
-    print 10;
-}
-print 11;

+ 0 - 9
old_tests/if/if

@@ -1,9 +0,0 @@
-print 5;
-if(true) {
-    print 6;
-}
-print 7;
-if(false) {
-    print 8;
-}
-print 9;

+ 0 - 6
old_tests/if/invert

@@ -1,6 +0,0 @@
-print !true;
-print !false;
-print !!true;
-print !!false;
-print !!!true;
-print !!!false;

+ 0 - 13
old_tests/if/or

@@ -1,13 +0,0 @@
-print false || false;
-print true || false;
-print false || true;
-print true || true;
-
-function test() {
-    print 1;
-    return true;
-}
-
-print false || test() || test();
-print false || test() || true || test();
-print true || test() || test();

+ 0 - 19
old_tests/loops/break

@@ -1,19 +0,0 @@
-for(i = 0; i < 10; i++) {
-    print i;
-    if(i == 4) {
-        break;
-    }
-}
-for(x = 0; x < 3; ++x) {
-    if(false) {
-        break;
-    }
-    while(true) {
-        print x;
-        break;
-        print y;
-    }
-    if(x == 1) {
-        break;
-    }
-}

+ 0 - 35
old_tests/loops/continue

@@ -1,35 +0,0 @@
-for(i = 0; i < 10; i++) {
-    if(i == 4) {
-        continue;
-    }
-    print i;
-}
-for(x = 0; x < 3; ++x) {
-    if(x == 1) {
-        continue;
-    }
-    for(y = 0; y < 3; y++) {
-        print x;
-        if(x == 2) {
-            continue;
-        }
-        print y;
-    }
-    i = 0;
-    while(i < 5) {
-        i++;
-        if(i == 3) {
-            continue;
-        }
-        print i;
-    }
-    continue;
-}
-i = 0;
-while(i < 5) {
-    i++;
-    if(i == 3) {
-        continue;
-    }
-    print i;
-}

+ 0 - 9
old_tests/loops/for

@@ -1,9 +0,0 @@
-for(i = 0; i < 10; i++) {
-    print i;
-}
-for(x = 0; x < 3; ++x) {
-    for(y = 0; y < 3; y++) {
-        print x;
-        print y;
-    }
-}

+ 0 - 5
old_tests/loops/while

@@ -1,5 +0,0 @@
-a = 0;
-while(a < 5) {
-    print a;
-    a = a + 1;
-}

+ 0 - 10
old_tests/loops/while_post_dec

@@ -1,10 +0,0 @@
-a = 5;
-while(a > 0) {
-    print a--;
-}
-
-a = 5;
-while(a > 0) {
-    print a;
-    a--;
-}

+ 0 - 10
old_tests/loops/while_post_inc

@@ -1,10 +0,0 @@
-a = 0;
-while(a < 5) {
-    print a++;
-}
-
-a = 0;
-while(a < 5) {
-    print a;
-    a++;
-}

+ 0 - 10
old_tests/loops/while_pre_dec

@@ -1,10 +0,0 @@
-a = 5;
-while(a > 0) {
-    print --a;
-}
-
-a = 5;
-while(a > 0) {
-    print a;
-    --a;
-}

+ 0 - 10
old_tests/loops/while_pre_inc

@@ -1,10 +0,0 @@
-a = 0;
-while(a < 5) {
-    print ++a;
-}
-
-a = 0;
-while(a < 5) {
-    print a;
-    ++a;
-}

+ 0 - 6
old_tests/mix

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

+ 0 - 3
old_tests/strings/const_string

@@ -1,3 +0,0 @@
-print "Hello World";
-print "umlaut üöäÜÖÄ";
-print "escaping: \"\\";

+ 0 - 3
old_tests/strings/const_string.out

@@ -1,3 +0,0 @@
-Hello World
-umlaut üöäÜÖÄ
-escaping: "\

+ 0 - 1
old_tests/types/null

@@ -1 +0,0 @@
-print null;

+ 0 - 1
old_tests/types/null.out

@@ -1 +0,0 @@
-null

+ 7 - 0
tests/bits/and

@@ -0,0 +1,7 @@
+void main() {
+    int a = 7;
+    a = a & 15;
+    print a;
+    a &= 9;
+    print a;
+}

+ 0 - 0
old_tests/bits/and.out → tests/bits/and.out


+ 4 - 0
tests/bits/invert

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

+ 0 - 0
old_tests/bits/invert.out → tests/bits/invert.out


+ 7 - 0
tests/bits/or

@@ -0,0 +1,7 @@
+void main() {
+    int a = 0;
+    a = a | 2;
+    print a;
+    a |= 5;
+    print a;
+}

+ 0 - 0
old_tests/bits/or.out → tests/bits/or.out


+ 11 - 0
tests/bits/shift

@@ -0,0 +1,11 @@
+void main() {
+    int a = 1;
+    a = a << 2;
+    a <<= 3;
+    print a;
+
+    a = 100;
+    a = a >> 2;
+    a >>= 3;
+    print a;
+}

+ 0 - 0
old_tests/bits/shift.out → tests/bits/shift.out


+ 7 - 0
tests/bits/xor

@@ -0,0 +1,7 @@
+void main() {
+    int a = 0;
+    a = a ^ 2;
+    print a;
+    a ^= 7;
+    print a;
+}

+ 0 - 0
old_tests/bits/xor.out → tests/bits/xor.out


+ 10 - 8
tests/calc/add

@@ -1,8 +1,10 @@
-print 1;
-print 2 + 3;
-print 3 + 4 + 5;
-print 6 + 7 + 8 + 9;
-print 3.5 + 5.5;
-print 4.0 + 1.0;
-print 1.0 + -2.0;
-print 6 + -7 + 8 + -9;
+void main() {
+    print 1;
+    print 2 + 3;
+    print 3 + 4 + 5;
+    print 6 + 7 + 8 + 9;
+    print 3.5 + 5.5;
+    print 4.0 + 1.0;
+    print 1.0 + -2.0;
+    print 6 + -7 + 8 + -9;
+}

+ 14 - 12
tests/calc/div

@@ -1,12 +1,14 @@
-print 1 / 2;
-print 7 / 3;
-print 7.0 / 3.0;
-print 7.0 / 3.0;
-print 7.0 / 3.0;
-print 3 / 4 + 5;
-print 6 + 7 / 8 + 9;
-print 3.5 / 5.5;
-print 4.0 / 1.0;
-print 1.0 / 2.0;
-print 20 * 2 / 3 / 5;
-print 20.0 * 2.0 / 3.0 / 5.0;
+void main() {
+    print 1 / 2;
+    print 7 / 3;
+    print 7.0 / 3.0;
+    print 7.0 / 3.0;
+    print 7.0 / 3.0;
+    print 3 / 4 + 5;
+    print 6 + 7 / 8 + 9;
+    print 3.5 / 5.5;
+    print 4.0 / 1.0;
+    print 1.0 / 2.0;
+    print 20 * 2 / 3 / 5;
+    print 20.0 * 2.0 / 3.0 / 5.0;
+}

+ 7 - 5
tests/calc/mod

@@ -1,5 +1,7 @@
-print 1 % 5;
-print 3 % 5;
-print 5 % 5;
-print 7 % 5;
-print 9 % 5;
+void main() {
+    print 1 % 5;
+    print 3 % 5;
+    print 5 % 5;
+    print 7 % 5;
+    print 9 % 5;
+}

+ 10 - 8
tests/calc/mul

@@ -1,8 +1,10 @@
-print 2 * 3;
-print 3 + 4 * 5;
-print 6 + 7 * 8 + 9;
-print (3 + 4) * 5;
-print ((3 + 2) * (5 + 1));
-print ((3.0 + 2.0) * (5.0 + 1.0));
-print ((3.0 + 2.0) * (5.0 + 1.0));
-print -3 * -5;
+void main() {
+    print 2 * 3;
+    print 3 + 4 * 5;
+    print 6 + 7 * 8 + 9;
+    print (3 + 4) * 5;
+    print ((3 + 2) * (5 + 1));
+    print ((3.0 + 2.0) * (5.0 + 1.0));
+    print ((3.0 + 2.0) * (5.0 + 1.0));
+    print -3 * -5;
+}

+ 6 - 4
tests/calc/sub

@@ -1,4 +1,6 @@
-print 0 - 5;
-print 2 - 5 + 3 - 6;
-print 2 - (5 + 3) - 6;
-print -(7 - 8);
+void main() {
+    print 0 - 5;
+    print 2 - 5 + 3 - 6;
+    print 2 - (5 + 3) - 6;
+    print -(7 - 8);
+}

+ 8 - 6
tests/comments/line

@@ -1,6 +1,8 @@
-print 1;
-print 2; //print 3;
-//print 4; print 5;
-print 6; //print 7;
-print 8;
-//print 9;
+void main() {
+    print 1;
+    print 2; //print 3;
+    //print 4; print 5;
+    print 6; //print 7;
+    print 8;
+    //print 9;
+}

+ 8 - 6
tests/comments/lines

@@ -1,6 +1,8 @@
-print 1;
-print 2; /*print 3;
-print 4; print 5;*/
-print 6; /*print 7;****/
-print 8;
-/*print 9;*/
+void main() {
+    print 1;
+    print 2; /*print 3;
+    print 4; print 5;*/
+    print 6; /*print 7;****/
+    print 8;
+    /*print 9;*/
+}

+ 16 - 14
tests/comparison/equal

@@ -1,14 +1,16 @@
-print 0 == 5;
-print 4 == 5;
-print 5 == 5;
-print 6 == 5;
-print 10 == 5;
-print 0.0 == 5.0;
-print 4.0 == 5.0;
-print 5.0 == 5.0;
-print 6.0 == 5.0;
-print 10.0 == 5.0;
-print false == false;
-print true == false;
-print false == true;
-print true == true;
+void main() {
+    print 0 == 5;
+    print 4 == 5;
+    print 5 == 5;
+    print 6 == 5;
+    print 10 == 5;
+    print 0.0 == 5.0;
+    print 4.0 == 5.0;
+    print 5.0 == 5.0;
+    print 6.0 == 5.0;
+    print 10.0 == 5.0;
+    print false == false;
+    print true == false;
+    print false == true;
+    print true == true;
+}

+ 12 - 10
tests/comparison/greater

@@ -1,10 +1,12 @@
-print 0 > 5;
-print 4 > 5;
-print 5 > 5;
-print 6 > 5;
-print 10 > 5;
-print 0.0 > 5.0;
-print 4.0 > 5.0;
-print 5.0 > 5.0;
-print 6.0 > 5.0;
-print 10.0 > 5.0;
+void main() {
+    print 0 > 5;
+    print 4 > 5;
+    print 5 > 5;
+    print 6 > 5;
+    print 10 > 5;
+    print 0.0 > 5.0;
+    print 4.0 > 5.0;
+    print 5.0 > 5.0;
+    print 6.0 > 5.0;
+    print 10.0 > 5.0;
+}

+ 12 - 10
tests/comparison/greater_equal

@@ -1,10 +1,12 @@
-print 0 >= 5;
-print 4 >= 5;
-print 5 >= 5;
-print 6 >= 5;
-print 10 >= 5;
-print 0.0 >= 5.0;
-print 4.0 >= 5.0;
-print 5.0 >= 5.0;
-print 6.0 >= 5.0;
-print 10.0 >= 5.0;
+void main() {
+    print 0 >= 5;
+    print 4 >= 5;
+    print 5 >= 5;
+    print 6 >= 5;
+    print 10 >= 5;
+    print 0.0 >= 5.0;
+    print 4.0 >= 5.0;
+    print 5.0 >= 5.0;
+    print 6.0 >= 5.0;
+    print 10.0 >= 5.0;
+}

+ 12 - 10
tests/comparison/less

@@ -1,10 +1,12 @@
-print 0 < 5;
-print 4 < 5;
-print 5 < 5;
-print 6 < 5;
-print 10 < 5;
-print 0.0 < 5.0;
-print 4.0 < 5.0;
-print 5.0 < 5.0;
-print 6.0 < 5.0;
-print 10.0 < 5.0;
+void main() {
+    print 0 < 5;
+    print 4 < 5;
+    print 5 < 5;
+    print 6 < 5;
+    print 10 < 5;
+    print 0.0 < 5.0;
+    print 4.0 < 5.0;
+    print 5.0 < 5.0;
+    print 6.0 < 5.0;
+    print 10.0 < 5.0;
+}

+ 12 - 10
tests/comparison/less_equal

@@ -1,10 +1,12 @@
-print 0 <= 5;
-print 4 <= 5;
-print 5 <= 5;
-print 6 <= 5;
-print 10 <= 5;
-print 0.0 <= 5.0;
-print 4.0 <= 5.0;
-print 5.0 <= 5.0;
-print 6.0 <= 5.0;
-print 10.0 <= 5.0;
+void main() {
+    print 0 <= 5;
+    print 4 <= 5;
+    print 5 <= 5;
+    print 6 <= 5;
+    print 10 <= 5;
+    print 0.0 <= 5.0;
+    print 4.0 <= 5.0;
+    print 5.0 <= 5.0;
+    print 6.0 <= 5.0;
+    print 10.0 <= 5.0;
+}

+ 16 - 14
tests/comparison/not_equal

@@ -1,14 +1,16 @@
-print 0 != 5;
-print 4 != 5;
-print 5 != 5;
-print 6 != 5;
-print 10 != 5;
-print 0.0 != 5.0;
-print 4.0 != 5.0;
-print 5.0 != 5.0;
-print 6.0 != 5.0;
-print 10.0 != 5.0;
-print false != false;
-print true != false;
-print false != true;
-print true != true;
+void main() {
+    print 0 != 5;
+    print 4 != 5;
+    print 5 != 5;
+    print 6 != 5;
+    print 10 != 5;
+    print 0.0 != 5.0;
+    print 4.0 != 5.0;
+    print 5.0 != 5.0;
+    print 6.0 != 5.0;
+    print 10.0 != 5.0;
+    print false != false;
+    print true != false;
+    print false != true;
+    print true != true;
+}

+ 20 - 0
tests/functions/arguments

@@ -0,0 +1,20 @@
+void wusi(int c, int d) {
+    print c;
+    print d;
+}
+
+void test(int a, int b) {
+    print a;
+    print b;
+    wusi(a, b);
+}
+
+void main() {
+    int a = 2;
+    int b = 3;
+
+    test(a, b);
+
+    print a;
+    print b;
+}

+ 6 - 0
tests/functions/arguments.out

@@ -0,0 +1,6 @@
+2
+3
+2
+3
+2
+3

+ 19 - 0
tests/functions/forward

@@ -0,0 +1,19 @@
+void test();
+void test(int a);
+
+void main() {
+    test();
+    test(1);
+    test();
+}
+
+void test() {
+    print 4;
+    print 5;
+}
+
+void test(int a) {
+    print a;
+    print 6;
+}
+

+ 0 - 0
old_tests/functions/forward.out → tests/functions/forward.out


+ 9 - 0
tests/functions/function

@@ -0,0 +1,9 @@
+void test() {
+    print 4;
+    print 5;
+}
+
+void main() {
+    test();
+    test();
+}

+ 0 - 0
old_tests/functions/function.out → tests/functions/function.out


+ 6 - 4
old_tests/functions/function2 → tests/functions/function2

@@ -1,13 +1,15 @@
-function wusi() {
+void wusi() {
     print 6;
     print 7;
 }
 
-function test() {
+void test() {
     print 4;
     print 5;
     wusi();
 }
 
-test();
-test();
+void main() {
+    test();
+    test();
+}

+ 0 - 0
old_tests/functions/function2.out → tests/functions/function2.out


+ 15 - 0
tests/functions/overloading

@@ -0,0 +1,15 @@
+void test(int a, int b) {
+    print a + 1;
+    print b + 2;
+}
+
+void test(int a, int b, int c) {
+    print a + 3;
+    print b + 4;
+    print c + 100;
+}
+
+void main() {
+    test(1, 2);
+    test(10, 20, 1);
+}

+ 0 - 0
old_tests/functions/overloading.out → tests/functions/overloading.out


+ 12 - 0
tests/functions/recursion

@@ -0,0 +1,12 @@
+int fac(int n) {
+    if(n < 2) {
+        return 1;
+    }
+    return n * fac(n - 1);
+}
+
+void main() {
+    print fac(5);
+    print fac(7);
+    print fac(12);
+}

+ 0 - 0
old_tests/functions/recursion.out → tests/functions/recursion.out


+ 9 - 0
tests/functions/return

@@ -0,0 +1,9 @@
+void test() {
+    print 5;
+    return;
+    print 6;
+}
+
+void main() {
+    test();
+}

+ 0 - 0
old_tests/functions/return.out → tests/functions/return.out


+ 15 - 0
tests/functions/return_value

@@ -0,0 +1,15 @@
+int test();
+
+int test(int a, int b) {
+    print 5;
+    return a + b;
+}
+
+void main() {
+    print test();
+    print test(2, 4);
+}
+
+int test() {
+    return 3;
+}

+ 1 - 0
old_tests/functions/return_value.out → tests/functions/return_value.out

@@ -1,2 +1,3 @@
+3
 5
 6

+ 18 - 0
tests/functions/scope

@@ -0,0 +1,18 @@
+void test(int a, int b) {
+    print a;
+    print b;
+    a = 4;
+    b = 5;
+    print a;
+    print b;
+}
+
+void main() {
+    int a = 2;
+    int b = 3;
+    print a;
+    print b;
+    test(a, b);
+    print a;
+    print b;
+}

+ 2 - 2
old_tests/functions/scope.out → tests/functions/scope.out

@@ -1,7 +1,7 @@
 2
 3
-null
-null
+2
+3
 4
 5
 2

+ 15 - 0
tests/if/and

@@ -0,0 +1,15 @@
+bool test() {
+    print 1;
+    return true;
+}
+
+void main() {
+    print false && false;
+    print true && false;
+    print false && true;
+    print true && true;
+
+    print false && test() && test();
+    print true && test() && false && test();
+    print true && test() && test();
+}

+ 0 - 0
old_tests/if/and.out → tests/if/and.out


+ 15 - 0
tests/if/else

@@ -0,0 +1,15 @@
+void main() {
+    print 5;
+    if(true) {
+        print 6;
+    } else {
+        print 7;
+    }
+    print 8;
+    if(false) {
+        print 9;
+    } else {
+        print 10;
+    }
+    print 11;
+}

+ 0 - 0
old_tests/if/else.out → tests/if/else.out


+ 13 - 10
old_tests/if/elseif → tests/if/elseif

@@ -1,24 +1,27 @@
-function test(a) {
+void test(int a) {
     if(a == 1) {
         print 10;
     } else if(a == 1) {
-        print null;
+        print 100;
     } else if(a == 2) {
         print 20;
     } else if(a == 3) {
         print 30;
     } else if(a == 2) {
-        print null;
+        print 200;
     } else if(a == 4) {
         print 40;
     } else {
         print 50;
     }
 }
-test(0);
-test(1);
-test(2);
-test(3);
-test(4);
-test(5);
-test(6);
+
+void main() {
+    test(0);
+    test(1);
+    test(2);
+    test(3);
+    test(4);
+    test(5);
+    test(6);
+}

+ 0 - 0
old_tests/if/elseif.out → tests/if/elseif.out


+ 11 - 0
tests/if/if

@@ -0,0 +1,11 @@
+void main() {
+    print 5;
+    if(true) {
+        print 6;
+    }
+    print 7;
+    if(false) {
+        print 8;
+    }
+    print 9;
+}

+ 0 - 0
old_tests/if/if.out → tests/if/if.out


+ 8 - 0
tests/if/invert

@@ -0,0 +1,8 @@
+void main() {
+    print !true;
+    print !false;
+    print !!true;
+    print !!false;
+    print !!!true;
+    print !!!false;
+}

+ 0 - 0
old_tests/if/invert.out → tests/if/invert.out


+ 15 - 0
tests/if/or

@@ -0,0 +1,15 @@
+bool test() {
+    print 1;
+    return true;
+}
+
+void main() {
+    print false || false;
+    print true || false;
+    print false || true;
+    print true || true;
+
+    print false || test() || test();
+    print false || test() || true || test();
+    print true || test() || test();
+}

+ 0 - 0
old_tests/if/or.out → tests/if/or.out


+ 21 - 0
tests/loops/break

@@ -0,0 +1,21 @@
+void main() {
+    for(int i = 0; i < 10; i++) {
+        print i;
+        if(i == 4) {
+            break;
+        }
+    }
+    for(int x = 0; x < 3; ++x) {
+        if(false) {
+            break;
+        }
+        while(true) {
+            print x;
+            break;
+            print 100;
+        }
+        if(x == 1) {
+            break;
+        }
+    }
+}

+ 0 - 0
old_tests/loops/break.out → tests/loops/break.out


+ 37 - 0
tests/loops/continue

@@ -0,0 +1,37 @@
+void main() {
+    for(int i = 0; i < 10; i++) {
+        if(i == 4) {
+            continue;
+        }
+        print i;
+    }
+    for(int x = 0; x < 3; ++x) {
+        if(x == 1) {
+            continue;
+        }
+        for(int y = 0; y < 3; y++) {
+            print x;
+            if(x == 2) {
+                continue;
+            }
+            print y;
+        }
+        int i = 0;
+        while(i < 5) {
+            i++;
+            if(i == 3) {
+                continue;
+            }
+            print i;
+        }
+        continue;
+    }
+    int i = 0;
+    while(i < 5) {
+        i++;
+        if(i == 3) {
+            continue;
+        }
+        print i;
+    }
+}

+ 0 - 0
old_tests/loops/continue.out → tests/loops/continue.out


+ 11 - 0
tests/loops/for

@@ -0,0 +1,11 @@
+void main() {
+    for(int i = 0; i < 10; i++) {
+        print i;
+    }
+    for(int x = 0; x < 3; ++x) {
+        for(int y = 0; y < 3; y++) {
+            print x;
+            print y;
+        }
+    }
+}

+ 0 - 0
old_tests/loops/for.out → tests/loops/for.out


+ 7 - 0
tests/loops/while

@@ -0,0 +1,7 @@
+void main() {
+    int a = 0;
+    while(a < 5) {
+        print a;
+        a = a + 1;
+    }
+}

+ 0 - 0
old_tests/loops/while.out → tests/loops/while.out


+ 12 - 0
tests/loops/while_post_dec

@@ -0,0 +1,12 @@
+void main() {
+    int a = 5;
+    while(a > 0) {
+        print a--;
+    }
+
+    a = 5;
+    while(a > 0) {
+        print a;
+        a--;
+    }
+}

+ 0 - 0
old_tests/loops/while_post_dec.out → tests/loops/while_post_dec.out


+ 12 - 0
tests/loops/while_post_inc

@@ -0,0 +1,12 @@
+void main() {
+    int a = 0;
+    while(a < 5) {
+        print a++;
+    }
+
+    a = 0;
+    while(a < 5) {
+        print a;
+        a++;
+    }
+}

+ 0 - 0
old_tests/loops/while_post_inc.out → tests/loops/while_post_inc.out


+ 12 - 0
tests/loops/while_pre_dec

@@ -0,0 +1,12 @@
+void main() {
+    int a = 5;
+    while(a > 0) {
+        print --a;
+    }
+
+    a = 5;
+    while(a > 0) {
+        print a;
+        --a;
+    }
+}

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio