瀏覽代碼

pre increment

Kajetan Johannes Hammerle 4 年之前
父節點
當前提交
632c32f3c3
共有 7 個文件被更改,包括 57 次插入3 次删除
  1. 15 2
      Compiler.c
  2. 1 0
      Operation.h
  3. 18 0
      Script.c
  4. 2 1
      Tokenizer.c
  5. 1 0
      Tokenizer.h
  6. 10 0
      tests/loops/while_pre_inc
  7. 10 0
      tests/loops/while_pre_inc.out

+ 15 - 2
Compiler.c

@@ -198,13 +198,21 @@ static void cPrimary() {
     }
 }
 
+static void cPreIncrement() {
+    cConsumeToken(T_LITERAL);
+    cAddOperation(OP_PRE_INCREMENT);
+    cAddInt(cAddVar(cReadString()));
+}
+
 static void cPreUnary() {
     if(cConsumeTokenIf(T_SUB)) {
         cPrimary();
         cAddOperation(OP_INVERT_SIGN);
-        return;
+    } else if(cConsumeTokenIf(T_INCREMENT)) {
+        cPreIncrement();
+    } else {
+        cPrimary();
     }
-    cPrimary();
 }
 
 static void cMul() {
@@ -468,6 +476,11 @@ static void cLine(Token t) {
         case T_RETURN: cReturn(); break;
         case T_IF: cIf(); break;
         case T_WHILE: cWhile(); break;
+        case T_INCREMENT:
+            cPreIncrement();
+            cConsumeToken(T_SEMICOLON);
+            cAddOperation(OP_POP);
+            break;
         default: cUnexpectedToken(t);
     }
 }

+ 1 - 0
Operation.h

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

+ 18 - 0
Script.c

@@ -148,6 +148,22 @@ static void sGet(Script* sc) {
     }
 }
 
+static void sPreIncrement(Script* sc) {
+    int value = 0;
+    if(sReadInt(sc, &value)) {
+        Object* o = sc->stack + value + sc->stackVarIndex;
+        if(o->type == OT_INT) {
+            o->data.intValue++;
+        } else if(o->type == OT_FLOAT) {
+            o->data.floatValue++;
+        } else {
+            sError(sc, "object is not a number on line %d", sc->line);
+            return;
+        }
+        sPush(sc, o);
+    }
+}
+
 static void sPushCodeInt(Script* sc) {
     int value = 0;
     if(sReadInt(sc, &value)) {
@@ -389,6 +405,7 @@ static void sConsumeInstruction(Script* sc) {
         case OP_POP: sPopEmpty(sc); break;
         case OP_SET: sSet(sc); break;
         case OP_GET: sGet(sc); break;
+        case OP_PRE_INCREMENT: sPreIncrement(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;
@@ -490,6 +507,7 @@ void sPrintCode(Script* sc) {
             case OP_POP: puts("Pop"); break;
             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_ADD: puts("Add"); break;
             case OP_SUB: puts("Sub"); break;
             case OP_MUL: puts("Mul"); break;

+ 2 - 1
Tokenizer.c

@@ -146,7 +146,7 @@ static bool tParseToken() {
     switch(c) {
         case ' ': return true;
         case '\n': line++; return true;
-        case '+': return tAddToken(T_ADD);
+        case '+': return tReadIf('+') ? tAddToken(T_INCREMENT) : tAddToken(T_ADD);
         case '-': return tAddToken(T_SUB);
         case '*': return tAddToken(T_MUL);
         case '/': return tAddToken(T_DIV);
@@ -267,6 +267,7 @@ const char* tGetTokenName(Token token) {
         case T_BIT_AND: return "&";
         case T_BIT_OR: return "|";
         case T_SET: return "=";
+        case T_INCREMENT: return "++";
         case T_LITERAL: return "literal";
         case T_PRINT: return "print";
         case T_IF: return "if";

+ 1 - 0
Tokenizer.h

@@ -27,6 +27,7 @@ typedef enum Token {
     T_BIT_AND,
     T_BIT_OR,
     T_SET,
+    T_INCREMENT,
     T_LITERAL,
     T_PRINT,
     T_IF,

+ 10 - 0
tests/loops/while_pre_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_pre_inc.out

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