Kajetan Johannes Hammerle 3 anni fa
parent
commit
b0783c3adf
4 ha cambiato i file con 54 aggiunte e 56 eliminazioni
  1. 12 0
      Object.c
  2. 2 0
      Object.h
  3. 38 55
      Script.c
  4. 2 1
      meson.build

+ 12 - 0
Object.c

@@ -0,0 +1,12 @@
+#include "Object.h"
+
+const char* oGetName(ObjectType ot) {
+    switch(ot) {
+        case OT_INT: return "int";
+        case OT_FLOAT: return "float";
+        case OT_NULL: return "null";
+        case OT_BOOL: return "bool";
+        case OT_VOID: return "void";
+        default: return "unknown";
+    }
+}

+ 2 - 0
Object.h

@@ -11,4 +11,6 @@ typedef struct Object {
     } data;
 } Object;
 
+const char* oGetName(ObjectType ot);
+
 #endif

+ 38 - 55
Script.c

@@ -49,6 +49,14 @@ static bool sReadInt(Script* sc, int* i) {
     return !sRead(sc, i, sizeof(int));
 }
 
+static bool sCheckType(Script* sc, Object* o, ObjectType ot) {
+    if(o->type == ot) {
+        return true;
+    }
+    sError(sc, "object is not of type %s on line %d", oGetName(ot), sc->line);
+    return false;
+}
+
 static bool sPush(Script* sc, Object* o) {
     if(sc->stackIndex >= SCRIPT_STACK_SIZE) {
         sError(sc, "stack overflow on line %d", sc->line);
@@ -116,11 +124,7 @@ static void sPushVars(Script* sc) {
 static void sPopVars(Script* sc) {
     int value = 0;
     Object o;
-    if(sReadInt(sc, &value) && !sPop(sc, &o)) {
-        if(o.type != OT_INT) {
-            sError(sc, "stack variable index has wrong type");
-            return;
-        }
+    if(sReadInt(sc, &value) && !sPop(sc, &o) && sCheckType(sc, &o, OT_INT)) {
         sc->stackVarIndex = o.data.intValue;
         if(sc->stackIndex < value) {
             sError(sc, "stack underflow on line %d", sc->line);
@@ -160,30 +164,20 @@ static void sPushCodeFloat(Script* sc) {
     sPushFloat(sc, value);
 }
 
-static bool sToFloat(Script* sc, Object* o, float* r) {
-    if(o->type == OT_FLOAT) {
-        *r = o->data.floatValue;
-        return true;
-    } else if(o->type == OT_INT) {
-        *r = o->data.intValue;
-        return true;
-    }
-    sError(sc, "object is not a number on line %d", sc->line);
-    return false;
-}
-
 static void sIntBinary(Script* sc, int (*fInt)(int, int), float (*fFloat)(float, float)) {
     Object o[2];
     if(sPop(sc, o) || sPop(sc, o + 1)) {
         return;
-    }
-    if(o[0].type == OT_INT && o[1].type == OT_INT) {
+    } else if(o[0].type == OT_INT && o[1].type == OT_INT) {
         sPushInt(sc, fInt(o[0].data.intValue, o[1].data.intValue));
-        return;
-    }
-    float f[2];
-    if(sToFloat(sc, o, f) && sToFloat(sc, o + 1, f + 1)) {
-        sPushFloat(sc, fFloat(f[0], f[1]));
+    } else if(o[0].type == OT_FLOAT && o[1].type == OT_INT) {
+        sPushFloat(sc, fFloat(o[0].data.floatValue, o[1].data.intValue));
+    } else if(o[0].type == OT_INT && o[1].type == OT_FLOAT) {
+        sPushFloat(sc, fFloat(o[0].data.intValue, o[1].data.floatValue));
+    } else if(o[0].type == OT_FLOAT && o[1].type == OT_FLOAT) {
+        sPushFloat(sc, fFloat(o[0].data.floatValue, o[1].data.floatValue));
+    } else {
+        sError(sc, "object is not a number on line %d", sc->line);
     }
 }
 
@@ -215,14 +209,16 @@ static void sBoolBinary(Script* sc, bool (*fInt)(int, int), bool (*fFloat)(float
     Object o[2];
     if(sPop(sc, o) || sPop(sc, o + 1)) {
         return;
-    }
-    if(o[0].type == OT_INT && o[1].type == OT_INT) {
+    } else if(o[0].type == OT_INT && o[1].type == OT_INT) {
         sPushBool(sc, fInt(o[0].data.intValue, o[1].data.intValue));
-        return;
-    }
-    float f[2];
-    if(sToFloat(sc, o, f) && sToFloat(sc, o + 1, f + 1)) {
-        sPushBool(sc, fFloat(f[0], f[1]));
+    } else if(o[0].type == OT_FLOAT && o[1].type == OT_INT) {
+        sPushBool(sc, fFloat(o[0].data.floatValue, o[1].data.intValue));
+    } else if(o[0].type == OT_INT && o[1].type == OT_FLOAT) {
+        sPushBool(sc, fFloat(o[0].data.intValue, o[1].data.floatValue));
+    } else if(o[0].type == OT_FLOAT && o[1].type == OT_FLOAT) {
+        sPushBool(sc, fFloat(o[0].data.floatValue, o[1].data.floatValue));
+    } else {
+        sError(sc, "object is not a number on line %d", sc->line);
     }
 }
 
@@ -246,8 +242,7 @@ static void sEqual(Script* sc) {
     Object o[2];
     if(sPop(sc, o) || sPop(sc, o + 1)) {
         return;
-    }
-    if(o[0].type == OT_INT && o[1].type == OT_INT) {
+    } else if(o[0].type == OT_INT && o[1].type == OT_INT) {
         sPushBool(sc, o[0].data.intValue == o[1].data.intValue);
     } else if(o[0].type == OT_INT && o[1].type == OT_FLOAT) {
         sPushBool(sc, o[0].data.intValue == o[1].data.floatValue);
@@ -266,13 +261,9 @@ static void sEqual(Script* sc) {
 
 static void sNot(Script* sc) {
     Object* o = sPeek(sc);
-    if(o == NULL) {
-        return;
-    } else if(o->type != OT_BOOL) {
-        sError(sc, "object is not a bool on line %d", sc->line);
-        return;
+    if(o != NULL && sCheckType(sc, o, OT_BOOL)) {
+        o->data.intValue = !o->data.intValue;
     }
-    o->data.intValue = !o->data.intValue;
 }
 
 static void sPrint(Script* sc) {
@@ -312,12 +303,8 @@ static void sGoSub(Script* sc) {
 static void sIfGoTo(Script* sc) {
     int gotoIndex;
     Object o;
-    if(sReadInt(sc, &gotoIndex) && !sPop(sc, &o)) {
-        if(o.type != OT_BOOL) {
-            sError(sc, "object is not a bool on line %d", sc->line);
-        } else if(!o.data.intValue) {
-            sc->readIndex = gotoIndex;
-        }
+    if(sReadInt(sc, &gotoIndex) && !sPop(sc, &o) && sCheckType(sc, &o, OT_BOOL) && !o.data.intValue) {
+        sc->readIndex = gotoIndex;
     }
 }
 
@@ -327,16 +314,12 @@ static void sSetReturn(Script* sc) {
 
 static void sReturn(Script* sc) {
     Object o;
-    if(sPop(sc, &o)) {
-        return;
-    } else if(o.type != OT_INT) {
-        sError(sc, "return address on stack is not an int");
-        return;
-    }
-    sc->readIndex = o.data.intValue;
-    if(sc->returnValue.type != OT_VOID) {
-        sPush(sc, &sc->returnValue);
-        sc->returnValue.type = OT_VOID;
+    if(!sPop(sc, &o) && sCheckType(sc, &o, OT_INT)) {
+        sc->readIndex = o.data.intValue;
+        if(sc->returnValue.type != OT_VOID) {
+            sPush(sc, &sc->returnValue);
+            sc->returnValue.type = OT_VOID;
+        }
     }
 }
 

+ 2 - 1
meson.build

@@ -9,7 +9,8 @@ src = [
     'Test.c', 
     'StringIntMap.c',
     'ByteCode.c',
-    'FunctionMap.c'
+    'FunctionMap.c',
+    'Object.c'
 ]
 
 executable('lonely_tiger',