{
TempFile f { };
int count;
+ bool backOutputLineNumbers = outputLineNumbers;
+ outputLineNumbers = false;
if(exp)
OutputExpression(exp, f);
count += f.Read(string + count, 1, 1023);
string[count] = '\0';
delete f;
+
+ outputLineNumbers = backOutputLineNumbers;
}
}
public char * PrintInt(int64 result)
{
char temp[100];
- if(result > MAXINT64)
- sprintf(temp, FORMAT64HEXLL /*"0x%I64XLL"*/, result);
+ if(result > MAXINT)
+ sprintf(temp, FORMAT64HEX /*"0x%I64XLL"*/, result);
else
- sprintf(temp, FORMAT64DLL /*"%I64d"*/, result);
+ sprintf(temp, FORMAT64D /*"%I64d"*/, result);
+ if(result > MAXINT || result < MININT)
+ strcat(temp, "LL");
return CopyString(temp);
}
{
char temp[100];
if(result > MAXDWORD)
- sprintf(temp, FORMAT64HEXLL /*"0x%I64xLL"*/, result);
+ sprintf(temp, FORMAT64HEX /*"0x%I64xLL"*/, result);
else
sprintf(temp, FORMAT64HEX /*"0x%I64x"*/, result);
+ if(result > MAXDWORD)
+ strcat(temp, "LL");
return CopyString(temp);
}
public char * PrintFloat(float result)
{
char temp[350];
- sprintf(temp, "%.16ff", result);
+ if(result.isInf)
+ {
+ if(result.signBit)
+ strcpy(temp, "-inf");
+ else
+ strcpy(temp, "inf");
+ }
+ else if(result.isNan)
+ {
+ if(result.signBit)
+ strcpy(temp, "-nan");
+ else
+ strcpy(temp, "nan");
+ }
+ else
+ sprintf(temp, "%.16ff", result);
return CopyString(temp);
}
public char * PrintDouble(double result)
{
char temp[350];
- sprintf(temp, "%.16f", result);
+ if(result.isInf)
+ {
+ if(result.signBit)
+ strcpy(temp, "-inf");
+ else
+ strcpy(temp, "inf");
+ }
+ else if(result.isNan)
+ {
+ if(result.signBit)
+ strcpy(temp, "-nan");
+ else
+ strcpy(temp, "nan");
+ }
+ else
+ sprintf(temp, "%.16f", result);
return CopyString(temp);
}
OldList * specifiers, * declarators;
OldList * declarations = null;
char structName[1024];
+ Specifier spec = null;
external = (classSym.registered && classSym.registered.type == structClass) ?
classSym.pointerExternal : classSym.structExternal;
structName[0] = 0;
FullClassNameCat(structName, name, false);
+ if(external && external.declaration && external.declaration.specifiers)
+ {
+ for(spec = external.declaration.specifiers->first; spec; spec = spec.next)
+ {
+ if(spec.type == structSpecifier || spec.type == unionSpecifier)
+ break;
+ }
+ }
+
/*if(!external)
external = MkExternalDeclaration(null);*/
- if(!skipNoHead)
+ if(!skipNoHead && (!spec || !spec.definitions))
{
bool addedPadding = false;
classSym.declaredStructSym = true;
}
if(skipNoHead || declarations)
{
- if(external && external.declaration)
+ if(spec)
{
- ((Specifier)external.declaration.specifiers->first).definitions = declarations;
+ if(declarations)
+ spec.definitions = declarations;
if(curExternal && curExternal.symbol && curExternal.symbol.idCode < classSym.id)
{
classSym._import.properties.Add(symbol._import);
}
imported = true;
- if(prop._class.module != privateModule && prop._class.module.importType != staticImport)
+ // Ugly work around for isNan properties declared within float/double classes which are initialized with ecereCOM
+ if((prop._class.module != privateModule || !strcmp(prop._class.name, "float") || !strcmp(prop._class.name, "double")) &&
+ prop._class.module.importType != staticImport)
dllImport = true;
}
if(!method.dataType.dllExport)
{
imported = true;
- if(method._class.module != privateModule && method._class.module.importType != staticImport)
+ if((method._class.module != privateModule || !strcmp(method._class.name, "float") || !strcmp(method._class.name, "double")) && method._class.module.importType != staticImport)
dllImport = true;
}
}
if(!convert.dataType)
convert.dataType = ProcessTypeString(convert.dataTypeString, false);
- if(MatchTypes(convert.dataType, dest, conversions, null, null, false, true, false, true))
+ // Only go ahead with this conversion flow while processing an existing conversion if the conversion data type is a class
+ if((!isConversionExploration || convert.dataType.kind == classType || !strcmp(_class.name, "String")) &&
+ MatchTypes(convert.dataType, dest, conversions, null, null,
+ (convert.dataType.kind == classType && !strcmp(convert.dataTypeString, "String")) ? true : false,
+ convert.dataType.kind == classType, false, true))
{
if(!conversions && !convert.Get)
return true;
if(dest._class.registered.dataType.kind == classType || source.truth || dest.truth/* ||
!strcmp(dest._class.registered.name, "bool") || (source.kind == classType && !strcmp(source._class.string, "bool"))*/)
{
- if(MatchTypes(source, dest._class.registered.dataType, conversions, null, null, true, true, false, false))
+ if(MatchTypes(source, dest._class.registered.dataType, conversions, null, null, true, dest._class.registered.dataType.kind == classType, false, false))
{
return true;
}
if(!convert.dataType)
convert.dataType = ProcessTypeString(convert.dataTypeString, false);
- if(convert.dataType != source && MatchTypes(convert.dataType, dest, conversions, null, null, true, true, false, true))
+ if(convert.dataType != source &&
+ (!isConversionExploration || convert.dataType.kind == classType || !strcmp(_class.name, "String")) &&
+ MatchTypes(convert.dataType, dest, conversions, null, null, convert.dataType.kind == classType, convert.dataType.kind == classType, false, true))
{
if(!conversions && !convert.Get)
return true;
{
if(!source._class.registered.dataType)
source._class.registered.dataType = ProcessTypeString(source._class.registered.dataTypeString, false);
- if(MatchTypes(source._class.registered.dataType, dest, conversions, null, null, true, true, false, false))
+ if(!isConversionExploration || source._class.registered.dataType.kind == classType || !strcmp(source._class.registered.name, "String"))
{
- return true;
+ if(MatchTypes(source._class.registered.dataType, dest, conversions, null, null, source._class.registered.dataType.kind == classType, source._class.registered.dataType.kind == classType, false, false))
+ return true;
+ // For bool to be accepted by byte, short, etc.
+ else if(MatchTypes(dest, source._class.registered.dataType, null, null, null, false, false, false, false))
+ return true;
}
}
}
else if(source.kind == enumType &&
(dest.kind == intType || dest.kind == shortType || dest.kind == charType || source.kind == _BoolType || dest.kind == longType || dest.kind == int64Type || dest.kind == intPtrType || dest.kind == intSizeType))
return true;
- else if(dest.kind == enumType &&
+ else if(dest.kind == enumType && !isConversionExploration &&
(source.kind == intType || source.kind == shortType || source.kind == charType || source.kind == _BoolType || source.kind == longType || source.kind == int64Type || source.kind == intPtrType || source.kind == intSizeType))
return true;
else if((dest.kind == functionType || (dest.kind == pointerType && dest.type.kind == functionType) || dest.kind == methodType) &&
bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, bool skipUnitBla)
{
- Type source = sourceExp.expType;
+ Type source;
Type realDest = dest;
Type backupSourceExpType = null;
+ Expression computedExp = sourceExp;
+ dest.refCount++;
+
+ if(sourceExp.isConstant && sourceExp.type != constantExp && sourceExp.type != identifierExp && sourceExp.type != castExp &&
+ dest.kind == classType && dest._class && dest._class.registered && dest._class.registered.type == enumClass)
+ {
+ computedExp = CopyExpression(sourceExp); // Keep the original expression, but compute for checking enum ranges
+ ComputeExpression(computedExp /*sourceExp*/);
+ }
+
+ source = sourceExp.expType;
if(dest.kind == pointerType && sourceExp.type == constantExp && !strtoul(sourceExp.constant, null, 0))
+ {
+ if(computedExp != sourceExp)
+ {
+ FreeExpression(computedExp);
+ computedExp = sourceExp;
+ }
+ FreeType(dest);
return true;
+ }
if(!skipUnitBla && source && dest && source.kind == classType && dest.kind == classType)
{
destBase = destBase.base);
//if(source._class.registered == dest._class.registered)
if(sourceBase == destBase)
- return true;
- }
+ {
+ if(computedExp != sourceExp)
+ {
+ FreeExpression(computedExp);
+ computedExp = sourceExp;
+ }
+ FreeType(dest);
+ return true;
+ }
+ }
}
if(source)
int64 value = MAXINT;
source.refCount++;
- dest.refCount++;
- if(sourceExp.type == constantExp)
+ if(computedExp.type == constantExp)
{
if(source.isSigned)
- value = strtoll(sourceExp.constant, null, 0);
+ value = strtoll(computedExp.constant, null, 0);
else
- value = strtoull(sourceExp.constant, null, 0);
+ value = strtoull(computedExp.constant, null, 0);
}
- else if(sourceExp.type == opExp && sourceExp.op.op == '-' && !sourceExp.op.exp1 && sourceExp.op.exp2 && sourceExp.op.exp2.type == constantExp)
+ else if(computedExp.type == opExp && sourceExp.op.op == '-' && !computedExp.op.exp1 && computedExp.op.exp2 && computedExp.op.exp2.type == constantExp)
{
if(source.isSigned)
- value = -strtoll(sourceExp.op.exp2.constant, null, 0);
+ value = -strtoll(computedExp.op.exp2.constant, null, 0);
else
- value = -strtoull(sourceExp.op.exp2.constant, null, 0);
+ value = -strtoull(computedExp.op.exp2.constant, null, 0);
+ }
+ if(computedExp != sourceExp)
+ {
+ FreeExpression(computedExp);
+ computedExp = sourceExp;
}
if(dest.kind != classType && source.kind == classType && source._class && source._class.registered &&
{
Class _class = source._class ? source._class.registered : null;
- if(_class && (_class.type == unitClass || !strcmp(_class.fullName, "bool") || /*_class.type == enumClass || */_class.type == bitClass )) // TOCHECK: enumClass, bitClass is new here...
+ if(_class && (_class.type == unitClass || /*!strcmp(_class.fullName, "bool") || /*_class.type == enumClass || */_class.type == bitClass )) // TOCHECK: enumClass, bitClass is new here...
{
/*
if(dest.kind != classType)
if(dest.kind == classType)
{
Class _class = dest._class ? dest._class.registered : null;
- if(_class && !dest.truth && (_class.type == unitClass || !strcmp(_class.fullName, "bool") ||
+ bool fittingValue = false;
+ if(_class && _class.type == enumClass)
+ {
+ Class enumClass = eSystem_FindClass(privateModule, "enum");
+ EnumClassData c = ACCESS_CLASSDATA(_class, enumClass);
+ if(c && value >= 0 && value <= c.largest)
+ fittingValue = true;
+ }
+
+ if(_class && !dest.truth && (_class.type == unitClass || fittingValue ||
(/*_class.type == enumClass*/_class.type != structClass && !value && source.kind == intType) || _class.type == bitClass)) // TOCHECK: enumClass, bitClass is new here...
{
if(_class.type == normalClass || _class.type == noHeadClass)
return false;
}
- if(!flag)
+ if(!flag && !sourceExp.opDestType)
{
Expression newExp { };
*newExp = *sourceExp;
}
else
{
+ if(computedExp != sourceExp)
+ {
+ FreeExpression(computedExp);
+ computedExp = sourceExp;
+ }
+
while((sourceExp.type == bracketsExp || sourceExp.type == extensionExpressionExp) && sourceExp.list) sourceExp = sourceExp.list->last;
if(sourceExp.type == identifierExp)
{
sourceExp.constant = CopyString(constant);
//for(;_class.base && _class.base.type != systemClass; _class = _class.base);
}
+ FreeType(dest);
return true;
}
}
// Loop through all enum classes
if(dest.classObjectType != typedObject && dest.kind == classType /*!= ellipsisType */&& MatchWithEnums_Module(privateModule, sourceExp, dest, id.string, conversions))
+ {
+ FreeType(dest);
return true;
+ }
}
+ FreeType(dest);
}
return false;
}
{ \
t value2 = op2.m; \
exp.type = constantExp; \
- exp.string = p(op1.m o value2); \
+ exp.string = p((t)(op1.m o value2)); \
if(!exp.expType) \
{ exp.expType = op1.type; if(op1.type) op1.type.refCount++; } \
return true; \
}
-#define BINARY_DIVIDE(o, name, m, t, p) \
+#define BINARY_DIVIDEINT(o, name, m, t, p) \
static bool name(Expression exp, Operand op1, Operand op2) \
{ \
t value2 = op2.m; \
return true; \
}
+#define BINARY_DIVIDEREAL(o, name, m, t, p) \
+ static bool name(Expression exp, Operand op1, Operand op2) \
+ { \
+ t value2 = op2.m; \
+ exp.type = constantExp; \
+ exp.string = p(op1.m o value2); \
+ if(!exp.expType) \
+ { exp.expType = op1.type; if(op1.type) op1.type.refCount++; } \
+ return true; \
+ }
+
#define UNARY(o, name, m, t, p) \
static bool name(Expression exp, Operand op1) \
{ \
macro(o, Char##name, c, char, PrintChar) \
macro(o, UChar##name, uc, unsigned char, PrintUChar)
+#define OPERATOR_REALTYPES(macro, o, name) \
+ macro(o, Float##name, f, float, PrintFloat) \
+ macro(o, Double##name, d, double, PrintDouble)
// binary arithmetic
OPERATOR_ALL(BINARY, +, Add)
OPERATOR_ALL(BINARY, -, Sub)
OPERATOR_ALL(BINARY, *, Mul)
-OPERATOR_ALL(BINARY_DIVIDE, /, Div)
-OPERATOR_INTTYPES(BINARY_DIVIDE, %, Mod)
+OPERATOR_INTTYPES(BINARY_DIVIDEINT, /, Div)
+OPERATOR_REALTYPES(BINARY_DIVIDEREAL, /, Div)
+OPERATOR_INTTYPES(BINARY_DIVIDEINT, %, Mod)
// unary arithmetic
OPERATOR_ALL(UNARY, -, Neg)
OPERATOR_ALL(BINARY, +=, AddAsign)
OPERATOR_ALL(BINARY, -=, SubAsign)
OPERATOR_ALL(BINARY, *=, MulAsign)
-OPERATOR_ALL(BINARY_DIVIDE, /=, DivAsign)
-OPERATOR_INTTYPES(BINARY_DIVIDE, %=, ModAsign)
+OPERATOR_INTTYPES(BINARY_DIVIDEINT, /=, DivAsign)
+OPERATOR_REALTYPES(BINARY_DIVIDEREAL, /=, DivAsign)
+OPERATOR_INTTYPES(BINARY_DIVIDEINT, %=, ModAsign)
// binary bitwise
OPERATOR_INTTYPES(BINARY, &, BitAnd)
OPERATOR_ALL(BINARY, <=, SmaEqu)
// tertiary condition operator
-OPERATOR_ALL(TERTIARY, ?, Cond)
+OPERATOR_INTTYPES(TERTIARY, ?, Cond)
//Add, Sub, Mul, Div, Mod, , Neg, Inc, Dec, Asign, AddAsign, SubAsign, MulAsign, DivAsign, ModAsign, BitAnd, BitOr, BitXor, LShift, RShift, BitNot, AndAsign, OrAsign, XorAsign, LShiftAsign, RShiftAsign, Not, Equ, Nqu, And, Or, Grt, Sma, GrtEqu, SmaEqu
#define OPERATOR_TABLE_ALL(name, type) \
type = type._class.registered.dataType;
}
- op.kind = type.kind;
- op.type = exp.expType;
if(exp.type == stringExp && op.kind == pointerType)
{
op.ui64 = (uint64)exp.string;
}
else if(exp.isConstant && exp.type == constantExp)
{
+ op.kind = type.kind;
+ op.type = exp.expType;
+
switch(op.kind)
{
case _BoolType:
if(type.isSigned)
{
op.i64 = (int64)_strtoi64(exp.constant, null, 0);
- op.ops = intOps;
+ op.ops = int64Ops;
}
else
{
op.ui64 = (uint64)_strtoui64(exp.constant, null, 0);
- op.ops = uintOps;
+ op.ops = uint64Ops;
}
op.kind = int64Type;
break;
op.kind = int64Type;
break;
case floatType:
- op.f = (float)strtod(exp.constant, null);
+ if(!strcmp(exp.constant, "inf")) op.f = float::inf();
+ else if(!strcmp(exp.constant, "-inf")) op.f = -float::inf();
+ else if(!strcmp(exp.constant, "nan")) op.f = float::nan();
+ else if(!strcmp(exp.constant, "-nan")) op.f = -float::nan();
+ else
+ op.f = (float)strtod(exp.constant, null);
op.ops = floatOps;
break;
case doubleType:
- op.d = (double)strtod(exp.constant, null);
+ if(!strcmp(exp.constant, "inf")) op.d = double::inf();
+ else if(!strcmp(exp.constant, "-inf")) op.d = -double::inf();
+ else if(!strcmp(exp.constant, "nan")) op.d = double::nan();
+ else if(!strcmp(exp.constant, "-nan")) op.d = -double::nan();
+ else
+ op.d = (double)strtod(exp.constant, null);
op.ops = doubleOps;
break;
//case classType: For when we have operator overloading...
{
BitMember bitMember = (BitMember) dataMember;
Type type;
- int part = 0;
- GetInt(value, &part);
+ uint64 part;
bits = (bits & ~bitMember.mask);
if(!bitMember.dataType)
bitMember.dataType = ProcessTypeString(bitMember.dataTypeString, false);
-
type = bitMember.dataType;
-
if(type.kind == classType && type._class && type._class.registered)
{
if(!type._class.registered.dataType)
type._class.registered.dataType = ProcessTypeString(type._class.registered.dataTypeString, false);
type = type._class.registered.dataType;
}
-
switch(type.kind)
{
case _BoolType:
- case charType:
- if(type.isSigned)
- bits |= ((char)part << bitMember.pos);
- else
- bits |= ((unsigned char)part << bitMember.pos);
- break;
- case shortType:
- if(type.isSigned)
- bits |= ((short)part << bitMember.pos);
- else
- bits |= ((unsigned short)part << bitMember.pos);
- break;
+ case charType: { byte v; type.isSigned ? GetChar(value, &v) : GetUChar(value, &v); part = (uint64)v; break; }
+ case shortType: { uint16 v; type.isSigned ? GetShort(value, &v) : GetUShort(value, &v); part = (uint64)v; break; }
case intType:
- case longType:
- if(type.isSigned)
- bits |= ((int)part << bitMember.pos);
- else
- bits |= ((unsigned int)part << bitMember.pos);
- break;
- case int64Type:
- if(type.isSigned)
- bits |= ((int64)part << bitMember.pos);
- else
- bits |= ((uint64)part << bitMember.pos);
- break;
- case intPtrType:
- if(type.isSigned)
- {
- bits |= ((intptr)part << bitMember.pos);
- }
- else
- {
- bits |= ((uintptr)part << bitMember.pos);
- }
- break;
- case intSizeType:
- if(type.isSigned)
- {
- bits |= ((ssize_t)(intsize)part << bitMember.pos);
- }
- else
- {
- bits |= ((size_t) (uintsize)part << bitMember.pos);
- }
- break;
+ case longType: { uint v; type.isSigned ? GetInt(value, &v) : GetUInt(value, &v); part = (uint64)v; break; }
+ case int64Type: { uint64 v; type.isSigned ? GetInt64(value, &v) : GetUInt64(value, &v); part = (uint64)v; break; }
+ case intPtrType: { intptr v; type.isSigned ? GetIntPtr(value, &v) : GetUIntPtr(value, &v); part = (uint64)v; break; }
+ case intSizeType: { intsize v; type.isSigned ? GetIntSize(value, &v) : GetUIntSize(value, &v); part = (uint64)v; break; }
}
+ bits += part << bitMember.pos;
}
}
}
case int64Type:
if(op.kind == charType || op.kind == shortType || op.kind == intType || op.kind == int64Type || op.kind == longType || op.kind == floatType || op.kind == doubleType ||
op.kind == pointerType || op.kind == enumType || op.kind == intPtrType || op.kind == intSizeType || op.kind == _BoolType)
- result = isSigned ? GetOpInt64(op, &op.i64) : GetOpUInt64(op, &op.ui64);
+ result = isSigned ? GetOpInt64(op, &op.i64) : GetOpUInt64(op, &op.ui64);
break;
case floatType:
if(op.kind == charType || op.kind == shortType || op.kind == intType || op.kind == int64Type || op.kind == longType ||
op.kind == enumType || op.kind == intPtrType || op.kind == intSizeType || op.kind == _BoolType)
- result = GetOpFloat(op, &op.f);
+ result = GetOpFloat(op, &op.f);
break;
case doubleType:
if(op.kind == charType || op.kind == shortType || op.kind == intType || op.kind == int64Type || op.kind == longType || op.kind == floatType ||
op.kind == enumType || op.kind == intPtrType || op.kind == intSizeType || op.kind == _BoolType)
- result = GetOpDouble(op, &op.d);
+ result = GetOpDouble(op, &op.d);
break;
case pointerType:
if(op.kind == charType || op.kind == shortType || op.kind == intType || op.kind == int64Type || op.kind == longType || op.kind == floatType || op.kind == doubleType ||
}
else
{
- if(op1 && op2 && op1.kind != op2.kind)
+ if(op1 && op2 && op1.type && op2.type && op1.kind != op2.kind)
{
if(Promote(op2, op1.kind, op1.type.isSigned))
op2.kind = op1.kind, op2.ops = op1.ops;
if(!n)
{
OldList * list = exp.list;
+ Expression prev = exp.prev;
+ Expression next = exp.next;
ComputeExpression(e);
//FreeExpContents(exp);
FreeType(exp.expType);
FreeType(exp.destType);
*exp = *e;
+ exp.prev = prev;
+ exp.next = next;
delete e;
delete list;
}
void (*Set)(void *, void *) = (void *)prop.Set;
exp.instance = Instantiation { };
exp.instance.data = new0 byte[_class.structSize];
- exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+ exp.instance._class = MkSpecifierName(_class.fullName);
exp.instance.loc = exp.loc;
exp.type = instanceExp;
Set(exp.instance.data, value.instance.data);
exp.instance = Instantiation { };
exp.instance.data = new0 byte[_class.structSize];
- exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+ exp.instance._class = MkSpecifierName(_class.fullName);
exp.instance.loc = exp.loc;
exp.type = instanceExp;
exp.instance = Instantiation { };
exp.instance.data = new0 byte[_class.structSize];
- exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+ exp.instance._class = MkSpecifierName(_class.fullName);
exp.instance.loc = exp.loc;
exp.type = instanceExp;
exp.instance = Instantiation { };
exp.instance.data = new0 byte[_class.structSize];
- exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+ exp.instance._class = MkSpecifierName(_class.fullName);
exp.instance.loc = exp.loc;
exp.type = instanceExp;
PopulateInstance(exp.instance);
break;
}
+ case floatType:
+ {
+ float floatValue;
+ void (*Set)(void *, float) = (void *)prop.Set;
+
+ exp.instance = Instantiation { };
+ exp.instance.data = new0 byte[_class.structSize];
+ exp.instance._class = MkSpecifierName(_class.fullName);
+ exp.instance.loc = exp.loc;
+ exp.type = instanceExp;
+
+ GetFloat(value, &floatValue);
+
+ Set(exp.instance.data, floatValue);
+ PopulateInstance(exp.instance);
+ break;
+ }
case doubleType:
{
double doubleValue;
exp.instance = Instantiation { };
exp.instance.data = new0 byte[_class.structSize];
- exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+ exp.instance._class = MkSpecifierName(_class.fullName);
exp.instance.loc = exp.loc;
exp.type = instanceExp;
exp.instance = Instantiation { };
exp.instance.data = new0 byte[_class.structSize];
- exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+ exp.instance._class = MkSpecifierName(_class.fullName);
exp.instance.loc = exp.loc;
//exp.instance.fullSet = true;
exp.type = instanceExp;
exp.instance = Instantiation { };
exp.instance.data = new0 byte[_class.structSize];
- exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
+ exp.instance._class = MkSpecifierName(_class.fullName);
exp.instance.loc = exp.loc;
//exp.instance.fullSet = true;
exp.type = instanceExp;
case charType:
if(type.isSigned)
{
- char value;
- GetChar(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintChar(value);
- exp.type = constantExp;
+ char value = 0;
+ if(GetChar(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintChar(value);
+ exp.type = constantExp;
+ }
}
else
{
- unsigned char value;
- GetUChar(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintUChar(value);
- exp.type = constantExp;
+ unsigned char value = 0;
+ if(GetUChar(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintUChar(value);
+ exp.type = constantExp;
+ }
}
break;
case shortType:
if(type.isSigned)
{
- short value;
- GetShort(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintShort(value);
- exp.type = constantExp;
+ short value = 0;
+ if(GetShort(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintShort(value);
+ exp.type = constantExp;
+ }
}
else
{
- unsigned short value;
- GetUShort(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintUShort(value);
- exp.type = constantExp;
+ unsigned short value = 0;
+ if(GetUShort(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintUShort(value);
+ exp.type = constantExp;
+ }
}
break;
case intType:
if(type.isSigned)
{
- int value;
- GetInt(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintInt(value);
- exp.type = constantExp;
+ int value = 0;
+ if(GetInt(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintInt(value);
+ exp.type = constantExp;
+ }
}
else
{
- unsigned int value;
- GetUInt(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintUInt(value);
- exp.type = constantExp;
+ unsigned int value = 0;
+ if(GetUInt(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintUInt(value);
+ exp.type = constantExp;
+ }
}
break;
case int64Type:
if(type.isSigned)
{
- int64 value;
- GetInt64(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintInt64(value);
- exp.type = constantExp;
+ int64 value = 0;
+ if(GetInt64(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintInt64(value);
+ exp.type = constantExp;
+ }
}
else
{
- uint64 value;
- GetUInt64(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintUInt64(value);
- exp.type = constantExp;
+ uint64 value = 0;
+ if(GetUInt64(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintUInt64(value);
+ exp.type = constantExp;
+ }
}
break;
case intPtrType:
if(type.isSigned)
{
- intptr value;
- GetIntPtr(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintInt64((int64)value);
- exp.type = constantExp;
+ intptr value = 0;
+ if(GetIntPtr(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintInt64((int64)value);
+ exp.type = constantExp;
+ }
}
else
{
- uintptr value;
- GetUIntPtr(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintUInt64((uint64)value);
- exp.type = constantExp;
+ uintptr value = 0;
+ if(GetUIntPtr(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintUInt64((uint64)value);
+ exp.type = constantExp;
+ }
}
break;
case intSizeType:
if(type.isSigned)
{
- intsize value;
- GetIntSize(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintInt64((int64)value);
- exp.type = constantExp;
+ intsize value = 0;
+ if(GetIntSize(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintInt64((int64)value);
+ exp.type = constantExp;
+ }
}
else
{
- uintsize value;
- GetUIntSize(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintUInt64((uint64)value);
- exp.type = constantExp;
+ uintsize value = 0;
+ if(GetUIntSize(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintUInt64((uint64)value);
+ exp.type = constantExp;
+ }
}
break;
case floatType:
{
- float value;
- GetFloat(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintFloat(value);
- exp.type = constantExp;
+ float value = 0;
+ if(GetFloat(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintFloat(value);
+ exp.type = constantExp;
+ }
break;
}
case doubleType:
{
- double value;
- GetDouble(e, &value);
- FreeExpContents(exp);
- exp.constant = PrintDouble(value);
- exp.type = constantExp;
+ double value = 0;
+ if(GetDouble(e, &value))
+ {
+ FreeExpContents(exp);
+ exp.constant = PrintDouble(value);
+ exp.type = constantExp;
+ }
break;
}
}
// TODO: Check this...
*newExp = *exp;
+ newExp.prev = null;
+ newExp.next = null;
newExp.destType = null;
if(convert.isGet)
exp.expType = type;
if(type)
type.refCount++;
- if(type && (type.kind == enumType || (_class && _class.type == enumClass)))
+
+ // Commented this out, it was making non-constant enum parameters seen as constant
+ // enums should have been resolved by ResolveIdWithClass, changed to constantExp and marked as constant
+ if(type && (type.kind == enumType /*|| (_class && _class.type == enumClass)*/))
// Add missing cases here... enum Classes...
exp.isConstant = true;
else
{
bool isSigned = constant[0] == '-';
- int64 i64 = strtoll(constant, null, 0);
- uint64 ui64 = strtoull(constant, null, 0);
- bool is64Bit = false;
+ char * endP = null;
+ int64 i64 = strtoll(constant, &endP, 0);
+ uint64 ui64 = strtoull(constant, &endP, 0);
+ bool is64Bit = endP && (!strcmp(endP, "LL") || !strcmp(endP, "ll"));
if(isSigned)
{
if(i64 < MININT)
bool useDestType = false, useSideType = false;
Location oldyylloc = yylloc;
bool useSideUnit = false;
+ Class destClass = (exp.destType && exp.destType.kind == classType && exp.destType._class) ? exp.destType._class.registered : null;
// Dummy type to prevent ProcessExpression of operands to say unresolved identifiers yet
Type dummy
case '+':
case '-':
useSideUnit = true;
+ useSideType = true;
+ useDestType = true;
+ break;
+
+ case LEFT_OP:
+ case RIGHT_OP:
+ useSideType = true;
+ useDestType = true;
+ break;
- // Just added these... testing
case '|':
- case '&':
case '^':
+ useSideType = true;
+ useDestType = true;
+ break;
- // DANGER: Verify units
case '/':
case '%':
+ useSideType = true;
+ useDestType = true;
+ break;
+ case '&':
case '*':
-
- if(exp.op.op != '*' || exp.op.exp1)
+ if(exp.op.exp1)
{
+ // For & operator, useDestType nicely ensures the result will fit in a bool (TODO: Fix for generic enum)
useSideType = true;
useDestType = true;
}
}
//dummy.kind = TypeDummy;
-
if(exp.op.exp1)
{
- if(exp.destType && exp.destType.kind == classType &&
- exp.destType._class && exp.destType._class.registered && useDestType &&
+ // Added this check here to use the dest type only for units derived from the base unit
+ // So that untyped units will use the side unit as opposed to the untyped destination unit
+ // This fixes (#771) sin(Degrees { 5 } + 5) to be equivalent to sin(Degrees { 10 }), since sin expects a generic Angle
+ if(exp.op.exp2 && useSideUnit && useDestType && destClass && destClass.type == unitClass && destClass.base.type != unitClass)
+ useDestType = false;
- ((exp.destType._class.registered.type == unitClass && useSideUnit) ||
- exp.destType._class.registered.type == enumClass ||
- exp.destType._class.registered.type == bitClass
- ))
+ if(destClass && useDestType &&
+ ((destClass.type == unitClass && useSideUnit) || destClass.type == enumClass || destClass.type == bitClass))
//(exp.destType._class.registered.type == unitClass || exp.destType._class.registered.type == enumClass) && useDestType)
{
if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
exp.op.exp1.destType = exp.destType;
+ exp.op.exp1.opDestType = true;
if(exp.destType)
exp.destType.refCount++;
}
ProcessExpressionType(exp.op.exp1);
if(exp.op.exp1.destType && exp.op.op != '=') exp.op.exp1.destType.count--;
+ exp.op.exp1.opDestType = false;
+
+ // Fix for unit and ++ / --
+ if(!exp.op.exp2 && (exp.op.op == INC_OP || exp.op.op == DEC_OP) && exp.op.exp1.expType && exp.op.exp1.expType.kind == classType &&
+ exp.op.exp1.expType._class && exp.op.exp1.expType._class.registered && exp.op.exp1.expType._class.registered.type == unitClass)
+ {
+ exp.op.exp2 = MkExpConstant("1");
+ exp.op.op = exp.op.op == INC_OP ? ADD_ASSIGN : SUB_ASSIGN;
+ assign = true;
+ }
+
if(exp.op.exp1.destType == dummy)
{
FreeType(dummy);
else
{
exp.op.exp2.destType = exp.destType;
+ if(!exp.op.exp1 || exp.op.op != '&')
+ exp.op.exp2.opDestType = true;
if(exp.destType)
exp.destType.refCount++;
}
if(type1) type1.refCount++;
exp.expType = type1;
}
- else if(exp.destType && exp.destType.kind == classType &&
- exp.destType._class && exp.destType._class.registered &&
-
- ((exp.destType._class.registered.type == unitClass && useDestType && useSideUnit) ||
- (exp.destType._class.registered.type == enumClass && useDestType))
- )
+ else if(destClass &&
+ ((destClass.type == unitClass && useDestType && useSideUnit) ||
+ (destClass.type == enumClass && useDestType)))
{
if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
exp.op.exp2.destType = exp.destType;
+ if(exp.op.op != '&')
+ exp.op.exp2.opDestType = true;
if(exp.destType)
exp.destType.refCount++;
}
e.cast.exp.needCast = true;
}
ProcessExpressionType(exp.op.exp2);
+ exp.op.exp2.opDestType = false;
if(exp.op.exp2.destType && exp.op.op != '=') exp.op.exp2.destType.count--;
if(assign && type1 && type1.kind == pointerType && exp.op.exp2.expType)
// If either both are class or both are not class
((type1.kind == classType && type1._class && strcmp(type1._class.string, "String")) == (type2.kind == classType && type2._class && strcmp(type2._class.string, "String"))))
{
- if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
- exp.op.exp2.destType = type1;
- type1.refCount++;
- if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
- exp.op.exp1.destType = type2;
- type2.refCount++;
+ // Added this check for enum subtraction to result in an int type:
+ if(exp.op.op == '-' &&
+ ((type1.kind == classType && type1._class.registered && type1._class.registered.type == enumClass) ||
+ (type2.kind == classType && type2._class.registered && type2._class.registered.type == enumClass)) )
+ {
+ Type intType;
+ if(!type1._class.registered.dataType)
+ type1._class.registered.dataType = ProcessTypeString(type1._class.registered.dataTypeString, false);
+ if(!type2._class.registered.dataType)
+ type2._class.registered.dataType = ProcessTypeString(type2._class.registered.dataTypeString, false);
+
+ intType = ProcessTypeString(
+ (type1._class.registered.dataType.kind == int64Type || type2._class.registered.dataType.kind == int64Type) ? "int64" : "int", false);
+
+ if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
+ if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
+ exp.op.exp1.destType = intType;
+ exp.op.exp2.destType = intType;
+ intType.refCount++;
+ }
+ else
+ {
+ if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
+ exp.op.exp2.destType = type1;
+ type1.refCount++;
+ if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
+ exp.op.exp1.destType = type2;
+ type2.refCount++;
+ }
+
// Warning here for adding Radians + Degrees with no destination type
if(!boolResult && type1.kind == classType && (!exp.destType || exp.destType.kind != classType) &&
type1._class.registered && type1._class.registered.type == unitClass &&
}
// TESTING THIS NEW CODE
- if(!boolResult || exp.op.op == '>' || exp.op.op == '<')
+ if(!boolResult || exp.op.op == '>' || exp.op.op == '<' || exp.op.op == GE_OP || exp.op.op == LE_OP)
{
- if(type1.kind == classType && type1._class && type1._class.registered && type1._class.registered.type == enumClass && exp.op.exp2.expType)
+ bool op1IsEnum = type1 && type1.kind == classType && type1._class && type1._class.registered && type1._class.registered.type == enumClass;
+ bool op2IsEnum = type2 && type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == enumClass;
+ if(exp.op.op == '*' || exp.op.op == '/' || exp.op.op == '-' || exp.op.op == '|' || exp.op.op == '^')
{
- if(CheckExpressionType(exp.op.exp1, exp.op.exp2.expType, false))
+ // Convert the enum to an int instead for these operators
+ if(op1IsEnum && exp.op.exp2.expType)
{
- if(exp.expType) FreeType(exp.expType);
- exp.expType = exp.op.exp1.expType;
- if(exp.op.exp2.expType) exp.op.exp1.expType.refCount++;
- valid = true;
+ if(CheckExpressionType(exp.op.exp1, exp.op.exp2.expType, false))
+ {
+ if(exp.expType) FreeType(exp.expType);
+ exp.expType = exp.op.exp2.expType;
+ if(exp.op.exp2.expType) exp.op.exp2.expType.refCount++;
+ valid = true;
+ }
+ }
+ else if(op2IsEnum && exp.op.exp1.expType)
+ {
+ if(CheckExpressionType(exp.op.exp2, exp.op.exp1.expType, false))
+ {
+ if(exp.expType) FreeType(exp.expType);
+ exp.expType = exp.op.exp1.expType;
+ if(exp.op.exp1.expType) exp.op.exp1.expType.refCount++;
+ valid = true;
+ }
}
}
-
- else if(type2 && (type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == enumClass && exp.op.exp1.expType))
+ else
{
- if(CheckExpressionType(exp.op.exp2, exp.op.exp1.expType, false))
+ if(op1IsEnum && exp.op.exp2.expType)
{
- if(exp.expType) FreeType(exp.expType);
- exp.expType = exp.op.exp2.expType;
- if(exp.op.exp2.expType) exp.op.exp2.expType.refCount++;
- valid = true;
+ if(CheckExpressionType(exp.op.exp1, exp.op.exp2.expType, false))
+ {
+ if(exp.expType) FreeType(exp.expType);
+ exp.expType = exp.op.exp1.expType;
+ if(exp.op.exp1.expType) exp.op.exp1.expType.refCount++;
+ valid = true;
+ }
+ }
+ else if(op2IsEnum && exp.op.exp1.expType)
+ {
+ if(CheckExpressionType(exp.op.exp2, exp.op.exp1.expType, false))
+ {
+ if(exp.expType) FreeType(exp.expType);
+ exp.expType = exp.op.exp2.expType;
+ if(exp.op.exp2.expType) exp.op.exp2.expType.refCount++;
+ valid = true;
+ }
}
}
}
if(!valid)
{
- if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
- exp.op.exp2.destType = type1;
- type1.refCount++;
+ // Added this first part of the if here to handle 5 + Degrees { 5 } with either a base unit dest or not a unit dest type
+ if(type2 && type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == unitClass &&
+ (type1.kind != classType || !type1._class || !type1._class.registered || type1._class.registered.type != unitClass))
+ {
+ if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
+ exp.op.exp1.destType = type2;
+ type2.refCount++;
+
+ if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false))
+ {
+ if(exp.expType) FreeType(exp.expType);
+ exp.expType = exp.op.exp1.destType;
+ if(exp.op.exp1.destType) exp.op.exp1.destType.refCount++;
+ }
+ }
+ else
+ {
+ if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
+ exp.op.exp2.destType = type1;
+ type1.refCount++;
/*
// Maybe this was meant to be an enum...
}
*/
- if(CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false))
- {
- if(exp.expType) FreeType(exp.expType);
- exp.expType = exp.op.exp2.destType;
- if(exp.op.exp2.destType) exp.op.exp2.destType.refCount++;
- }
- else if(type1 && type2)
- {
- char expString1[10240];
- char expString2[10240];
- char type1String[1024];
- char type2String[1024];
- expString1[0] = '\0';
- expString2[0] = '\0';
- type1String[0] = '\0';
- type2String[0] = '\0';
- if(inCompiler)
+ if(CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false))
{
- PrintExpression(exp.op.exp1, expString1);
- ChangeCh(expString1, '\n', ' ');
- PrintExpression(exp.op.exp2, expString2);
- ChangeCh(expString2, '\n', ' ');
- PrintType(exp.op.exp1.expType, type1String, false, true);
- PrintType(exp.op.exp2.expType, type2String, false, true);
+ if(exp.expType) FreeType(exp.expType);
+ exp.expType = exp.op.exp2.destType;
+ if(exp.op.exp2.destType) exp.op.exp2.destType.refCount++;
}
+ else if(type1 && type2)
+ {
+ char expString1[10240];
+ char expString2[10240];
+ char type1String[1024];
+ char type2String[1024];
+ expString1[0] = '\0';
+ expString2[0] = '\0';
+ type1String[0] = '\0';
+ type2String[0] = '\0';
+ if(inCompiler)
+ {
+ PrintExpression(exp.op.exp1, expString1);
+ ChangeCh(expString1, '\n', ' ');
+ PrintExpression(exp.op.exp2, expString2);
+ ChangeCh(expString2, '\n', ' ');
+ PrintType(exp.op.exp1.expType, type1String, false, true);
+ PrintType(exp.op.exp2.expType, type2String, false, true);
+ }
- Compiler_Warning($"incompatible expressions %s (%s) and %s (%s)\n", expString1, type1String, expString2, type2String);
+ Compiler_Warning($"incompatible expressions %s (%s) and %s (%s)\n", expString1, type1String, expString2, type2String);
- if(type1.kind == classType && type1._class && type1._class.registered && type1._class.registered.type == enumClass)
- {
- exp.expType = exp.op.exp1.expType;
- if(exp.op.exp1.expType) exp.op.exp1.expType.refCount++;
- }
- else if(type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == enumClass)
- {
- exp.expType = exp.op.exp2.expType;
- if(exp.op.exp2.expType) exp.op.exp2.expType.refCount++;
+ if(type1.kind == classType && type1._class && type1._class.registered && type1._class.registered.type == enumClass)
+ {
+ exp.expType = exp.op.exp1.expType;
+ if(exp.op.exp1.expType) exp.op.exp1.expType.refCount++;
+ }
+ else if(type2.kind == classType && type2._class && type2._class.registered && type2._class.registered.type == enumClass)
+ {
+ exp.expType = exp.op.exp2.expType;
+ if(exp.op.exp2.expType) exp.op.exp2.expType.refCount++;
+ }
}
}
}
if(!e.next)
{
FreeType(e.destType);
+ e.opDestType = exp.opDestType;
e.destType = exp.destType;
if(e.destType) { exp.destType.refCount++; e.destType.count++; inced = true; }
}
ListAdd(stmt.expressions, MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eInstance_Watch")), args));
}
else
- Compiler_Error($"Property %s not found in class %s\n", prop.name, _class.fullName);
+ Compiler_Error($"Property %s not found in class %s\n", propID.string, _class.fullName);
}
}
}
ListAdd(stmt.expressions, MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eInstance_StopWatching")), args));
}
else
- Compiler_Error($"Property %s not found in class %s\n", prop.name, _class.fullName);
+ Compiler_Error($"Property %s not found in class %s\n", propID.string, _class.fullName);
}
}
else if(external.type == declarationExternal)
{
currentClass = null;
- ProcessDeclaration(external.declaration);
+ if(external.declaration)
+ ProcessDeclaration(external.declaration);
}
else if(external.type == classExternal)
{
}
currentClass = null;
thisNameSpace = null;
+ curExternal = null;
delete temp.symbol;
delete temp;