|
@@ -77,8 +77,15 @@ static void cError(const char* format, ...) {
|
|
longjmp(errorJump, 0);
|
|
longjmp(errorJump, 0);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static const char* cGetName(DataType dt) {
|
|
|
|
+ if(dtIsStruct(dt)) {
|
|
|
|
+ return structs.data[dt - STRUCT_OFFSET].name;
|
|
|
|
+ }
|
|
|
|
+ return dtGetName(dt);
|
|
|
|
+}
|
|
|
|
+
|
|
static void cInvalidOperation(DataType a, DataType b, const char* op) {
|
|
static void cInvalidOperation(DataType a, DataType b, const char* op) {
|
|
- cError("invalid operation: %s %s %s", dtGetName(a), op, dtGetName(b));
|
|
|
|
|
|
+ cError("invalid operation: %s %s %s", cGetName(a), op, cGetName(b));
|
|
}
|
|
}
|
|
|
|
|
|
static void cNotDeclared(const char* name) {
|
|
static void cNotDeclared(const char* name) {
|
|
@@ -210,7 +217,7 @@ static DataType cLoadVariable(Variable* v) {
|
|
case DT_INT: cAddOperation(OP_LOAD_INT); break;
|
|
case DT_INT: cAddOperation(OP_LOAD_INT); break;
|
|
case DT_BOOL: cAddOperation(OP_LOAD_BOOL); break;
|
|
case DT_BOOL: cAddOperation(OP_LOAD_BOOL); break;
|
|
case DT_FLOAT: cAddOperation(OP_LOAD_FLOAT); break;
|
|
case DT_FLOAT: cAddOperation(OP_LOAD_FLOAT); break;
|
|
- default: cError("cannot load type %s", dtGetName(v->type));
|
|
|
|
|
|
+ default: cError("cannot load type %s", cGetName(v->type));
|
|
}
|
|
}
|
|
cAddInt(v->address);
|
|
cAddInt(v->address);
|
|
return v->type;
|
|
return v->type;
|
|
@@ -228,7 +235,7 @@ static void cStoreVariable(Variable* v, DataType dt, const char* name) {
|
|
if(dtIsArray(v->type)) {
|
|
if(dtIsArray(v->type)) {
|
|
cAddOperation(OP_STORE_ARRAY);
|
|
cAddOperation(OP_STORE_ARRAY);
|
|
} else {
|
|
} else {
|
|
- cError("cannot store type %s", dtGetName(v->type));
|
|
|
|
|
|
+ cError("cannot store type %s", cGetName(v->type));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
cAddInt(v->address);
|
|
cAddInt(v->address);
|
|
@@ -329,7 +336,7 @@ static DataType cPreUnary() {
|
|
switch(result) {
|
|
switch(result) {
|
|
case DT_INT: cAddOperation(OP_INVERT_SIGN_INT); break;
|
|
case DT_INT: cAddOperation(OP_INVERT_SIGN_INT); break;
|
|
case DT_FLOAT: cAddOperation(OP_INVERT_SIGN_FLOAT); break;
|
|
case DT_FLOAT: cAddOperation(OP_INVERT_SIGN_FLOAT); break;
|
|
- default: cError("cannot invert sign of %s", dtGetName(result));
|
|
|
|
|
|
+ default: cError("cannot invert sign of %s", cGetName(result));
|
|
}
|
|
}
|
|
return result;
|
|
return result;
|
|
} else if(cConsumeTokenIf(T_INCREMENT)) {
|
|
} else if(cConsumeTokenIf(T_INCREMENT)) {
|
|
@@ -343,7 +350,7 @@ static DataType cPreUnary() {
|
|
}
|
|
}
|
|
DataType result = cPrimary();
|
|
DataType result = cPrimary();
|
|
if(result != DT_BOOL) {
|
|
if(result != DT_BOOL) {
|
|
- cError("! needs a bool not %s", dtGetName(result));
|
|
|
|
|
|
+ cError("! needs a bool not %s", cGetName(result));
|
|
}
|
|
}
|
|
cAddOperation(OP_NOT);
|
|
cAddOperation(OP_NOT);
|
|
if((counter & 1) == 0) {
|
|
if((counter & 1) == 0) {
|
|
@@ -355,7 +362,7 @@ static DataType cPreUnary() {
|
|
if(result == DT_INT) {
|
|
if(result == DT_INT) {
|
|
cAddOperation(OP_BIT_NOT);
|
|
cAddOperation(OP_BIT_NOT);
|
|
} else {
|
|
} else {
|
|
- cError("~ needs an int not %s", dtGetName(result));
|
|
|
|
|
|
+ cError("~ needs an int not %s", cGetName(result));
|
|
}
|
|
}
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
@@ -565,7 +572,7 @@ static void cLineLiteral() {
|
|
if(cConsumeTokenIf(T_OPEN_BRACKET)) {
|
|
if(cConsumeTokenIf(T_OPEN_BRACKET)) {
|
|
DataType dt = cCallFunction(literal);
|
|
DataType dt = cCallFunction(literal);
|
|
if(dt != DT_VOID) {
|
|
if(dt != DT_VOID) {
|
|
- cError("function returns %s not void", dtGetName(dt));
|
|
|
|
|
|
+ cError("function returns %s not void", cGetName(dt));
|
|
}
|
|
}
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -635,13 +642,13 @@ static void cReturn() {
|
|
}
|
|
}
|
|
DataType dt = cExpression();
|
|
DataType dt = cExpression();
|
|
if(dt != returnType) {
|
|
if(dt != returnType) {
|
|
- cError("wrong return type, should be %s", dtGetName(returnType));
|
|
|
|
|
|
+ cError("wrong return type, should be %s", cGetName(returnType));
|
|
}
|
|
}
|
|
switch(dt) {
|
|
switch(dt) {
|
|
case DT_INT: cAddReturn(OP_RETURN_INT); break;
|
|
case DT_INT: cAddReturn(OP_RETURN_INT); break;
|
|
case DT_BOOL: cAddReturn(OP_RETURN_BOOL); break;
|
|
case DT_BOOL: cAddReturn(OP_RETURN_BOOL); break;
|
|
case DT_FLOAT: cAddReturn(OP_RETURN_FLOAT); break;
|
|
case DT_FLOAT: cAddReturn(OP_RETURN_FLOAT); break;
|
|
- default: cError("cannot return %s", dtGetName(dt));
|
|
|
|
|
|
+ default: cError("cannot return %s", cGetName(dt));
|
|
}
|
|
}
|
|
cConsumeToken(T_SEMICOLON);
|
|
cConsumeToken(T_SEMICOLON);
|
|
}
|
|
}
|
|
@@ -652,7 +659,7 @@ static void cPrint() {
|
|
case DT_INT: cAddOperation(OP_PRINT_INT); break;
|
|
case DT_INT: cAddOperation(OP_PRINT_INT); break;
|
|
case DT_FLOAT: cAddOperation(OP_PRINT_FLOAT); break;
|
|
case DT_FLOAT: cAddOperation(OP_PRINT_FLOAT); break;
|
|
case DT_BOOL: cAddOperation(OP_PRINT_BOOL); break;
|
|
case DT_BOOL: cAddOperation(OP_PRINT_BOOL); break;
|
|
- default: cError("cannot print type %s", dtGetName(dt));
|
|
|
|
|
|
+ default: cError("cannot print type %s", cGetName(dt));
|
|
}
|
|
}
|
|
cConsumeToken(T_SEMICOLON);
|
|
cConsumeToken(T_SEMICOLON);
|
|
}
|
|
}
|
|
@@ -661,7 +668,7 @@ static void cIf() {
|
|
cConsumeToken(T_OPEN_BRACKET);
|
|
cConsumeToken(T_OPEN_BRACKET);
|
|
DataType dt = cExpression();
|
|
DataType dt = cExpression();
|
|
if(dt != DT_BOOL) {
|
|
if(dt != DT_BOOL) {
|
|
- cError("if expects a bool not %s", dtGetName(dt));
|
|
|
|
|
|
+ cError("if expects a bool not %s", cGetName(dt));
|
|
}
|
|
}
|
|
cConsumeToken(T_CLOSE_BRACKET);
|
|
cConsumeToken(T_CLOSE_BRACKET);
|
|
cAddOperation(OP_IF_GOTO);
|
|
cAddOperation(OP_IF_GOTO);
|
|
@@ -696,7 +703,7 @@ static void cWhile() {
|
|
cConsumeToken(T_OPEN_BRACKET);
|
|
cConsumeToken(T_OPEN_BRACKET);
|
|
DataType dt = cExpression();
|
|
DataType dt = cExpression();
|
|
if(dt != DT_BOOL) {
|
|
if(dt != DT_BOOL) {
|
|
- cError("while expects a bool not %s", dtGetName(dt));
|
|
|
|
|
|
+ cError("while expects a bool not %s", cGetName(dt));
|
|
}
|
|
}
|
|
cConsumeToken(T_CLOSE_BRACKET);
|
|
cConsumeToken(T_CLOSE_BRACKET);
|
|
cAddOperation(OP_IF_GOTO);
|
|
cAddOperation(OP_IF_GOTO);
|
|
@@ -771,7 +778,7 @@ static void cFor() {
|
|
int startCheck = code->length;
|
|
int startCheck = code->length;
|
|
DataType dt = cExpression();
|
|
DataType dt = cExpression();
|
|
if(dt != DT_BOOL) {
|
|
if(dt != DT_BOOL) {
|
|
- cError("for expects a bool not %s", dtGetName(dt));
|
|
|
|
|
|
+ cError("for expects a bool not %s", cGetName(dt));
|
|
}
|
|
}
|
|
cConsumeToken(T_SEMICOLON);
|
|
cConsumeToken(T_SEMICOLON);
|
|
cAddOperation(OP_IF_GOTO);
|
|
cAddOperation(OP_IF_GOTO);
|
|
@@ -865,6 +872,8 @@ static void cFunctionArgument(Function* f) {
|
|
Token t = cReadTokenAndLine();
|
|
Token t = cReadTokenAndLine();
|
|
switch(t) {
|
|
switch(t) {
|
|
case T_INT: cFunctionAddArgument(f, DT_INT); break;
|
|
case T_INT: cFunctionAddArgument(f, DT_INT); break;
|
|
|
|
+ case T_FLOAT: cFunctionAddArgument(f, DT_FLOAT); break;
|
|
|
|
+ case T_BOOL: cFunctionAddArgument(f, DT_BOOL); break;
|
|
default: cUnexpectedToken(t);
|
|
default: cUnexpectedToken(t);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1022,7 +1031,7 @@ static void cLinkQueuedFunctions() {
|
|
cError("unknown function");
|
|
cError("unknown function");
|
|
} else if(f->returnType != found->returnType) {
|
|
} else if(f->returnType != found->returnType) {
|
|
line = f->line;
|
|
line = f->line;
|
|
- cError("function return type is not %s", dtGetName(f->returnType));
|
|
|
|
|
|
+ cError("function return type is not %s", cGetName(f->returnType));
|
|
}
|
|
}
|
|
cSetInt(f->address, found->address);
|
|
cSetInt(f->address, found->address);
|
|
}
|
|
}
|