|
@@ -74,10 +74,10 @@ TYPE_OP(BIT_AND, NOTHING, NOTHING, "&")
|
|
|
TYPE_OP(LEFT_SHIFT, NOTHING, NOTHING, "<<")
|
|
|
TYPE_OP(RIGHT_SHIFT, NOTHING, NOTHING, ">>")
|
|
|
|
|
|
-static check_format(1, 2) void cError(const char* format, ...) {
|
|
|
+static check_format(2, 3) void cError(int codeLine, const char* format, ...) {
|
|
|
va_list args;
|
|
|
va_start(args, format);
|
|
|
- eInitErrorV(error, path, line, format, args);
|
|
|
+ eInitErrorV(error, path, line, codeLine, format, args);
|
|
|
va_end(args);
|
|
|
longjmp(errorJump, 0);
|
|
|
}
|
|
@@ -86,24 +86,30 @@ static const char* cGetName(DataType dt) {
|
|
|
return dtGetName(&structs, dt);
|
|
|
}
|
|
|
|
|
|
-static void cInvalidOperation(DataType a, DataType b, const char* op) {
|
|
|
- cError("invalid operation: %s %s %s", cGetName(a), op, cGetName(b));
|
|
|
+static void cInvalidOperation(int codeLine, DataType a, DataType b,
|
|
|
+ const char* op) {
|
|
|
+ cError(codeLine, "invalid operation: %s %s %s", cGetName(a), op,
|
|
|
+ cGetName(b));
|
|
|
}
|
|
|
|
|
|
-static void cNotDeclared(const char* name) {
|
|
|
- cError("variable %s has not been declared", name);
|
|
|
+static void cNotDeclared(int codeLine, const char* name) {
|
|
|
+ cError(codeLine, "variable %s has not been declared", name);
|
|
|
}
|
|
|
|
|
|
-static void cDeclared(const char* name) {
|
|
|
- cError("%s has already been declared", name);
|
|
|
+static void cDeclared(int codeLine, const char* name) {
|
|
|
+ cError(codeLine, "%s has already been declared", name);
|
|
|
}
|
|
|
|
|
|
-static void cTooMuchArguments(void) {
|
|
|
- cError("too much function arguments");
|
|
|
+static void cTooMuchArguments(int codeLine) {
|
|
|
+ cError(codeLine, "too much function arguments");
|
|
|
}
|
|
|
|
|
|
-static void cUnexpectedToken(Token t) {
|
|
|
- cError("unexpected token: %s", tGetName(t));
|
|
|
+static void cUnexpectedToken(int codeLine, Token t) {
|
|
|
+ cError(codeLine, "unexpected token: %s", tGetName(t));
|
|
|
+}
|
|
|
+
|
|
|
+static void cCannotGetSize(int codeLine, DataType dt) {
|
|
|
+ cError(codeLine, "cannot get size of data type: %s", cGetName(dt));
|
|
|
}
|
|
|
|
|
|
#define BUFFER_SIZE 256
|
|
@@ -116,7 +122,7 @@ static void cUnknownFunction(Function* f) {
|
|
|
max += snprintf(buffer + max, (size_t)(BUFFER_SIZE - max),
|
|
|
i > 0 ? ", %s" : "%s", name);
|
|
|
}
|
|
|
- cError("unknown function: %s(%s)", f->name, buffer);
|
|
|
+ cError(__LINE__, "unknown function: %s(%s)", f->name, buffer);
|
|
|
}
|
|
|
|
|
|
static void cAddOperation(Operation token) {
|
|
@@ -163,7 +169,8 @@ static Token cReadTokenAndLine(void) {
|
|
|
static void cConsumeToken(Token wanted) {
|
|
|
Token t = cReadTokenAndLine();
|
|
|
if(wanted != t) {
|
|
|
- cError("expected '%s' got '%s'", tGetName(wanted), tGetName(t));
|
|
|
+ cError(__LINE__, "expected '%s' got '%s'", tGetName(wanted),
|
|
|
+ tGetName(t));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -174,7 +181,7 @@ static bool cConsumeTokenIf(Token t) {
|
|
|
static void cConstantInt32(void) {
|
|
|
int32 value;
|
|
|
if(tReadInt32(&value)) {
|
|
|
- cError("int token without an int");
|
|
|
+ cError(__LINE__, "int token without an int");
|
|
|
}
|
|
|
cAddInt32Operation(OP_PUSH_INT, value);
|
|
|
}
|
|
@@ -182,7 +189,7 @@ static void cConstantInt32(void) {
|
|
|
static void cConstantFloat(void) {
|
|
|
float value;
|
|
|
if(tReadFloat(&value)) {
|
|
|
- cError("float token without a float");
|
|
|
+ cError(__LINE__, "float token without a float");
|
|
|
}
|
|
|
cAddOperation(OP_PUSH_FLOAT);
|
|
|
bcAddBytes(code, &value, sizeof(float));
|
|
@@ -191,13 +198,17 @@ static void cConstantFloat(void) {
|
|
|
static const char* cReadString(void) {
|
|
|
const char* literal = tReadString();
|
|
|
if(literal == NULL) {
|
|
|
- cError("literal without string on line %d", line);
|
|
|
+ cError(__LINE__, "literal without string");
|
|
|
}
|
|
|
return literal;
|
|
|
}
|
|
|
|
|
|
static int cGetSize(DataType dt) {
|
|
|
- return dtGetSize(dt, &structs);
|
|
|
+ int size;
|
|
|
+ if(dtGetSize(dt, &structs, &size)) {
|
|
|
+ cError(__LINE__, "cannot get size of data type");
|
|
|
+ }
|
|
|
+ return size;
|
|
|
}
|
|
|
|
|
|
static DataType cExtendType(DataType dt) {
|
|
@@ -217,7 +228,7 @@ static DataType cReadType(Token t, bool force) {
|
|
|
Struct* st = stsSearch(&structs, name);
|
|
|
if(st == NULL) {
|
|
|
if(force) {
|
|
|
- cError("struct %s does not exist", name);
|
|
|
+ cError(__LINE__, "struct %s does not exist", name);
|
|
|
} else {
|
|
|
return dtVoid();
|
|
|
}
|
|
@@ -226,7 +237,7 @@ static DataType cReadType(Token t, bool force) {
|
|
|
}
|
|
|
default:
|
|
|
if(force) {
|
|
|
- cUnexpectedToken(t);
|
|
|
+ cUnexpectedToken(__LINE__, t);
|
|
|
}
|
|
|
return dtVoid();
|
|
|
}
|
|
@@ -249,7 +260,7 @@ static void cLoadRef(DataType type) {
|
|
|
}
|
|
|
switch(dtGetType(type)) {
|
|
|
DT_OPERATION(LOAD);
|
|
|
- default: cError("cannot load type %s", cGetName(type));
|
|
|
+ default: cError(__LINE__, "cannot load type %s", cGetName(type));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -271,7 +282,7 @@ static void cCallFunctionArguments(Function* f) {
|
|
|
while(true) {
|
|
|
DataType dt = cUnpackedExpression();
|
|
|
if(fAddArgument(f, dt, &structs)) {
|
|
|
- cTooMuchArguments();
|
|
|
+ cTooMuchArguments(__LINE__);
|
|
|
} else if(cConsumeTokenIf(T_CLOSE_BRACKET)) {
|
|
|
return;
|
|
|
}
|
|
@@ -311,17 +322,17 @@ static DataType cCallFunction(const char* name) {
|
|
|
static void cStore(DataType left, DataType right, const char* name) {
|
|
|
if(dtIsArray(left)) {
|
|
|
if(!dtCompare(left, right)) {
|
|
|
- cInvalidOperation(left, right, name);
|
|
|
+ cInvalidOperation(__LINE__, left, right, name);
|
|
|
}
|
|
|
cAddOperation(OP_STORE_ARRAY);
|
|
|
return;
|
|
|
}
|
|
|
if(!dtCompare(left, right)) {
|
|
|
- cInvalidOperation(left, right, name);
|
|
|
+ cInvalidOperation(__LINE__, left, right, name);
|
|
|
}
|
|
|
switch(dtGetType(left)) {
|
|
|
DT_OPERATION(STORE);
|
|
|
- default: cError("cannot store type %s", cGetName(left));
|
|
|
+ default: cError(__LINE__, "cannot store type %s", cGetName(left));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -334,7 +345,8 @@ static DataType cLiteral(void) {
|
|
|
if(!vsSearch(&vars, &v, literal)) {
|
|
|
if(dtIsPointer(v.type)) {
|
|
|
if(!dtIsStruct(v.type)) {
|
|
|
- cError("non struct type %s should not be a pointer here",
|
|
|
+ cError(__LINE__,
|
|
|
+ "non struct type %s should not be a pointer here",
|
|
|
cGetName(v.type));
|
|
|
}
|
|
|
cAddInt32Operation(OP_PUSH_STRUCT_REFERENCE, v.address);
|
|
@@ -346,7 +358,7 @@ static DataType cLiteral(void) {
|
|
|
cAddInt32Operation(OP_DEREFERENCE_GVAR, v.address);
|
|
|
return dtToPointer(v.type);
|
|
|
}
|
|
|
- cNotDeclared(literal);
|
|
|
+ cNotDeclared(__LINE__, literal);
|
|
|
return dtVoid();
|
|
|
}
|
|
|
|
|
@@ -371,14 +383,14 @@ static DataType cBracketPrimary(void) {
|
|
|
|
|
|
static void cArrayIndex(void) {
|
|
|
if(!dtIsInt(cUnpackedExpression())) {
|
|
|
- cError("array index must be an int");
|
|
|
+ cError(__LINE__, "array index must be an int");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static DataType cAllocArray(void) {
|
|
|
DataType dt = cReadType(cReadTokenAndLine(), true);
|
|
|
if(dtIsArray(dt)) {
|
|
|
- cError("array type must not be an array");
|
|
|
+ cError(__LINE__, "array type must not be an array");
|
|
|
}
|
|
|
cConsumeToken(T_OPEN_SQUARE_BRACKET);
|
|
|
cArrayIndex();
|
|
@@ -390,7 +402,7 @@ static DataType cAllocArray(void) {
|
|
|
static DataType cLength(void) {
|
|
|
DataType array = cUnpackedExpression();
|
|
|
if(!dtIsArray(array)) {
|
|
|
- cError("length expects an array");
|
|
|
+ cError(__LINE__, "length expects an array");
|
|
|
}
|
|
|
cAddOperation(OP_LENGTH);
|
|
|
return dtInt();
|
|
@@ -406,19 +418,20 @@ static DataType cPrimary(void) {
|
|
|
case T_LITERAL: return cLiteral();
|
|
|
case T_NEW: return cAllocArray();
|
|
|
case T_LENGTH: return cLength();
|
|
|
- default: cUnexpectedToken(t); return dtVoid();
|
|
|
+ default: cUnexpectedToken(__LINE__, t); return dtVoid();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void cRemoveReference(DataType* dt, const char* name) {
|
|
|
if(!dtRemovePointer(dt)) {
|
|
|
- cError("%s needs a reference not %s", name, cGetName(*dt));
|
|
|
+ cError(__LINE__, "%s needs a reference not %s", name, cGetName(*dt));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void cExpectType(DataType actual, DataType wanted, const char* name) {
|
|
|
if(!dtCompare(actual, wanted)) {
|
|
|
- cError("%s needs %s not %s", name, cGetName(wanted), cGetName(actual));
|
|
|
+ cError(__LINE__, "%s needs %s not %s", name, cGetName(wanted),
|
|
|
+ cGetName(actual));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -437,21 +450,26 @@ static void cPostChange(DataType* dt, int8 change, const char* name) {
|
|
|
if(dtIsInt(*dt)) {
|
|
|
cChangeType(dt, OP_CHANGE_INT, OP_PUSH_POST_CHANGE_INT, change);
|
|
|
} else {
|
|
|
- cError("%s needs an int not %s", name, cGetName(*dt));
|
|
|
+ cError(__LINE__, "%s needs an int not %s", name, cGetName(*dt));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static DataType cStructAccess(DataType dt) {
|
|
|
Struct* st = dtGetStruct(&structs, dt);
|
|
|
if(st == NULL) {
|
|
|
- cError(". expects a struct not %s", cGetName(dt));
|
|
|
+ cError(__LINE__, ". expects a struct not %s", cGetName(dt));
|
|
|
}
|
|
|
cConsumeToken(T_LITERAL);
|
|
|
const char* name = cReadString();
|
|
|
Variable inner;
|
|
|
- if(vSearchStruct(&inner, &structs, st, name)) {
|
|
|
- cError("%s has no member %s", st->name, name);
|
|
|
- } else if(inner.address > 0) {
|
|
|
+ switch(vSearchStruct(&inner, &structs, st, name)) {
|
|
|
+ case VE_CANNOT_FIND:
|
|
|
+ cError(__LINE__, "%s has no member %s", st->name, name);
|
|
|
+ break;
|
|
|
+ case VE_SIZE_ERROR: cCannotGetSize(__LINE__, dt); break;
|
|
|
+ default: break;
|
|
|
+ }
|
|
|
+ if(inner.address > 0) {
|
|
|
cAddInt32Operation(OP_PUSH_INT, inner.address);
|
|
|
cAddInt32Operation(OP_ADD_REFERENCE, 1);
|
|
|
}
|
|
@@ -470,7 +488,7 @@ static DataType cAccess(void) {
|
|
|
dt = cStructAccess(dt);
|
|
|
} else if(cConsumeTokenIf(T_OPEN_SQUARE_BRACKET)) {
|
|
|
if(!dtIsArray(dt)) {
|
|
|
- cError("[] needs an array");
|
|
|
+ cError(__LINE__, "[] needs an array");
|
|
|
}
|
|
|
cAddOperation(OP_LOAD_ARRAY);
|
|
|
dtRemovePointer(&dt);
|
|
@@ -489,7 +507,7 @@ static DataType cPreChange(DataType dt, int8 change, const char* name) {
|
|
|
if(dtIsInt(dt)) {
|
|
|
cChangeType(&dt, OP_CHANGE_INT, OP_PUSH_PRE_CHANGE_INT, change);
|
|
|
} else {
|
|
|
- cError("%s needs an int not %s", name, cGetName(dt));
|
|
|
+ cError(__LINE__, "%s needs an int not %s", name, cGetName(dt));
|
|
|
}
|
|
|
return dt;
|
|
|
}
|
|
@@ -500,7 +518,7 @@ static DataType cInvertSign(DataType dt) {
|
|
|
} else if(dtIsFloat(dt)) {
|
|
|
cAddOperation(OP_INVERT_SIGN_FLOAT);
|
|
|
} else {
|
|
|
- cError("cannot invert sign of %s", cGetName(dt));
|
|
|
+ cError(__LINE__, "cannot invert sign of %s", cGetName(dt));
|
|
|
}
|
|
|
return dt;
|
|
|
}
|
|
@@ -509,7 +527,7 @@ static DataType cCast(DataType in, DataType a, Operation aOp, DataType out) {
|
|
|
if(dtCompare(in, a)) {
|
|
|
cAddOperation(aOp);
|
|
|
} else {
|
|
|
- cError("cannot cast %s to %s", cGetName(in), cGetName(out));
|
|
|
+ cError(__LINE__, "cannot cast %s to %s", cGetName(in), cGetName(out));
|
|
|
}
|
|
|
return out;
|
|
|
}
|
|
@@ -524,7 +542,7 @@ static DataType cUnaryBitNot(DataType dt) {
|
|
|
if(dtIsInt(dt)) {
|
|
|
cAddOperation(OP_BIT_NOT_INT);
|
|
|
} else {
|
|
|
- cError("~ needs an int not %s", cGetName(dt));
|
|
|
+ cError(__LINE__, "~ needs an int not %s", cGetName(dt));
|
|
|
}
|
|
|
return dt;
|
|
|
}
|
|
@@ -559,7 +577,7 @@ static void cAddTypeOperation(DataType* a, Parser bf, const TypedOp* op) {
|
|
|
*a = cUnpack(*a);
|
|
|
DataType b = cUnpack(bf());
|
|
|
if(!dtCompare(*a, b)) {
|
|
|
- cInvalidOperation(*a, b, op->name);
|
|
|
+ cInvalidOperation(__LINE__, *a, b, op->name);
|
|
|
} else if(dtIsInt(*a) && op->intOp != OP_NOTHING) {
|
|
|
cAddOperation(op->intOp);
|
|
|
} else if(dtIsFloat(*a) && op->floatOp != OP_NOTHING) {
|
|
@@ -567,7 +585,7 @@ static void cAddTypeOperation(DataType* a, Parser bf, const TypedOp* op) {
|
|
|
} else if(dtIsArray(*a) && op->pointerOp != OP_NOTHING) {
|
|
|
cAddOperation(op->pointerOp);
|
|
|
} else {
|
|
|
- cInvalidOperation(*a, b, op->name);
|
|
|
+ cInvalidOperation(__LINE__, *a, b, op->name);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -675,7 +693,7 @@ static DataType cLogical(Parser f, Token t, Operation jump, Operation op) {
|
|
|
int32 p = cReserveInt32();
|
|
|
DataType b = f();
|
|
|
if(!dtIsInt(a) || !dtIsInt(b)) {
|
|
|
- cInvalidOperation(a, b, tGetName(t));
|
|
|
+ cInvalidOperation(__LINE__, a, b, tGetName(t));
|
|
|
}
|
|
|
cAddOperation(op);
|
|
|
cSetInt32(p, code->length);
|
|
@@ -698,7 +716,7 @@ static void cConsumeBody(void) {
|
|
|
while(!cConsumeTokenIf(T_CLOSE_CURVED_BRACKET)) {
|
|
|
if(tPeekToken() == T_END) {
|
|
|
line = oldLine;
|
|
|
- cError("non closed curved bracket");
|
|
|
+ cError(__LINE__, "non closed curved bracket");
|
|
|
}
|
|
|
cLine();
|
|
|
}
|
|
@@ -713,7 +731,7 @@ static void cConsumeScope(void) {
|
|
|
|
|
|
static void cAddReturn(Operation op) {
|
|
|
if(returnIndex >= RETURN_BUFFER) {
|
|
|
- cError("too much returns in function");
|
|
|
+ cError(__LINE__, "too much returns in function");
|
|
|
}
|
|
|
cAddOperation(op);
|
|
|
returns[returnIndex++] = cReserveInt32();
|
|
@@ -728,7 +746,8 @@ static void cReturn(void) {
|
|
|
}
|
|
|
DataType dt = cUnpackedExpression();
|
|
|
if(!dtCompare(returnType, dt)) {
|
|
|
- cError("wrong return type, should be %s", cGetName(returnType));
|
|
|
+ cError(__LINE__, "wrong return type, should be %s",
|
|
|
+ cGetName(returnType));
|
|
|
} else if(dtIsInt(dt)) {
|
|
|
cAddReturn(OP_RETURN_INT);
|
|
|
} else if(dtIsFloat(dt)) {
|
|
@@ -736,7 +755,7 @@ static void cReturn(void) {
|
|
|
} else if(dtIsArray(dt)) {
|
|
|
cAddReturn(OP_RETURN_POINTER);
|
|
|
} else {
|
|
|
- cError("cannot return %s", cGetName(dt));
|
|
|
+ cError(__LINE__, "cannot return %s", cGetName(dt));
|
|
|
}
|
|
|
cConsumeToken(T_SEMICOLON);
|
|
|
hasReturn = 2;
|
|
@@ -820,16 +839,20 @@ static void cSetVariable(void) {
|
|
|
case T_BIT_XOR_SET: cOperationSet(dt, &TYPED_BIT_XOR); break;
|
|
|
case T_LEFT_SHIFT_SET: cOperationSet(dt, &TYPED_LEFT_SHIFT); break;
|
|
|
case T_RIGHT_SHIFT_SET: cOperationSet(dt, &TYPED_RIGHT_SHIFT); break;
|
|
|
- default: cUnexpectedToken(t);
|
|
|
+ default: cUnexpectedToken(__LINE__, t);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void cDeclareSet(Variables* vs, DataType dt, const char* var,
|
|
|
Operation op) {
|
|
|
if(vsInScope(vs, var)) {
|
|
|
- cDeclared(var);
|
|
|
+ cDeclared(__LINE__, var);
|
|
|
+ }
|
|
|
+ Variable* v;
|
|
|
+ switch(vsAdd(vs, var, dt, &structs, &v)) {
|
|
|
+ case VE_SIZE_ERROR: cCannotGetSize(__LINE__, dt); break;
|
|
|
+ default: break;
|
|
|
}
|
|
|
- Variable* v = vsAdd(vs, var, dt, &structs);
|
|
|
if(!dtIsStruct(dt) || dtIsArray(dt)) {
|
|
|
cConsumeToken(T_SET);
|
|
|
cAddInt32Operation(op, v->address);
|
|
@@ -895,9 +918,9 @@ static void cFor(void) {
|
|
|
|
|
|
static void cBreak(void) {
|
|
|
if(forWhileStack == 0) {
|
|
|
- cError("break without for or while");
|
|
|
+ cError(__LINE__, "break without for or while");
|
|
|
} else if(breakIndex >= BREAK_BUFFER) {
|
|
|
- cError("too much breaks");
|
|
|
+ cError(__LINE__, "too much breaks");
|
|
|
}
|
|
|
cAddOperation(OP_GOTO);
|
|
|
breaks[breakIndex++] = cReserveInt32();
|
|
@@ -906,7 +929,7 @@ static void cBreak(void) {
|
|
|
|
|
|
static void cContinue(void) {
|
|
|
if(forWhileStack == 0) {
|
|
|
- cError("continue without for or while");
|
|
|
+ cError(__LINE__, "continue without for or while");
|
|
|
}
|
|
|
cAddInt32Operation(OP_GOTO, continueAt);
|
|
|
cConsumeToken(T_SEMICOLON);
|
|
@@ -933,7 +956,7 @@ static void cLine(void) {
|
|
|
|
|
|
static void cBuildFunction(Function* f, DataType rType, const char* fName) {
|
|
|
if(dtIsStruct(rType) && !dtIsArray(rType)) {
|
|
|
- cError("structs cannot be returned");
|
|
|
+ cError(__LINE__, "structs cannot be returned");
|
|
|
}
|
|
|
fInit(f, fName, line);
|
|
|
f->returnType = rType;
|
|
@@ -947,14 +970,18 @@ static void cBuildFunction(Function* f, DataType rType, const char* fName) {
|
|
|
cConsumeToken(T_LITERAL);
|
|
|
const char* name = cReadString();
|
|
|
if(vsInScope(&vars, name)) {
|
|
|
- cDeclared(name);
|
|
|
+ cDeclared(__LINE__, name);
|
|
|
}
|
|
|
if(dtIsStruct(dt)) {
|
|
|
dt = dtToPointer(dt);
|
|
|
}
|
|
|
- vsAdd(&vars, name, dt, &structs);
|
|
|
+ Variable* v;
|
|
|
+ switch(vsAdd(&vars, name, dt, &structs, &v)) {
|
|
|
+ case VE_SIZE_ERROR: cCannotGetSize(__LINE__, dt); break;
|
|
|
+ default: break;
|
|
|
+ }
|
|
|
if(fAddArgument(f, dt, &structs)) {
|
|
|
- cTooMuchArguments();
|
|
|
+ cTooMuchArguments(__LINE__);
|
|
|
} else if(cConsumeTokenIf(T_CLOSE_BRACKET)) {
|
|
|
return;
|
|
|
}
|
|
@@ -966,11 +993,11 @@ static void cAddFunction(Function* found, Function* f) {
|
|
|
if(found == NULL) {
|
|
|
fsAdd(&functions, f);
|
|
|
} else if(found->global) {
|
|
|
- cError("system functions cannot be overwritten");
|
|
|
+ cError(__LINE__, "system functions cannot be overwritten");
|
|
|
} else if(found->address != -1 || f->address == -1 || found->global) {
|
|
|
- cError("function registered twice");
|
|
|
+ cError(__LINE__, "function registered twice");
|
|
|
} else if(!dtCompare(found->returnType, f->returnType)) {
|
|
|
- cError("function redeclared with different return type");
|
|
|
+ cError(__LINE__, "function redeclared with different return type");
|
|
|
} else {
|
|
|
found->address = f->address;
|
|
|
}
|
|
@@ -984,7 +1011,7 @@ static void cInnerFunction(Function* f) {
|
|
|
returnIndex = 0;
|
|
|
cConsumeScope();
|
|
|
if(!dtIsVoid(returnType) && hasReturn <= 0) {
|
|
|
- cError("missing return");
|
|
|
+ cError(__LINE__, "missing return");
|
|
|
}
|
|
|
cAddInt32Operation(OP_RETURN, vars.maxAddress);
|
|
|
cSetInt32(p, vars.maxAddress);
|
|
@@ -1016,7 +1043,7 @@ static void cStruct(void) {
|
|
|
cConsumeToken(T_LITERAL);
|
|
|
const char* name = cReadString();
|
|
|
if(stsSearch(&structs, name) != NULL) {
|
|
|
- cError("struct '%s' registered twice", name);
|
|
|
+ cError(__LINE__, "struct '%s' registered twice", name);
|
|
|
}
|
|
|
Struct* st = stsAdd(&structs, name);
|
|
|
DataType self = dtStruct(st);
|
|
@@ -1024,7 +1051,7 @@ static void cStruct(void) {
|
|
|
while(!cConsumeTokenIf(T_CLOSE_CURVED_BRACKET)) {
|
|
|
DataType dt = cReadExtendedType(cReadTokenAndLine(), true);
|
|
|
if(dtCompare(dt, self)) {
|
|
|
- cError("struct %s contains itself", name);
|
|
|
+ cError(__LINE__, "struct %s contains itself", name);
|
|
|
}
|
|
|
cConsumeToken(T_LITERAL);
|
|
|
stAddVariable(st, cReadString(), dt);
|