|
@@ -20,6 +20,7 @@ static bool sPrinter(Object* o) {
|
|
|
case OT_FLOAT: printf("%.2f\n", o->data.floatValue); return false;
|
|
|
case OT_NULL: printf("null\n"); return false;
|
|
|
case OT_BOOL: printf(o->data.intValue ? "true\n" : "false\n"); return false;
|
|
|
+ case OT_VOID: printf("void\n"); return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
@@ -223,6 +224,10 @@ static void sGoSub(Script* sc) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void sSetReturn(Script* sc) {
|
|
|
+ sPop(sc, &sc->returnValue);
|
|
|
+}
|
|
|
+
|
|
|
static void sReturn(Script* sc) {
|
|
|
Object o;
|
|
|
if(sPop(sc, &o)) {
|
|
@@ -232,6 +237,10 @@ static void sReturn(Script* sc) {
|
|
|
return;
|
|
|
}
|
|
|
sc->readIndex = o.data.intValue;
|
|
|
+ if(sc->returnValue.type != OT_VOID) {
|
|
|
+ sPush(sc, &sc->returnValue);
|
|
|
+ sc->returnValue.type = OT_VOID;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void sConsumeInstruction(Script* sc) {
|
|
@@ -252,6 +261,7 @@ static void sConsumeInstruction(Script* sc) {
|
|
|
case OP_LINE: sLine(sc); break;
|
|
|
case OP_GOTO: sGoTo(sc); break;
|
|
|
case OP_GOSUB: sGoSub(sc); break;
|
|
|
+ case OP_SET_RETURN: sSetReturn(sc); break;
|
|
|
case OP_RETURN: sReturn(sc); break;
|
|
|
}
|
|
|
}
|
|
@@ -265,6 +275,7 @@ Script* sInit(ByteCode* code) {
|
|
|
sc->error[0] = '\0';
|
|
|
sc->code = code;
|
|
|
sc->readIndex = 0;
|
|
|
+ sc->returnValue.type = OT_VOID;
|
|
|
sc->stackIndex = 0;
|
|
|
sc->stackVarIndex = 0;
|
|
|
sc->line = 0;
|
|
@@ -288,4 +299,59 @@ void sRun(Script* sc) {
|
|
|
|
|
|
void sSetPrinter(ObjectPrinter p) {
|
|
|
printer = p;
|
|
|
+}
|
|
|
+
|
|
|
+static void sPrintInt(Script* sc, const char* msg) {
|
|
|
+ int value = 0;
|
|
|
+ sReadInt(sc, &value);
|
|
|
+ printf("%s %d\n", msg, value);
|
|
|
+}
|
|
|
+
|
|
|
+static void sPrint2Int(Script* sc, const char* msg) {
|
|
|
+ int a = 0;
|
|
|
+ sReadInt(sc, &a);
|
|
|
+ int b = 0;
|
|
|
+ sReadInt(sc, &b);
|
|
|
+ printf("%s %d %d\n", msg, a, b);
|
|
|
+}
|
|
|
+
|
|
|
+static void sPrintInt16(Script* sc, const char* msg) {
|
|
|
+ int value = 0;
|
|
|
+ sRead(sc, &value, 2);
|
|
|
+ printf("%s %d\n", msg, value);
|
|
|
+}
|
|
|
+
|
|
|
+static void sPrintFloat(Script* sc, const char* msg) {
|
|
|
+ float value = 0;
|
|
|
+ sRead(sc, &value, sizeof(float));
|
|
|
+ printf("%s %.2f\n", msg, value);
|
|
|
+}
|
|
|
+
|
|
|
+void sPrintCode(Script* sc) {
|
|
|
+ int oldRead = sc->readIndex;
|
|
|
+ sc->readIndex = 0;
|
|
|
+ while(sHasData(sc)) {
|
|
|
+ printf(" %3d | ", sc->readIndex);
|
|
|
+ switch(sReadOperation(sc)) {
|
|
|
+ case OP_NOTHING: puts("Nothing"); break;
|
|
|
+ case OP_PUSH_INT: sPrintInt(sc, "Push Int"); break;
|
|
|
+ case OP_PUSH_FLOAT: sPrintFloat(sc, "Push Float"); break;
|
|
|
+ case OP_PUSH_NULL: puts("Push null"); break;
|
|
|
+ case OP_PUSH_TRUE: puts("Push true"); break;
|
|
|
+ case OP_PUSH_FALSE: puts("Push false"); break;
|
|
|
+ case OP_PUSH: sPrint2Int(sc, "Push"); break;
|
|
|
+ case OP_POP: sPrintInt(sc, "Pop"); break;
|
|
|
+ case OP_SET: sPrintInt(sc, "Set"); break;
|
|
|
+ case OP_GET: sPrintInt(sc, "Get"); break;
|
|
|
+ case OP_ADD: puts("Add"); break;
|
|
|
+ case OP_MUL: puts("Mul"); 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_SET_RETURN: puts("Set Return"); break;
|
|
|
+ case OP_RETURN: puts("Return"); break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ sc->readIndex = oldRead;
|
|
|
}
|