Browse Source

post increment

Kajetan Johannes Hammerle 3 years ago
parent
commit
59e60655a1
5 changed files with 52 additions and 1 deletions
  1. 12 0
      Compiler.c
  2. 1 0
      Operation.h
  3. 19 1
      Script.c
  4. 10 0
      tests/loops/while_post_inc
  5. 10 0
      tests/loops/while_post_inc.out

+ 12 - 0
Compiler.c

@@ -172,10 +172,17 @@ static void cCallFunction(const char* literal, bool noReturn) {
     }
 }
 
+static void cPostIncrement(const char* literal) {
+    cAddOperation(OP_POST_INCREMENT);
+    cAddInt(cAddVar(literal));
+}
+
 static void cLiteral() {
     const char* literal = cReadString();
     if(cConsumeTokenIf(T_OPEN_BRACKET)) {
         cCallFunction(literal, false);
+    } else if(cConsumeTokenIf(T_INCREMENT)) {
+        cPostIncrement(literal);
     } else {
         cGetVar(literal);
     }
@@ -322,6 +329,11 @@ static void cLineLiteral() {
             cCallFunction(literal, true);
             cConsumeToken(T_SEMICOLON);
             break;
+        case T_INCREMENT:
+            cPostIncrement(literal);
+            cConsumeToken(T_SEMICOLON);
+            cAddOperation(OP_POP);
+            break;
         default: cUnexpectedToken(t);
     }
 }

+ 1 - 0
Operation.h

@@ -14,6 +14,7 @@ typedef enum Operation {
     OP_SET,
     OP_GET,
     OP_PRE_INCREMENT,
+    OP_POST_INCREMENT,
     OP_ADD,
     OP_SUB,
     OP_MUL,

+ 19 - 1
Script.c

@@ -157,13 +157,29 @@ static void sPreIncrement(Script* sc) {
         } else if(o->type == OT_FLOAT) {
             o->data.floatValue++;
         } else {
-            sError(sc, "object is not a number on line %d", sc->line);
+            sError(sc, "variable is not a number on line %d", sc->line);
             return;
         }
         sPush(sc, o);
     }
 }
 
+static void sPostIncrement(Script* sc) {
+    int value = 0;
+    if(sReadInt(sc, &value)) {
+        Object* o = sc->stack + value + sc->stackVarIndex;
+        if(o->type == OT_INT) {
+            sPush(sc, o);
+            o->data.intValue++;
+        } else if(o->type == OT_FLOAT) {
+            sPush(sc, o);
+            o->data.floatValue++;
+        } else {
+            sError(sc, "variable is not a number on line %d", sc->line);
+        }
+    }
+}
+
 static void sPushCodeInt(Script* sc) {
     int value = 0;
     if(sReadInt(sc, &value)) {
@@ -406,6 +422,7 @@ static void sConsumeInstruction(Script* sc) {
         case OP_SET: sSet(sc); break;
         case OP_GET: sGet(sc); break;
         case OP_PRE_INCREMENT: sPreIncrement(sc); break;
+        case OP_POST_INCREMENT: sPostIncrement(sc); break;
         case OP_ADD: sNumberBinary(sc, sIntAdd, sFloatAdd); break;
         case OP_SUB: sNumberBinary(sc, sIntSub, sFloatSub); break;
         case OP_MUL: sNumberBinary(sc, sIntMul, sFloatMul); break;
@@ -508,6 +525,7 @@ void sPrintCode(Script* sc) {
             case OP_SET: sPrintInt(sc, "Set"); break;
             case OP_GET: sPrintInt(sc, "Get"); break;
             case OP_PRE_INCREMENT: sPrintInt(sc, "Pre Increment"); break;
+            case OP_POST_INCREMENT: sPrintInt(sc, "Post Increment"); break;
             case OP_ADD: puts("Add"); break;
             case OP_SUB: puts("Sub"); break;
             case OP_MUL: puts("Mul"); break;

+ 10 - 0
tests/loops/while_post_inc

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

+ 10 - 0
tests/loops/while_post_inc.out

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