|
@@ -32,6 +32,7 @@ static int16 line = 1;
|
|
|
static bool onLine = false;
|
|
|
|
|
|
static Variables vars;
|
|
|
+static Variables globalVars;
|
|
|
static Functions functions;
|
|
|
static Functions functionQueue;
|
|
|
static Structs structs;
|
|
@@ -219,7 +220,7 @@ static DataType cExtendType(DataType dt, bool constant) {
|
|
|
return dt;
|
|
|
}
|
|
|
|
|
|
-static DataType cReadType(Token t) {
|
|
|
+static DataType cReadType(Token t, bool force) {
|
|
|
bool c = t == T_CONST;
|
|
|
if(c) {
|
|
|
t = cReadTokenAndLine();
|
|
@@ -233,11 +234,19 @@ static DataType cReadType(Token t) {
|
|
|
{
|
|
|
Struct* st = stsSearch(&structs, cReadString());
|
|
|
if(st == NULL) {
|
|
|
- cError("struct %s does not exist");
|
|
|
+ if(force) {
|
|
|
+ cError("struct %s does not exist");
|
|
|
+ } else {
|
|
|
+ return dtVoid();
|
|
|
+ }
|
|
|
}
|
|
|
return cExtendType(dtStruct(st), c);
|
|
|
}
|
|
|
- default: cUnexpectedToken(t); return dtVoid();
|
|
|
+ default:
|
|
|
+ if(force) {
|
|
|
+ cUnexpectedToken(t);
|
|
|
+ }
|
|
|
+ return dtVoid();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -334,11 +343,15 @@ static DataType cLiteral() {
|
|
|
return cCallFunction(literal);
|
|
|
}
|
|
|
Variable v;
|
|
|
- if(vsSearch(&vars, &v, literal)) {
|
|
|
- cNotDeclared(literal);
|
|
|
+ if(!vsSearch(&vars, &v, literal)) {
|
|
|
+ cAddInt32Operation(OP_DEREFERENCE_VAR, v.address);
|
|
|
+ return dtToVariable(v.type);
|
|
|
+ } else if(!vsSearch(&globalVars, &v, literal)) {
|
|
|
+ cAddInt32Operation(OP_DEREFERENCE_GVAR, v.address);
|
|
|
+ return dtToVariable(v.type);
|
|
|
}
|
|
|
- cAddInt32Operation(OP_DEREFERENCE_VAR, v.address);
|
|
|
- return dtToVariable(v.type);
|
|
|
+ cNotDeclared(literal);
|
|
|
+ return dtVoid();
|
|
|
}
|
|
|
|
|
|
static DataType cText() {
|
|
@@ -367,7 +380,7 @@ static void cArrayIndex(const char* name) {
|
|
|
}
|
|
|
|
|
|
static DataType cAllocArray() {
|
|
|
- DataType dt = cReadType(cReadTokenAndLine());
|
|
|
+ DataType dt = cReadType(cReadTokenAndLine(), true);
|
|
|
cConsumeToken(T_OPEN_SQUARE_BRACKET);
|
|
|
cArrayIndex("size");
|
|
|
cConsumeToken(T_CLOSE_SQUARE_BRACKET);
|
|
@@ -881,8 +894,7 @@ static void cSetVariable() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void cDeclare(DataType dt, bool constant) {
|
|
|
- dt = cExtendType(dt, constant);
|
|
|
+static void cDeclare(DataType dt) {
|
|
|
cConsumeToken(T_LITERAL);
|
|
|
const char* var = cReadString();
|
|
|
if(vsInScope(&vars, var)) {
|
|
@@ -901,25 +913,11 @@ static void cDeclare(DataType dt, bool constant) {
|
|
|
}
|
|
|
|
|
|
static bool cDeclaration(Token t) {
|
|
|
- bool c = t == T_CONST;
|
|
|
- if(c) {
|
|
|
- t = cReadTokenAndLine();
|
|
|
- }
|
|
|
- if(t == T_LITERAL) {
|
|
|
- const char* literal = cReadString();
|
|
|
- Struct* st = stsSearch(&structs, literal);
|
|
|
- if(st != NULL) {
|
|
|
- cDeclare(dtStruct(st), c);
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- switch(t) {
|
|
|
- case T_INT32: cDeclare(dtInt32(), c); break;
|
|
|
- case T_INT64: cDeclare(dtInt64(), c); break;
|
|
|
- case T_BOOL: cDeclare(dtBool(), c); break;
|
|
|
- case T_FLOAT: cDeclare(dtFloat(), c); break;
|
|
|
- default: return false;
|
|
|
+ DataType dt = cReadType(t, false);
|
|
|
+ if(dtIsVoid(dt)) {
|
|
|
+ return false;
|
|
|
}
|
|
|
+ cDeclare(dt);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -1007,9 +1005,8 @@ static void cLine() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void cBuildFunction(Function* f, DataType rType) {
|
|
|
- cConsumeToken(T_LITERAL);
|
|
|
- fInit(f, cReadString(), line);
|
|
|
+static void cBuildFunction(Function* f, DataType rType, const char* name) {
|
|
|
+ fInit(f, name, line);
|
|
|
f->returnType = rType;
|
|
|
vsReset(&vars);
|
|
|
cConsumeToken(T_OPEN_BRACKET);
|
|
@@ -1017,7 +1014,7 @@ static void cBuildFunction(Function* f, DataType rType) {
|
|
|
return;
|
|
|
}
|
|
|
while(true) {
|
|
|
- DataType dt = cReadType(cReadTokenAndLine());
|
|
|
+ DataType dt = cReadType(cReadTokenAndLine(), true);
|
|
|
cConsumeToken(T_LITERAL);
|
|
|
const char* name = cReadString();
|
|
|
if(vsInScope(&vars, name)) {
|
|
@@ -1065,9 +1062,9 @@ static void cInnerFunction(Function* f) {
|
|
|
returnIndex = 0;
|
|
|
}
|
|
|
|
|
|
-static void cFunction(DataType rType) {
|
|
|
+static void cFunction(DataType rType, const char* name) {
|
|
|
Function f;
|
|
|
- cBuildFunction(&f, rType);
|
|
|
+ cBuildFunction(&f, rType, name);
|
|
|
Function* found = fsSearch(&functions, &f, true);
|
|
|
if(cConsumeTokenIf(T_SEMICOLON)) {
|
|
|
cAddFunction(found, &f);
|
|
@@ -1093,7 +1090,7 @@ static void cStruct() {
|
|
|
DataType self = dtStruct(st);
|
|
|
cConsumeToken(T_OPEN_CURVED_BRACKET);
|
|
|
while(!cConsumeTokenIf(T_CLOSE_CURVED_BRACKET)) {
|
|
|
- DataType dt = cReadType(cReadTokenAndLine());
|
|
|
+ DataType dt = cReadType(cReadTokenAndLine(), true);
|
|
|
if(dtCompare(dt, self)) {
|
|
|
cError("struct %s contains itself", name);
|
|
|
}
|
|
@@ -1105,11 +1102,35 @@ static void cStruct() {
|
|
|
}
|
|
|
|
|
|
static void cGlobalScope(Token t) {
|
|
|
- switch(t) {
|
|
|
- case T_VOID: cFunction(dtVoid()); break;
|
|
|
- case T_STRUCT: cStruct(); break;
|
|
|
- default: cFunction(cReadType(t));
|
|
|
+ if(t == T_STRUCT) {
|
|
|
+ cStruct();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ DataType dt = dtVoid();
|
|
|
+ if(t != T_VOID) {
|
|
|
+ dt = cReadType(t, true);
|
|
|
}
|
|
|
+ cConsumeToken(T_LITERAL);
|
|
|
+ const char* name = cReadString();
|
|
|
+ if(tPeekToken() == T_OPEN_BRACKET) {
|
|
|
+ cFunction(dt, name);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(vsInScope(&globalVars, name)) {
|
|
|
+ cDeclared(name);
|
|
|
+ }
|
|
|
+ Variable* v = vsAdd(&globalVars, name, dt, &structs);
|
|
|
+ if(dt.type != DT_STRUCT || dtIsPointer(dt)) {
|
|
|
+ cConsumeToken(T_SET);
|
|
|
+ cAddInt32Operation(OP_DEREFERENCE_GVAR, v->address);
|
|
|
+ DataType right = cUnpackedExpression();
|
|
|
+ if(!right.constant) {
|
|
|
+ dt.constant = 0;
|
|
|
+ }
|
|
|
+ cStore(dt, right, "=");
|
|
|
+ }
|
|
|
+ cConsumeToken(T_SEMICOLON);
|
|
|
}
|
|
|
|
|
|
static void cCallMain() {
|
|
@@ -1124,6 +1145,8 @@ static void cCallMain() {
|
|
|
}
|
|
|
|
|
|
static void cForEachLine() {
|
|
|
+ cAddOperation(OP_GRESERVE);
|
|
|
+ int p = cReserveInt32();
|
|
|
while(true) {
|
|
|
Token t = cReadTokenAndLine();
|
|
|
if(t == T_END) {
|
|
@@ -1132,6 +1155,8 @@ static void cForEachLine() {
|
|
|
cGlobalScope(t);
|
|
|
}
|
|
|
cCallMain();
|
|
|
+ cSetInt32(p, globalVars.maxAddress);
|
|
|
+ cAddInt32Operation(OP_GRESERVE, -globalVars.maxAddress);
|
|
|
}
|
|
|
|
|
|
static void cLinkQueuedFunctions() {
|
|
@@ -1152,6 +1177,7 @@ static void cAllocAndCompile() {
|
|
|
returnType = dtVoid();
|
|
|
onLine = false;
|
|
|
vsInit(&vars);
|
|
|
+ vsInit(&globalVars);
|
|
|
fsInit(&functions);
|
|
|
fsInit(&functionQueue);
|
|
|
stsInit(&structs);
|
|
@@ -1162,6 +1188,7 @@ static void cAllocAndCompile() {
|
|
|
stsDelete(&structs);
|
|
|
fsDelete(&functionQueue);
|
|
|
fsDelete(&functions);
|
|
|
+ vsDelete(&globalVars);
|
|
|
vsDelete(&vars);
|
|
|
}
|
|
|
|