|
@@ -31,12 +31,38 @@ typedef struct {
|
|
|
c->line __VA_OPT__(, ) __VA_ARGS__); \
|
|
c->line __VA_OPT__(, ) __VA_ARGS__); \
|
|
|
longjmp(c->jump, 1)
|
|
longjmp(c->jump, 1)
|
|
|
|
|
|
|
|
-#define CODE(command) \
|
|
|
|
|
- do { \
|
|
|
|
|
- if(command) { \
|
|
|
|
|
- THROW_ERROR("Too less memory for code"); \
|
|
|
|
|
- } \
|
|
|
|
|
- } while(false)
|
|
|
|
|
|
|
+[[noreturn]] static void throwOutOfCodeMemory(Context* c) {
|
|
|
|
|
+ THROW_ERROR("Too less memory for code");
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void codePushInstruction(Context* c, Instruction i) {
|
|
|
|
|
+ if(bufferWriteU8(&c->code->code, i)) {
|
|
|
|
|
+ throwOutOfCodeMemory(c);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void codePushI32(Context* c, i32 i) {
|
|
|
|
|
+ if(bufferWriteI32(&c->code->code, i)) {
|
|
|
|
|
+ throwOutOfCodeMemory(c);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void codePushConstantString(Context* c, const char* s) {
|
|
|
|
|
+ if(bufferWriteString(&c->code->code, s)) {
|
|
|
|
|
+ throwOutOfCodeMemory(c);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static size_t codeGetWritePosition(const Context* c) {
|
|
|
|
|
+ return c->code->code.writeIndex;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void codeRewriteI32(Context* c, size_t pos, i32 i) {
|
|
|
|
|
+ size_t oldPos = codeGetWritePosition(c);
|
|
|
|
|
+ c->code->code.writeIndex = pos;
|
|
|
|
|
+ codePushI32(c, i);
|
|
|
|
|
+ c->code->code.writeIndex = oldPos;
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
static i32 addVariable(Context* c, const char* name) {
|
|
static i32 addVariable(Context* c, const char* name) {
|
|
|
for(Variable* v = c->variables; v != nullptr; v = v->next) {
|
|
for(Variable* v = c->variables; v != nullptr; v = v->next) {
|
|
@@ -89,15 +115,15 @@ static Token consumeNewline(Context* c) {
|
|
|
static void compileConstant(Context* c) {
|
|
static void compileConstant(Context* c) {
|
|
|
Token token = tokenizerNext(c->tokenizer);
|
|
Token token = tokenizerNext(c->tokenizer);
|
|
|
if(token.type == STRING) {
|
|
if(token.type == STRING) {
|
|
|
- CODE(codePushInstruction(c->code, PUSH_CONSTANT_STRING));
|
|
|
|
|
- CODE(codePushConstantString(c->code, token.stringValue));
|
|
|
|
|
- } else if(token.type == INT64) {
|
|
|
|
|
- CODE(codePushInstruction(c->code, PUSH_INT64));
|
|
|
|
|
- CODE(codePushI64(c->code, token.intValue));
|
|
|
|
|
|
|
+ codePushInstruction(c, PUSH_CONSTANT_STRING);
|
|
|
|
|
+ codePushConstantString(c, token.stringValue);
|
|
|
|
|
+ } else if(token.type == INT32) {
|
|
|
|
|
+ codePushInstruction(c, PUSH_INT64);
|
|
|
|
|
+ codePushI32(c, token.intValue);
|
|
|
} else if(token.type == LITERAL) {
|
|
} else if(token.type == LITERAL) {
|
|
|
i32 index = addVariable(c, token.stringValue);
|
|
i32 index = addVariable(c, token.stringValue);
|
|
|
- CODE(codePushInstruction(c->code, READ_VARIABLE));
|
|
|
|
|
- CODE(codePushI64(c->code, index));
|
|
|
|
|
|
|
+ codePushInstruction(c, READ_VARIABLE);
|
|
|
|
|
+ codePushI32(c, index);
|
|
|
} else {
|
|
} else {
|
|
|
unexpectedToken(c, token);
|
|
unexpectedToken(c, token);
|
|
|
}
|
|
}
|
|
@@ -108,7 +134,7 @@ static void compileAdd(Context* c) {
|
|
|
while(tokenizerPeek(c->tokenizer).type == PLUS) {
|
|
while(tokenizerPeek(c->tokenizer).type == PLUS) {
|
|
|
tokenizerNext(c->tokenizer);
|
|
tokenizerNext(c->tokenizer);
|
|
|
compileConstant(c);
|
|
compileConstant(c);
|
|
|
- CODE(codePushInstruction(c->code, ADD));
|
|
|
|
|
|
|
+ codePushInstruction(c, ADD);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -120,9 +146,9 @@ static void compileLine(Context* c, Token token);
|
|
|
|
|
|
|
|
static void compileIf(Context* c) {
|
|
static void compileIf(Context* c) {
|
|
|
compileExpression(c);
|
|
compileExpression(c);
|
|
|
- CODE(codePushInstruction(c->code, JUMP_ON_0));
|
|
|
|
|
- size_t posIndex = codeGetWritePosition(c->code);
|
|
|
|
|
- CODE(codePushSize(c->code, 0));
|
|
|
|
|
|
|
+ codePushInstruction(c, JUMP_ON_0);
|
|
|
|
|
+ size_t posIndex = codeGetWritePosition(c);
|
|
|
|
|
+ codePushI32(c, 0);
|
|
|
consumeToken(c, THEN);
|
|
consumeToken(c, THEN);
|
|
|
consumeNewline(c);
|
|
consumeNewline(c);
|
|
|
while(true) {
|
|
while(true) {
|
|
@@ -133,18 +159,15 @@ static void compileIf(Context* c) {
|
|
|
}
|
|
}
|
|
|
consumeToken(c, ENDIF);
|
|
consumeToken(c, ENDIF);
|
|
|
consumeNewline(c);
|
|
consumeNewline(c);
|
|
|
- size_t endIndex = codeGetWritePosition(c->code);
|
|
|
|
|
- codeSetWritePosition(c->code, posIndex);
|
|
|
|
|
- CODE(codePushSize(c->code, endIndex));
|
|
|
|
|
- codeSetWritePosition(c->code, endIndex);
|
|
|
|
|
|
|
+ codeRewriteI32(c, posIndex, (i32)codeGetWritePosition(c));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void compileSetVariable(Context* c, const char* name) {
|
|
static void compileSetVariable(Context* c, const char* name) {
|
|
|
consumeToken(c, EQUAL);
|
|
consumeToken(c, EQUAL);
|
|
|
compileExpression(c);
|
|
compileExpression(c);
|
|
|
i32 index = addVariable(c, name);
|
|
i32 index = addVariable(c, name);
|
|
|
- CODE(codePushInstruction(c->code, SET_VARIABLE));
|
|
|
|
|
- CODE(codePushI64(c->code, index));
|
|
|
|
|
|
|
+ codePushInstruction(c, SET_VARIABLE);
|
|
|
|
|
+ codePushI32(c, index);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void compileLine(Context* c, Token token) {
|
|
static void compileLine(Context* c, Token token) {
|
|
@@ -161,10 +184,10 @@ static void compileLine(Context* c, Token token) {
|
|
|
if(strcmp(s, "print") == 0) {
|
|
if(strcmp(s, "print") == 0) {
|
|
|
while(tokenizerPeek(c->tokenizer).type != NEWLINE) {
|
|
while(tokenizerPeek(c->tokenizer).type != NEWLINE) {
|
|
|
compileExpression(c);
|
|
compileExpression(c);
|
|
|
- CODE(codePushInstruction(c->code, PRINT));
|
|
|
|
|
|
|
+ codePushInstruction(c, PRINT);
|
|
|
}
|
|
}
|
|
|
consumeNewline(c);
|
|
consumeNewline(c);
|
|
|
- CODE(codePushInstruction(c->code, PRINT_NEWLINE));
|
|
|
|
|
|
|
+ codePushInstruction(c, PRINT_NEWLINE);
|
|
|
} else if(tokenizerPeek(c->tokenizer).type == EQUAL) {
|
|
} else if(tokenizerPeek(c->tokenizer).type == EQUAL) {
|
|
|
compileSetVariable(c, s);
|
|
compileSetVariable(c, s);
|
|
|
} else {
|
|
} else {
|
|
@@ -174,9 +197,9 @@ static void compileLine(Context* c, Token token) {
|
|
|
|
|
|
|
|
static void parseTokens(Context* c) {
|
|
static void parseTokens(Context* c) {
|
|
|
codeReset(c->code);
|
|
codeReset(c->code);
|
|
|
- CODE(codePushInstruction(c->code, PUSH_STACK_VARIABLES));
|
|
|
|
|
- size_t stackVarsLoc = codeGetWritePosition(c->code);
|
|
|
|
|
- CODE(codePushI64(c->code, 0));
|
|
|
|
|
|
|
+ codePushInstruction(c, PUSH_STACK_VARIABLES);
|
|
|
|
|
+ size_t stackVarsLoc = codeGetWritePosition(c);
|
|
|
|
|
+ codePushI32(c, 0);
|
|
|
|
|
|
|
|
while(true) {
|
|
while(true) {
|
|
|
Token token = tokenizerNext(c->tokenizer);
|
|
Token token = tokenizerNext(c->tokenizer);
|
|
@@ -186,12 +209,9 @@ static void parseTokens(Context* c) {
|
|
|
compileLine(c, token);
|
|
compileLine(c, token);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- size_t oldPos = codeGetWritePosition(c->code);
|
|
|
|
|
- codeSetWritePosition(c->code, stackVarsLoc);
|
|
|
|
|
if(c->variables != nullptr) {
|
|
if(c->variables != nullptr) {
|
|
|
- CODE(codePushI64(c->code, c->variables->index + 1));
|
|
|
|
|
|
|
+ codeRewriteI32(c, stackVarsLoc, c->variables->index + 1);
|
|
|
}
|
|
}
|
|
|
- codeSetWritePosition(c->code, oldPos);
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Error compileFile(Tokenizer* t, Code* code) {
|
|
Error compileFile(Tokenizer* t, Code* code) {
|