|
@@ -183,6 +183,10 @@ static int sIntAdd(int a, int b) {
|
|
|
return a + b;
|
|
|
}
|
|
|
|
|
|
+static int sIntSub(int a, int b) {
|
|
|
+ return b - a;
|
|
|
+}
|
|
|
+
|
|
|
static int sIntMul(int a, int b) {
|
|
|
return a * b;
|
|
|
}
|
|
@@ -191,10 +195,37 @@ static float sFloatAdd(float a, float b) {
|
|
|
return a + b;
|
|
|
}
|
|
|
|
|
|
+static float sFloatSub(float a, float b) {
|
|
|
+ return b - a;
|
|
|
+}
|
|
|
+
|
|
|
static float sFloatMul(float a, float b) {
|
|
|
return a * b;
|
|
|
}
|
|
|
|
|
|
+static void sBoolBinary(Script* sc, bool (*fInt)(int, int), bool (*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) {
|
|
|
+ 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]));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static bool sIntLess(int a, int b) {
|
|
|
+ return b < a;
|
|
|
+}
|
|
|
+
|
|
|
+static bool sFloatLess(float a, float b) {
|
|
|
+ return b < a;
|
|
|
+}
|
|
|
+
|
|
|
static void sPrint(Script* sc) {
|
|
|
Object o;
|
|
|
if(!sPop(sc, &o) && printer(&o)) {
|
|
@@ -229,6 +260,18 @@ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void sSetReturn(Script* sc) {
|
|
|
sPop(sc, &sc->returnValue);
|
|
|
}
|
|
@@ -262,11 +305,14 @@ static void sConsumeInstruction(Script* sc) {
|
|
|
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_LESS: sBoolBinary(sc, sIntLess, sFloatLess); break;
|
|
|
case OP_PRINT: sPrint(sc); break;
|
|
|
case OP_LINE: sLine(sc); break;
|
|
|
case OP_GOTO: sGoTo(sc); break;
|
|
|
case OP_GOSUB: sGoSub(sc); break;
|
|
|
+ case OP_IF_GOTO: sIfGoTo(sc); break;
|
|
|
case OP_SET_RETURN: sSetReturn(sc); break;
|
|
|
case OP_RETURN: sReturn(sc); break;
|
|
|
}
|
|
@@ -351,11 +397,14 @@ void sPrintCode(Script* sc) {
|
|
|
case OP_SET: sPrintInt(sc, "Set"); break;
|
|
|
case OP_GET: sPrintInt(sc, "Get"); break;
|
|
|
case OP_ADD: puts("Add"); break;
|
|
|
+ case OP_SUB: puts("Sub"); break;
|
|
|
case OP_MUL: puts("Mul"); break;
|
|
|
+ case OP_LESS: puts("Less"); break;
|
|
|
case OP_PRINT: puts("Print"); break;
|
|
|
case OP_LINE: sPrintInt16(sc, "------------ Line"); break;
|
|
|
case OP_GOTO: sPrintInt(sc, "GoTo"); break;
|
|
|
case OP_GOSUB: sPrint2Int(sc, "GoSub"); break;
|
|
|
+ case OP_IF_GOTO: sPrintInt(sc, "If GoTo"); break;
|
|
|
case OP_SET_RETURN: puts("Set Return"); break;
|
|
|
case OP_RETURN: puts("Return"); break;
|
|
|
}
|