{
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);
}
//public Operand GetOperand(Expression exp);
#define GETVALUE(name, t) \
- public bool Get##name(Expression exp, t * value2) \
+ public bool GetOp##name(Operand op2, t * value2) \
{ \
- Operand op2 = GetOperand(exp); \
if(op2.kind == intType && op2.type.isSigned) *value2 = (t) op2.i; \
else if(op2.kind == intType) *value2 = (t) op2.ui; \
else if(op2.kind == int64Type && op2.type.isSigned) *value2 = (t) op2.i64; \
else \
return false; \
return true; \
+ } \
+ public bool Get##name(Expression exp, t * value2) \
+ { \
+ Operand op2 = GetOperand(exp); \
+ return GetOp##name(op2, value2); \
}
// To help the deubugger currently not preprocessing...
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;
}
Expression exp;
char * string = PrintHexUInt64(arg.expression.ui64);
exp = MkExpCast(MkTypeName(specs, decl), MkExpConstant(string));
+ delete string;
ProcessExpressionType(exp);
ComputeExpression(exp);
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) \
{ \
#define OPERATOR_ALL(macro, o, name) \
macro(o, Int##name, i, int, PrintInt) \
macro(o, UInt##name, ui, unsigned int, PrintUInt) \
- macro(o, Int64##name, i, int, PrintInt64) \
- macro(o, UInt64##name, ui, unsigned int, PrintUInt64) \
+ macro(o, Int64##name, i64, int64, PrintInt64) \
+ macro(o, UInt64##name, ui64, uint64, PrintUInt64) \
macro(o, Short##name, s, short, PrintShort) \
macro(o, UShort##name, us, unsigned short, PrintUShort) \
macro(o, Char##name, c, char, PrintChar) \
#define OPERATOR_INTTYPES(macro, o, name) \
macro(o, Int##name, i, int, PrintInt) \
macro(o, UInt##name, ui, unsigned int, PrintUInt) \
- macro(o, Int64##name, i, int, PrintInt64) \
- macro(o, UInt64##name, ui, unsigned int, PrintUInt64) \
+ macro(o, Int64##name, i64, int64, PrintInt64) \
+ macro(o, UInt64##name, ui64, uint64, PrintUInt64) \
macro(o, Short##name, s, short, PrintShort) \
macro(o, UShort##name, us, unsigned short, PrintUShort) \
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) \
case 'v': output[d] = '\v'; break;
case '\\': output[d] = '\\'; break;
case '\"': output[d] = '\"'; break;
- default: output[d++] = '\\'; output[d] = ch;
- //default: output[d] = ch;
+ case '\'': output[d] = '\''; break;
+ default: output[d] = ch;
}
d++;
escaped = false;
output[d] = '\0';
}
+// String Unescape Copy
+
+// TOFIX: THIS DOESN'T HANDLE NUMERIC ESCAPE CODES (OCTAL/HEXADECIMAL...)?
+// This is the same as ReadString above (which also misses numeric escape codes) except it doesn't handle external quotes
+public int UnescapeString(char * d, char * s, int len)
+{
+ int j = 0, k = 0;
+ char ch;
+ while(j < len && (ch = s[j]))
+ {
+ switch(ch)
+ {
+ case '\\':
+ switch((ch = s[++j]))
+ {
+ case 'n': d[k] = '\n'; break;
+ case 't': d[k] = '\t'; break;
+ case 'a': d[k] = '\a'; break;
+ case 'b': d[k] = '\b'; break;
+ case 'f': d[k] = '\f'; break;
+ case 'r': d[k] = '\r'; break;
+ case 'v': d[k] = '\v'; break;
+ case '\\': d[k] = '\\'; break;
+ case '\"': d[k] = '\"'; break;
+ case '\'': d[k] = '\''; break;
+ default: d[k] = '\\'; d[k] = ch;
+ }
+ break;
+ default:
+ d[k] = ch;
+ }
+ j++, k++;
+ }
+ d[k] = '\0';
+ return k;
+}
+
+public char * OffsetEscapedString(char * s, int len, int offset)
+{
+ char ch;
+ int j = 0, k = 0;
+ while(j < len && k < offset && (ch = s[j]))
+ {
+ if(ch == '\\') ++j;
+ j++, k++;
+ }
+ return (k == offset) ? s + j : null;
+}
+
public Operand GetOperand(Expression exp)
{
Operand op { };
type = type._class.registered.dataType;
}
- op.kind = type.kind;
- op.type = exp.expType;
- if(exp.isConstant && exp.type == constantExp)
+ if(exp.type == stringExp && op.kind == pointerType)
+ {
+ op.ui64 = (uint64)exp.string;
+ op.kind = pointerType;
+ op.ops = uint64Ops;
+ }
+ else if(exp.isConstant && exp.type == constantExp)
{
+ op.kind = type.kind;
+ op.type = exp.expType;
+
switch(op.kind)
{
case _BoolType:
case charType:
{
if(exp.constant[0] == '\'')
+ {
op.c = exp.constant[1];
+ op.ops = charOps;
+ }
else if(type.isSigned)
{
op.c = (char)strtol(exp.constant, null, 0);
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...
case classType:
op.ui64 = _strtoui64(exp.constant, null, 0);
op.kind = pointerType;
- op.ops = uintOps;
+ op.ops = uint64Ops;
// op.ptrSize =
break;
}
{
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;
}
}
}
}
}
+static bool Promote(Operand op, TypeKind kind, bool isSigned)
+{
+ bool result = false;
+ switch(kind)
+ {
+ case shortType:
+ if(op.kind == charType || op.kind == enumType || op.kind == _BoolType)
+ result = isSigned ? GetOpShort(op, &op.s) : GetOpUShort(op, &op.us);
+ break;
+ case intType:
+ case longType:
+ if(op.kind == charType || op.kind == shortType || op.kind == enumType || op.kind == _BoolType)
+ result = isSigned ? GetOpInt(op, &op.i) : GetOpUInt(op, &op.ui);
+ break;
+ 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);
+ 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);
+ 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);
+ 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 ||
+ op.kind == pointerType || op.kind == enumType || op.kind == intPtrType || op.kind == intSizeType || op.kind == _BoolType)
+ result = GetOpUIntPtr(op, &op.ui64);
+ break;
+ case enumType:
+ 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 ? GetOpInt(op, &op.i) : GetOpUInt(op, &op.ui);
+ break;
+ case intPtrType:
+ if(op.kind == charType || op.kind == shortType || op.kind == intType || op.kind == longType || op.kind == enumType || op.kind == _BoolType)
+ result = isSigned ? GetOpIntPtr(op, &op.i64) : GetOpUIntPtr(op, &op.i64);
+ break;
+ case intSizeType:
+ if(op.kind == charType || op.kind == shortType || op.kind == intType || op.kind == longType || op.kind == enumType || op.kind == _BoolType)
+ result = isSigned ? GetOpIntSize(op, &op.ui64) : GetOpUIntSize(op, &op.ui64);
+ break;
+ }
+ return result;
+}
+
void CallOperator(Expression exp, Expression exp1, Expression exp2, Operand op1, Operand op2)
{
if(exp.op.op == SIZEOF)
}
else
{
+ 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;
+ else if(Promote(op1, op2.kind, op2.type.isSigned))
+ op1.kind = op2.kind, op1.ops = op2.ops;
+ }
switch(exp.op.op)
{
// binary arithmetic
// We don't care about operations with only exp2 (INC_OP, DEC_OP...)
if(exp.op.exp2)
- ComputeExpression(exp.op.exp2);
+ {
+ Expression e = exp.op.exp2;
+
+ while((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list)
+ {
+ if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
+ {
+ if(e.type == extensionCompoundExp)
+ e = ((Statement)e.compound.compound.statements->last).expressions->last;
+ else
+ e = e.list->last;
+ }
+ }
+ if(exp.op.op == TokenType::sizeOf && e && e.expType)
+ {
+ if(e.type == stringExp && e.string)
+ {
+ char * string = e.string;
+ int len = strlen(string);
+ char * tmp = new char[len-2+1];
+ len = UnescapeString(tmp, string + 1, len - 2);
+ delete tmp;
+ FreeExpContents(exp);
+ exp.type = constantExp;
+ exp.constant = PrintUInt(len + 1);
+ }
+ else
+ {
+ Type type = e.expType;
+ type.refCount++;
+ FreeExpContents(exp);
+ exp.type = constantExp;
+ exp.constant = PrintUInt(ComputeTypeSize(type));
+ FreeType(type);
+ }
+ break;
+ }
+ else
+ ComputeExpression(exp.op.exp2);
+ }
if(exp.op.exp1)
{
ComputeExpression(exp.op.exp1);
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)
return null;
}
+public bool GetParseError() { return parseError; }
+
Expression ParseExpressionString(char * expression)
{
+ parseError = false;
+
fileInput = TempFile { };
fileInput.Write(expression, 1, strlen(expression));
fileInput.Seek(0, start);
case identifierExp:
{
Identifier id = exp.identifier;
- if(!id) return;
+ if(!id || !topContext) return;
// DOING THIS LATER NOW...
if(id._class && id._class.name)
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;
if(c == definedExpStackPos && c < sizeof(definedExpStack) / sizeof(void *))
{
Location backupYylloc = yylloc;
+ File backInput = fileInput;
definedExpStack[definedExpStackPos++] = definedExp;
+
fileInput = TempFile { };
fileInput.Write(definedExp.value, 1, strlen(definedExp.value));
fileInput.Seek(0, start);
resetScanner();
expression_yyparse();
delete fileInput;
+ if(backInput)
+ fileInput = backInput;
yylloc = backupYylloc;
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++;
}
type1.refCount++;
}
if(exp.op.exp2.destType && exp.op.op != '=') exp.op.exp2.destType.count++;
+ // Cannot lose the cast on a sizeof
+ if(exp.op.op == SIZEOF)
+ {
+ Expression e = exp.op.exp2;
+ while((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list)
+ {
+ if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
+ {
+ if(e.type == extensionCompoundExp)
+ e = ((Statement)e.compound.compound.statements->last).expressions->last;
+ else
+ e = e.list->last;
+ }
+ }
+ if(e.type == castExp && e.cast.exp)
+ 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)
type2.isSigned = true;
}
else
+ {
type2 = exp.op.exp2.expType;
+ if(type2) type2.refCount++;
+ }
}
dummy.kind = voidType;
// 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 &&
MkExpMember(classExp, MkIdentifier("typeSize"))))))));
if(!exp.op.exp2.expType)
+ {
+ if(type2)
+ FreeType(type2);
type2 = exp.op.exp2.expType = ProcessTypeString("int", false);
+ type2.refCount++;
+ }
ProcessExpressionType(exp.op.exp2);
}
exp.op.exp2.destType.refCount++;
CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false);
+ if(type2)
+ FreeType(type2);
type2 = exp.op.exp2.destType;
+ if(type2) type2.refCount++;
exp.expType = type2;
type2.refCount++;
}
// 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++;
+ }
}
}
}
yylloc = oldyylloc;
FreeType(dummy);
+ if(type2)
+ FreeType(type2);
break;
}
case bracketsExp:
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; }
}
Expression exp;
char * string = PrintHexUInt64(arg.expression.ui64);
exp = MkExpCast(MkTypeName(specs, decl), MkExpConstant(string));
+ delete string;
ProcessExpressionType(exp);
ComputeExpression(exp);
FreeExpContents(exp);
exp.type = identifierExp;
exp.identifier = MkIdentifier("class");
- ProcessExpressionType(exp);
+ FreeType(exp.expType);
+ exp.expType = MkClassType("ecere::com::Class");
return;
}
yylloc = exp.member.member.loc;
Expression exp;
char * string = PrintHexUInt64(arg.expression.ui64);
exp = MkExpCast(MkTypeName(specs, decl), MkExpConstant(string));
+ delete string;
ProcessExpressionType(exp);
ComputeExpression(exp);
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);
}
}
DeclareFunctionUtil("eSystem_New0");
DeclareFunctionUtil("eSystem_Renew");
DeclareFunctionUtil("eSystem_Renew0");
+ DeclareFunctionUtil("eSystem_Delete");
DeclareFunctionUtil("eClass_GetProperty");
DeclareFunctionUtil("eInstance_FireSelfWatchers");
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;