|
@@ -4,14 +4,15 @@
|
|
|
#include <string.h>
|
|
|
|
|
|
#include "Compiler.h"
|
|
|
+#include "DataType.h"
|
|
|
#include "tokenizer/Tokenizer.h"
|
|
|
#include "utils/FunctionMap.h"
|
|
|
-#include "utils/StringIntMap.h"
|
|
|
+#include "utils/Variables.h"
|
|
|
#include "vm/Operation.h"
|
|
|
|
|
|
#define ERROR_LENGTH 256
|
|
|
-#define RETURN_BUFFER 16
|
|
|
-#define BREAK_BUFFER 32
|
|
|
+//#define RETURN_BUFFER 16
|
|
|
+//#define BREAK_BUFFER 32
|
|
|
|
|
|
static jmp_buf errorJump;
|
|
|
static char error[ERROR_LENGTH] = {'\0'};
|
|
@@ -20,18 +21,41 @@ static ByteCode* code;
|
|
|
|
|
|
static int16 line = 1;
|
|
|
|
|
|
-static int varIndex = 0;
|
|
|
-static StringIntMap vars[2];
|
|
|
-static FunctionMap functions;
|
|
|
+static Variables vars;
|
|
|
+// static FunctionMap functions;
|
|
|
|
|
|
-static int returns[RETURN_BUFFER];
|
|
|
+/*static int returns[RETURN_BUFFER];
|
|
|
static int returnIndex = 0;
|
|
|
static int returnState = 0;
|
|
|
|
|
|
static int breaks[BREAK_BUFFER];
|
|
|
static int breakIndex = 0;
|
|
|
static int forWhileStack = 0;
|
|
|
-static int continueAt = 0;
|
|
|
+static int continueAt = 0;*/
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ Operation intOp;
|
|
|
+ Operation floatOp;
|
|
|
+ Operation boolOp;
|
|
|
+ const char* name;
|
|
|
+} TypedOp;
|
|
|
+
|
|
|
+static const TypedOp TYPED_MUL = {OP_MUL_INT, OP_MUL_FLOAT, OP_NOTHING, "*"};
|
|
|
+static const TypedOp TYPED_DIV = {OP_DIV_INT, OP_DIV_FLOAT, OP_NOTHING, "/"};
|
|
|
+static const TypedOp TYPED_MOD = {OP_MOD_INT, OP_NOTHING, OP_NOTHING, "%"};
|
|
|
+static const TypedOp TYPED_ADD = {OP_ADD_INT, OP_ADD_FLOAT, OP_NOTHING, "+"};
|
|
|
+static const TypedOp TYPED_SUB = {OP_SUB_INT, OP_SUB_FLOAT, OP_NOTHING, "-"};
|
|
|
+static const TypedOp TYPED_LESS = {OP_LESS_INT, OP_LESS_FLOAT, OP_NOTHING, "<"};
|
|
|
+static const TypedOp TYPED_LESS_EQUAL = {OP_GREATER_INT, OP_GREATER_FLOAT,
|
|
|
+ OP_NOTHING, "<="};
|
|
|
+static const TypedOp TYPED_GREATER = {OP_GREATER_INT, OP_GREATER_FLOAT,
|
|
|
+ OP_NOTHING, ">"};
|
|
|
+static const TypedOp TYPED_GREATER_EQUAL = {OP_LESS_INT, OP_LESS_FLOAT,
|
|
|
+ OP_NOTHING, ">="};
|
|
|
+static const TypedOp TYPED_EQUAL = {OP_EQUAL_INT, OP_EQUAL_FLOAT, OP_EQUAL_BOOL,
|
|
|
+ "=="};
|
|
|
+static const TypedOp TYPED_NOT_EQUAL = {OP_EQUAL_INT, OP_EQUAL_FLOAT,
|
|
|
+ OP_EQUAL_BOOL, "!="};
|
|
|
|
|
|
static void cError(const char* format, ...) {
|
|
|
va_list args;
|
|
@@ -41,11 +65,23 @@ static void cError(const char* format, ...) {
|
|
|
longjmp(errorJump, 0);
|
|
|
}
|
|
|
|
|
|
-static int cAddVar(const char* var) {
|
|
|
+static void cInvalidOperation(DataType a, DataType b, const char* op) {
|
|
|
+ cError("invalid operation: %s %s %s", dtGetName(a), op, dtGetName(b));
|
|
|
+}
|
|
|
+
|
|
|
+static void cNotDeclared(const char* name) {
|
|
|
+ cError("variable %s has not been declared", name);
|
|
|
+}
|
|
|
+
|
|
|
+static void cNotInitialized(const char* name) {
|
|
|
+ cError("variable %s has not been initialized", name);
|
|
|
+}
|
|
|
+
|
|
|
+/*static int cAddVar(const char* var) {
|
|
|
int index = vars[varIndex].entries;
|
|
|
simAdd(vars + varIndex, var, &index);
|
|
|
return index;
|
|
|
-}
|
|
|
+}*/
|
|
|
|
|
|
static void cUnexpectedToken(Token t) {
|
|
|
cError("unexpected token on line %d: %s", line, tGetName(t));
|
|
@@ -56,13 +92,13 @@ static void cAddOperation(Operation token) {
|
|
|
bcAddBytes(code, &c, 1);
|
|
|
}
|
|
|
|
|
|
-static int cReserveInt() {
|
|
|
+/*static int cReserveInt() {
|
|
|
return bcReserveBytes(code, sizeof(int));
|
|
|
}
|
|
|
|
|
|
static void cSetInt(int p, int i) {
|
|
|
bcSetBytes(code, p, &i, sizeof(int));
|
|
|
-}
|
|
|
+}*/
|
|
|
|
|
|
static void cAddInt(int i) {
|
|
|
bcAddBytes(code, &i, sizeof(int));
|
|
@@ -72,11 +108,7 @@ static void cAddInt16(int16 i) {
|
|
|
bcAddBytes(code, &i, sizeof(int16));
|
|
|
}
|
|
|
|
|
|
-static void cAddFloat(float f) {
|
|
|
- bcAddBytes(code, &f, sizeof(float));
|
|
|
-}
|
|
|
-
|
|
|
-static int cAddPush(int offset) {
|
|
|
+/*static int cAddPush(int offset) {
|
|
|
cAddOperation(OP_PUSH_VARS);
|
|
|
int p = cReserveInt();
|
|
|
cAddInt(offset);
|
|
@@ -87,7 +119,7 @@ static void cAddPop(int p, int vars) {
|
|
|
cAddOperation(OP_POP_VARS);
|
|
|
cAddInt(vars);
|
|
|
cSetInt(p, vars);
|
|
|
-}
|
|
|
+}*/
|
|
|
|
|
|
static Token cReadTokenAndLine() {
|
|
|
Token t = tReadToken();
|
|
@@ -128,10 +160,10 @@ static void cConstantFloat() {
|
|
|
cError("float token without a float on line %d", line);
|
|
|
}
|
|
|
cAddOperation(OP_PUSH_FLOAT);
|
|
|
- cAddFloat(value);
|
|
|
+ bcAddBytes(code, &value, sizeof(float));
|
|
|
}
|
|
|
|
|
|
-static void cConstantString() {
|
|
|
+/*static void cConstantString() {
|
|
|
int length;
|
|
|
const char* s = tReadString(&length);
|
|
|
if(s == NULL) {
|
|
@@ -140,7 +172,7 @@ static void cConstantString() {
|
|
|
cAddOperation(OP_PUSH_CONST_STRING);
|
|
|
cAddInt(length);
|
|
|
bcAddBytes(code, s, length);
|
|
|
-}
|
|
|
+}*/
|
|
|
|
|
|
static const char* cReadString() {
|
|
|
int length;
|
|
@@ -151,9 +183,9 @@ static const char* cReadString() {
|
|
|
return literal;
|
|
|
}
|
|
|
|
|
|
-static void cExpression();
|
|
|
+static DataType cExpression();
|
|
|
|
|
|
-static int cCallFunctionArguments() {
|
|
|
+/*static int cCallFunctionArguments() {
|
|
|
int arguments = 0;
|
|
|
while(!cConsumeTokenIf(T_CLOSE_BRACKET)) {
|
|
|
arguments++;
|
|
@@ -187,28 +219,36 @@ static void cCallFunction(const char* literal, bool noReturn) {
|
|
|
cAddOperation(OP_POP);
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
+}*/
|
|
|
|
|
|
-static void cAddReference(const char* var) {
|
|
|
- if(cConsumeTokenIf(T_OPEN_SQUARE_BRACKET)) {
|
|
|
- cExpression();
|
|
|
- cAddOperation(OP_REFERENCE_FROM_ARRAY);
|
|
|
- cAddInt(cAddVar(var));
|
|
|
- cConsumeToken(T_CLOSE_SQUARE_BRACKET);
|
|
|
- } else {
|
|
|
- cAddOperation(OP_REFERENCE_FROM_VAR);
|
|
|
- cAddInt(cAddVar(var));
|
|
|
- }
|
|
|
+static void cAddReference(int address) {
|
|
|
+ // if(cConsumeTokenIf(T_OPEN_SQUARE_BRACKET)) {
|
|
|
+ // cExpression();
|
|
|
+ // cAddOperation(OP_REFERENCE_FROM_ARRAY);
|
|
|
+ // cAddInt(cAddVar(var));
|
|
|
+ // cConsumeToken(T_CLOSE_SQUARE_BRACKET);
|
|
|
+ //} else {
|
|
|
+ cAddOperation(OP_REFERENCE_FROM_VAR);
|
|
|
+ cAddInt(address);
|
|
|
+ //}
|
|
|
}
|
|
|
|
|
|
-static void cLiteral() {
|
|
|
+static DataType cLiteral() {
|
|
|
const char* literal = cReadString();
|
|
|
- if(cConsumeTokenIf(T_OPEN_BRACKET)) {
|
|
|
+ /*if(cConsumeTokenIf(T_OPEN_BRACKET)) {
|
|
|
cCallFunction(literal, false);
|
|
|
return;
|
|
|
- }
|
|
|
- cAddReference(literal);
|
|
|
- if(cConsumeTokenIf(T_INCREMENT)) {
|
|
|
+ }*/
|
|
|
+ Variable* v = vSearch(&vars, literal);
|
|
|
+ if(v == NULL) {
|
|
|
+ cNotDeclared(literal);
|
|
|
+ } else if(!v->initialized) {
|
|
|
+ cNotInitialized(literal);
|
|
|
+ }
|
|
|
+ cAddReference(v->address);
|
|
|
+ cAddOperation(OP_DEREFERENCE_INT);
|
|
|
+ return v->type;
|
|
|
+ /*if(cConsumeTokenIf(T_INCREMENT)) {
|
|
|
cAddOperation(OP_POST_INCREMENT);
|
|
|
} else if(cConsumeTokenIf(T_DECREMENT)) {
|
|
|
cAddOperation(OP_POST_DECREMENT);
|
|
@@ -222,46 +262,54 @@ static void cLiteral() {
|
|
|
}
|
|
|
} else {
|
|
|
cAddOperation(OP_DEREFERENCE);
|
|
|
- }
|
|
|
+ }*/
|
|
|
}
|
|
|
|
|
|
-static void cArray() {
|
|
|
+/*static void cArray() {
|
|
|
cConsumeToken(T_OPEN_SQUARE_BRACKET);
|
|
|
cExpression();
|
|
|
cConsumeToken(T_CLOSE_SQUARE_BRACKET);
|
|
|
cAddOperation(OP_ALLOCATE_ARRAY);
|
|
|
+}*/
|
|
|
+
|
|
|
+static DataType cBracketPrimary() {
|
|
|
+ DataType result = cExpression();
|
|
|
+ cConsumeToken(T_CLOSE_BRACKET);
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
-static void cPrimary() {
|
|
|
+static DataType cPrimary() {
|
|
|
Token t = cReadTokenAndLine();
|
|
|
switch(t) {
|
|
|
- case T_INT: cConstantInt(); break;
|
|
|
- case T_FLOAT: cConstantFloat(); break;
|
|
|
- case T_TEXT: cConstantString(); break;
|
|
|
- case T_NULL: cAddOperation(OP_PUSH_NULL); break;
|
|
|
- case T_TRUE: cAddOperation(OP_PUSH_TRUE); break;
|
|
|
- case T_FALSE: cAddOperation(OP_PUSH_FALSE); break;
|
|
|
- case T_OPEN_BRACKET:
|
|
|
- cExpression();
|
|
|
- cConsumeToken(T_CLOSE_BRACKET);
|
|
|
- break;
|
|
|
- case T_LITERAL: cLiteral(); break;
|
|
|
- case T_ARRAY: cArray(); break;
|
|
|
- default: cUnexpectedToken(t); break;
|
|
|
+ case T_CONST_INT: cConstantInt(); return DT_INT;
|
|
|
+ case T_FLOAT: cConstantFloat(); return DT_FLOAT;
|
|
|
+ // case T_TEXT: cConstantString(); break;
|
|
|
+ // case T_NULL: cAddOperation(OP_PUSH_NULL); break;
|
|
|
+ case T_TRUE: cAddOperation(OP_PUSH_TRUE); return DT_BOOL;
|
|
|
+ case T_FALSE: cAddOperation(OP_PUSH_FALSE); return DT_BOOL;
|
|
|
+ case T_OPEN_BRACKET: return cBracketPrimary();
|
|
|
+ case T_LITERAL: return cLiteral();
|
|
|
+ // case T_ARRAY: cArray(); break;
|
|
|
+ default: cUnexpectedToken(t); return DT_VOID;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void cPreChange(Operation op) {
|
|
|
+/*static void cPreChange(Operation op) {
|
|
|
cConsumeToken(T_LITERAL);
|
|
|
cAddReference(cReadString());
|
|
|
cAddOperation(op);
|
|
|
-}
|
|
|
+}*/
|
|
|
|
|
|
-static void cPreUnary() {
|
|
|
+static DataType cPreUnary() {
|
|
|
if(cConsumeTokenIf(T_SUB)) {
|
|
|
- cPrimary();
|
|
|
- cAddOperation(OP_INVERT_SIGN);
|
|
|
- } else if(cConsumeTokenIf(T_INCREMENT)) {
|
|
|
+ DataType result = cPrimary();
|
|
|
+ switch(result) {
|
|
|
+ case DT_INT: cAddOperation(OP_INVERT_SIGN_INT); break;
|
|
|
+ case DT_FLOAT: cAddOperation(OP_INVERT_SIGN_FLOAT); break;
|
|
|
+ default: cError("cannot invert sign of %s", dtGetName(result));
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ } /*else if(cConsumeTokenIf(T_INCREMENT)) {
|
|
|
cPreChange(OP_PRE_INCREMENT);
|
|
|
} else if(cConsumeTokenIf(T_DECREMENT)) {
|
|
|
cPreChange(OP_PRE_DECREMENT);
|
|
@@ -278,47 +326,56 @@ static void cPreUnary() {
|
|
|
} else if(cConsumeTokenIf(T_BIT_NOT)) {
|
|
|
cPrimary();
|
|
|
cAddOperation(OP_BIT_NOT);
|
|
|
+ } else {*/
|
|
|
+ return cPrimary();
|
|
|
+ //}
|
|
|
+}
|
|
|
+
|
|
|
+static void cAddTypeOperation(DataType a, DataType b, const TypedOp* op) {
|
|
|
+ if(a == DT_INT && b == DT_INT && op->intOp != OP_NOTHING) {
|
|
|
+ cAddOperation(op->intOp);
|
|
|
+ } else if(a == DT_FLOAT && b == DT_FLOAT && op->floatOp != OP_NOTHING) {
|
|
|
+ cAddOperation(op->floatOp);
|
|
|
+ } else if(a == DT_BOOL && b == DT_BOOL && op->boolOp != OP_NOTHING) {
|
|
|
+ cAddOperation(op->boolOp);
|
|
|
} else {
|
|
|
- cPrimary();
|
|
|
+ cInvalidOperation(a, b, op->name);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void cMul() {
|
|
|
- cPreUnary();
|
|
|
+static DataType cMul() {
|
|
|
+ DataType a = cPreUnary();
|
|
|
while(true) {
|
|
|
if(cConsumeTokenIf(T_MUL)) {
|
|
|
- cPreUnary();
|
|
|
- cAddOperation(OP_MUL);
|
|
|
+ cAddTypeOperation(a, cPreUnary(), &TYPED_MUL);
|
|
|
} else if(cConsumeTokenIf(T_DIV)) {
|
|
|
- cPreUnary();
|
|
|
- cAddOperation(OP_DIV);
|
|
|
+ cAddTypeOperation(a, cPreUnary(), &TYPED_DIV);
|
|
|
} else if(cConsumeTokenIf(T_MOD)) {
|
|
|
- cPreUnary();
|
|
|
- cAddOperation(OP_MOD);
|
|
|
+ cAddTypeOperation(a, cPreUnary(), &TYPED_MOD);
|
|
|
} else {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
+ return a;
|
|
|
}
|
|
|
|
|
|
-static void cAdd() {
|
|
|
- cMul();
|
|
|
+static DataType cAdd() {
|
|
|
+ DataType a = cMul();
|
|
|
while(true) {
|
|
|
if(cConsumeTokenIf(T_ADD)) {
|
|
|
- cMul();
|
|
|
- cAddOperation(OP_ADD);
|
|
|
+ cAddTypeOperation(a, cMul(), &TYPED_ADD);
|
|
|
} else if(cConsumeTokenIf(T_SUB)) {
|
|
|
- cMul();
|
|
|
- cAddOperation(OP_SUB);
|
|
|
+ cAddTypeOperation(a, cMul(), &TYPED_SUB);
|
|
|
} else {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
+ return a;
|
|
|
}
|
|
|
|
|
|
-static void cShift() {
|
|
|
- cAdd();
|
|
|
- while(true) {
|
|
|
+static DataType cShift() {
|
|
|
+ return cAdd();
|
|
|
+ /*while(true) {
|
|
|
if(cConsumeTokenIf(T_LEFT_SHIFT)) {
|
|
|
cAdd();
|
|
|
cAddOperation(OP_LEFT_SHIFT);
|
|
@@ -328,87 +385,89 @@ static void cShift() {
|
|
|
} else {
|
|
|
break;
|
|
|
}
|
|
|
- }
|
|
|
+ }*/
|
|
|
}
|
|
|
|
|
|
-static void cComparison() {
|
|
|
- cShift();
|
|
|
+static DataType cComparison() {
|
|
|
+ DataType a = cShift();
|
|
|
while(true) {
|
|
|
if(cConsumeTokenIf(T_LESS)) {
|
|
|
- cShift();
|
|
|
- cAddOperation(OP_LESS);
|
|
|
+ cAddTypeOperation(a, cShift(), &TYPED_LESS);
|
|
|
+ a = DT_BOOL;
|
|
|
} else if(cConsumeTokenIf(T_LESS_EQUAL)) {
|
|
|
- cShift();
|
|
|
- cAddOperation(OP_GREATER);
|
|
|
+ cAddTypeOperation(a, cShift(), &TYPED_LESS_EQUAL);
|
|
|
cAddOperation(OP_NOT);
|
|
|
+ a = DT_BOOL;
|
|
|
} else if(cConsumeTokenIf(T_GREATER)) {
|
|
|
- cShift();
|
|
|
- cAddOperation(OP_GREATER);
|
|
|
+ cAddTypeOperation(a, cShift(), &TYPED_GREATER);
|
|
|
+ a = DT_BOOL;
|
|
|
} else if(cConsumeTokenIf(T_GREATER_EQUAL)) {
|
|
|
- cShift();
|
|
|
- cAddOperation(OP_LESS);
|
|
|
+ cAddTypeOperation(a, cShift(), &TYPED_GREATER_EQUAL);
|
|
|
cAddOperation(OP_NOT);
|
|
|
+ a = DT_BOOL;
|
|
|
} else {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
+ return a;
|
|
|
}
|
|
|
|
|
|
-static void cEqual() {
|
|
|
- cComparison();
|
|
|
+static DataType cEqual() {
|
|
|
+ DataType a = cComparison();
|
|
|
while(true) {
|
|
|
if(cConsumeTokenIf(T_EQUAL)) {
|
|
|
- cComparison();
|
|
|
- cAddOperation(OP_EQUAL);
|
|
|
+ cAddTypeOperation(a, cComparison(), &TYPED_EQUAL);
|
|
|
+ a = DT_BOOL;
|
|
|
} else if(cConsumeTokenIf(T_NOT_EQUAL)) {
|
|
|
- cComparison();
|
|
|
- cAddOperation(OP_EQUAL);
|
|
|
+ cAddTypeOperation(a, cComparison(), &TYPED_NOT_EQUAL);
|
|
|
cAddOperation(OP_NOT);
|
|
|
+ a = DT_BOOL;
|
|
|
} else {
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
+ return a;
|
|
|
}
|
|
|
|
|
|
-static void cBitAnd() {
|
|
|
- cEqual();
|
|
|
- while(cConsumeTokenIf(T_BIT_AND)) {
|
|
|
+static DataType cBitAnd() {
|
|
|
+ return cEqual();
|
|
|
+ /*while(cConsumeTokenIf(T_BIT_AND)) {
|
|
|
cEqual();
|
|
|
cAddOperation(OP_BIT_AND);
|
|
|
- }
|
|
|
+ }*/
|
|
|
}
|
|
|
|
|
|
-static void cBitXor() {
|
|
|
- cBitAnd();
|
|
|
- while(cConsumeTokenIf(T_BIT_XOR)) {
|
|
|
+static DataType cBitXor() {
|
|
|
+ return cBitAnd();
|
|
|
+ /*while(cConsumeTokenIf(T_BIT_XOR)) {
|
|
|
cBitAnd();
|
|
|
cAddOperation(OP_BIT_XOR);
|
|
|
- }
|
|
|
+ }*/
|
|
|
}
|
|
|
|
|
|
-static void cBitOr() {
|
|
|
- cBitXor();
|
|
|
- while(cConsumeTokenIf(T_BIT_OR)) {
|
|
|
+static DataType cBitOr() {
|
|
|
+ return cBitXor();
|
|
|
+ /*while(cConsumeTokenIf(T_BIT_OR)) {
|
|
|
cBitXor();
|
|
|
cAddOperation(OP_BIT_OR);
|
|
|
- }
|
|
|
+ }*/
|
|
|
}
|
|
|
|
|
|
-static void cAnd() {
|
|
|
- cBitOr();
|
|
|
- while(cConsumeTokenIf(T_AND)) {
|
|
|
+static DataType cAnd() {
|
|
|
+ return cBitOr();
|
|
|
+ /*while(cConsumeTokenIf(T_AND)) {
|
|
|
cAddOperation(OP_DUPLICATE);
|
|
|
cAddOperation(OP_IF_GOTO);
|
|
|
int p = cReserveInt();
|
|
|
cBitOr();
|
|
|
cAddOperation(OP_AND);
|
|
|
cSetInt(p, code->length);
|
|
|
- }
|
|
|
+ }*/
|
|
|
}
|
|
|
|
|
|
-static void cOr() {
|
|
|
- cAnd();
|
|
|
- while(cConsumeTokenIf(T_OR)) {
|
|
|
+static DataType cOr() {
|
|
|
+ return cAnd();
|
|
|
+ /*while(cConsumeTokenIf(T_OR)) {
|
|
|
cAddOperation(OP_DUPLICATE);
|
|
|
cAddOperation(OP_NOT);
|
|
|
cAddOperation(OP_IF_GOTO);
|
|
@@ -416,29 +475,44 @@ static void cOr() {
|
|
|
cAnd();
|
|
|
cAddOperation(OP_OR);
|
|
|
cSetInt(p, code->length);
|
|
|
- }
|
|
|
+ }*/
|
|
|
}
|
|
|
|
|
|
-static void cExpression() {
|
|
|
- cOr();
|
|
|
+static DataType cExpression() {
|
|
|
+ return cOr();
|
|
|
}
|
|
|
|
|
|
-static void cOperationSet(Operation op) {
|
|
|
+/*static void cOperationSet(Operation op) {
|
|
|
cAddOperation(OP_DUPLICATE);
|
|
|
cAddOperation(OP_DEREFERENCE);
|
|
|
cExpression();
|
|
|
cAddOperation(op);
|
|
|
cAddOperation(OP_SET);
|
|
|
-}
|
|
|
+}*/
|
|
|
|
|
|
static void cLineLiteral() {
|
|
|
const char* literal = cReadString();
|
|
|
- if(cConsumeTokenIf(T_OPEN_BRACKET)) {
|
|
|
+ /*if(cConsumeTokenIf(T_OPEN_BRACKET)) {
|
|
|
cCallFunction(literal, true);
|
|
|
return;
|
|
|
+ }*/
|
|
|
+ Variable* v = vSearch(&vars, literal);
|
|
|
+ if(v == NULL) {
|
|
|
+ cNotDeclared(literal);
|
|
|
+ }
|
|
|
+ cAddReference(v->address);
|
|
|
+ cConsumeToken(T_SET);
|
|
|
+ DataType dt = cExpression();
|
|
|
+ if(v->type != dt) {
|
|
|
+ cInvalidOperation(v->type, dt, "=");
|
|
|
+ }
|
|
|
+ if(dt == DT_INT) {
|
|
|
+ cAddOperation(OP_SET_INT);
|
|
|
+ } else {
|
|
|
+ cError("%s cannot be set", dtGetName(dt));
|
|
|
}
|
|
|
- cAddReference(literal);
|
|
|
- Token t = cReadTokenAndLine();
|
|
|
+ v->initialized = true;
|
|
|
+ /*Token t = cReadTokenAndLine();
|
|
|
switch(t) {
|
|
|
case T_SET:
|
|
|
cExpression();
|
|
@@ -463,10 +537,10 @@ static void cLineLiteral() {
|
|
|
cAddOperation(OP_POP);
|
|
|
break;
|
|
|
default: cUnexpectedToken(t);
|
|
|
- }
|
|
|
+ }*/
|
|
|
}
|
|
|
|
|
|
-static int cFunctionArguments() {
|
|
|
+/*static int cFunctionArguments() {
|
|
|
int arguments = 0;
|
|
|
while(!cConsumeTokenIf(T_CLOSE_BRACKET)) {
|
|
|
cConsumeToken(T_LITERAL);
|
|
@@ -565,15 +639,20 @@ static void cReturn() {
|
|
|
cAddReturn();
|
|
|
cConsumeToken(T_SEMICOLON);
|
|
|
}
|
|
|
-}
|
|
|
+}*/
|
|
|
|
|
|
static void cPrint() {
|
|
|
- cExpression();
|
|
|
+ DataType dt = cExpression();
|
|
|
+ switch(dt) {
|
|
|
+ case DT_INT: cAddOperation(OP_PRINT_INT); break;
|
|
|
+ case DT_FLOAT: cAddOperation(OP_PRINT_FLOAT); break;
|
|
|
+ case DT_BOOL: cAddOperation(OP_PRINT_BOOL); break;
|
|
|
+ default: cError("cannot print data type %s", dtGetName(dt));
|
|
|
+ }
|
|
|
cConsumeToken(T_SEMICOLON);
|
|
|
- cAddOperation(OP_PRINT);
|
|
|
}
|
|
|
|
|
|
-static void cIf() {
|
|
|
+/*static void cIf() {
|
|
|
cConsumeToken(T_OPEN_BRACKET);
|
|
|
cExpression();
|
|
|
cConsumeToken(T_CLOSE_BRACKET);
|
|
@@ -620,24 +699,46 @@ static void cWhile() {
|
|
|
cAddInt(start);
|
|
|
cSetInt(ifP, code->length);
|
|
|
cConsumeBreaks(breakStart, code->length);
|
|
|
+}*/
|
|
|
+
|
|
|
+static void cInt() {
|
|
|
+ cConsumeToken(T_LITERAL);
|
|
|
+ const char* var = cReadString();
|
|
|
+ Variable* v = vSearch(&vars, var);
|
|
|
+ if(v != NULL) {
|
|
|
+ cError("%s has already been declared", var);
|
|
|
+ }
|
|
|
+ v = vAdd(&vars, var, DT_INT);
|
|
|
+ if(tPeekToken() == T_SEMICOLON) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ cConsumeToken(T_SET);
|
|
|
+ cAddReference(v->address);
|
|
|
+ DataType dt = cExpression();
|
|
|
+ if(dt != DT_INT) {
|
|
|
+ cInvalidOperation(DT_INT, dt, "=");
|
|
|
+ }
|
|
|
+ cAddOperation(OP_SET_INT);
|
|
|
+ v->initialized = true;
|
|
|
}
|
|
|
|
|
|
static void cLineExpression(Token t) {
|
|
|
switch(t) {
|
|
|
case T_LITERAL: cLineLiteral(); break;
|
|
|
- case T_INCREMENT:
|
|
|
+ case T_INT: cInt(); break;
|
|
|
+ /*case T_INCREMENT:
|
|
|
cPreChange(OP_PRE_INCREMENT);
|
|
|
cAddOperation(OP_POP);
|
|
|
break;
|
|
|
case T_DECREMENT:
|
|
|
cPreChange(OP_PRE_DECREMENT);
|
|
|
cAddOperation(OP_POP);
|
|
|
- break;
|
|
|
+ break;*/
|
|
|
default: cUnexpectedToken(t);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void cFor() {
|
|
|
+/*static void cFor() {
|
|
|
cConsumeToken(T_OPEN_BRACKET);
|
|
|
cLineExpression(cReadTokenAndLine());
|
|
|
cConsumeToken(T_SEMICOLON);
|
|
@@ -685,20 +786,20 @@ static void cContinue() {
|
|
|
cAddOperation(OP_GOTO);
|
|
|
cAddInt(continueAt);
|
|
|
cConsumeToken(T_SEMICOLON);
|
|
|
-}
|
|
|
+}*/
|
|
|
|
|
|
static void cLine(Token t) {
|
|
|
cAddOperation(OP_LINE);
|
|
|
cAddInt16(line);
|
|
|
switch(t) {
|
|
|
case T_PRINT: cPrint(); break;
|
|
|
- case T_FUNCTION: cFunction(); break;
|
|
|
- case T_RETURN: cReturn(); break;
|
|
|
- case T_IF: cIf(); break;
|
|
|
- case T_WHILE: cWhile(); break;
|
|
|
- case T_FOR: cFor(); break;
|
|
|
- case T_BREAK: cBreak(); break;
|
|
|
- case T_CONTINUE: cContinue(); break;
|
|
|
+ // case T_FUNCTION: cFunction(); break;
|
|
|
+ // case T_RETURN: cReturn(); break;
|
|
|
+ // case T_IF: cIf(); break;
|
|
|
+ // case T_WHILE: cWhile(); break;
|
|
|
+ // case T_FOR: cFor(); break;
|
|
|
+ // case T_BREAK: cBreak(); break;
|
|
|
+ // case T_CONTINUE: cContinue(); break;
|
|
|
default: cLineExpression(t); cConsumeToken(T_SEMICOLON);
|
|
|
}
|
|
|
}
|
|
@@ -711,7 +812,7 @@ static void cForEachLine() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void cLinkQueuedFunctions() {
|
|
|
+/*static void cLinkQueuedFunctions() {
|
|
|
for(int i = 0; i < functions.queueEntries; i++) {
|
|
|
Function* f = fmSearch(&functions, functions.queue[i].name,
|
|
|
functions.queue[i].arguments);
|
|
@@ -726,26 +827,24 @@ static void cLinkQueuedFunctions() {
|
|
|
code->code[functions.queue[i].reserved + sizeof(int) * 2] = OP_POP;
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
+}*/
|
|
|
|
|
|
static void cAllocAndCompile() {
|
|
|
- varIndex = 0;
|
|
|
- returnIndex = 0;
|
|
|
- returnState = 0;
|
|
|
- forWhileStack = 0;
|
|
|
- breakIndex = 0;
|
|
|
- simInit(vars);
|
|
|
- simInit(vars + 1);
|
|
|
- fmInit(&functions);
|
|
|
+ // varIndex = 0;
|
|
|
+ // returnIndex = 0;
|
|
|
+ // returnState = 0;
|
|
|
+ // forWhileStack = 0;
|
|
|
+ // breakIndex = 0;
|
|
|
+ vInit(&vars);
|
|
|
+ // fmInit(&functions);
|
|
|
if(!setjmp(errorJump)) {
|
|
|
- int p = cAddPush(0);
|
|
|
+ // int p = cAddPush(0);
|
|
|
cForEachLine();
|
|
|
- cAddPop(p, vars[varIndex].entries);
|
|
|
- cLinkQueuedFunctions();
|
|
|
+ // cAddPop(p, vars[varIndex].entries);
|
|
|
+ // cLinkQueuedFunctions();
|
|
|
}
|
|
|
- fmDelete(&functions);
|
|
|
- simDelete(vars + 1);
|
|
|
- simDelete(vars);
|
|
|
+ // fmDelete(&functions);
|
|
|
+ vDelete(&vars);
|
|
|
}
|
|
|
|
|
|
ByteCode* cCompile() {
|
|
@@ -761,4 +860,8 @@ ByteCode* cCompile() {
|
|
|
|
|
|
const char* cGetError() {
|
|
|
return error;
|
|
|
+}
|
|
|
+
|
|
|
+int cGetLine() {
|
|
|
+ return line;
|
|
|
}
|