|
@@ -108,9 +108,9 @@ static bool sPeek(Script* sc, void* data, int length) {
|
|
|
} \
|
|
|
POP_PUSH(type, Type)
|
|
|
|
|
|
-#define PUSH_CONSTANT(type, Type, init) \
|
|
|
+#define PUSH_CONSTANT(type, Type) \
|
|
|
{ \
|
|
|
- type value = init; \
|
|
|
+ type value; \
|
|
|
if(sRead##Type(sc, &value)) { \
|
|
|
sPush##Type(sc, value); \
|
|
|
} \
|
|
@@ -134,16 +134,20 @@ static bool sPeek(Script* sc, void* data, int length) {
|
|
|
OP_BASE(type, Type, Type, op, check)
|
|
|
#define NUMBER_OP(type, Type, op) CHECKED_NUMBER_OP(type, Type, op, )
|
|
|
#define BOOL_OP(type, Type, op) OP_BASE(type, Type, Bool, op, )
|
|
|
+#define DIVISION(type, Type) \
|
|
|
+ CHECKED_NUMBER_OP(type, Type, /, ZERO_CHECK("division"));
|
|
|
+#define MODULE(type, Type) \
|
|
|
+ CHECKED_NUMBER_OP(type, Type, %, ZERO_CHECK("module"));
|
|
|
|
|
|
READ_POP_PUSH(int, Int)
|
|
|
READ_POP_PUSH(float, Float)
|
|
|
POP_PUSH(bool, Bool)
|
|
|
|
|
|
-#define PRINT(type, Type, init) \
|
|
|
+#define PRINT(type, Type, printer) \
|
|
|
{ \
|
|
|
- type value = init; \
|
|
|
+ type value; \
|
|
|
if(sPop##Type(sc, &value)) { \
|
|
|
- type##Printer(value); \
|
|
|
+ printer(value); \
|
|
|
} \
|
|
|
}
|
|
|
|
|
@@ -277,37 +281,43 @@ static void sPeekTrueGoTo(Script* sc) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+#define CASE_NUMBER_OP(name, op) \
|
|
|
+ case OP_##name##_INT: NUMBER_OP(int, Int, op); break; \
|
|
|
+ case OP_##name##_FLOAT: \
|
|
|
+ NUMBER_OP(float, Float, op); \
|
|
|
+ break;
|
|
|
+#define CASE_BOOL_OP(name, op) \
|
|
|
+ case OP_##name##_INT: BOOL_OP(int, Int, op); break; \
|
|
|
+ case OP_##name##_FLOAT: \
|
|
|
+ BOOL_OP(float, Float, op); \
|
|
|
+ break;
|
|
|
+#define CASE_TYPE(TYPE, Type, type) \
|
|
|
+ case OP_LOAD_##TYPE: sLoad(sc, sizeof(type)); break; \
|
|
|
+ case OP_STORE_##TYPE: sStore(sc, sizeof(type)); break; \
|
|
|
+ case OP_RETURN_##TYPE: RETURN(type, Type); break; \
|
|
|
+ case OP_PRINT_##TYPE: PRINT(type, Type, type##Printer); break; \
|
|
|
+ case OP_EQUAL_##TYPE: BOOL_OP(type, Type, ==); break;
|
|
|
+
|
|
|
static void sConsumeInstruction(Script* sc) {
|
|
|
switch(sReadOperation(sc)) {
|
|
|
+ CASE_NUMBER_OP(ADD, +);
|
|
|
+ CASE_NUMBER_OP(SUB, -);
|
|
|
+ CASE_NUMBER_OP(MUL, *);
|
|
|
+ CASE_BOOL_OP(LESS, <);
|
|
|
+ CASE_BOOL_OP(GREATER, >);
|
|
|
+ CASE_TYPE(INT, Int, int);
|
|
|
+ CASE_TYPE(BOOL, Bool, bool);
|
|
|
+ CASE_TYPE(FLOAT, Float, float);
|
|
|
case OP_NOTHING: break;
|
|
|
- case OP_PUSH_INT: PUSH_CONSTANT(int, Int, 0); break;
|
|
|
- case OP_PUSH_FLOAT: PUSH_CONSTANT(float, Float, 0.0f); break;
|
|
|
+ case OP_PUSH_INT: PUSH_CONSTANT(int, Int); break;
|
|
|
+ case OP_PUSH_FLOAT: PUSH_CONSTANT(float, Float); break;
|
|
|
case OP_PUSH_TRUE: sPushBool(sc, true); break;
|
|
|
case OP_PUSH_FALSE: sPushBool(sc, false); break;
|
|
|
- case OP_ADD_INT: NUMBER_OP(int, Int, +); break;
|
|
|
- case OP_ADD_FLOAT: NUMBER_OP(float, Float, +); break;
|
|
|
- case OP_SUB_INT: NUMBER_OP(int, Int, -); break;
|
|
|
- case OP_SUB_FLOAT: NUMBER_OP(float, Float, -); break;
|
|
|
- case OP_MUL_INT: NUMBER_OP(int, Int, *); break;
|
|
|
- case OP_MUL_FLOAT: NUMBER_OP(float, Float, *); break;
|
|
|
- case OP_DIV_INT:
|
|
|
- CHECKED_NUMBER_OP(int, Int, /, ZERO_CHECK("division"));
|
|
|
- break;
|
|
|
- case OP_DIV_FLOAT:
|
|
|
- CHECKED_NUMBER_OP(float, Float, /, ZERO_CHECK("division"));
|
|
|
- break;
|
|
|
- case OP_MOD_INT:
|
|
|
- CHECKED_NUMBER_OP(int, Int, %, ZERO_CHECK("module"));
|
|
|
- break;
|
|
|
+ case OP_DIV_INT: DIVISION(int, Int); break;
|
|
|
+ case OP_DIV_FLOAT: DIVISION(float, Float); break;
|
|
|
+ case OP_MOD_INT: MODULE(int, Int); break;
|
|
|
case OP_INVERT_SIGN_INT: INVERT_SIGN(int, Int); break;
|
|
|
case OP_INVERT_SIGN_FLOAT: INVERT_SIGN(float, Float); break;
|
|
|
- case OP_LESS_INT: BOOL_OP(int, Int, <); break;
|
|
|
- case OP_LESS_FLOAT: BOOL_OP(float, Float, <); break;
|
|
|
- case OP_GREATER_INT: BOOL_OP(int, Int, >); break;
|
|
|
- case OP_GREATER_FLOAT: BOOL_OP(float, Float, >); break;
|
|
|
- case OP_EQUAL_INT: BOOL_OP(int, Int, ==); break;
|
|
|
- case OP_EQUAL_FLOAT: BOOL_OP(float, Float, ==); break;
|
|
|
- case OP_EQUAL_BOOL: BOOL_OP(bool, Bool, ==); break;
|
|
|
case OP_NOT: sNot(sc); break;
|
|
|
case OP_AND: BOOL_OP(bool, Bool, &&); break;
|
|
|
case OP_OR: BOOL_OP(bool, Bool, ||); break;
|
|
@@ -317,9 +327,6 @@ static void sConsumeInstruction(Script* sc) {
|
|
|
case OP_BIT_XOR: NUMBER_OP(int, Int, ^); break;
|
|
|
case OP_LEFT_SHIFT: NUMBER_OP(int, Int, <<); break;
|
|
|
case OP_RIGHT_SHIFT: NUMBER_OP(int, Int, >>); break;
|
|
|
- case OP_PRINT_INT: PRINT(int, Int, 0); break;
|
|
|
- case OP_PRINT_FLOAT: PRINT(float, Float, 0.0f); break;
|
|
|
- case OP_PRINT_BOOL: PRINT(bool, Bool, false); break;
|
|
|
case OP_LINE: sLine(sc); break;
|
|
|
case OP_GOTO: sGoTo(sc); break;
|
|
|
case OP_IF_GOTO: sIfGoTo(sc); break;
|
|
@@ -327,11 +334,7 @@ static void sConsumeInstruction(Script* sc) {
|
|
|
case OP_PEEK_TRUE_GOTO: sPeekTrueGoTo(sc); break;
|
|
|
case OP_GOSUB: sGoSub(sc); break;
|
|
|
case OP_RETURN: sReturn(sc); break;
|
|
|
- case OP_RETURN_INT: RETURN(int, Int); break;
|
|
|
- case OP_RETURN_BOOL: RETURN(bool, Bool); break;
|
|
|
case OP_RESERVE: sReserveBytes(sc); break;
|
|
|
- case OP_LOAD_INT: sLoad(sc, sizeof(int)); break;
|
|
|
- case OP_STORE_INT: sStore(sc, sizeof(int)); break;
|
|
|
}
|
|
|
// sCollectGarbage(sc);
|
|
|
}
|