|
@@ -401,6 +401,17 @@ static void compileSetVariable(Context* c, const char* name, bool forceGlobal) {
|
|
|
codePushInstructionI32(c, SET_VARIABLE, addVariable(c, name, forceGlobal));
|
|
codePushInstructionI32(c, SET_VARIABLE, addVariable(c, name, forceGlobal));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static void rewriteLoopJumps(
|
|
|
|
|
+ Context* c, const BreakContinue* w, i32 end, i32 con) {
|
|
|
|
|
+ while(c->loopJumps != w) {
|
|
|
|
|
+ BreakContinue* next = c->loopJumps->next;
|
|
|
|
|
+ codeRewriteI32(
|
|
|
|
|
+ c, c->loopJumps->address, c->loopJumps->stop ? end : con);
|
|
|
|
|
+ memoryFree(c->loopJumps);
|
|
|
|
|
+ c->loopJumps = next;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
static void compileFor(Context* c) {
|
|
static void compileFor(Context* c) {
|
|
|
c->inLoop++;
|
|
c->inLoop++;
|
|
|
Token t = consumeToken(c, TT_LITERAL);
|
|
Token t = consumeToken(c, TT_LITERAL);
|
|
@@ -431,14 +442,30 @@ static void compileFor(Context* c) {
|
|
|
i32 endStart = (i32)codeGetWritePosition(c);
|
|
i32 endStart = (i32)codeGetWritePosition(c);
|
|
|
codeRewriteI32(c, end, endStart);
|
|
codeRewriteI32(c, end, endStart);
|
|
|
|
|
|
|
|
- while(c->loopJumps != currentJumps) {
|
|
|
|
|
- BreakContinue* next = c->loopJumps->next;
|
|
|
|
|
- codeRewriteI32(
|
|
|
|
|
- c, c->loopJumps->address,
|
|
|
|
|
- c->loopJumps->stop ? endStart : continueStart);
|
|
|
|
|
- memoryFree(c->loopJumps);
|
|
|
|
|
- c->loopJumps = next;
|
|
|
|
|
|
|
+ rewriteLoopJumps(c, currentJumps, endStart, continueStart);
|
|
|
|
|
+ c->inLoop--;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void compileWhile(Context* c) {
|
|
|
|
|
+ c->inLoop++;
|
|
|
|
|
+ size_t checkStart = codeGetWritePosition(c);
|
|
|
|
|
+ compileExpression(c);
|
|
|
|
|
+ consumeNewline(c);
|
|
|
|
|
+ size_t end = codePushInstructionI32(c, JUMP_ON_0, 0);
|
|
|
|
|
+
|
|
|
|
|
+ BreakContinue* currentJumps = c->loopJumps;
|
|
|
|
|
+ while(!peekToken(c, TT_END)) {
|
|
|
|
|
+ compileLine(c, tokenizerNext(c->tokenizer));
|
|
|
}
|
|
}
|
|
|
|
|
+ consumeToken(c, TT_END);
|
|
|
|
|
+ consumeNewline(c);
|
|
|
|
|
+
|
|
|
|
|
+ i32 continueStart = (i32)codeGetWritePosition(c);
|
|
|
|
|
+ codePushInstructionI32(c, JUMP, (i32)checkStart);
|
|
|
|
|
+ i32 endStart = (i32)codeGetWritePosition(c);
|
|
|
|
|
+ codeRewriteI32(c, end, endStart);
|
|
|
|
|
+
|
|
|
|
|
+ rewriteLoopJumps(c, currentJumps, endStart, continueStart);
|
|
|
c->inLoop--;
|
|
c->inLoop--;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -579,6 +606,8 @@ static void compileLine(Context* c, Token token) {
|
|
|
consumeNewline(c);
|
|
consumeNewline(c);
|
|
|
} else if(token.type == TT_FOR) {
|
|
} else if(token.type == TT_FOR) {
|
|
|
compileFor(c);
|
|
compileFor(c);
|
|
|
|
|
+ } else if(token.type == TT_WHILE) {
|
|
|
|
|
+ compileWhile(c);
|
|
|
} else if(token.type == TT_FUNCTION) {
|
|
} else if(token.type == TT_FUNCTION) {
|
|
|
compileFunction(c);
|
|
compileFunction(c);
|
|
|
} else if(token.type == TT_RETURN) {
|
|
} else if(token.type == TT_RETURN) {
|