|
@@ -6,6 +6,7 @@
|
|
|
#include "Code.h"
|
|
#include "Code.h"
|
|
|
#include "Constants.h"
|
|
#include "Constants.h"
|
|
|
#include "Memory.h"
|
|
#include "Memory.h"
|
|
|
|
|
+#include "SystemFunctions.h"
|
|
|
|
|
|
|
|
void codeInit(Code* c) {
|
|
void codeInit(Code* c) {
|
|
|
*c = (Code){};
|
|
*c = (Code){};
|
|
@@ -27,7 +28,6 @@ void codeReset(Code* c) {
|
|
|
if(iPopValue(c, &name)) \
|
|
if(iPopValue(c, &name)) \
|
|
|
return true
|
|
return true
|
|
|
|
|
|
|
|
-#define INT_VALUE(value) ((Value){.type = VT_INT32, .data = (value)})
|
|
|
|
|
#define CSTRING_VALUE(value) \
|
|
#define CSTRING_VALUE(value) \
|
|
|
((Value){.type = VT_CONSTANT_STRING, .data = (value)})
|
|
((Value){.type = VT_CONSTANT_STRING, .data = (value)})
|
|
|
|
|
|
|
@@ -82,6 +82,11 @@ static bool iPopValue(Code* c, Value* v) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static bool iPop(Code* c) {
|
|
|
|
|
+ POP_VALUE(a);
|
|
|
|
|
+ return false;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
static bool iAdd(Code* c) {
|
|
static bool iAdd(Code* c) {
|
|
|
POP_VALUE(a);
|
|
POP_VALUE(a);
|
|
|
POP_VALUE(b);
|
|
POP_VALUE(b);
|
|
@@ -174,20 +179,6 @@ static bool iPushInt(Code* c) {
|
|
|
return iPushValue(c, INT_VALUE(i));
|
|
return iPushValue(c, INT_VALUE(i));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static bool iPrint(Code* c) {
|
|
|
|
|
- POP_VALUE(a);
|
|
|
|
|
- switch(a.type) {
|
|
|
|
|
- case VT_INT32: printf("%d", a.data); break;
|
|
|
|
|
- case VT_CONSTANT_STRING: printf("%s", c->code.data + a.data); break;
|
|
|
|
|
- }
|
|
|
|
|
- return false;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-static bool iPrintNewline() {
|
|
|
|
|
- putchar('\n');
|
|
|
|
|
- return false;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
static bool iJump(Code* c) {
|
|
static bool iJump(Code* c) {
|
|
|
i32 jumpPos = 0;
|
|
i32 jumpPos = 0;
|
|
|
if(codeReadI32(c, &jumpPos)) {
|
|
if(codeReadI32(c, &jumpPos)) {
|
|
@@ -309,6 +300,36 @@ static bool iPushStackVariables(Code* c) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static bool iCallSystem(Code* c) {
|
|
|
|
|
+ i32 amountIndex = 0;
|
|
|
|
|
+ if(codeReadI32(c, &amountIndex)) {
|
|
|
|
|
+ SET_ERROR("CallSystem without argument amount");
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ i32 amount = amountIndex & 0xFF;
|
|
|
|
|
+ i32 index = amountIndex >> 8;
|
|
|
|
|
+ if(amount < 0 || amount > (i32)MAX_SYSTEM_FUNCTION_ARGUMENTS) {
|
|
|
|
|
+ SET_ERROR("CallSystem with invalid amount");
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ Value values[MAX_SYSTEM_FUNCTION_ARGUMENTS];
|
|
|
|
|
+ for(i32 i = amount - 1; i >= 0; i--) {
|
|
|
|
|
+ if(iPopValue(c, values + i)) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ SystemFunction f = getSystemFunction(index);
|
|
|
|
|
+ if(f == nullptr) {
|
|
|
|
|
+ SET_ERROR("Invalid system function index");
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ Value r = {};
|
|
|
|
|
+ if(f(c, &r, values, amount)) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ return iPushValue(c, r);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
static bool execute(Code* c, Instruction command) {
|
|
static bool execute(Code* c, Instruction command) {
|
|
|
switch(command) {
|
|
switch(command) {
|
|
|
case ADD: return iAdd(c);
|
|
case ADD: return iAdd(c);
|
|
@@ -317,8 +338,7 @@ static bool execute(Code* c, Instruction command) {
|
|
|
case DIV: return iDiv(c);
|
|
case DIV: return iDiv(c);
|
|
|
case PUSH_CONSTANT_STRING: return iPushConstantString(c);
|
|
case PUSH_CONSTANT_STRING: return iPushConstantString(c);
|
|
|
case PUSH_INT32: return iPushInt(c);
|
|
case PUSH_INT32: return iPushInt(c);
|
|
|
- case PRINT: return iPrint(c);
|
|
|
|
|
- case PRINT_NEWLINE: return iPrintNewline();
|
|
|
|
|
|
|
+ case POP: return iPop(c);
|
|
|
case JUMP: return iJump(c);
|
|
case JUMP: return iJump(c);
|
|
|
case JUMP_ON_0: return iJumpIf(c);
|
|
case JUMP_ON_0: return iJumpIf(c);
|
|
|
case JUMP_SUB: return iJumpSub(c);
|
|
case JUMP_SUB: return iJumpSub(c);
|
|
@@ -335,6 +355,7 @@ static bool execute(Code* c, Instruction command) {
|
|
|
case SMALLER: return iSmaller(c);
|
|
case SMALLER: return iSmaller(c);
|
|
|
case GREATER_OR_EQUAL: return iGreaterOrEqual(c);
|
|
case GREATER_OR_EQUAL: return iGreaterOrEqual(c);
|
|
|
case SMALLER_OR_EQUAL: return iSmallerOrEqual(c);
|
|
case SMALLER_OR_EQUAL: return iSmallerOrEqual(c);
|
|
|
|
|
+ case CALL_SYSTEM: return iCallSystem(c);
|
|
|
case STOP: return true;
|
|
case STOP: return true;
|
|
|
}
|
|
}
|
|
|
return false;
|
|
return false;
|
|
@@ -390,8 +411,7 @@ void codeDump(const Code* code) {
|
|
|
DUMP(MUL);
|
|
DUMP(MUL);
|
|
|
DUMP(DIV);
|
|
DUMP(DIV);
|
|
|
DUMP_INT(PUSH_INT32);
|
|
DUMP_INT(PUSH_INT32);
|
|
|
- DUMP(PRINT);
|
|
|
|
|
- DUMP(PRINT_NEWLINE);
|
|
|
|
|
|
|
+ DUMP(POP);
|
|
|
DUMP_INT(JUMP);
|
|
DUMP_INT(JUMP);
|
|
|
DUMP_INT(JUMP_ON_0);
|
|
DUMP_INT(JUMP_ON_0);
|
|
|
DUMP_INT2(JUMP_SUB);
|
|
DUMP_INT2(JUMP_SUB);
|
|
@@ -408,6 +428,7 @@ void codeDump(const Code* code) {
|
|
|
DUMP(SMALLER);
|
|
DUMP(SMALLER);
|
|
|
DUMP(GREATER_OR_EQUAL);
|
|
DUMP(GREATER_OR_EQUAL);
|
|
|
DUMP(SMALLER_OR_EQUAL);
|
|
DUMP(SMALLER_OR_EQUAL);
|
|
|
|
|
+ DUMP_INT(CALL_SYSTEM);
|
|
|
DUMP(STOP);
|
|
DUMP(STOP);
|
|
|
case PUSH_CONSTANT_STRING:
|
|
case PUSH_CONSTANT_STRING:
|
|
|
fprintf(
|
|
fprintf(
|