Kajetan Johannes Hammerle 3 лет назад
Родитель
Сommit
cfddaa0cc5
7 измененных файлов с 35 добавлено и 5 удалено
  1. 3 0
      Compiler.c
  2. 1 0
      Operation.h
  3. 18 5
      Script.c
  4. 2 0
      Tokenizer.c
  5. 1 0
      Tokenizer.h
  6. 5 0
      tests/calc/mod
  7. 5 0
      tests/calc/mod.out

+ 3 - 0
Compiler.c

@@ -207,6 +207,9 @@ static void cMul() {
         } else if(cConsumeTokenIf(T_DIV)) {
             cPrimary();
             cAddOperation(OP_DIV);
+        } else if(cConsumeTokenIf(T_MOD)) {
+            cPrimary();
+            cAddOperation(OP_MOD);
         } else {
             break;
         }

+ 1 - 0
Operation.h

@@ -17,6 +17,7 @@ typedef enum Operation {
     OP_SUB,
     OP_MUL,
     OP_DIV,
+    OP_MOD,
     OP_LESS,
     OP_GREATER,
     OP_EQUAL,

+ 18 - 5
Script.c

@@ -164,7 +164,7 @@ static void sPushCodeFloat(Script* sc) {
     sPushFloat(sc, value);
 }
 
-static void sIntBinary(Script* sc, int (*fInt)(int, int), float (*fFloat)(float, float)) {
+static void sNumberBinary(Script* sc, int (*fInt)(int, int), float (*fFloat)(float, float)) {
     Object o[2];
     if(sPop(sc, o) || sPop(sc, o + 1)) {
         return;
@@ -181,6 +181,13 @@ static void sIntBinary(Script* sc, int (*fInt)(int, int), float (*fFloat)(float,
     }
 }
 
+static void sIntBinary(Script* sc, int (*f)(int, int)) {
+    Object o[2];
+    if(!sPop(sc, o) && !sPop(sc, o + 1) && sCheckType(sc, o, OT_INT) && sCheckType(sc, o + 1, OT_INT)) {
+        sPushInt(sc, f(o[0].data.intValue, o[1].data.intValue));
+    }
+}
+
 static int sIntAdd(int a, int b) {
     return a + b;
 }
@@ -197,6 +204,10 @@ static int sIntDiv(int a, int b) {
     return b / a;
 }
 
+static int sMod(int a, int b) {
+    return b % a;
+}
+
 static float sFloatAdd(float a, float b) {
     return a + b;
 }
@@ -344,10 +355,11 @@ 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_ADD: sIntBinary(sc, sIntAdd, sFloatAdd); break;
-        case OP_SUB: sIntBinary(sc, sIntSub, sFloatSub); break;
-        case OP_MUL: sIntBinary(sc, sIntMul, sFloatMul); break;
-        case OP_DIV: sIntBinary(sc, sIntDiv, sFloatDiv); 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;
+        case OP_DIV: sNumberBinary(sc, sIntDiv, sFloatDiv); break;
+        case OP_MOD: sIntBinary(sc, sMod); break;
         case OP_LESS: sBoolBinary(sc, sIntLess, sFloatLess); break;
         case OP_GREATER: sBoolBinary(sc, sIntGreater, sFloatGreater); break;
         case OP_EQUAL: sEqual(sc); break;
@@ -444,6 +456,7 @@ void sPrintCode(Script* sc) {
             case OP_SUB: puts("Sub"); break;
             case OP_MUL: puts("Mul"); break;
             case OP_DIV: puts("Div"); break;
+            case OP_MOD: puts("Mod"); break;
             case OP_LESS: puts("Less"); break;
             case OP_GREATER: puts("Greater"); break;
             case OP_EQUAL: puts("Equal"); break;

+ 2 - 0
Tokenizer.c

@@ -149,6 +149,7 @@ static bool tParseToken() {
         case '-': return tAddToken(T_SUB);
         case '*': return tAddToken(T_MUL);
         case '/': return tAddToken(T_DIV);
+        case '%': return tAddToken(T_MOD);
         case '<': return tReadIf('=') ? tAddToken(T_LESS_EQUAL) : tAddToken(T_LESS);
         case '>': return tReadIf('=') ? tAddToken(T_GREATER_EQUAL) : tAddToken(T_GREATER);
         case '=': return tReadIf('=') ? tAddToken(T_EQUAL) : tAddToken(T_SET);
@@ -250,6 +251,7 @@ const char* tGetTokenName(Token token) {
         case T_SUB: return "-";
         case T_MUL: return "*";
         case T_DIV: return "/";
+        case T_MOD: return "%";
         case T_LESS: return "<";
         case T_LESS_EQUAL: return "<=";
         case T_GREATER: return ">";

+ 1 - 0
Tokenizer.h

@@ -14,6 +14,7 @@ typedef enum Token {
     T_SUB,
     T_MUL,
     T_DIV,
+    T_MOD,
     T_LESS,
     T_LESS_EQUAL,
     T_GREATER,

+ 5 - 0
tests/calc/mod

@@ -0,0 +1,5 @@
+print 1 % 5;
+print 3 % 5;
+print 5 % 5;
+print 7 % 5;
+print 9 % 5;

+ 5 - 0
tests/calc/mod.out

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