|
|
@@ -6,7 +6,9 @@
|
|
|
#include <string.h>
|
|
|
|
|
|
#include "Code.h"
|
|
|
+#include "Constants.h"
|
|
|
#include "Memory.h"
|
|
|
+#include "SystemFunctions.h"
|
|
|
|
|
|
typedef struct Variable Variable;
|
|
|
|
|
|
@@ -432,11 +434,7 @@ static void compileFunction(Context* c) {
|
|
|
c->inFunction = false;
|
|
|
}
|
|
|
|
|
|
-static void compileCallFunction(Context* c, Token t) {
|
|
|
- // used to store return address and variable index
|
|
|
- codePushInstructionI32(c, PUSH_INT32, 0);
|
|
|
- codePushInstructionI32(c, PUSH_INT32, 0);
|
|
|
-
|
|
|
+static i32 compileCallFunctionArguments(Context* c) {
|
|
|
consumeToken(c, TT_OPEN_ROUND_BRACKET);
|
|
|
i32 offset = 0;
|
|
|
while(!peekToken(c, TT_CLOSE_ROUND_BRACKET)) {
|
|
|
@@ -447,11 +445,31 @@ static void compileCallFunction(Context* c, Token t) {
|
|
|
compileExpression(c);
|
|
|
}
|
|
|
consumeToken(c, TT_CLOSE_ROUND_BRACKET);
|
|
|
+ return offset;
|
|
|
+}
|
|
|
|
|
|
- codePushInstruction(c, JUMP_SUB);
|
|
|
- size_t pos = codeGetWritePosition(c);
|
|
|
- codePushI32(c, addCallFunction(c, t.stringValue, (i32)pos, offset));
|
|
|
- codePushI32(c, offset);
|
|
|
+static void compileCallFunction(Context* c, Token t) {
|
|
|
+ i32 index = getSystemFunctionIndex(t.stringValue);
|
|
|
+ if(index >= 0) {
|
|
|
+ i32 args = compileCallFunctionArguments(c);
|
|
|
+ i32 wantedArgs = getSystemFunctionArguments(index);
|
|
|
+ if(wantedArgs >= 0 && args != wantedArgs) {
|
|
|
+ THROW_ERROR(
|
|
|
+ "System function '%s' called with invalid amount of arguments",
|
|
|
+ t.stringValue);
|
|
|
+ }
|
|
|
+ static_assert(MAX_SYSTEM_FUNCTION_ARGUMENTS < (1 << 8));
|
|
|
+ codePushInstructionI32(c, CALL_SYSTEM, (index << 8) | args);
|
|
|
+ } else {
|
|
|
+ // used to store return address and variable index
|
|
|
+ codePushInstructionI32(c, PUSH_INT32, 0);
|
|
|
+ codePushInstructionI32(c, PUSH_INT32, 0);
|
|
|
+ i32 offset = compileCallFunctionArguments(c);
|
|
|
+ codePushInstruction(c, JUMP_SUB);
|
|
|
+ size_t pos = codeGetWritePosition(c);
|
|
|
+ codePushI32(c, addCallFunction(c, t.stringValue, (i32)pos, offset));
|
|
|
+ codePushI32(c, offset);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void compileReturn(Context* c) {
|
|
|
@@ -467,17 +485,11 @@ static void compileReturn(Context* c) {
|
|
|
|
|
|
static void compileLineLiteral(Context* c, Token token) {
|
|
|
const char* s = token.stringValue;
|
|
|
- if(strcmp(s, "print") == 0) {
|
|
|
- while(!peekToken(c, TT_NEWLINE)) {
|
|
|
- compileExpression(c);
|
|
|
- codePushInstruction(c, PRINT);
|
|
|
- }
|
|
|
- consumeNewline(c);
|
|
|
- codePushInstruction(c, PRINT_NEWLINE);
|
|
|
- } else if(peekToken(c, TT_ASSIGN)) {
|
|
|
+ if(peekToken(c, TT_ASSIGN)) {
|
|
|
compileSetVariable(c, s, false);
|
|
|
} else if(peekToken(c, TT_OPEN_ROUND_BRACKET)) {
|
|
|
compileCallFunction(c, token);
|
|
|
+ codePushInstruction(c, POP);
|
|
|
} else {
|
|
|
THROW_ERROR("Unexpected literal(%s)", s);
|
|
|
}
|