|
@@ -264,17 +264,27 @@ static void compileConstant(Context* c) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static void compileUnary(Context* c) {
|
|
|
|
|
+ if(tokenizerPeek(c->tokenizer).type == TT_NOT) {
|
|
|
|
|
+ consumeToken(c, TT_NOT);
|
|
|
|
|
+ compileUnary(c);
|
|
|
|
|
+ codePushInstruction(c, NOT);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ compileConstant(c);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
static void compileMul(Context* c) {
|
|
static void compileMul(Context* c) {
|
|
|
- compileConstant(c);
|
|
|
|
|
|
|
+ compileUnary(c);
|
|
|
while(true) {
|
|
while(true) {
|
|
|
Token t = tokenizerPeek(c->tokenizer);
|
|
Token t = tokenizerPeek(c->tokenizer);
|
|
|
- if(t.type == TT_ASTERISK) {
|
|
|
|
|
|
|
+ if(t.type == TT_MULTIPLY) {
|
|
|
tokenizerNext(c->tokenizer);
|
|
tokenizerNext(c->tokenizer);
|
|
|
- compileMul(c);
|
|
|
|
|
|
|
+ compileUnary(c);
|
|
|
codePushInstruction(c, MUL);
|
|
codePushInstruction(c, MUL);
|
|
|
- } else if(t.type == TT_SLASH) {
|
|
|
|
|
|
|
+ } else if(t.type == TT_DIVIDE) {
|
|
|
tokenizerNext(c->tokenizer);
|
|
tokenizerNext(c->tokenizer);
|
|
|
- compileMul(c);
|
|
|
|
|
|
|
+ compileUnary(c);
|
|
|
codePushInstruction(c, DIV);
|
|
codePushInstruction(c, DIV);
|
|
|
} else {
|
|
} else {
|
|
|
break;
|
|
break;
|
|
@@ -286,11 +296,11 @@ static void compileAdd(Context* c) {
|
|
|
compileMul(c);
|
|
compileMul(c);
|
|
|
while(true) {
|
|
while(true) {
|
|
|
Token t = tokenizerPeek(c->tokenizer);
|
|
Token t = tokenizerPeek(c->tokenizer);
|
|
|
- if(t.type == TT_PLUS) {
|
|
|
|
|
|
|
+ if(t.type == TT_ADD) {
|
|
|
tokenizerNext(c->tokenizer);
|
|
tokenizerNext(c->tokenizer);
|
|
|
compileMul(c);
|
|
compileMul(c);
|
|
|
codePushInstruction(c, ADD);
|
|
codePushInstruction(c, ADD);
|
|
|
- } else if(t.type == TT_MINUS) {
|
|
|
|
|
|
|
+ } else if(t.type == TT_SUBTRACT) {
|
|
|
tokenizerNext(c->tokenizer);
|
|
tokenizerNext(c->tokenizer);
|
|
|
compileMul(c);
|
|
compileMul(c);
|
|
|
codePushInstruction(c, SUB);
|
|
codePushInstruction(c, SUB);
|
|
@@ -300,8 +310,60 @@ static void compileAdd(Context* c) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void compileExpression(Context* c) {
|
|
|
|
|
|
|
+static void compileCompare(Context* c) {
|
|
|
compileAdd(c);
|
|
compileAdd(c);
|
|
|
|
|
+ while(true) {
|
|
|
|
|
+ Token t = tokenizerPeek(c->tokenizer);
|
|
|
|
|
+ if(t.type == TT_EQUAL) {
|
|
|
|
|
+ tokenizerNext(c->tokenizer);
|
|
|
|
|
+ compileAdd(c);
|
|
|
|
|
+ codePushInstruction(c, EQUAL);
|
|
|
|
|
+ } else if(t.type == TT_NOT_EQUAL) {
|
|
|
|
|
+ tokenizerNext(c->tokenizer);
|
|
|
|
|
+ compileAdd(c);
|
|
|
|
|
+ codePushInstruction(c, NOT_EQUAL);
|
|
|
|
|
+ } else if(t.type == TT_GREATER) {
|
|
|
|
|
+ tokenizerNext(c->tokenizer);
|
|
|
|
|
+ compileAdd(c);
|
|
|
|
|
+ codePushInstruction(c, GREATER);
|
|
|
|
|
+ } else if(t.type == TT_SMALLER) {
|
|
|
|
|
+ tokenizerNext(c->tokenizer);
|
|
|
|
|
+ compileAdd(c);
|
|
|
|
|
+ codePushInstruction(c, SMALLER);
|
|
|
|
|
+ } else if(t.type == TT_GREATER_OR_EQUAL) {
|
|
|
|
|
+ tokenizerNext(c->tokenizer);
|
|
|
|
|
+ compileAdd(c);
|
|
|
|
|
+ codePushInstruction(c, GREATER_OR_EQUAL);
|
|
|
|
|
+ } else if(t.type == TT_SMALLER_OR_EQUAL) {
|
|
|
|
|
+ tokenizerNext(c->tokenizer);
|
|
|
|
|
+ compileAdd(c);
|
|
|
|
|
+ codePushInstruction(c, SMALLER_OR_EQUAL);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void compileLogical(Context* c) {
|
|
|
|
|
+ compileCompare(c);
|
|
|
|
|
+ while(true) {
|
|
|
|
|
+ Token t = tokenizerPeek(c->tokenizer);
|
|
|
|
|
+ if(t.type == TT_AND) {
|
|
|
|
|
+ tokenizerNext(c->tokenizer);
|
|
|
|
|
+ compileCompare(c);
|
|
|
|
|
+ codePushInstruction(c, AND);
|
|
|
|
|
+ } else if(t.type == TT_OR) {
|
|
|
|
|
+ tokenizerNext(c->tokenizer);
|
|
|
|
|
+ compileCompare(c);
|
|
|
|
|
+ codePushInstruction(c, OR);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+static void compileExpression(Context* c) {
|
|
|
|
|
+ compileLogical(c);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void compileLine(Context* c, Token token);
|
|
static void compileLine(Context* c, Token token);
|
|
@@ -311,21 +373,17 @@ static void compileIf(Context* c) {
|
|
|
codePushInstruction(c, JUMP_ON_0);
|
|
codePushInstruction(c, JUMP_ON_0);
|
|
|
size_t posIndex = codeGetWritePosition(c);
|
|
size_t posIndex = codeGetWritePosition(c);
|
|
|
codePushI32(c, 0);
|
|
codePushI32(c, 0);
|
|
|
- consumeToken(c, TT_THEN);
|
|
|
|
|
consumeNewline(c);
|
|
consumeNewline(c);
|
|
|
- while(true) {
|
|
|
|
|
- if(tokenizerPeek(c->tokenizer).type == TT_ENDIF) {
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ while(tokenizerPeek(c->tokenizer).type != TT_END) {
|
|
|
compileLine(c, tokenizerNext(c->tokenizer));
|
|
compileLine(c, tokenizerNext(c->tokenizer));
|
|
|
}
|
|
}
|
|
|
- consumeToken(c, TT_ENDIF);
|
|
|
|
|
|
|
+ consumeToken(c, TT_END);
|
|
|
consumeNewline(c);
|
|
consumeNewline(c);
|
|
|
codeRewriteI32(c, posIndex, (i32)codeGetWritePosition(c));
|
|
codeRewriteI32(c, posIndex, (i32)codeGetWritePosition(c));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void compileSetVariable(Context* c, const char* name, bool forceGlobal) {
|
|
static void compileSetVariable(Context* c, const char* name, bool forceGlobal) {
|
|
|
- consumeToken(c, TT_EQUAL);
|
|
|
|
|
|
|
+ consumeToken(c, TT_ASSIGN);
|
|
|
compileExpression(c);
|
|
compileExpression(c);
|
|
|
i32 index = addVariable(c, name, forceGlobal);
|
|
i32 index = addVariable(c, name, forceGlobal);
|
|
|
codePushInstruction(c, SET_VARIABLE);
|
|
codePushInstruction(c, SET_VARIABLE);
|
|
@@ -462,7 +520,7 @@ static void compileLine(Context* c, Token token) {
|
|
|
}
|
|
}
|
|
|
consumeNewline(c);
|
|
consumeNewline(c);
|
|
|
codePushInstruction(c, PRINT_NEWLINE);
|
|
codePushInstruction(c, PRINT_NEWLINE);
|
|
|
- } else if(tokenizerPeek(c->tokenizer).type == TT_EQUAL) {
|
|
|
|
|
|
|
+ } else if(tokenizerPeek(c->tokenizer).type == TT_ASSIGN) {
|
|
|
compileSetVariable(c, s, false);
|
|
compileSetVariable(c, s, false);
|
|
|
} else if(tokenizerPeek(c->tokenizer).type == TT_OPEN_ROUND_BRACKET) {
|
|
} else if(tokenizerPeek(c->tokenizer).type == TT_OPEN_ROUND_BRACKET) {
|
|
|
compileCallFunction(c, token);
|
|
compileCallFunction(c, token);
|