|
@@ -62,7 +62,7 @@ static void cAddFloat(float f) {
|
|
|
bcAddBytes(code, &f, sizeof(float));
|
|
|
}
|
|
|
|
|
|
-static Token tReadTokenAndLine() {
|
|
|
+static Token cReadTokenAndLine() {
|
|
|
Token t = tReadToken();
|
|
|
if(tReadInt16(&line)) {
|
|
|
return t;
|
|
@@ -71,7 +71,7 @@ static Token tReadTokenAndLine() {
|
|
|
}
|
|
|
|
|
|
static bool cConsumeToken(Token wanted) {
|
|
|
- Token t = tReadTokenAndLine();
|
|
|
+ Token t = cReadTokenAndLine();
|
|
|
if(wanted == t) {
|
|
|
return true;
|
|
|
}
|
|
@@ -81,7 +81,7 @@ static bool cConsumeToken(Token wanted) {
|
|
|
|
|
|
static bool cConsumeTokenIf(Token t) {
|
|
|
if(tPeekToken() == t) {
|
|
|
- tReadTokenAndLine();
|
|
|
+ cReadTokenAndLine();
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
@@ -121,7 +121,7 @@ static bool cGetVar() {
|
|
|
}
|
|
|
|
|
|
static bool cPrimary() {
|
|
|
- Token t = tReadTokenAndLine();
|
|
|
+ Token t = cReadTokenAndLine();
|
|
|
switch(t) {
|
|
|
case T_INT: return cConstantInt();
|
|
|
case T_FLOAT: return cConstantFloat();
|
|
@@ -173,14 +173,24 @@ static bool cSetVar(const char* literal) {
|
|
|
|
|
|
static bool cCallFunction(const char* literal) {
|
|
|
int index;
|
|
|
- if(simSearch(&functions, literal, &index)) {
|
|
|
- cAddOperation(OP_GOSUB);
|
|
|
- cAddInt(index);
|
|
|
- } else {
|
|
|
+ if(!simSearch(&functions, literal, &index)) {
|
|
|
cError("unknown function on line %d", line);
|
|
|
return false;
|
|
|
}
|
|
|
- return cConsumeToken(T_CLOSE_BRACKET) && cConsumeToken(T_SEMICOLON);
|
|
|
+ int arguments = 0;
|
|
|
+ while(!cConsumeTokenIf(T_CLOSE_BRACKET)) {
|
|
|
+ arguments++;
|
|
|
+ if(!cExpression()) {
|
|
|
+ return false;
|
|
|
+ } else if(cConsumeTokenIf(T_COMMA) && tPeekToken() == T_CLOSE_BRACKET) {
|
|
|
+ cUnexpectedToken(tPeekToken());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ cAddOperation(OP_GOSUB);
|
|
|
+ cAddInt(index);
|
|
|
+ cAddInt(arguments);
|
|
|
+ return cConsumeToken(T_SEMICOLON);
|
|
|
}
|
|
|
|
|
|
static bool cLiteral() {
|
|
@@ -189,7 +199,7 @@ static bool cLiteral() {
|
|
|
cError("literal without string on line %d", line);
|
|
|
return false;
|
|
|
}
|
|
|
- Token t = tReadTokenAndLine();
|
|
|
+ Token t = cReadTokenAndLine();
|
|
|
if(t == T_SET) {
|
|
|
return cSetVar(literal);
|
|
|
} else if(t == T_OPEN_BRACKET) {
|
|
@@ -214,7 +224,32 @@ static bool cFunction() {
|
|
|
cError("function literal without a function name on line %d", line);
|
|
|
return false;
|
|
|
}
|
|
|
- if(!cConsumeToken(T_OPEN_BRACKET) || !cConsumeToken(T_CLOSE_BRACKET) || !cConsumeToken(T_OPEN_CURVED_BRACKET)) {
|
|
|
+ if(!cConsumeToken(T_OPEN_BRACKET)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ varIndex = 1;
|
|
|
+ vars[1].entries = 0;
|
|
|
+
|
|
|
+ int arguments = 0;
|
|
|
+ while(!cConsumeTokenIf(T_CLOSE_BRACKET)) {
|
|
|
+ if(!cConsumeToken(T_LITERAL)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ arguments++;
|
|
|
+ const char* arg = tReadString();
|
|
|
+ if(arg == NULL) {
|
|
|
+ cError("function argument literal without string on line %d", line);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ cAddVar(arg);
|
|
|
+ if(cConsumeTokenIf(T_COMMA) && tPeekToken() != T_LITERAL) {
|
|
|
+ cUnexpectedToken(tPeekToken());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!cConsumeToken(T_OPEN_CURVED_BRACKET)) {
|
|
|
return false;
|
|
|
}
|
|
|
cAddOperation(OP_GOTO);
|
|
@@ -226,10 +261,9 @@ static bool cFunction() {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- varIndex = 1;
|
|
|
- vars[1].entries = 0;
|
|
|
cAddOperation(OP_PUSH);
|
|
|
int pushIndex = cReserveInt();
|
|
|
+ cAddInt(arguments);
|
|
|
|
|
|
int oldLine = line;
|
|
|
while(!cConsumeTokenIf(T_CLOSE_CURVED_BRACKET)) {
|
|
@@ -257,7 +291,7 @@ static bool cPrint() {
|
|
|
}
|
|
|
|
|
|
static bool cLine() {
|
|
|
- Token t = tReadTokenAndLine();
|
|
|
+ Token t = cReadTokenAndLine();
|
|
|
if(t == T_END) {
|
|
|
return false;
|
|
|
}
|
|
@@ -277,6 +311,7 @@ static bool cLine() {
|
|
|
static void cForEachLine() {
|
|
|
cAddOperation(OP_PUSH);
|
|
|
int globalVars = cReserveInt();
|
|
|
+ cAddInt(0);
|
|
|
while(cLine()) {
|
|
|
}
|
|
|
cAddOperation(OP_POP);
|