|  | @@ -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);
 |