sdk: const correctness
[sdk] / compiler / libec / src / pass15.ec
index 3628003..95ced2a 100644 (file)
@@ -47,6 +47,8 @@ Time findSymbolTotalTime;
    {
       TempFile f { };
       int count;
+      bool backOutputLineNumbers = outputLineNumbers;
+      outputLineNumbers = false;
 
       if(exp)
          OutputExpression(exp, f);
@@ -55,6 +57,8 @@ Time findSymbolTotalTime;
       count += f.Read(string + count, 1, 1023);
       string[count] = '\0';
       delete f;
+
+      outputLineNumbers = backOutputLineNumbers;
    }
 }
 
@@ -88,6 +92,7 @@ bool NeedCast(Type type1, Type type2)
    {
       switch(type1.kind)
       {
+         case _BoolType:
          case charType:
          case shortType:
          case intType:
@@ -100,7 +105,7 @@ bool NeedCast(Type type1, Type type2)
          case classType:
             return type1._class != type2._class;
          case pointerType:
-            return NeedCast(type1.type, type2.type);
+            return (type1.type && type2.type && type1.type.constant != type2.type.constant) || NeedCast(type1.type, type2.type);
          default:
             return true; //false; ????
       }
@@ -200,10 +205,12 @@ static void ReplaceClassMembers(Expression exp, Class _class)
 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);
 }
 
@@ -240,9 +247,11 @@ public char * PrintHexUInt(uint64 result)
 {
    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);
 }
 
@@ -296,14 +305,44 @@ public char * PrintUChar(unsigned char result)
 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);
 }
 
@@ -313,9 +352,8 @@ public char * PrintDouble(double result)
 //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; \
@@ -327,13 +365,18 @@ public char * PrintDouble(double result)
       else if(op2.kind == shortType && op2.type.isSigned) *value2 = (t) op2.s;   \
       else if(op2.kind == shortType) *value2 = (t) op2.us;                        \
       else if(op2.kind == charType && op2.type.isSigned) *value2 = (t) op2.c;    \
-      else if(op2.kind == charType) *value2 = (t) op2.uc;                         \
+      else if(op2.kind == _BoolType || op2.kind == charType) *value2 = (t) op2.uc; \
       else if(op2.kind == floatType) *value2 = (t) op2.f;                         \
       else if(op2.kind == doubleType) *value2 = (t) op2.d;                        \
       else if(op2.kind == pointerType) *value2 = (t) op2.ui64;                    \
       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...
@@ -360,10 +403,9 @@ void ComputeClassMembers(Class _class, bool isMember)
 {
    DataMember member = isMember ? (DataMember) _class : null;
    Context context = isMember ? null : SetupTemplatesContext(_class);
-   if(member || ((_class.type == bitClass || _class.type == normalClass || _class.type == structClass || _class.type == noHeadClass) && 
+   if(member || ((_class.type == bitClass || _class.type == normalClass || _class.type == structClass || _class.type == noHeadClass) &&
                  (_class.type == bitClass || (!_class.structSize || _class.structSize == _class.offset)) && _class.computeSize))
    {
-      int c;
       int unionMemberOffset = 0;
       int bitFields = 0;
 
@@ -440,7 +482,7 @@ void ComputeClassMembers(Class _class, bool isMember)
                   int alignment = 0;
 
                   // Prevent infinite recursion
-                  if(dataMember.dataType.kind != classType || 
+                  if(dataMember.dataType.kind != classType ||
                      ((!dataMember.dataType._class || !dataMember.dataType._class.registered || dataMember.dataType._class.registered != _class ||
                      _class.type != structClass)))
                      ComputeTypeSize(dataMember.dataType);
@@ -607,7 +649,7 @@ void ComputeClassMembers(Class _class, bool isMember)
       {
          member.memberOffset = unionMemberOffset;
       }
-      
+
       if(!isMember)
       {
          /*if(_class.type == structClass)
@@ -668,7 +710,7 @@ public void ComputeModuleClasses(Module module)
 {
    Class _class;
    OldLink subModule;
-   
+
    for(subModule = module.modules.first; subModule; subModule = subModule.next)
       ComputeModuleClasses(subModule.data);
    for(_class = module.classes.first; _class; _class = _class.next)
@@ -684,6 +726,7 @@ public int ComputeTypeSize(Type type)
       type.computing = true;
       switch(type.kind)
       {
+         case _BoolType: type.alignment = size = sizeof(char); break;   // Assuming 1 byte _Bool
          case charType: type.alignment = size = sizeof(char); break;
          case intType: type.alignment = size = sizeof(int); break;
          case int64Type: type.alignment = size = sizeof(int64); break;
@@ -707,8 +750,8 @@ public int ComputeTypeSize(Type type)
                   size += type.alignment - (size % type.alignment);
 
             }
-            else if(_class && (_class.type == unitClass || 
-                   _class.type == enumClass || 
+            else if(_class && (_class.type == unitClass ||
+                   _class.type == enumClass ||
                    _class.type == bitClass))
             {
                if(!_class.dataType)
@@ -720,12 +763,19 @@ public int ComputeTypeSize(Type type)
             break;
          }
          case pointerType: case subClassType: size = type.alignment = targetBits / 8; /*sizeof(void *); */break;
-         case arrayType: 
+         case arrayType:
             if(type.arraySizeExp)
             {
                ProcessExpressionType(type.arraySizeExp);
                ComputeExpression(type.arraySizeExp);
-               if(!type.arraySizeExp.isConstant || (type.arraySizeExp.expType.kind != intType && type.arraySizeExp.expType.kind != enumType && 
+               if(!type.arraySizeExp.isConstant || (type.arraySizeExp.expType.kind != intType &&
+                  type.arraySizeExp.expType.kind != shortType &&
+                  type.arraySizeExp.expType.kind != charType &&
+                  type.arraySizeExp.expType.kind != longType &&
+                  type.arraySizeExp.expType.kind != int64Type &&
+                  type.arraySizeExp.expType.kind != intSizeType &&
+                  type.arraySizeExp.expType.kind != intPtrType &&
+                  type.arraySizeExp.expType.kind != enumType &&
                   (type.arraySizeExp.expType.kind != classType || !type.arraySizeExp.expType._class.registered || type.arraySizeExp.expType._class.registered.type != enumClass)))
                {
                   Location oldLoc = yylloc;
@@ -759,7 +809,7 @@ public int ComputeTypeSize(Type type)
             size = ComputeTypeSize(type.type) * type.arraySize;
             if(type.type)
                type.alignment = type.type.alignment;
-            
+
             break;
          case structType:
          {
@@ -786,7 +836,7 @@ public int ComputeTypeSize(Type type)
             for(member = type.members.first; member; member = member.next)
             {
                uint addSize = ComputeTypeSize(member);
-               
+
                member.offset = size;
                if(member.alignment && size % member.alignment)
                   member.offset += member.alignment - (size % member.alignment);
@@ -836,7 +886,8 @@ public int ComputeTypeSize(Type type)
    DataMember topMember = isMember ? (DataMember) _class : null;
    uint totalSize = 0;
    uint maxSize = 0;
-   int alignment, size;
+   int alignment;
+   uint size;
    DataMember member;
    Context context = isMember ? null : SetupTemplatesContext(_class);
    if(addedPadding)
@@ -874,7 +925,7 @@ public int ComputeTypeSize(Type type)
                   OldList * specs = MkList(), * decls = MkList();
                   Declarator decl;
 
-                  decl = SpecDeclFromString(member.dataTypeString, specs, 
+                  decl = SpecDeclFromString(member.dataTypeString, specs,
                      MkDeclaratorIdentifier(MkIdentifier(member.name)));
                   ListAdd(decls, MkStructDeclarator(decl, null));
                   ListAdd(declarations, MkClassDefDeclaration(MkStructDeclaration(specs, decls, null)));
@@ -912,10 +963,10 @@ public int ComputeTypeSize(Type type)
             case structMember:
             {
                OldList * specs = MkList(), * list = MkList();
-               
+
                size = 0;
                AddMembers(list, (Class)member, true, &size, topClass, null);
-               ListAdd(specs, 
+               ListAdd(specs,
                   MkStructOrUnion((member.type == unionMember)?unionSpecifier:structSpecifier, null, list));
                ListAdd(declarations, MkClassDefDeclaration(MkStructDeclaration(specs, null, null)));
                alignment = member.structAlignment;
@@ -947,8 +998,8 @@ public int ComputeTypeSize(Type type)
       {
          char sizeString[50];
          sprintf(sizeString, "%d", maxSize - totalSize);
-         ListAdd(declarations, 
-            MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifier(CHAR)), 
+         ListAdd(declarations,
+            MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifier(CHAR)),
             MkListOne(MkDeclaratorArray(MkDeclaratorIdentifier(MkIdentifier("__ecere_padding")), MkExpConstant(sizeString))), null)));
          if(addedPadding)
             *addedPadding = true;
@@ -962,10 +1013,9 @@ public int ComputeTypeSize(Type type)
 static int DeclareMembers(Class _class, bool isMember)
 {
    DataMember topMember = isMember ? (DataMember) _class : null;
-   uint totalSize = 0;
    DataMember member;
    Context context = isMember ? null : SetupTemplatesContext(_class);
-   
+
    if(!isMember && (_class.type == structClass || _class.type == noHeadClass) && _class.base.type != systemClass)
       DeclareMembers(_class.base, false);
 
@@ -1003,7 +1053,7 @@ static int DeclareMembers(Class _class, bool isMember)
    return topMember ? topMember.memberID : _class.memberID;
 }
 
-void DeclareStruct(char * name, bool skipNoHead)
+void DeclareStruct(const char * name, bool skipNoHead)
 {
    External external = null;
    Symbol classSym = FindClass(name);
@@ -1011,7 +1061,7 @@ void DeclareStruct(char * name, bool skipNoHead)
    if(!inCompiler || !classSym) return;
 
    // We don't need any declaration for bit classes...
-   if(classSym.registered && 
+   if(classSym.registered &&
       (classSym.registered.type == bitClass || classSym.registered.type == unitClass || classSym.registered.type == enumClass))
       return;
 
@@ -1026,7 +1076,8 @@ void DeclareStruct(char * name, bool skipNoHead)
       OldList * specifiers, * declarators;
       OldList * declarations = null;
       char structName[1024];
-      external = (classSym.registered && classSym.registered.type == structClass) ? 
+      Specifier spec = null;
+      external = (classSym.registered && classSym.registered.type == structClass) ?
          classSym.pointerExternal : classSym.structExternal;
 
       // TEMPORARY HACK: Pass 3 will move up struct declarations without moving members
@@ -1043,17 +1094,26 @@ void DeclareStruct(char * name, bool skipNoHead)
          }
          return;
       }
-      
+
       //if(!skipNoHead)
          DeclareMembers(classSym.registered, false);
 
       structName[0] = 0;
       FullClassNameCat(structName, name, false);
 
-      /*if(!external)      
+      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;
@@ -1073,9 +1133,10 @@ void DeclareStruct(char * name, bool skipNoHead)
       }
       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)
             {
@@ -1095,7 +1156,7 @@ void DeclareStruct(char * name, bool skipNoHead)
          }
          else
          {
-            if(!external)      
+            if(!external)
                external = MkExternalDeclaration(null);
 
             specifiers = MkList();
@@ -1252,7 +1313,9 @@ void DeclareProperty(Property prop, char * setName, char * getName)
                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;
       }
 
@@ -1281,7 +1344,7 @@ void DeclareProperty(Property prop, char * setName, char * getName)
             declarators = MkList();
             params = MkList();
 
-            ListAdd(params, MkTypeName(MkListOne(MkSpecifierName /*MkClassName*/(prop._class.fullName)), 
+            ListAdd(params, MkTypeName(MkListOne(MkSpecifierName /*MkClassName*/(prop._class.fullName)),
                MkDeclaratorIdentifier(MkIdentifier("this"))));
 
             d = MkDeclaratorIdentifier(MkIdentifier(getName));
@@ -1317,13 +1380,13 @@ void DeclareProperty(Property prop, char * setName, char * getName)
                d = PlugDeclarator(typeDecl, d);
             else
             {
-               ListAdd(params, MkTypeName(specifiers, 
+               ListAdd(params, MkTypeName(specifiers,
                   PlugDeclarator(typeDecl, MkDeclaratorIdentifier(MkIdentifier("value")))));
                specifiers = MkList();
             }
 
             d = MkDeclaratorFunction(d, params);
+
             //if(imported)
             if(dllImport)
                specifiers->Insert(null, MkSpecifier(EXTERN));
@@ -1372,7 +1435,7 @@ void DeclareProperty(Property prop, char * setName, char * getName)
             // TESTING COMMENTING THIS FIRST LINE OUT, what was the problem? Trying to add noHeadClass here ...
             if(!prop.conversion || prop._class.type == structClass)
             {
-               ListAdd(params, MkTypeName(MkListOne(MkSpecifierName/*MkClassName*/(prop._class.fullName)), 
+               ListAdd(params, MkTypeName(MkListOne(MkSpecifierName/*MkClassName*/(prop._class.fullName)),
                   MkDeclaratorIdentifier(MkIdentifier("this"))));
             }
 
@@ -1454,7 +1517,7 @@ void DeclareProperty(Property prop, char * setName, char * getName)
 
          {
             OldList * list = MkList();
-            ListAdd(list, MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null), 
+            ListAdd(list, MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null),
                   MkDeclaratorIdentifier(MkIdentifier(propName))), null));
 
             if(!imported)
@@ -1467,7 +1530,7 @@ void DeclareProperty(Property prop, char * setName, char * getName)
 
                MangleClassName(propName);
 
-               ListAdd(list, MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null), 
+               ListAdd(list, MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null),
                      MkDeclaratorIdentifier(MkIdentifier(propName))), null));
             }
             decl = MkDeclaration(specifiers, list);
@@ -1671,8 +1734,16 @@ void ProcessMemberInitData(MemberInit member, Class _class, Class * curClass, Da
             ClassTemplateArgument arg = _class.templateArgs[id];
             if(arg.dataTypeString)
             {
+               bool constant = type.constant;
                // FreeType(type);
                type = ProcessTypeString(arg.dataTypeString, false);
+               if(type.kind == classType && constant) type.constant = true;
+               else if(type.kind == pointerType)
+               {
+                  Type t = type.type;
+                  while(t.kind == pointerType) t = t.type;
+                  if(constant) t.constant = constant;
+               }
                freeType = true;
                if(type && _class.templateClass)
                   type.passAsTemplate = true;
@@ -1695,7 +1766,7 @@ void ProcessMemberInitData(MemberInit member, Class _class, Class * curClass, Da
          int c;
          int paramCount = 0;
          int lastParam = -1;
-         
+
          char templateString[1024];
          ClassTemplateParameter param;
          sprintf(templateString, "%s<", expClass.templateClass.fullName);
@@ -1708,7 +1779,7 @@ void ProcessMemberInitData(MemberInit member, Class _class, Class * curClass, Da
                int id = p;
                Class sClass;
                ClassTemplateArgument arg;
-               for(sClass = cClass.base; sClass; sClass = sClass.base) 
+               for(sClass = cClass.base; sClass; sClass = sClass.base)
                {
                   if(sClass.templateClass) sClass = sClass.templateClass;
                   id += sClass.templateParams.count;
@@ -1723,12 +1794,12 @@ void ProcessMemberInitData(MemberInit member, Class _class, Class * curClass, Da
                   Class nextClass;
                   if(sClass.templateClass) sClass = sClass.templateClass;
 
-                  for(nextClass = sClass.base; nextClass; nextClass = nextClass.base) 
+                  for(nextClass = sClass.base; nextClass; nextClass = nextClass.base)
                   {
                      if(nextClass.templateClass) nextClass = nextClass.templateClass;
                      p += nextClass.templateParams.count;
                   }
-                  
+
                   for(cParam = sClass.templateParams.first; cParam; cParam = cParam.next, p++)
                   {
                      if(cParam.type == TemplateParameterType::type && arg.dataTypeString && !strcmp(cParam.name, arg.dataTypeString))
@@ -1762,6 +1833,7 @@ void ProcessMemberInitData(MemberInit member, Class _class, Class * curClass, Da
                         Expression exp;
                         char * string = PrintHexUInt64(arg.expression.ui64);
                         exp = MkExpCast(MkTypeName(specs, decl), MkExpConstant(string));
+                        delete string;
 
                         ProcessExpressionType(exp);
                         ComputeExpression(exp);
@@ -1797,7 +1869,7 @@ void ProcessMemberInitData(MemberInit member, Class _class, Class * curClass, Da
                      lastParam = p;
                   }
                   p++;
-               }               
+               }
             }
          }
          {
@@ -1836,7 +1908,7 @@ void ProcessMemberInitData(MemberInit member, Class _class, Class * curClass, Da
             }
          }
          //else if(!MatchTypes(member.exp.expType, type, null, _class, null, true, true, false, false))
-         else if(!MatchTypes(member.initializer.exp.expType, type, null, null, _class, true, true, false, false))
+         else if(!MatchTypes(member.initializer.exp.expType, type, null, null, _class, true, true, false, false, true))
          {
             Compiler_Error($"incompatible instance method %s\n", ident.string);
          }
@@ -1905,7 +1977,7 @@ void ProcessInstantiationType(Instantiation inst)
       MembersInit members;
       Symbol classSym; // = inst._class.symbol; // FindClass(inst._class.name);
       Class _class;
-      
+
       /*if(!inst._class.symbol)
          inst._class.symbol = FindClass(inst._class.name);*/
       classSym = inst._class.symbol;
@@ -1954,7 +2026,7 @@ void ProcessInstantiationType(Instantiation inst)
                      strcat(name, nameID.string);
                      strcat(name, "_");
                      sprintf(number, "_%08d", instMethodID++);
-                     strcat(name, number);                     
+                     strcat(name, number);
                      nameID.string = CopyString(name);
                   }
 
@@ -1963,7 +2035,7 @@ void ProcessInstantiationType(Instantiation inst)
                   {
                      Symbol symbol = declarator.symbol;
                      Method method = eClass_FindMethod(_class, unmangled, privateModule);
-                                    
+
                      if(method && method.type == virtualMethod)
                      {
                         symbol.method = method;
@@ -1971,7 +2043,7 @@ void ProcessInstantiationType(Instantiation inst)
 
                         if(!symbol.type.thisClass)
                         {
-                           if(method.dataType.thisClass && currentClass && 
+                           if(method.dataType.thisClass && currentClass &&
                               eClass_IsDerived(currentClass, method.dataType.thisClass.registered))
                            {
                               if(!currentClass.symbol)
@@ -2007,8 +2079,7 @@ void ProcessInstantiationType(Instantiation inst)
 
                   if(inCompiler)
                   {
-
-                     Type type = declarator.symbol.type;
+                     //Type type = declarator.symbol.type;
                      External oldExternal = curExternal;
 
                      // *** Commented this out... Any negative impact? Yes: makes double prototypes declarations... Why was it commented out?
@@ -2038,7 +2109,7 @@ void ProcessInstantiationType(Instantiation inst)
                         delete declarator.symbol.string;
                         declarator.symbol.string = CopyString(name);
                      }
-                     
+
                      if(!declarator.symbol.parent && globalContext.symbols.root != (BTNode)declarator.symbol)
                      {
                         printf("TOCHECK: Will this ever be in a list? Yes.\n");
@@ -2049,7 +2120,7 @@ void ProcessInstantiationType(Instantiation inst)
 
                      }
                      */
-                  
+
                      //curExternal = curExternal.prev;
                      //afterExternal = afterExternal->next;
 
@@ -2071,11 +2142,11 @@ void ProcessInstantiationType(Instantiation inst)
                            {
                               //Declaration decl = MkDeclaration(members.function.specifiers, MkListOne(MkInitDeclarator(CopyDeclarator(declarator), null)));
 
-                              Declaration decl = MkDeclaration(CopyList(createdExternal.function.specifiers, CopySpecifier), 
+                              Declaration decl = MkDeclaration(CopyList(createdExternal.function.specifiers, CopySpecifier),
                                  MkListOne(MkInitDeclarator(CopyDeclarator(declarator), null)));
-                     
+
                               //externalDecl = MkExternalDeclaration(decl);
-                        
+
                               //***** ast->Insert(external.prev, externalDecl);
                               //ast->Insert(curExternal.prev, externalDecl);
                               externalDecl.declaration = decl;
@@ -2234,7 +2305,7 @@ public Context SetupTemplatesContext(Class _class)
                   // ADD DATA TYPE HERE...
                   p.param = param = TemplateParameter
                   {
-                     identifier = MkIdentifier(p.name), type = p.type, 
+                     identifier = MkIdentifier(p.name), type = p.type,
                      dataTypeString = p.dataTypeString /*, dataType = { specs, decl }*/
                   };
                }
@@ -2338,7 +2409,7 @@ public void ProcessPropertyType(Property prop)
    }
 }
 
-public void DeclareMethod(Method method, char * name)
+public void DeclareMethod(Method method, const char * name)
 {
    Symbol symbol = method.symbol;
    if(!symbol || (!symbol.pointerExternal && method.type == virtualMethod) || symbol.id > (curExternal ? curExternal.symbol.idCode : -1))
@@ -2360,7 +2431,7 @@ public void DeclareMethod(Method method, char * name)
             if(!classSym._import)
             {
                ModuleImport module;
-               
+
                if(method._class.module && method._class.module.name)
                   module = FindModule(method._class.module);
                else
@@ -2404,14 +2475,14 @@ public void DeclareMethod(Method method, char * name)
             }
             /*
             if(!method.thisClass || strcmp(method.thisClass, "void"))
-               symbol.type.params.Insert(null, 
+               symbol.type.params.Insert(null,
                   MkClassType(method.thisClass ? method.thisClass : method._class.fullName));
             */
          }
          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;
          }
       }
@@ -2482,7 +2553,7 @@ public void DeclareMethod(Method method, char * name)
                {
                   Class _class = method.dataType.thisClass ? method.dataType.thisClass.registered : method._class;
                   TypeName thisParam = MkTypeName(MkListOne(
-                     MkSpecifierName/*MkClassName*/(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)), 
+                     MkSpecifierName/*MkClassName*/(method.dataType.thisClass ? method.dataType.thisClass.string : method._class.fullName)),
                      (_class && _class.type == systemClass) ? MkDeclaratorPointer(MkPointer(null,null), MkDeclaratorIdentifier(MkIdentifier("this"))) : MkDeclaratorIdentifier(MkIdentifier("this")));
                   TypeName firstParam = ((TypeName)funcDecl.function.parameters->first);
                   Specifier firstSpec = firstParam.qualifiers ? firstParam.qualifiers->first : null;
@@ -2504,7 +2575,7 @@ public void DeclareMethod(Method method, char * name)
             else if(!funcDecl.function.parameters)
             {
                funcDecl.function.parameters = MkList();
-               funcDecl.function.parameters->Insert(null, 
+               funcDecl.function.parameters->Insert(null,
                   MkTypeName(MkListOne(MkSpecifier(VOID)),null));
             }*/
          }
@@ -2557,7 +2628,7 @@ char * ReplaceThisClass(Class _class)
       int p = 0;
       ClassTemplateParameter param;
       int lastParam = -1;
-      
+
       char className[1024];
       strcpy(className, _class.fullName);
       for(param = _class.templateParams.first; param; param = param.next)
@@ -2587,7 +2658,7 @@ char * ReplaceThisClass(Class _class)
       return CopyString(className);
    }
    else
-      return CopyString(_class.fullName);   
+      return CopyString(_class.fullName);
 }
 
 Type ReplaceThisClassType(Class _class)
@@ -2600,7 +2671,7 @@ Type ReplaceThisClassType(Class _class)
       int lastParam = -1;
       char className[1024];
       strcpy(className, _class.fullName);
-      
+
       for(param = _class.templateParams.first; param; param = param.next)
       {
          // if((!param.defaultArg.dataTypeString && !param.defaultArg.expression.ui64))
@@ -2744,7 +2815,7 @@ bool DeclareFunction(GlobalFunction function, char * name)
             if(funcDecl && !funcDecl.function.parameters)
             {
                funcDecl.function.parameters = MkList();
-               funcDecl.function.parameters->Insert(null, 
+               funcDecl.function.parameters->Insert(null,
                   MkTypeName(MkListOne(MkSpecifier(VOID)),null));
             }
 
@@ -2851,10 +2922,27 @@ class Conversion : struct
    Type resultType;
 };
 
-public bool MatchTypes(Type source, Type dest, OldList conversions, Class owningClassSource, Class owningClassDest, bool doConversion, bool enumBaseType, bool acceptReversedParams, bool isConversionExploration)
+public bool MatchTypes(Type source, Type dest, OldList conversions, Class owningClassSource, Class owningClassDest, bool doConversion, bool enumBaseType, bool acceptReversedParams,
+                       bool isConversionExploration, bool warnConst)
 {
    if(source && dest)
    {
+      if(warnConst &&
+         ((source.kind == classType && source._class && source._class.registered) || source.kind == arrayType || source.kind == pointerType) &&
+         ((dest.kind == classType && dest._class && dest._class.registered) || /*dest.kind == arrayType || */dest.kind == pointerType))
+      {
+         Class sourceClass = source.kind == classType ? source._class.registered : null;
+         Class destClass = dest.kind == classType ? dest._class.registered : null;
+         if((!sourceClass || (sourceClass && sourceClass.type == normalClass && !sourceClass.structSize)) &&
+            (!destClass || (destClass && destClass.type == normalClass && !destClass.structSize)))
+         {
+            Type sourceType = source, destType = dest;
+            while(sourceType.type && (sourceType.kind == pointerType || sourceType.kind == arrayType)) sourceType = sourceType.type;
+            while(destType.type && (destType.kind == pointerType || destType.kind == arrayType)) destType = destType.type;
+            if(!destType.constant && sourceType.constant)
+               Compiler_Warning($"discarding const qualifier\n");
+         }
+      }
       // Property convert;
 
       if(source.kind == templateType && dest.kind != templateType)
@@ -2889,7 +2977,7 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
          if(dest.classObjectType == anyObject && source.classObjectType != typedObject)
             return true;
       }
-      
+
       if((dest.kind == structType && source.kind == structType) ||
          (dest.kind == unionType && source.kind == unionType))
       {
@@ -2906,13 +2994,12 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
          || source.kind == subClassType || source.kind == pointerType || source.kind == arrayType || source.kind == functionType || source.kind == thisClassType)
 
          /*source.kind != voidType && source.kind != structType && source.kind != unionType  */
-      
+
          /*&& (source.kind != classType /-*|| source._class.registered.type != structClass)*/)
          return true;
       if(!isConversionExploration && source.kind == pointerType && source.type.kind == voidType &&
          ((dest.kind == classType && (!dest._class || !dest._class.registered || dest._class.registered.type == structClass || dest._class.registered.type == normalClass || dest._class.registered.type == noHeadClass || dest._class.registered.type == systemClass))
          || dest.kind == subClassType || dest.kind == pointerType || dest.kind == arrayType || dest.kind == functionType || dest.kind == thisClassType)
-
          /* dest.kind != voidType && dest.kind != structType && dest.kind != unionType  */
 
          /*&& (dest.kind != classType || dest._class.registered.type != structClass)*/)
@@ -2939,16 +3026,16 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
          // Don't match enum inheriting from other enum if resolving enumeration values
          // TESTING: !dest.classObjectType
          else if(source._class && dest._class && (dest.classObjectType == source.classObjectType || !dest.classObjectType) &&
-            (enumBaseType || 
-               (!source._class.registered || source._class.registered.type != enumClass) || 
+            (enumBaseType ||
+               (!source._class.registered || source._class.registered.type != enumClass) ||
                (!dest._class.registered || dest._class.registered.type != enumClass)) && eClass_IsDerived(source._class.registered, dest._class.registered))
             return true;
          else
          {
             // Added this so that DefinedColor = Color doesn't go through ColorRGB property
-            if(enumBaseType && 
+            if(enumBaseType &&
                dest._class && dest._class.registered && dest._class.registered.type == enumClass &&
-               source._class && source._class.registered && source._class.registered.type != enumClass)
+               ((source._class && source._class.registered && source._class.registered.type != enumClass) || source.kind == classType)) // Added this here for a base enum to be acceptable for a derived enum (#139)
             {
                if(eClass_IsDerived(dest._class.registered, source._class.registered))
                {
@@ -2979,14 +3066,18 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
 
                      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, warnConst))
                      {
                         if(!conversions && !convert.Get)
                            return true;
                         else if(conversions != null)
                         {
-                           if(_class.type == unitClass && convert.dataType.kind == classType && convert.dataType._class && 
-                              convert.dataType._class.registered && _class.base == convert.dataType._class.registered.base && 
+                           if(_class.type == unitClass && convert.dataType.kind == classType && convert.dataType._class &&
+                              convert.dataType._class.registered && _class.base == convert.dataType._class.registered.base &&
                               (dest.kind != classType || dest._class.registered != _class.base))
                               return true;
                            else
@@ -2994,6 +3085,7 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
                               Conversion conv { convert = convert, isGet = true };
                               // conversions.Add(conv);
                               conversions.Insert(after, conv);
+
                               return true;
                            }
                         }
@@ -3015,38 +3107,54 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
                {
                   if(convert.memberAccess == publicAccess || _class.module == privateModule)
                   {
+                     Type constType = null;
+                     bool success = false;
                      // Conversion after = (conversions != null) ? conversions.last : null;
 
                      if(!convert.dataType)
                         convert.dataType = ProcessTypeString(convert.dataTypeString, false);
+
+                     if(warnConst && convert.dataType.kind == pointerType && convert.dataType.type && dest.constant)
+                     {
+                        Type ptrType { };
+                        constType = { kind = pointerType, refCount = 1, type = ptrType };
+                        CopyTypeInto(ptrType, convert.dataType.type);
+                        ptrType.refCount++;
+                        ptrType.constant = true;
+                     }
+
                      // Just added this equality check to prevent recursion.... Make it safer?
                      // Changed enumBaseType to false here to prevent all int-compatible enums to show up in AnchorValues
-                     if(convert.dataType != dest && MatchTypes(source, convert.dataType, conversions, null, null, true, false /*true*/, false, true))
+                     if((constType || convert.dataType != dest) && MatchTypes(source, constType ? constType : convert.dataType, conversions, null, null, true, false /*true*/, false, true, warnConst))
                      {
                         if(!conversions && !convert.Set)
-                           return true;
+                           success = true;
                         else if(conversions != null)
                         {
-                           if(_class.type == unitClass && convert.dataType.kind == classType && convert.dataType._class && 
-                              convert.dataType._class.registered && _class.base == convert.dataType._class.registered.base && 
+                           if(_class.type == unitClass && convert.dataType.kind == classType && convert.dataType._class &&
+                              convert.dataType._class.registered && _class.base == convert.dataType._class.registered.base &&
                               (source.kind != classType || source._class.registered != _class.base))
-                              return true;
+                              success = true;
                            else
                            {
                               // *** Testing this! ***
                               Conversion conv { convert = convert };
                               conversions.Add(conv);
                               //conversions.Insert(after, conv);
-                              return true;
+                              success = true;
                            }
                         }
                      }
+                     if(success)
+                        return true;
+                     if(constType)
+                        FreeType(constType);
                   }
                }
             }
             /*if(dest._class.registered && !strcmp(dest._class.registered.name, "bool"))
             {
-               if(source.kind != voidType && source.kind != structType && source.kind != unionType && 
+               if(source.kind != voidType && source.kind != structType && source.kind != unionType &&
                   (source.kind != classType || source._class.registered.type != structClass))
                   return true;
             }*/
@@ -3060,7 +3168,7 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
                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, warnConst))
                   {
                      return true;
                   }
@@ -3083,14 +3191,16 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
 
                      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, warnConst))
                      {
                         if(!conversions && !convert.Get)
                            return true;
                         else if(conversions != null)
                         {
-                           if(_class.type == unitClass && convert.dataType.kind == classType && convert.dataType._class && 
-                              convert.dataType._class.registered && _class.base == convert.dataType._class.registered.base && 
+                           if(_class.type == unitClass && convert.dataType.kind == classType && convert.dataType._class &&
+                              convert.dataType._class.registered && _class.base == convert.dataType._class.registered.base &&
                               (dest.kind != classType || dest._class.registered != _class.base))
                               return true;
                            else
@@ -3112,9 +3222,13 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
             {
                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, warnConst))
+                     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, warnConst))
+                     return true;
                }
             }
          }
@@ -3122,44 +3236,44 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
 
       if(source.kind == classType || source.kind == subClassType)
          ;
-      else if(dest.kind == source.kind && 
+      else if(dest.kind == source.kind &&
          (dest.kind != structType && dest.kind != unionType &&
           dest.kind != functionType && dest.kind != arrayType && dest.kind != pointerType && dest.kind != methodType))
           return true;
       // RECENTLY ADDED THESE
       else if(dest.kind == doubleType && source.kind == floatType)
          return true;
-      else if(dest.kind == shortType && source.kind == charType)
+      else if(dest.kind == shortType && (source.kind == charType || source.kind == _BoolType))
          return true;
-      else if(dest.kind == intType && (source.kind == shortType || source.kind == charType || source.kind == intSizeType /* Exception here for size_t */))
+      else if(dest.kind == intType && (source.kind == shortType || source.kind == charType || source.kind == _BoolType || source.kind == intSizeType /* Exception here for size_t */))
          return true;
-      else if(dest.kind == int64Type && (source.kind == shortType || source.kind == charType || source.kind == intType || source.kind == intPtrType || source.kind == intSizeType))
+      else if(dest.kind == int64Type && (source.kind == shortType || source.kind == charType || source.kind == _BoolType || source.kind == intType || source.kind == intPtrType || source.kind == intSizeType))
          return true;
-      else if(dest.kind == intPtrType && (source.kind == shortType || source.kind == charType || source.kind == intType || source.kind == intSizeType || source.kind == int64Type))
+      else if(dest.kind == intPtrType && (source.kind == shortType || source.kind == charType || source.kind == _BoolType || source.kind == intType || source.kind == intSizeType || source.kind == int64Type))
          return true;
-      else if(dest.kind == intSizeType && (source.kind == shortType || source.kind == charType || source.kind == intType || source.kind == int64Type || source.kind == intPtrType))
+      else if(dest.kind == intSizeType && (source.kind == shortType || source.kind == charType || source.kind == _BoolType || source.kind == intType || source.kind == int64Type || source.kind == intPtrType))
          return true;
       else if(source.kind == enumType &&
-         (dest.kind == intType || dest.kind == shortType || dest.kind == charType || dest.kind == longType || dest.kind == int64Type || dest.kind == intPtrType || dest.kind == intSizeType))
+         (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 &&
-         (source.kind == intType || source.kind == shortType || source.kind == charType || source.kind == longType || source.kind == int64Type || source.kind == intPtrType || source.kind == intSizeType))
+      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) && 
+      else if((dest.kind == functionType || (dest.kind == pointerType && dest.type.kind == functionType) || dest.kind == methodType) &&
               ((source.kind == functionType || (source.kind == pointerType && source.type.kind == functionType) || source.kind == methodType)))
       {
          Type paramSource, paramDest;
 
-         if(dest.kind == methodType)     
+         if(dest.kind == methodType)
             owningClassDest = dest.methodClass ? dest.methodClass : dest.method._class;
-         if(source.kind == methodType)   
+         if(source.kind == methodType)
             owningClassSource = source.methodClass ? source.methodClass : source.method._class;
 
          if(dest.kind == pointerType && dest.type.kind == functionType) dest = dest.type;
          if(source.kind == pointerType && source.type.kind == functionType) source = source.type;
-         if(dest.kind == methodType) 
+         if(dest.kind == methodType)
             dest = dest.method.dataType;
-         if(source.kind == methodType) 
+         if(source.kind == methodType)
             source = source.method.dataType;
 
          paramSource = source.params.first;
@@ -3167,8 +3281,8 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
          paramDest = dest.params.first;
          if(paramDest && paramDest.kind == voidType) paramDest = null;
 
-     
-         if((dest.staticMethod || (!dest.thisClass && !owningClassDest)) && 
+
+         if((dest.staticMethod || (!dest.thisClass && !owningClassDest)) &&
             !(source.staticMethod || (!source.thisClass && !owningClassSource)))
          {
             // Source thisClass must be derived from destination thisClass
@@ -3204,7 +3318,7 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
                      if(owningClassDest)
                        Compiler_Error($"%s expected to be derived from method class\n", owningClassDest.fullName);
                      else
-                        Compiler_Error($"overriding class expected to be derived from method class\n");      
+                        Compiler_Error($"overriding class expected to be derived from method class\n");
                      return false;
                   }
                }
@@ -3230,7 +3344,7 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
                      //if(owningClass)
                         Compiler_Error($"%s expected to be derived from method class\n", /*owningClass.name*/ source.thisClass.registered.fullName);
                      //else
-                        //Compiler_Error($"overriding class expected to be derived from method class\n");      
+                        //Compiler_Error($"overriding class expected to be derived from method class\n");
                      return false;
                   }
                }
@@ -3239,14 +3353,14 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
 
 
          // Source return type must be derived from destination return type
-         if(!MatchTypes(source.returnType, dest.returnType, null, null, null, true, true, false, false))
+         if(!MatchTypes(source.returnType, dest.returnType, null, null, null, true, true, false, false, warnConst))
          {
             Compiler_Warning($"incompatible return type for function\n");
             return false;
          }
 
          // Check parameters
-      
+
          for(; paramDest; paramDest = paramDest.next)
          {
             if(!paramSource)
@@ -3295,14 +3409,14 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
                }
 
                // paramDest must be derived from paramSource
-               if(!MatchTypes(paramDestType, paramSourceType, null, null, null, true, true, false, false) && 
-                  (!acceptReversedParams || !MatchTypes(paramSourceType, paramDestType, null, null, null, true, true, false, false)))
+               if(!MatchTypes(paramDestType, paramSourceType, null, null, null, true, true, false, false, warnConst) &&
+                  (!acceptReversedParams || !MatchTypes(paramSourceType, paramDestType, null, null, null, true, true, false, false, warnConst)))
                {
                   char type[1024];
                   type[0] = 0;
                   PrintType(paramDest, type, false, true);
                   Compiler_Warning($"incompatible parameter %s (expected %s)\n", paramSource.name, type);
-                  
+
                   if(paramDestType != paramDest)
                      FreeType(paramDestType);
                   return false;
@@ -3310,7 +3424,7 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
                if(paramDestType != paramDest)
                   FreeType(paramDestType);
             }
-         
+
             paramSource = paramSource.next;
          }
          if(paramSource)
@@ -3324,10 +3438,10 @@ public bool MatchTypes(Type source, Type dest, OldList conversions, Class owning
       {
          return true;
       }
-      else if((dest.kind == pointerType || dest.kind == arrayType) && 
+      else if((dest.kind == pointerType || dest.kind == arrayType) &&
          (source.kind == arrayType || source.kind == pointerType))
       {
-         if(MatchTypes(source.type, dest.type, null, null, null, true, true, false, false))
+         if(MatchTypes(source.type, dest.type, null, null, null, true, true, false, false, warnConst))
             return true;
       }
    }
@@ -3340,7 +3454,7 @@ static void FreeConvert(Conversion convert)
       FreeType(convert.resultType);
 }
 
-bool MatchWithEnums_NameSpace(NameSpace nameSpace, Expression sourceExp, Type dest, 
+bool MatchWithEnums_NameSpace(NameSpace nameSpace, Expression sourceExp, Type dest,
                               char * string, OldList conversions)
 {
    BTNamedLink link;
@@ -3358,7 +3472,7 @@ bool MatchWithEnums_NameSpace(NameSpace nameSpace, Expression sourceExp, Type de
             _class.symbol = FindClass(_class.fullName);
          type._class = _class.symbol;
 
-         if(MatchTypes(type, dest, &converts, null, null, true, false, false, false))
+         if(MatchTypes(type, dest, &converts, null, null, true, false, false, false, false))
          {
             NamedLink value;
             Class enumClass = eSystem_FindClass(privateModule, "enum");
@@ -3391,7 +3505,7 @@ bool MatchWithEnums_NameSpace(NameSpace nameSpace, Expression sourceExp, Type de
                         sourceExp.constant = CopyString(constant);
                         //for(;baseClass.base && baseClass.base.type != systemClass; baseClass = baseClass.base);
                      }
-                  
+
                      while(converts.first)
                      {
                         Conversion convert = converts.first;
@@ -3418,7 +3532,7 @@ bool MatchWithEnums_NameSpace(NameSpace nameSpace, Expression sourceExp, Type de
 public bool ModuleVisibility(Module searchIn, Module searchFor)
 {
    SubModule subModule;
-   
+
    if(searchFor == searchIn)
       return true;
 
@@ -3452,30 +3566,57 @@ bool MatchWithEnums_Module(Module mainModule, Expression sourceExp, Type dest, c
    return false;
 }
 
-bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, bool skipUnitBla)
+bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, bool skipUnitBla, bool warnConst)
 {
-   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)
    {
        if(source._class && source._class.registered && source._class.registered.type == unitClass)
        {
           Class sourceBase, destBase;
-          for(sourceBase = source._class.registered; 
+          for(sourceBase = source._class.registered;
               sourceBase && sourceBase.base && sourceBase.base.type != systemClass;
               sourceBase = sourceBase.base);
-          for(destBase = dest._class.registered; 
+          for(destBase = dest._class.registered;
               destBase && destBase.base && destBase.base.type != systemClass;
               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)
@@ -3485,24 +3626,28 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
       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 && 
+      if(dest.kind != classType && source.kind == classType && source._class && source._class.registered &&
          !strcmp(source._class.registered.fullName, "ecere::com::unichar"))
       {
          FreeType(source);
@@ -3531,13 +3676,13 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
                tempType._class = _class.symbol;
                tempType.truth = dest.truth;
                if(tempType._class)
-                  MatchTypes(tempSource, tempDest, conversions, null, null, true, true, false, false);
+                  MatchTypes(tempSource, tempDest, conversions, null, null, true, true, false, false, warnConst);
 
                // NOTE: To handle bad warnings on int64 vs 32 bit eda::Id incompatibilities
                backupSourceExpType = sourceExp.expType;
                sourceExp.expType = dest; dest.refCount++;
                //sourceExp.expType = MkClassType(_class.fullName);
-               flag = true;            
+               flag = true;
 
                delete tempType;
             }
@@ -3549,13 +3694,13 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
          {
             if(!dest._class.registered.dataType)
                dest._class.registered.dataType = ProcessTypeString(dest._class.registered.dataTypeString, false);
-            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, true, false, false, warnConst))
             {
                FreeType(source);
                FreeType(sourceExp.expType);
                source = sourceExp.expType = MkClassType(dest._class.string);
                source.refCount++;
-               
+
                //source.kind = classType;
                //source._class = dest._class;
             }
@@ -3575,7 +3720,7 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
                FreeType(source);
                source = sourceExp.expType = MkClassType(dest._class.string);
                source.refCount++;
-               
+
                //source.kind = classType;
                //source._class = dest._class;
             }
@@ -3609,7 +3754,7 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
       {
          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)
@@ -3617,14 +3762,14 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
                // Testing this simpler piece of code... (Broke Units Conversion to no unit Logic)
                if(!source._class.registered.dataType)
                   source._class.registered.dataType = ProcessTypeString(source._class.registered.dataTypeString, false);
-               
+
                FreeType(dest);
                dest = MkClassType(source._class.string);
                //if(MatchTypes(source._class.registered.dataType, dest, conversions, null, null, true, false, false))
                //   dest = MkClassType(source._class.string);
             }
             */
-            
+
             if(dest.kind != classType)
             {
                Type tempType { };
@@ -3642,15 +3787,15 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
                tempType.classObjectType = source.classObjectType;
 
                if(tempType._class)
-                  MatchTypes(tempSource, tempDest, conversions, null, null, true, true, false, false);
-               
+                  MatchTypes(tempSource, tempDest, conversions, null, null, true, true, false, false, warnConst);
+
                // PUT THIS BACK TESTING UNITS?
                if(conversions.last)
                {
                   ((Conversion)(conversions.last)).resultType = dest;
                   dest.refCount++;
                }
-               
+
                FreeType(sourceExp.expType);
                sourceExp.expType = MkClassType(_class.fullName);
                sourceExp.expType.truth = source.truth;
@@ -3676,7 +3821,7 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
                dest = MkClassType(source._class.string);
                dest.truth = source.truth;
                dest.classObjectType = source.classObjectType;
-               
+
                FreeType(source);
                source = _class.dataType;
                source.refCount++;
@@ -3688,7 +3833,7 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
 
       if(!flag)
       {
-         if(MatchTypes(source, dest, conversions, null, null, true, true, false, false))
+         if(MatchTypes(source, dest, conversions, null, null, true, true, false, false, warnConst))
          {
             FreeType(source);
             FreeType(dest);
@@ -3712,7 +3857,16 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
       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)
@@ -3750,40 +3904,40 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
          }
 
          // Accept lower precision types for units, since we want to keep the unit type
-         if(dest.kind == doubleType && 
+         if(dest.kind == doubleType &&
             (source.kind == doubleType || source.kind == floatType || dest.kind == int64Type || source.kind == intType || source.kind == shortType ||
-             source.kind == charType))
+             source.kind == charType || source.kind == _BoolType))
          {
             specs = MkListOne(MkSpecifier(DOUBLE));
          }
-         else if(dest.kind == floatType && 
+         else if(dest.kind == floatType &&
             (source.kind == floatType || dest.kind == int64Type || source.kind == intType || source.kind == shortType || source.kind == charType ||
-            source.kind == doubleType))
+            source.kind == _BoolType || source.kind == doubleType))
          {
             specs = MkListOne(MkSpecifier(FLOAT));
          }
          else if(dest.kind == int64Type && (source.kind == int64Type || source.kind == intType || source.kind == shortType || source.kind == charType ||
-            source.kind == floatType || source.kind == doubleType))
+            source.kind == _BoolType || source.kind == floatType || source.kind == doubleType))
          {
             specs = MkList();
             if(!dest.isSigned) ListAdd(specs, MkSpecifier(UNSIGNED));
             ListAdd(specs, MkSpecifier(INT64));
          }
          else if(dest.kind == intType && (source.kind == intType || source.kind == shortType || source.kind == charType ||
-            source.kind == floatType || source.kind == doubleType))
+            source.kind == _BoolType || source.kind == floatType || source.kind == doubleType))
          {
             specs = MkList();
             if(!dest.isSigned) ListAdd(specs, MkSpecifier(UNSIGNED));
             ListAdd(specs, MkSpecifier(INT));
          }
-         else if(dest.kind == shortType && (source.kind == shortType || source.kind == charType || source.kind == intType ||
+         else if(dest.kind == shortType && (source.kind == shortType || source.kind == charType || source.kind == _BoolType || source.kind == intType ||
             source.kind == floatType || source.kind == doubleType))
          {
             specs = MkList();
             if(!dest.isSigned) ListAdd(specs, MkSpecifier(UNSIGNED));
             ListAdd(specs, MkSpecifier(SHORT));
          }
-         else if(dest.kind == charType && (source.kind == charType || source.kind == shortType || source.kind == intType ||
+         else if(dest.kind == charType && (source.kind == charType || source.kind == _BoolType || source.kind == shortType || source.kind == intType ||
             source.kind == floatType || source.kind == doubleType))
          {
             specs = MkList();
@@ -3803,45 +3957,51 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
             return false;
          }
       }
-      else if(dest.kind == doubleType && 
+      else if(dest.kind == doubleType &&
          (source.kind == doubleType || source.kind == floatType || source.kind == int64Type || source.kind == intType || source.kind == enumType || source.kind == shortType ||
-          source.kind == charType))
+          source.kind == _BoolType || source.kind == charType))
       {
          specs = MkListOne(MkSpecifier(DOUBLE));
       }
-      else if(dest.kind == floatType && 
-         (source.kind == floatType || source.kind == enumType || source.kind == int64Type || source.kind == intType || source.kind == shortType || source.kind == charType))
+      else if(dest.kind == floatType &&
+         (source.kind == floatType || source.kind == enumType || source.kind == int64Type || source.kind == intType || source.kind == shortType || source.kind == _BoolType || source.kind == charType))
       {
          specs = MkListOne(MkSpecifier(FLOAT));
       }
-      else if(dest.kind == charType && (source.kind == charType || source.kind == enumType || source.kind == shortType || source.kind == intType) && 
+      else if(dest.kind == _BoolType && (source.kind == _BoolType || source.kind == charType || source.kind == enumType || source.kind == shortType || source.kind == intType) &&
+         (value == 1 || value == 0))
+      {
+         specs = MkList();
+         ListAdd(specs, MkSpecifier(BOOL));
+      }
+      else if(dest.kind == charType && (source.kind == _BoolType || source.kind == charType || source.kind == enumType || source.kind == shortType || source.kind == intType) &&
          (dest.isSigned ? (value >= -128 && value <= 127) : (value >= 0 && value <= 255)))
       {
          specs = MkList();
          if(!dest.isSigned) ListAdd(specs, MkSpecifier(UNSIGNED));
          ListAdd(specs, MkSpecifier(CHAR));
       }
-      else if(dest.kind == shortType && (source.kind == enumType || source.kind == charType || source.kind == shortType || 
+      else if(dest.kind == shortType && (source.kind == enumType || source.kind == _BoolType || source.kind == charType || source.kind == shortType ||
          (source.kind == intType && (dest.isSigned ? (value >= -32768 && value <= 32767) : (value >= 0 && value <= 65535)))))
       {
          specs = MkList();
          if(!dest.isSigned) ListAdd(specs, MkSpecifier(UNSIGNED));
          ListAdd(specs, MkSpecifier(SHORT));
       }
-      else if(dest.kind == intType && (source.kind == enumType || source.kind == shortType || source.kind == charType || source.kind == intType))
+      else if(dest.kind == intType && (source.kind == enumType || source.kind == shortType || source.kind == _BoolType || source.kind == charType || source.kind == intType))
       {
          specs = MkList();
          if(!dest.isSigned) ListAdd(specs, MkSpecifier(UNSIGNED));
          ListAdd(specs, MkSpecifier(INT));
       }
-      else if(dest.kind == int64Type && (source.kind == enumType || source.kind == shortType || source.kind == charType || source.kind == intType || source.kind == int64Type))
+      else if(dest.kind == int64Type && (source.kind == enumType || source.kind == shortType || source.kind == _BoolType || source.kind == charType || source.kind == intType || source.kind == int64Type))
       {
          specs = MkList();
          if(!dest.isSigned) ListAdd(specs, MkSpecifier(UNSIGNED));
          ListAdd(specs, MkSpecifier(INT64));
       }
-      else if(dest.kind == enumType && 
-         (source.kind == int64Type || source.kind == intType || source.kind == shortType || source.kind == charType))
+      else if(dest.kind == enumType &&
+         (source.kind == int64Type || source.kind == intType || source.kind == shortType || source.kind == _BoolType || source.kind == charType))
       {
          specs = MkListOne(MkEnum(MkIdentifier(dest.enumName), null));
       }
@@ -3858,7 +4018,7 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
          return false;
       }
 
-      if(!flag)
+      if(!flag && !sourceExp.opDestType)
       {
          Expression newExp { };
          *newExp = *sourceExp;
@@ -3881,7 +4041,7 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
          }
          else
             sourceExp.cast.exp = newExp;
-         
+
          FreeType(sourceExp.expType);
          sourceExp.expType = null;
          ProcessExpressionType(sourceExp);
@@ -3897,6 +4057,12 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
    }
    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)
       {
@@ -3936,6 +4102,7 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
                            sourceExp.constant = CopyString(constant);
                            //for(;_class.base && _class.base.type != systemClass; _class = _class.base);
                         }
+                        FreeType(dest);
                         return true;
                      }
                   }
@@ -3945,8 +4112,12 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
 
          // 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;
 }
@@ -3966,13 +4137,13 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
    {                                                              \
       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;                                           \
@@ -3983,11 +4154,22 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
       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)                \
    {                                                              \
       exp.type = constantExp;                                    \
-      exp.string = p(o op1.m);                                   \
+      exp.string = p((t)(o op1.m));                                   \
       if(!exp.expType) \
          { exp.expType = op1.type; if(op1.type) op1.type.refCount++; } \
       return true;                                                \
@@ -3996,6 +4178,8 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
 #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, 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) \
@@ -4006,18 +4190,24 @@ bool MatchTypeExpression(Expression sourceExp, Type dest, OldList conversions, b
 #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, 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)
@@ -4031,8 +4221,9 @@ OPERATOR_ALL(BINARY, =, Asign)
 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)
@@ -4069,7 +4260,7 @@ OPERATOR_ALL(BINARY, >=, GrtEqu)
 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) \
@@ -4102,6 +4293,8 @@ OPERATOR_ALL(TERTIARY, ?, Cond)
 
 OPERATOR_TABLE_ALL(int, Int)
 OPERATOR_TABLE_ALL(uint, UInt)
+OPERATOR_TABLE_ALL(int64, Int64)
+OPERATOR_TABLE_ALL(uint64, UInt64)
 OPERATOR_TABLE_ALL(short, Short)
 OPERATOR_TABLE_ALL(ushort, UShort)
 OPERATOR_TABLE_INTTYPES(float, Float)
@@ -4139,15 +4332,15 @@ public void ReadString(char * output,  char * string)
             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;
       }
-      else 
+      else
       {
-         if(ch == '\"') 
+         if(ch == '\"')
             quoted ^= true;
          else if(quoted)
          {
@@ -4161,30 +4354,90 @@ public void ReadString(char * output,  char * string)
    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 = exp.expType;
    if(type)
    {
-      while(type.kind == classType && 
+      while(type.kind == classType &&
          type._class.registered && (type._class.registered.type == bitClass || type._class.registered.type == unitClass || type._class.registered.type == enumClass))
       {
          if(!type._class.registered.dataType)
             type._class.registered.dataType = ProcessTypeString(type._class.registered.dataTypeString, false);
          type = type._class.registered.dataType;
-         
+
+      }
+      if(exp.type == stringExp && op.kind == pointerType)
+      {
+         op.ui64 = (uint64)exp.string;
+         op.kind = pointerType;
+         op.ops = uint64Ops;
       }
-      op.kind = type.kind;
-      op.type = exp.expType;
-      if(exp.isConstant && exp.type == constantExp)
+      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);
@@ -4227,47 +4480,57 @@ public Operand GetOperand(Expression exp)
                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 = intType;
+               op.kind = int64Type;
                break;
             case intPtrType:
                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 = intType;
+               op.kind = int64Type;
                break;
             case intSizeType:
                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 = intType;
+               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...
@@ -4278,8 +4541,8 @@ public Operand GetOperand(Expression exp)
             case classType:
                op.ui64 = _strtoui64(exp.constant, null, 0);
                op.kind = pointerType;
-               op.ops = uintOps;
-               // op.ptrSize = 
+               op.ops = uint64Ops;
+               // op.ptrSize =
                break;
          }
       }
@@ -4287,7 +4550,7 @@ public Operand GetOperand(Expression exp)
    return op;
 }
 
-static void UnusedFunction()
+static __attribute__((unused)) void UnusedFunction()
 {
    int a;
    a.OnGetString(0,0,0);
@@ -4420,7 +4683,11 @@ void PopulateInstance(Instantiation inst)
    Class _class = classSym.registered;
    DataMember dataMember;
    OldList * memberList = MkList();
-   inst.members = MkListOne(MkMembersInitList(memberList));
+   // Added this check and ->Add to prevent memory leaks on bad code
+   if(!inst.members)
+      inst.members = MkListOne(MkMembersInitList(memberList));
+   else
+      inst.members->Add(MkMembersInitList(memberList));
    for(dataMember = _class.membersAndProperties.first; dataMember; dataMember = dataMember.next)
    {
       if(!dataMember.isProperty)
@@ -4466,7 +4733,7 @@ void PopulateInstance(Instantiation inst)
                      exp.type = identifierExp;
                      exp.destType = MkClassType(_class.fullName);
                      ProcessExpressionType(exp);
-                  }                     
+                  }
                }
                if(_class.type == enumClass || _class.type == unitClass || _class.type == bitClass)
                {
@@ -4533,13 +4800,17 @@ void ComputeInstantiation(Expression exp)
 
    if(_class && (_class.type == structClass || _class.type == normalClass || _class.type == noHeadClass ))
    {
-      // Don't recompute the instantiation... 
+      // Don't recompute the instantiation...
       // Non Simple classes will have become constants by now
-      if(inst.data) 
+      if(inst.data)
          return;
 
       if(_class.type == normalClass || _class.type == noHeadClass)
+      {
          inst.data = (byte *)eInstance_New(_class);
+         if(_class.type == normalClass)
+            ((Instance)inst.data)._refCount++;
+      }
       else
          inst.data = new0 byte[_class.structSize];
    }
@@ -4575,9 +4846,13 @@ void ComputeInstantiation(Expression exp)
                            else
                            {
                               dataMember = curMember;
-                              
+
                               // CHANGED THIS HERE
                               eClass_FindDataMemberAndOffset(_class, dataMember.name, &dataMemberOffset, privateModule, null, null);
+
+                              // 2013/17/29 -- It seems that this was missing here!
+                              if(_class.type == normalClass)
+                                 dataMemberOffset += _class.base.structSize;
                               // dataMemberOffset = dataMember.offset;
                            }
                            found = true;
@@ -4630,7 +4905,7 @@ void ComputeInstantiation(Expression exp)
                         {
                            if(!dataMember.dataType)
                               dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
-                           
+
                            type = dataMember.dataType;
                         }
 
@@ -4649,7 +4924,7 @@ void ComputeInstantiation(Expression exp)
                                     type = prop.dataType;
                                  else
                                  {
-                                    dataMember = eClass_FindDataMemberAndOffset(type._class.registered, 
+                                    dataMember = eClass_FindDataMemberAndOffset(type._class.registered,
                                        ident.string, &dataMemberOffset, privateModule, null, null);
                                     if(dataMember)
                                        type = dataMember.dataType;
@@ -4693,7 +4968,7 @@ void ComputeInstantiation(Expression exp)
                            if(dataMember)
                            {
                               void * ptr = inst.data + dataMemberOffset;
-                              
+
                               if(value.type == constantExp)
                               {
                                  switch(type.kind)
@@ -4868,69 +5143,29 @@ void ComputeInstantiation(Expression exp)
                            {
                               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._class.registered.dataType = ProcessTypeString(type._class.registered.dataTypeString, false);
                                  type = type._class.registered.dataType;
                               }
-
                               switch(type.kind)
                               {
-                                 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 _BoolType:
+                                 case charType:       { byte v; type.isSigned ? GetChar(value, (char *)&v) : GetUChar(value, &v); part = (uint64)v; break; }
+                                 case shortType:      { uint16 v; type.isSigned ? GetShort(value, (uint16 *)&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, (uint *)&v) : GetUInt(value, &v); part = (uint64)v; break; }
+                                 case int64Type:      { uint64 v; type.isSigned ? GetInt64(value, (uint64 *)&v) : GetUInt64(value, &v); part = (uint64)v; break; }
+                                 case intPtrType:     { uintptr v; type.isSigned ? GetIntPtr(value, (uintptr *)&v) : GetUIntPtr(value, &v); part = (uint64)v; break; }
+                                 case intSizeType:    { uintsize v; type.isSigned ? GetIntSize(value, (uintsize *)&v) : GetUIntSize(value, &v); part = (uint64)v; break; }
                               }
+                              bits |= part << bitMember.pos;
                            }
                         }
                      }
@@ -4941,7 +5176,7 @@ void ComputeInstantiation(Expression exp)
                            ComputeExpression(member.initializer.exp);
                            exp.constant = member.initializer.exp.constant;
                            exp.type = constantExp;
-                           
+
                            member.initializer.exp.constant = null;
                         }
                      }
@@ -4963,6 +5198,57 @@ void ComputeInstantiation(Expression exp)
    }
 }
 
+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)
@@ -5008,6 +5294,13 @@ void CallOperator(Expression exp, Expression exp1, Expression exp2, Operand op1,
       }
       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
@@ -5117,7 +5410,46 @@ void ComputeExpression(Expression exp)
 
          // 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);
@@ -5131,7 +5463,7 @@ void ComputeExpression(Expression exp)
                if(op2.type) op2.type.refCount++;
             }
          }
-         else 
+         else
          {
             exp1 = exp.op.exp2;
             op1 = GetOperand(exp1);
@@ -5190,7 +5522,7 @@ void ComputeExpression(Expression exp)
             case '-':
                if(exp.op.exp1)
                {
-                  if(op1.ops.Sub) 
+                  if(op1.ops.Sub)
                   {
                      FreeExpContents(exp);
                      op1.ops.Sub(exp, op1, op2);
@@ -5198,7 +5530,7 @@ void ComputeExpression(Expression exp)
                }
                else
                {
-                  if(op1.ops.Neg) 
+                  if(op1.ops.Neg)
                   {
                      FreeExpContents(exp);
                      op1.ops.Neg(exp, op1);
@@ -5221,7 +5553,7 @@ void ComputeExpression(Expression exp)
                break;
             // Binary only operators
             case '/':
-               if(op1.ops.Div) 
+               if(op1.ops.Div)
                {
                   FreeExpContents(exp);
                   op1.ops.Div(exp, op1, op2);
@@ -5299,14 +5631,14 @@ void ComputeExpression(Expression exp)
                }
                break;
             case '|':
-               if(op1.ops.BitOr) 
+               if(op1.ops.BitOr)
                {
                   FreeExpContents(exp);
                   op1.ops.BitOr(exp, op1, op2);
                }
                break;
             case '^':
-               if(op1.ops.BitXor) 
+               if(op1.ops.BitXor)
                {
                   FreeExpContents(exp);
                   op1.ops.BitXor(exp, op1, op2);
@@ -5337,11 +5669,15 @@ void ComputeExpression(Expression exp)
             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;
             }
@@ -5417,7 +5753,7 @@ void ComputeExpression(Expression exp)
                _class = classSym ? classSym.registered : null;
                prop = eClass_FindProperty(_class, convertTo.fullName, privateModule);
             }
-      
+
             if(prop)
             {
                if(prop.compiled)
@@ -5452,7 +5788,7 @@ void ComputeExpression(Expression exp)
                            double value;
                            double (*Get)(double);
                            GetDouble(exp.member.exp, &value);
-                     
+
                            if(convertTo)
                               Get = (void *)prop.Set;
                            else
@@ -5489,7 +5825,7 @@ void ComputeExpression(Expression exp)
                                     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);
@@ -5504,10 +5840,10 @@ void ComputeExpression(Expression exp)
 
                                  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;
-                              
+
                                  GetInt(value, &intValue);
 
                                  Set(exp.instance.data, intValue);
@@ -5524,7 +5860,7 @@ void ComputeExpression(Expression exp)
                                  exp.instance._class = MkSpecifierName/*MkClassName*/(_class.fullName);
                                  exp.instance.loc = exp.loc;
                                  exp.type = instanceExp;
-                              
+
                                  GetInt64(value, &intValue);
 
                                  Set(exp.instance.data, intValue);
@@ -5539,10 +5875,10 @@ void ComputeExpression(Expression exp)
 
                                  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;
-                              
+
                                  GetIntPtr(value, &intValue);
 
                                  Set(exp.instance.data, intValue);
@@ -5557,7 +5893,7 @@ void ComputeExpression(Expression exp)
 
                                  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;
 
@@ -5567,20 +5903,37 @@ void ComputeExpression(Expression exp)
                                  PopulateInstance(exp.instance);
                                  break;
                               }
-                              case doubleType:
+                              case floatType:
                               {
-                                 double doubleValue;
-                                 void (*Set)(void *, double) = (void *)prop.Set;
+                                 float floatValue;
+                                 void (*Set)(void *, float) = (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;
-                              
-                                 GetDouble(value, &doubleValue);
 
-                                 Set(exp.instance.data, doubleValue);
+                                 GetFloat(value, &floatValue);
+
+                                 Set(exp.instance.data, floatValue);
+                                 PopulateInstance(exp.instance);
+                                 break;
+                              }
+                              case doubleType:
+                              {
+                                 double doubleValue;
+                                 void (*Set)(void *, double) = (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;
+
+                                 GetDouble(value, &doubleValue);
+
+                                 Set(exp.instance.data, doubleValue);
                                  PopulateInstance(exp.instance);
                                  break;
                               }
@@ -5634,7 +5987,7 @@ void ComputeExpression(Expression exp)
 
                                     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;
@@ -5666,7 +6019,7 @@ void ComputeExpression(Expression exp)
 
                                     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;
@@ -5724,7 +6077,7 @@ void ComputeExpression(Expression exp)
          Type type = ProcessType(exp.typeName.qualifiers, exp.typeName.declarator);
          FreeExpContents(exp);
          exp.constant = PrintUInt(ComputeTypeSize(type));
-         exp.type = constantExp;         
+         exp.type = constantExp;
          FreeType(type);
          break;
       }
@@ -5746,6 +6099,8 @@ void ComputeExpression(Expression exp)
                FullClassNameCat(className, classSym.string, true);
                MangleClassName(className);
 
+               DeclareClass(classSym, className);
+
                FreeExpContents(exp);
                exp.type = pointerExp;
                exp.member.exp = MkExpIdentifier(MkIdentifier(className));
@@ -5781,133 +6136,162 @@ void ComputeExpression(Expression exp)
                   type = _class.dataType;
                }
             }
-            
+
             switch(type.kind)
             {
+               case _BoolType:
                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;
                }
             }
@@ -5940,11 +6324,11 @@ void ComputeExpression(Expression exp)
          if(op2.type) FreeType(op2.type);
          if(op3.type) FreeType(op3.type);
          break;
-      }  
+      }
    }
 }
 
-static bool CheckExpressionType(Expression exp, Type destType, bool skipUnitBla)
+static bool CheckExpressionType(Expression exp, Type destType, bool skipUnitBla, bool warnConst)
 {
    bool result = true;
    if(destType)
@@ -5955,7 +6339,7 @@ static bool CheckExpressionType(Expression exp, Type destType, bool skipUnitBla)
       if(destType.kind == voidType)
          return false;
 
-      if(!MatchTypeExpression(exp, destType, &converts, skipUnitBla))
+      if(!MatchTypeExpression(exp, destType, &converts, skipUnitBla, warnConst))
          result = false;
       if(converts.count)
       {
@@ -5970,6 +6354,8 @@ static bool CheckExpressionType(Expression exp, Type destType, bool skipUnitBla)
 
                // TODO: Check this...
                *newExp = *exp;
+               newExp.prev = null;
+               newExp.next = null;
                newExp.destType = null;
 
                if(convert.isGet)
@@ -5992,7 +6378,7 @@ static bool CheckExpressionType(Expression exp, Type destType, bool skipUnitBla)
                }
                else
                {
-               
+
                   /*if(exp.isConstant)
                   {
                      // Color { ColorRGB = [exp] };
@@ -6064,13 +6450,13 @@ static bool CheckExpressionType(Expression exp, Type destType, bool skipUnitBla)
 
       if(!result && exp.expType && converts.count)      // TO TEST: Added converts.count here to avoid a double warning with function type
       {
-         result = MatchTypes(exp.expType, exp.destType, null, null, null, true, true, false, false);
+         result = MatchTypes(exp.expType, exp.destType, null, null, null, true, true, false, false, warnConst);
       }
       if(!result && exp.expType && exp.destType)
       {
-         if((exp.destType.kind == classType && exp.expType.kind == pointerType && 
+         if((exp.destType.kind == classType && exp.expType.kind == pointerType &&
              exp.expType.type.kind == classType && exp.expType.type._class == exp.destType._class && exp.destType._class.registered && exp.destType._class.registered.type == structClass) ||
-            (exp.expType.kind == classType && exp.destType.kind == pointerType && 
+            (exp.expType.kind == classType && exp.destType.kind == pointerType &&
             exp.destType.type.kind == classType && exp.destType.type._class == exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type == structClass))
             result = true;
       }
@@ -6084,7 +6470,6 @@ void CheckTemplateTypes(Expression exp)
    if(exp.destType && exp.destType.passAsTemplate && exp.expType && exp.expType.kind != templateType && !exp.expType.passAsTemplate)
    {
       Expression newExp { };
-      Statement compound;
       Context context;
       *newExp = *exp;
       if(exp.destType) exp.destType.refCount++;
@@ -6110,7 +6495,7 @@ void CheckTemplateTypes(Expression exp)
                OldList * unionDefs = MkList();
                OldList * statements = MkList();
                context = PushContext();
-               ListAdd(unionDefs, MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifier(DOUBLE)), MkListOne(MkDeclaratorIdentifier(MkIdentifier("d"))), null))); 
+               ListAdd(unionDefs, MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifier(DOUBLE)), MkListOne(MkDeclaratorIdentifier(MkIdentifier("d"))), null)));
                ListAdd(unionDefs, MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifierName("uint64")), MkListOne(MkDeclaratorIdentifier(MkIdentifier("i"))), null)));
                specs = MkListOne(MkStructOrUnion(unionSpecifier, null, unionDefs ));
                exp.type = extensionCompoundExp;
@@ -6157,7 +6542,7 @@ void CheckTemplateTypes(Expression exp)
                OldList * unionDefs = MkList();
                OldList * statements = MkList();
                context = PushContext();
-               ListAdd(unionDefs, MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifier(DOUBLE)), MkListOne(MkDeclaratorIdentifier(MkIdentifier("d"))), null))); 
+               ListAdd(unionDefs, MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifier(DOUBLE)), MkListOne(MkDeclaratorIdentifier(MkIdentifier("d"))), null)));
                ListAdd(unionDefs, MkClassDefDeclaration(MkStructDeclaration(MkListOne(MkSpecifierName("uint64")), MkListOne(MkDeclaratorIdentifier(MkIdentifier("i"))), null)));
                specs = MkListOne(MkStructOrUnion(unionSpecifier, null, unionDefs ));
                exp.type = extensionCompoundExp;
@@ -6216,7 +6601,7 @@ void CheckTemplateTypes(Expression exp)
                typeString[0] = '\0';
                PrintType(exp.expType, typeString, false, false);
                decl = SpecDeclFromString(typeString, specs, null);
-               
+
                exp.type = castExp;
                //exp.cast.typeName = MkTypeName(MkListOne(MkSpecifierName("uint64")), null);
                exp.cast.typeName = MkTypeName(specs, decl);
@@ -6233,7 +6618,7 @@ void CheckTemplateTypes(Expression exp)
 //    - Tree of all symbols within (stored without namespace)
 //    - Tree of sub-namespaces
 
-static Symbol ScanWithNameSpace(BinaryTree tree, char * nameSpace, char * name)
+static Symbol ScanWithNameSpace(BinaryTree tree, const char * nameSpace, const char * name)
 {
    int nsLen = strlen(nameSpace);
    Symbol symbol;
@@ -6263,11 +6648,11 @@ static Symbol ScanWithNameSpace(BinaryTree tree, char * nameSpace, char * name)
    return null;
 }
 
-static Symbol FindWithNameSpace(BinaryTree tree, char * name)
+static Symbol FindWithNameSpace(BinaryTree tree, const char * name)
 {
    int c;
    char nameSpace[1024];
-   char * namePart;
+   const char * namePart;
    bool gotColon = false;
 
    nameSpace[0] = '\0';
@@ -6312,7 +6697,7 @@ static Symbol FindWithNameSpace(BinaryTree tree, char * name)
 
 static void ProcessDeclaration(Declaration decl);
 
-/*static */Symbol FindSymbol(char * name, Context startContext, Context endContext, bool isStruct, bool globalNameSpace)
+/*static */Symbol FindSymbol(const char * name, Context startContext, Context endContext, bool isStruct, bool globalNameSpace)
 {
 #ifdef _DEBUG
    //Time startTime = GetTime();
@@ -6353,7 +6738,7 @@ static void ProcessDeclaration(Declaration decl);
 
          // Modified this recently...
          Context tmpContext = curContext;
-         curContext = null;         
+         curContext = null;
          symbol.pointerExternal = MkExternalDeclaration(MkDeclaration(CopyList(function.specifiers, CopySpecifier), MkListOne(MkInitDeclarator(CopyDeclarator(function.declarator), null))));
          curContext = tmpContext;
 
@@ -6384,7 +6769,7 @@ static void GetTypeSpecs(Type type, OldList * specs)
    if(!type.isSigned && type.kind != intPtrType && type.kind != intSizeType) ListAdd(specs, MkSpecifier(UNSIGNED));
    switch(type.kind)
    {
-      case classType: 
+      case classType:
       {
          if(type._class.registered)
          {
@@ -6397,11 +6782,12 @@ static void GetTypeSpecs(Type type, OldList * specs)
       case doubleType: ListAdd(specs, MkSpecifier(DOUBLE)); break;
       case floatType: ListAdd(specs, MkSpecifier(FLOAT)); break;
       case charType: ListAdd(specs, MkSpecifier(CHAR)); break;
+      case _BoolType: ListAdd(specs, MkSpecifier(_BOOL)); break;
       case shortType: ListAdd(specs, MkSpecifier(SHORT)); break;
       case int64Type: ListAdd(specs, MkSpecifier(INT64)); break;
       case intPtrType: ListAdd(specs, MkSpecifierName(type.isSigned ? "intptr" : "uintptr")); break;
       case intSizeType: ListAdd(specs, MkSpecifierName(type.isSigned ? "intsize" : "uintsize")); break;
-      case intType: 
+      case intType:
       default:
          ListAdd(specs, MkSpecifier(INT)); break;
    }
@@ -6453,6 +6839,7 @@ static void PrintTypeSpecs(Type type, char * string, bool fullName, bool printCo
          case intPtrType:  strcat(string, type.isSigned ? "intptr" : "uintptr"); break;
          case intSizeType:  strcat(string, type.isSigned ? "intsize" : "uintsize"); break;
          case charType: strcat(string, type.isSigned ? "char" : "byte"); break;
+         case _BoolType: strcat(string, "_Bool"); break;
          case shortType: strcat(string, type.isSigned ? "short" : "uint16"); break;
          case floatType: strcat(string, "float"); break;
          case doubleType: strcat(string, "double"); break;
@@ -6507,7 +6894,7 @@ static void PrintTypeSpecs(Type type, char * string, bool fullName, bool printCo
          case subClassType:
             strcat(string, "subclass(");
             strcat(string, type._class ? type._class.string : "int");
-            strcat(string, ")");                  
+            strcat(string, ")");
             break;
          case templateType:
             strcat(string, type.templateParameter.identifier.string);
@@ -6693,8 +7080,12 @@ Type FindMemberAndOffset(Type type, char * string, uint * offset)
    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);
@@ -6890,6 +7281,12 @@ void ReplaceExpContents(Expression checkedExp, Expression newExp)
 void ApplyAnyObjectLogic(Expression e)
 {
    Type destType = /*(e.destType && e.destType.kind == ellipsisType) ? ellipsisDestType : */e.destType;
+#ifdef _DEBUG
+   char debugExpString[4096];
+   debugExpString[0] = '\0';
+   PrintExpression(e, debugExpString);
+#endif
+
    if(destType && (/*destType.classObjectType == ClassObjectType::typedObject || */destType.classObjectType == anyObject))
    {
       //if(e.destType && e.destType.kind == ellipsisType) usedEllipsis = true;
@@ -6918,8 +7315,8 @@ void ApplyAnyObjectLogic(Expression e)
             if(classSym) _class = classSym.registered;
          }
 
-         if((_class && (_class.type == enumClass || _class.type == unitClass || _class.type == bitClass || _class.type == systemClass) && strcmp(_class.fullName, "class") && strcmp(_class.fullName, "ecere::com::Class")) || // Patched so that class isn't considered SYSTEM...
-            (!e.expType.classObjectType && (((type.kind != pointerType && type.kind != subClassType && (type.kind != classType || !type._class || !type._class.registered || type._class.registered.type == structClass))) ||
+         if((_class && (_class.type == enumClass || _class.type == unitClass || _class.type == bitClass || _class.type == systemClass) && strcmp(_class.fullName, "class") && strcmp(_class.fullName, "uintptr") && strcmp(_class.fullName, "intptr")) || // Patched so that class isn't considered SYSTEM...
+            (!e.expType.classObjectType && (((type.kind != pointerType && type.kind != intPtrType && type.kind != subClassType && (type.kind != classType || !type._class || !type._class.registered || type._class.registered.type == structClass))) ||
             destType.byReference)))
          {
             if(!_class || strcmp(_class.fullName, "char *"))     // TESTING THIS WITH NEW String class...
@@ -6946,7 +7343,7 @@ void ApplyAnyObjectLogic(Expression e)
                   newExp = checkedExp.op.exp2;
                   checkedExp.op.exp2 = null;
                   FreeExpContents(checkedExp);
-                  
+
                   if(e.expType && e.expType.passAsTemplate)
                   {
                      char size[100];
@@ -6962,7 +7359,7 @@ void ApplyAnyObjectLogic(Expression e)
                }
                else if(!e.byReference || (_class && _class.type == noHeadClass))     // TESTING THIS HERE...
                {
-                  Expression checkedExp, newExp;
+                  Expression checkedExp; //, newExp;
 
                   {
                      // TODO: Move code from debugTools.ec for hasAddress flag, this is just temporary
@@ -6995,13 +7392,13 @@ void ApplyAnyObjectLogic(Expression e)
                         newExp.destType = ProcessType(specs, decl);
 
                         curContext = context;
-                        e.type = extensionCompoundExp;
 
                         // We need a current compound for this
                         if(curCompound)
                         {
                            char name[100];
                            OldList * stmts = MkList();
+                           e.type = extensionCompoundExp;
                            sprintf(name, "__internalValue%03X", internalValueCounter++);
                            if(!curCompound.compound.declarations)
                               curCompound.compound.declarations = MkList();
@@ -7016,11 +7413,11 @@ void ApplyAnyObjectLogic(Expression e)
                         /*
                         e.compound = MkCompoundStmt(
                            MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(
-                              MkDeclaratorIdentifier(MkIdentifier("__internalValue")), MkInitializerAssignment(newExp))))), 
+                              MkDeclaratorIdentifier(MkIdentifier("__internalValue")), MkInitializerAssignment(newExp))))),
 
                            MkListOne(MkExpressionStmt(MkListOne(MkExpIdentifier(MkIdentifier("__internalValue"))))));
                         */
-                        
+
                         {
                            Type type = e.destType;
                            e.destType = { };
@@ -7076,7 +7473,7 @@ void ApplyAnyObjectLogic(Expression e)
       // FixReference(e, true);
    }
 //#if 0
-   if((!destType || destType.kind == ellipsisType || destType.kind == voidType) && e.expType && (e.expType.classObjectType == anyObject || e.expType.classObjectType == typedObject) && 
+   if((!destType || destType.kind == ellipsisType || destType.kind == voidType) && e.expType && (e.expType.classObjectType == anyObject || e.expType.classObjectType == typedObject) &&
       (e.expType.byReference || (e.expType.kind == classType && e.expType._class && e.expType._class.registered &&
          (e.expType._class.registered.type == bitClass || e.expType._class.registered.type == enumClass || e.expType._class.registered.type == unitClass ) )))
    {
@@ -7121,11 +7518,11 @@ void ApplyAnyObjectLogic(Expression e)
 // TOFIX: Try this for a nice IDE crash!
 //#endif
    // The other way around
-   else 
+   else
 //#endif
-   if(destType && e.expType && 
+   if(destType && e.expType &&
          //e.expType.kind == classType && e.expType._class && e.expType._class.registered && !strcmp(e.expType._class.registered.name, "class") &&
-         (e.expType.classObjectType == anyObject || e.expType.classObjectType == typedObject) && 
+         (e.expType.classObjectType == anyObject || e.expType.classObjectType == typedObject) &&
          !destType.classObjectType && /*(destType.kind != pointerType || !destType.type || destType.type.kind != voidType) &&*/ destType.kind != voidType)
    {
       if(destType.kind == ellipsisType)
@@ -7146,7 +7543,7 @@ void ApplyAnyObjectLogic(Expression e)
          if(e.expType.kind == classType && e.expType._class && e.expType._class.registered && strcmp(e.expType._class.registered.name, "class"))
             type = e.expType;
          else
-            type = destType;            
+            type = destType;
 
          backupClassObjectType = type.classObjectType;
          backupByReference = type.byReference;
@@ -7166,16 +7563,21 @@ void ApplyAnyObjectLogic(Expression e)
          thisExp.next = null;
          e.Clear();
 
-         if( ( type.kind == classType && type._class && type._class.registered && strcmp(type._class.registered.fullName, "ecere::com::Instance") &&
-                   (type._class.registered.type == systemClass || type._class.registered.type == bitClass || 
+         if( ( type.kind == classType && type._class && type._class.registered &&
+                   (type._class.registered.type == systemClass || type._class.registered.type == bitClass ||
                     type._class.registered.type == enumClass || type._class.registered.type == unitClass) ) ||
-             (type.kind != pointerType && type.kind != arrayType && type.kind != classType) ||
+             (type.kind != pointerType && type.kind != intPtrType && type.kind != arrayType && type.kind != classType) ||
              (!destType.byReference && byReference && (destType.kind != pointerType || type.kind != pointerType)))
          {
             e.type = opExp;
             e.op.op = '*';
             e.op.exp1 = null;
             e.op.exp2 = MkExpCast(MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl)), thisExp);
+
+            e.expType = { };
+            CopyTypeInto(e.expType, type);
+            e.expType.byReference = false;
+            e.expType.refCount = 1;
          }
          else
          {
@@ -7183,30 +7585,97 @@ void ApplyAnyObjectLogic(Expression e)
             e.cast.typeName = MkTypeName(specs, decl);
             e.cast.exp = thisExp;
             e.byReference = true;
+            e.expType = type;
+            type.refCount++;
          }
-         e.expType = type;
          e.destType = destType;
-         type.refCount++;
          destType.refCount++;
       }
    }
 }
 
+void ApplyLocation(Expression exp, Location loc)
+{
+   exp.loc = loc;
+   switch(exp.type)
+   {
+      case opExp:
+         if(exp.op.exp1) ApplyLocation(exp.op.exp1, loc);
+         if(exp.op.exp2) ApplyLocation(exp.op.exp2, loc);
+         break;
+      case bracketsExp:
+         if(exp.list)
+         {
+            Expression e;
+            for(e = exp.list->first; e; e = e.next)
+               ApplyLocation(e, loc);
+         }
+         break;
+      case indexExp:
+         if(exp.index.index)
+         {
+            Expression e;
+            for(e = exp.index.index->first; e; e = e.next)
+               ApplyLocation(e, loc);
+         }
+         if(exp.index.exp)
+            ApplyLocation(exp.index.exp, loc);
+         break;
+      case callExp:
+         if(exp.call.arguments)
+         {
+            Expression arg;
+            for(arg = exp.call.arguments->first; arg; arg = arg.next)
+               ApplyLocation(arg, loc);
+         }
+         if(exp.call.exp)
+            ApplyLocation(exp.call.exp, loc);
+         break;
+      case memberExp:
+      case pointerExp:
+         if(exp.member.exp)
+            ApplyLocation(exp.member.exp, loc);
+         break;
+      case castExp:
+         if(exp.cast.exp)
+            ApplyLocation(exp.cast.exp, loc);
+         break;
+      case conditionExp:
+         if(exp.cond.exp)
+         {
+            Expression e;
+            for(e = exp.cond.exp->first; e; e = e.next)
+               ApplyLocation(e, loc);
+         }
+         if(exp.cond.cond)
+            ApplyLocation(exp.cond.cond, loc);
+         if(exp.cond.elseExp)
+            ApplyLocation(exp.cond.elseExp, loc);
+         break;
+      case vaArgExp:
+         if(exp.vaArg.exp)
+            ApplyLocation(exp.vaArg.exp, loc);
+         break;
+      default:
+         break;
+   }
+}
+
 void ProcessExpressionType(Expression exp)
 {
    bool unresolved = false;
    Location oldyylloc = yylloc;
    bool notByReference = false;
-#ifdef _DEBUG   
+#ifdef _DEBUG
    char debugExpString[4096];
    debugExpString[0] = '\0';
    PrintExpression(exp, debugExpString);
 #endif
-   if(!exp || exp.expType) 
+   if(!exp || exp.expType)
       return;
 
    //eSystem_Logf("%s\n", expString);
-   
+
    // Testing this here
    yylloc = exp.loc;
    switch(exp.type)
@@ -7214,7 +7683,7 @@ void ProcessExpressionType(Expression exp)
       case identifierExp:
       {
          Identifier id = exp.identifier;
-         if(!id) return;
+         if(!id || !topContext) return;
 
          // DOING THIS LATER NOW...
          if(id._class && id._class.name)
@@ -7255,7 +7724,7 @@ void ProcessExpressionType(Expression exp)
             // Enums should be resolved here (Special pass in opExp to fix identifiers not seen as enum on the first pass)
             if(!symbol/* && exp.destType*/)
             {
-               if(exp.destType && CheckExpressionType(exp, exp.destType, false))
+               if(exp.destType && CheckExpressionType(exp, exp.destType, false, false))
                   break;
                else
                {
@@ -7301,19 +7770,22 @@ void ProcessExpressionType(Expression exp)
                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;
 
                // TOCHECK: Why was !strcmp(id.string, "this") commented out?
                if(symbol.isParam || !strcmp(id.string, "this"))
                {
-                  if(_class && _class.type == structClass)
+                  if(_class && _class.type == structClass && !type.declaredWithStruct)
                      exp.byReference = true;
-                  
+
                   //TESTING COMMENTING THIS OUT IN FAVOR OF ApplyAnyObjectLogic
-                  /*if(type && _class && (type.classObjectType == typedObject || type.classObjectType == anyObject) && 
-                     ((_class.type == unitClass || _class.type == enumClass || _class.type == bitClass) || 
+                  /*if(type && _class && (type.classObjectType == typedObject || type.classObjectType == anyObject) &&
+                     ((_class.type == unitClass || _class.type == enumClass || _class.type == bitClass) ||
                      (type.byReference && (_class.type == normalClass || _class.type == noHeadClass))))
                   {
                      Identifier id = exp.identifier;
@@ -7330,7 +7802,7 @@ void ProcessExpressionType(Expression exp)
                      exp.list = MkListOne(MkExpOp(null, '*', MkExpIdentifier(exp.identifier)));
                      ((Expression)exp.list->first).op.exp2.expType = exp.expType;
                      exp.expType = null;
-                     ProcessExpressionType(exp);                     
+                     ProcessExpressionType(exp);
                   }
                   else if(symbol.isIterator != 4)
                   {
@@ -7369,7 +7841,9 @@ void ProcessExpressionType(Expression exp)
                   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);
@@ -7379,6 +7853,8 @@ void ProcessExpressionType(Expression exp)
                      resetScanner();
                      expression_yyparse();
                      delete fileInput;
+                     if(backInput)
+                        fileInput = backInput;
 
                      yylloc = backupYylloc;
 
@@ -7387,7 +7863,7 @@ void ProcessExpressionType(Expression exp)
                         FreeIdentifier(id);
                         exp.type = bracketsExp;
                         exp.list = MkListOne(parsedExpression);
-                        parsedExpression.loc = yylloc;
+                        ApplyLocation(parsedExpression, yylloc);
                         ProcessExpressionType(exp);
                         definedExpStackPos--;
                         return;
@@ -7488,6 +7964,7 @@ void ProcessExpressionType(Expression exp)
          //_class = classSym ? classSym.registered : null;
 
          ProcessInstantiationType(exp.instance);
+
          exp.isConstant = exp.instance.isConstant;
 
          /*
@@ -7508,16 +7985,17 @@ void ProcessExpressionType(Expression exp)
          if(exp.instance._class)
          {
             exp.expType = MkClassType(exp.instance._class.name);
-            /*if(exp.expType._class && exp.expType._class.registered && 
+            /*if(exp.expType._class && exp.expType._class.registered &&
                (exp.expType._class.registered.type == normalClass || exp.expType._class.registered.type == noHeadClass))
                exp.expType.byReference = true;*/
-         }         
+         }
          break;
       }
       case constantExp:
       {
          if(!exp.expType)
          {
+            char * constant = exp.constant;
             Type type
             {
                refCount = 1;
@@ -7525,14 +8003,14 @@ void ProcessExpressionType(Expression exp)
             };
             exp.expType = type;
 
-            if(exp.constant[0] == '\'')
+            if(constant[0] == '\'')
             {
-               if((int)((byte *)exp.constant)[1] > 127)
+               if((int)((byte *)constant)[1] > 127)
                {
                   int nb;
-                  unichar ch = UTF8GetChar(exp.constant + 1, &nb);
-                  if(nb < 2) ch = exp.constant[1];
-                  delete exp.constant;
+                  unichar ch = UTF8GetChar(constant + 1, &nb);
+                  if(nb < 2) ch = constant[1];
+                  delete constant;
                   exp.constant = PrintUInt(ch);
                   // type.kind = (ch > 0xFFFF) ? intType : shortType;
                   type.kind = classType; //(ch > 0xFFFF) ? intType : shortType;
@@ -7546,28 +8024,67 @@ void ProcessExpressionType(Expression exp)
                   type.isSigned = true;
                }
             }
-            else if(strchr(exp.constant, '.'))
-            {
-               char ch = exp.constant[strlen(exp.constant)-1];
-               if(ch == 'f')
-                  type.kind = floatType;
-               else
-                  type.kind = doubleType;
-               type.isSigned = true;
-            }
             else
             {
-               if(exp.constant[0] == '0' && exp.constant[1])
-                  type.isSigned = false;
-               else if(strchr(exp.constant, 'L') || strchr(exp.constant, 'l'))
-                  type.isSigned = false;
-               else if(strtoll(exp.constant, null, 0) > MAXINT)
-                  type.isSigned = false;
+               char * dot = strchr(constant, '.');
+               bool isHex = (constant[0] == '0' && (constant[1] == 'x' || constant[1] == 'X'));
+               char * exponent;
+               if(isHex)
+               {
+                  exponent = strchr(constant, 'p');
+                  if(!exponent) exponent = strchr(constant, 'P');
+               }
                else
+               {
+                  exponent = strchr(constant, 'e');
+                  if(!exponent) exponent = strchr(constant, 'E');
+               }
+
+               if(dot || exponent)
+               {
+                  if(strchr(constant, 'f') || strchr(constant, 'F'))
+                     type.kind = floatType;
+                  else
+                     type.kind = doubleType;
                   type.isSigned = true;
-               type.kind = intType;
+               }
+               else
+               {
+                  bool isSigned = constant[0] == '-';
+                  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)
+                        is64Bit = true;
+                  }
+                  else
+                  {
+                     if(ui64 > MAXINT)
+                     {
+                        if(ui64 > MAXDWORD)
+                        {
+                           is64Bit = true;
+                           if(ui64 <= MAXINT64 && (constant[0] != '0' || !constant[1]))
+                              isSigned = true;
+                        }
+                     }
+                     else if(constant[0] != '0' || !constant[1])
+                        isSigned = true;
+                  }
+                  type.kind = is64Bit ? int64Type : intType;
+                  type.isSigned = isSigned;
+               }
             }
             exp.isConstant = true;
+            if(exp.destType && exp.destType.kind == doubleType)
+               type.kind = doubleType;
+            else if(exp.destType && exp.destType.kind == floatType)
+               type.kind = floatType;
+            else if(exp.destType && exp.destType.kind == int64Type)
+               type.kind = int64Type;
          }
          break;
       }
@@ -7583,6 +8100,7 @@ void ProcessExpressionType(Expression exp)
                refCount = 1;
                kind = charType;
                constant = true;
+               isSigned = true;
             }
          };
          break;
@@ -7617,6 +8135,7 @@ void ProcessExpressionType(Expression exp)
          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
@@ -7628,7 +8147,7 @@ void ProcessExpressionType(Expression exp)
          switch(exp.op.op)
          {
             // Assignment Operators
-            case '=': 
+            case '=':
             case MUL_ASSIGN:
             case DIV_ASSIGN:
             case MOD_ASSIGN:
@@ -7667,19 +8186,32 @@ void ProcessExpressionType(Expression exp)
             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;
                }
@@ -7715,21 +8247,22 @@ void ProcessExpressionType(Expression exp)
          }
 
          //dummy.kind = TypeDummy;
-
          if(exp.op.exp1)
          {
-            if(exp.destType && exp.destType.kind == classType &&
-               exp.destType._class && exp.destType._class.registered && useDestType &&
-               
-              ((exp.destType._class.registered.type == unitClass && useSideUnit) || 
-               exp.destType._class.registered.type == enumClass ||
-               exp.destType._class.registered.type == bitClass
-               )) 
+            // 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;
+
+            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++;
             }
@@ -7737,14 +8270,25 @@ void ProcessExpressionType(Expression exp)
             {
                if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
                exp.op.exp1.destType = dummy;
-               dummy.refCount++;               
+               dummy.refCount++;
             }
 
             // TESTING THIS HERE...
             if(exp.op.exp1.destType && exp.op.op != '=') exp.op.exp1.destType.count++;
-            ProcessExpressionType(exp.op.exp1);
+               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);
@@ -7768,6 +8312,8 @@ void ProcessExpressionType(Expression exp)
                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++;
                }
@@ -7795,7 +8341,7 @@ void ProcessExpressionType(Expression exp)
                }
                else
                {
-                  // Don't convert to the type for those... (e.g.: Degrees a; a /= 2;) 
+                  // Don't convert to the type for those... (e.g.: Degrees a; a /= 2;)
                   if(exp.op.op == MUL_ASSIGN || exp.op.op == DIV_ASSIGN ||exp.op.op == MOD_ASSIGN ||exp.op.op == LEFT_ASSIGN ||exp.op.op == RIGHT_ASSIGN/* ||
                      exp.op.op == AND_ASSIGN || exp.op.op == OR_ASSIGN*/);
                   else
@@ -7809,15 +8355,14 @@ void ProcessExpressionType(Expression exp)
                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++;
             }
@@ -7829,7 +8374,7 @@ void ProcessExpressionType(Expression exp)
             }
 
             // TESTING THIS HERE... (DANGEROUS)
-            if(type1 && boolResult && useSideType && type1.kind == classType && type1._class && type1._class.registered && 
+            if(type1 && boolResult && useSideType && type1.kind == classType && type1._class && type1._class.registered &&
                (type1._class.registered.type == bitClass || type1._class.registered.type == enumClass))
             {
                FreeType(exp.op.exp2.destType);
@@ -7837,30 +8382,48 @@ void ProcessExpressionType(Expression exp)
                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)
             {
                if(exp.op.exp2.expType.kind == intSizeType || exp.op.exp2.expType.kind == intPtrType || exp.op.exp2.expType.kind == int64Type || exp.op.exp2.expType.kind == intType || exp.op.exp2.expType.kind == shortType || exp.op.exp2.expType.kind == charType)
                {
-                  if(exp.op.op != '=' && type1.type.kind == voidType) 
+                  if(exp.op.op != '=' && type1.type.kind == voidType)
                      Compiler_Error($"void *: unknown size\n");
                }
-               else if(exp.op.exp2.expType.kind == pointerType || exp.op.exp2.expType.kind == arrayType || exp.op.exp2.expType.kind == functionType || exp.op.exp2.expType.kind == methodType|| 
+               else if(exp.op.exp2.expType.kind == pointerType || exp.op.exp2.expType.kind == arrayType || exp.op.exp2.expType.kind == functionType || exp.op.exp2.expType.kind == methodType||
                            (type1.type.kind == voidType && exp.op.exp2.expType.kind == classType && exp.op.exp2.expType._class.registered &&
-                              (exp.op.exp2.expType._class.registered.type == normalClass || 
+                              (exp.op.exp2.expType._class.registered.type == normalClass ||
                               exp.op.exp2.expType._class.registered.type == structClass ||
                               exp.op.exp2.expType._class.registered.type == noHeadClass)))
                {
                   if(exp.op.op == ADD_ASSIGN)
-                     Compiler_Error($"cannot add two pointers\n");                   
+                     Compiler_Error($"cannot add two pointers\n");
                }
-               else if((exp.op.exp2.expType.kind == classType && type1.kind == pointerType && type1.type.kind == classType && 
+               else if((exp.op.exp2.expType.kind == classType && type1.kind == pointerType && type1.type.kind == classType &&
                   type1.type._class == exp.op.exp2.expType._class && exp.op.exp2.expType._class.registered && exp.op.exp2.expType._class.registered.type == structClass))
                {
                   if(exp.op.op == ADD_ASSIGN)
-                     Compiler_Error($"cannot add two pointers\n");                   
+                     Compiler_Error($"cannot add two pointers\n");
                }
                else if(inCompiler)
                {
@@ -7868,7 +8431,7 @@ void ProcessExpressionType(Expression exp)
                   char type2String[1024];
                   type1String[0] = '\0';
                   type2String[0] = '\0';
-                  
+
                   PrintType(exp.op.exp2.expType, type1String, false, true);
                   PrintType(type1, type2String, false, true);
                   ChangeCh(expString, '\n', ' ');
@@ -7882,7 +8445,24 @@ void ProcessExpressionType(Expression exp)
                exp.op.exp2.destType = null;
             }
 
-            type2 = exp.op.exp2.expType;
+            if(exp.op.op == '-' && !exp.op.exp1 && exp.op.exp2.expType && !exp.op.exp2.expType.isSigned)
+            {
+               type2 = { };
+               type2.refCount = 1;
+               CopyTypeInto(type2, exp.op.exp2.expType);
+               type2.isSigned = true;
+            }
+            else if(exp.op.op == '~' && !exp.op.exp1 && exp.op.exp2.expType && (!exp.op.exp2.expType.isSigned || exp.op.exp2.expType.kind != intType))
+            {
+               type2 = { kind = intType };
+               type2.refCount = 1;
+               type2.isSigned = true;
+            }
+            else
+            {
+               type2 = exp.op.exp2.expType;
+               if(type2) type2.refCount++;
+            }
          }
 
          dummy.kind = voidType;
@@ -7892,7 +8472,7 @@ void ProcessExpressionType(Expression exp)
             exp.expType = Type
             {
                refCount = 1;
-               kind = intType;
+               kind = intSizeType;
             };
             exp.isConstant = true;
          }
@@ -7909,7 +8489,7 @@ void ProcessExpressionType(Expression exp)
          {
             if(boolOps)
             {
-               if(exp.op.exp1) 
+               if(exp.op.exp1)
                {
                   if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
                   exp.op.exp1.destType = MkClassType("bool");
@@ -7917,12 +8497,12 @@ void ProcessExpressionType(Expression exp)
                   if(!exp.op.exp1.expType)
                      ProcessExpressionType(exp.op.exp1);
                   else
-                     CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false);
+                     CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false);
                   FreeType(exp.op.exp1.expType);
                   exp.op.exp1.expType = MkClassType("bool");
                   exp.op.exp1.expType.truth = true;
                }
-               if(exp.op.exp2) 
+               if(exp.op.exp2)
                {
                   if(exp.op.exp2.destType) FreeType(exp.op.exp2.destType);
                   exp.op.exp2.destType = MkClassType("bool");
@@ -7930,34 +8510,58 @@ void ProcessExpressionType(Expression exp)
                   if(!exp.op.exp2.expType)
                      ProcessExpressionType(exp.op.exp2);
                   else
-                     CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false);
+                     CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false, false);
                   FreeType(exp.op.exp2.expType);
                   exp.op.exp2.expType = MkClassType("bool");
                   exp.op.exp2.expType.truth = true;
                }
             }
-            else if(exp.op.exp1 && exp.op.exp2 && 
-               ((useSideType /*&& 
-                     (useSideUnit || 
+            else if(exp.op.exp1 && exp.op.exp2 &&
+               ((useSideType /*&&
+                     (useSideUnit ||
                         ((!type1 || type1.kind != classType || type1._class.registered.type != unitClass) &&
                          (!type2 || type2.kind != classType || type2._class.registered.type != unitClass)))*/) ||
-                  ((!type1 || type1.kind != classType || !strcmp(type1._class.string, "String")) && 
+                  ((!type1 || type1.kind != classType || !strcmp(type1._class.string, "String")) &&
                   (!type2 || type2.kind != classType || !strcmp(type2._class.string, "String")))))
             {
                if(type1 && type2 &&
                   // 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 && 
-                     type2._class.registered && type2._class.registered.type == unitClass && 
+                  if(!boolResult && type1.kind == classType && (!exp.destType || exp.destType.kind != classType) &&
+                     type1._class.registered && type1._class.registered.type == unitClass &&
+                     type2._class.registered && type2._class.registered.type == unitClass &&
                      type1._class.registered != type2._class.registered)
                      Compiler_Warning($"operating on %s and %s with an untyped result, assuming %s\n",
                         type1._class.string, type2._class.string, type1._class.string);
@@ -7970,7 +8574,7 @@ void ProcessExpressionType(Expression exp)
                         Expression classExp = MkExpMember(argExp, MkIdentifier("dataTypeClass"));
 
                         exp.op.exp1 = MkExpBrackets(MkListOne(MkExpCast(
-                           MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), 
+                           MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)),
                            exp.op.exp1)));
 
                         ProcessExpressionType(exp.op.exp1);
@@ -7979,36 +8583,41 @@ void ProcessExpressionType(Expression exp)
                         {
                            ProcessExpressionType(classExp);
 
-                           exp.op.exp2 = MkExpBrackets(MkListOne(MkExpOp(exp.op.exp2, '*', 
+                           exp.op.exp2 = MkExpBrackets(MkListOne(MkExpOp(exp.op.exp2, '*',
                               // ((_class.type == noHeadClass || _class.type == normalClass) ? sizeof(void *) : type.size)
                               MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(
                                  // noHeadClass
                                  MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpConstant("5")),
-                                    OR_OP, 
+                                    OR_OP,
                                  // normalClass
                                  MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpConstant("0"))))),
                                     MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(
-                                       MkPointer(null, null), null)))),                                  
+                                       MkPointer(null, null), null)))),
                                        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);
                         }
                      }
                   }
-                  
+
                   if(!boolResult && ((type1.kind == pointerType || type1.kind == arrayType || (type1.kind == classType && !strcmp(type1._class.string, "String"))) && (type2.kind == intSizeType || type2.kind == intPtrType || type2.kind == int64Type || type2.kind == intType || type2.kind == shortType || type2.kind == charType)))
                   {
-                     if(type1.kind != classType && type1.type.kind == voidType) 
+                     if(type1.kind != classType && type1.type.kind == voidType)
                         Compiler_Error($"void *: unknown size\n");
                      exp.expType = type1;
                      if(type1) type1.refCount++;
                   }
                   else if(!boolResult && ((type2.kind == pointerType || type2.kind == arrayType || (type2.kind == classType && !strcmp(type2._class.string, "String"))) && (type1.kind == intSizeType || type1.kind == intPtrType || type1.kind == int64Type || type1.kind == intType || type1.kind == shortType || type1.kind == charType)))
                   {
-                     if(type2.kind != classType && type2.type.kind == voidType) 
+                     if(type2.kind != classType && type2.type.kind == voidType)
                         Compiler_Error($"void *: unknown size\n");
                      exp.expType = type2;
                      if(type2) type2.refCount++;
@@ -8018,7 +8627,7 @@ void ProcessExpressionType(Expression exp)
                   {
                      Compiler_Warning($"different levels of indirection\n");
                   }
-                  else 
+                  else
                   {
                      bool success = false;
                      if(type1.kind == pointerType && type2.kind == pointerType)
@@ -8028,7 +8637,7 @@ void ProcessExpressionType(Expression exp)
                         else if(exp.op.op == '-')
                         {
                            // Pointer Subtraction gives integer
-                           if(MatchTypes(type1.type, type2.type, null, null, null, false, false, false, false))
+                           if(MatchTypes(type1.type, type2.type, null, null, null, false, false, false, false, false))
                            {
                               exp.expType = Type
                               {
@@ -8050,28 +8659,28 @@ void ProcessExpressionType(Expression exp)
                                     exp.list = MkListOne(MkExpOp(
                                        MkExpBrackets(MkListOne(MkExpOp(
                                              MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), MkExpBrackets(MkListOne(exp.op.exp1)))
-                                             , exp.op.op, 
-                                             MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), MkExpBrackets(MkListOne(exp.op.exp2)))))), '/', 
-                                          
+                                             , exp.op.op,
+                                             MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), MkExpBrackets(MkListOne(exp.op.exp2)))))), '/',
+
                                              //MkExpMember(classExp, MkIdentifier("typeSize"))
 
                                              // ((_class.type == noHeadClass || _class.type == normalClass) ? sizeof(void *) : type.size)
                                              MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(MkExpOp(
                                                 // noHeadClass
                                                 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("noHeadClass"))),
-                                                   OR_OP, 
+                                                   OR_OP,
                                                 // normalClass
                                                 MkExpOp(MkExpMember(CopyExpression(classExp), MkIdentifier("type")), EQ_OP, MkExpIdentifier(MkIdentifier("normalClass")))))),
                                                    MkListOne(MkExpTypeSize(MkTypeName(MkListOne(MkSpecifier(VOID)), MkDeclaratorPointer(
-                                                      MkPointer(null, null), null)))),                                  
+                                                      MkPointer(null, null), null)))),
                                                       MkExpMember(classExp, MkIdentifier("typeSize")))))
 
-                                             
+
                                              ));
-                                    
+
                                     ProcessExpressionType(((Expression)exp.list->first).op.exp2);
                                     FreeType(dummy);
-                                    return;                                       
+                                    return;
                                  }
                               }
                            }
@@ -8081,14 +8690,14 @@ void ProcessExpressionType(Expression exp)
                      if(!success && exp.op.exp1.type == constantExp)
                      {
                         // If first expression is constant, try to match that first
-                        if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false))
+                        if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false))
                         {
                            if(exp.expType) FreeType(exp.expType);
                            exp.expType = exp.op.exp1.destType;
                            if(exp.op.exp1.destType) exp.op.exp1.destType.refCount++;
                            success = true;
                         }
-                        else if(CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false))
+                        else if(CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false, false))
                         {
                            if(exp.expType) FreeType(exp.expType);
                            exp.expType = exp.op.exp2.destType;
@@ -8098,14 +8707,14 @@ void ProcessExpressionType(Expression exp)
                      }
                      else if(!success)
                      {
-                        if(CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false))
+                        if(CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false, false))
                         {
                            if(exp.expType) FreeType(exp.expType);
                            exp.expType = exp.op.exp2.destType;
                            if(exp.op.exp2.destType) exp.op.exp2.destType.refCount++;
                            success = true;
                         }
-                        else if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false))
+                        else if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false))
                         {
                            if(exp.expType) FreeType(exp.expType);
                            exp.expType = exp.op.exp1.destType;
@@ -8145,7 +8754,7 @@ void ProcessExpressionType(Expression exp)
                   exp.op.exp1.destType = type2._class.registered.dataType;
                   if(type2._class.registered.dataType)
                      type2._class.registered.dataType.refCount++;
-                  CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false);
+                  CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false);
                   exp.expType = type2;
                   if(type2) type2.refCount++;
                }
@@ -8156,7 +8765,7 @@ void ProcessExpressionType(Expression exp)
                   exp.op.exp2.destType = type1._class.registered.dataType;
                   if(type1._class.registered.dataType)
                      type1._class.registered.dataType.refCount++;
-                  CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false);
+                  CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false, false);
                   exp.expType = type1;
                   if(type1) type1.refCount++;
                }
@@ -8173,13 +8782,16 @@ void ProcessExpressionType(Expression exp)
                      exp.op.exp2.destType = type1._class.registered.dataType;
                      exp.op.exp2.destType.refCount++;
 
-                     CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false);
+                     CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false, false);
+                     if(type2)
+                        FreeType(type2);
                      type2 = exp.op.exp2.destType;
+                     if(type2) type2.refCount++;
 
                      exp.expType = type2;
                      type2.refCount++;
                   }
-                  
+
                   if(!boolResult && useSideUnit && type2 && type2.kind == classType && type2._class.registered && type2._class.registered.type == unitClass && type1 && type1.kind != classType)
                   {
                      if(exp.op.exp1.destType) FreeType(exp.op.exp1.destType);
@@ -8189,43 +8801,88 @@ void ProcessExpressionType(Expression exp)
                      exp.op.exp1.destType = type2._class.registered.dataType;
                      exp.op.exp1.destType.refCount++;
 
-                     CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false);
+                     CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false);
                      type1 = exp.op.exp1.destType;
                      exp.expType = type1;
                      type1.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, 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, 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, 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, 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, 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...
@@ -8249,7 +8906,7 @@ void ProcessExpressionType(Expression exp)
                         if(type2._class.registered.dataType)
                            type2._class.registered.dataType.refCount++;
                         CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false);
-                        
+
                         //exp.expType = type2._class.registered.dataType; //type2;
                         //if(type2) type2.refCount++;
                      }
@@ -8267,43 +8924,44 @@ void ProcessExpressionType(Expression exp)
                      }
                      */
 
-                     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, 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++;
+                           }
                         }
                      }
                   }
@@ -8315,7 +8973,7 @@ void ProcessExpressionType(Expression exp)
                   {
                      Type oldType = exp.op.exp1.expType;
                      exp.op.exp1.expType = null;
-                     if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false))
+                     if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false))
                         FreeType(oldType);
                      else
                         exp.op.exp1.expType = oldType;
@@ -8344,7 +9002,7 @@ void ProcessExpressionType(Expression exp)
                   }
                   */
 
-                  if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false))
+                  if(CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false))
                   {
                      if(exp.expType) FreeType(exp.expType);
                      exp.expType = exp.op.exp1.destType;
@@ -8361,7 +9019,7 @@ void ProcessExpressionType(Expression exp)
                   exp.op.exp1.destType = type2._class.registered.dataType;
                   if(type2._class.registered.dataType)
                      type2._class.registered.dataType.refCount++;
-                  CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false);
+                  CheckExpressionType(exp.op.exp1, exp.op.exp1.destType, false, false);
                }
                if(exp.op.op == '!')
                {
@@ -8383,13 +9041,13 @@ void ProcessExpressionType(Expression exp)
                   exp.op.exp2.destType = type1._class.registered.dataType;
                   if(type1._class.registered.dataType)
                      type1._class.registered.dataType.refCount++;
-                  CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false);
+                  CheckExpressionType(exp.op.exp2, exp.op.exp2.destType, false, false);
                }
                exp.expType = type1;
                if(type1) type1.refCount++;
             }
          }
-         
+
          yylloc = exp.loc;
          if(exp.op.exp1 && !exp.op.exp1.expType)
          {
@@ -8435,6 +9093,8 @@ void ProcessExpressionType(Expression exp)
          yylloc = oldyylloc;
 
          FreeType(dummy);
+         if(type2)
+            FreeType(type2);
          break;
       }
       case bracketsExp:
@@ -8448,6 +9108,7 @@ void ProcessExpressionType(Expression exp)
             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; }
             }
@@ -8474,7 +9135,7 @@ void ProcessExpressionType(Expression exp)
             FreeType(exp.expType);
             FreeType(exp.destType);
             delete exp.list;
-            
+
             *exp = *e;
 
             exp.prev = prev;
@@ -8498,16 +9159,28 @@ void ProcessExpressionType(Expression exp)
          if(exp.index.exp.expType)
          {
             Type source = exp.index.exp.expType;
-            if(source.kind == classType && source._class && source._class.registered && source._class.registered != containerClass &&
-               eClass_IsDerived(source._class.registered, containerClass) && 
-               source._class.registered.templateArgs)
+            if(source.kind == classType && source._class && source._class.registered)
             {
                Class _class = source._class.registered;
-               exp.expType = ProcessTypeString(_class.templateArgs[2].dataTypeString, false);
-
-               if(exp.index.index && exp.index.index->last)
+               Class c = _class.templateClass ? _class.templateClass : _class;
+               if(_class != containerClass && eClass_IsDerived(c, containerClass) && _class.templateArgs)
                {
-                  ((Expression)exp.index.index->last).destType = ProcessTypeString(_class.templateArgs[1].dataTypeString, false);
+                  exp.expType = ProcessTypeString(_class.templateArgs[2].dataTypeString, false);
+
+                  if(exp.index.index && exp.index.index->last)
+                  {
+                     Type type = ProcessTypeString(_class.templateArgs[1].dataTypeString, false);
+
+                     if(type.kind == classType) type.constant = true;
+                     else if(type.kind == pointerType)
+                     {
+                        Type t = type;
+                        while(t.kind == pointerType) t = t.type;
+                        t.constant = true;
+                     }
+
+                     ((Expression)exp.index.index->last).destType = type;
+                  }
                }
             }
          }
@@ -8590,7 +9263,7 @@ void ProcessExpressionType(Expression exp)
                   a = exp.call.arguments->first;
                   tempExp1 = a;
                }
-               
+
                if(a)
                {
                   exp.call.arguments->Clear();
@@ -8638,7 +9311,7 @@ void ProcessExpressionType(Expression exp)
                               if(b.expType)
                                  b.expType.refCount++;
                               ListAdd(exp.list, MkExpOp(CopyExpression(tempExp2), '=', b));
-                           }                        
+                           }
 
                            decl = MkDeclaration(specs, decls);
                            if(!curCompound.compound.declarations)
@@ -8651,7 +9324,7 @@ void ProcessExpressionType(Expression exp)
                   if(!strcmp(id.string, "Max") || !strcmp(id.string, "Min"))
                   {
                      int op = (!strcmp(id.string, "Max")) ? '>' : '<';
-                     ListAdd(exp.list, 
+                     ListAdd(exp.list,
                         MkExpCondition(MkExpBrackets(MkListOne(
                            MkExpOp(CopyExpression(tempExp1), op, CopyExpression(tempExp2)))),
                            MkListOne(CopyExpression(tempExp1)), CopyExpression(tempExp2)));
@@ -8661,7 +9334,7 @@ void ProcessExpressionType(Expression exp)
                   }
                   else if(!strcmp(id.string, "Abs"))
                   {
-                     ListAdd(exp.list, 
+                     ListAdd(exp.list,
                         MkExpCondition(MkExpBrackets(MkListOne(
                            MkExpOp(CopyExpression(tempExp1), '<', MkExpConstant("0")))),
                            MkListOne(MkExpOp(null, '-', CopyExpression(tempExp1))), CopyExpression(tempExp1)));
@@ -8672,7 +9345,7 @@ void ProcessExpressionType(Expression exp)
                   else if(!strcmp(id.string, "Sgn"))
                   {
                      // ((!(a))?(0):(((a)<0)?(-1):(1)))
-                     ListAdd(exp.list, 
+                     ListAdd(exp.list,
                         MkExpCondition(MkExpBrackets(MkListOne(
                            MkExpOp(null, '!', CopyExpression(tempExp1)))), MkListOne(MkExpConstant("0")),
                               MkExpBrackets(MkListOne(MkExpCondition(MkExpBrackets(MkListOne(
@@ -8717,7 +9390,7 @@ void ProcessExpressionType(Expression exp)
          {
             methodType = functionType;
             functionType = methodType.method.dataType;
-            
+
             //if(functionType.returnType && functionType.returnType.kind == thisClassType)
             // TOCHECK: Instead of doing this here could this be done per param?
             if(exp.call.exp.expType.usedClass)
@@ -8739,12 +9412,12 @@ void ProcessExpressionType(Expression exp)
                      Context context = SetupTemplatesContext(exp.call.exp.expType.usedClass);
 
                      decl = SpecDeclFromString(typeString, specs, null);
-                     
+
                      // SET THIS TO FALSE WHEN PROCESSING THISCLASS OUTSIDE THE CLASS
                      if(thisClass != (exp.call.exp.expType.usedClass.templateClass ? exp.call.exp.expType.usedClass.templateClass :
                         exp.call.exp.expType.usedClass))
                         thisClassParams = false;
-                     
+
                      ReplaceThisClassSpecifiers(specs, exp.call.exp.expType.usedClass);
                      {
                         Class backupThisClass = thisClass;
@@ -8799,9 +9472,10 @@ void ProcessExpressionType(Expression exp)
             }
 
             // WHY WAS THIS COMMENTED OUT ? Broke DisplaySystem::FontExtent(this ? displaySystem : null, font, text, len, width, height);
-            if(!functionType.staticMethod)
+            // Fixed #141 by adding '&& !functionType.extraParam'
+            if(!functionType.staticMethod && !functionType.extraParam)
             {
-               if(memberExp && memberExp.member.exp && memberExp.member.exp.expType && memberExp.member.exp.expType.kind == subClassType && 
+               if(memberExp && memberExp.member.exp && memberExp.member.exp.expType && memberExp.member.exp.expType.kind == subClassType &&
                   memberExp.member.exp.expType._class)
                {
                   type = MkClassType(memberExp.member.exp.expType._class.string);
@@ -8817,8 +9491,13 @@ void ProcessExpressionType(Expression exp)
                else if(!memberExp && (functionType.thisClass || (methodType && methodType.methodClass)))
                {
                   type = MkClassType(functionType.thisClass ? functionType.thisClass.string : (methodType ? methodType.methodClass.fullName : null));
+                  type.byReference = functionType.byReference;
+                  type.typedByReference = functionType.typedByReference;
                   if(e)
                   {
+                     // Allow manually passing a class for typed object
+                     if(e.next && type.kind == classType && (functionType && functionType.thisClass) && functionType.classObjectType == typedObject)
+                        e = e.next;
                      e.destType = type;
                      e = e.next;
                      type = functionType.params.first;
@@ -8884,15 +9563,25 @@ void ProcessExpressionType(Expression exp)
                   }
                   if(curParam && _class.templateArgs[id].dataTypeString)
                   {
+                     bool constant = type.constant;
                      ClassTemplateArgument arg = _class.templateArgs[id];
                      {
                         Context context = SetupTemplatesContext(_class);
-                     
+
                         /*if(!arg.dataType)
                            arg.dataType = ProcessTypeString(arg.dataTypeString, false);*/
                         templatedType = ProcessTypeString(arg.dataTypeString, false);
                         FinishTemplatesContext(context);
                      }
+
+                     if(templatedType.kind == classType && constant) templatedType.constant = true;
+                     else if(templatedType.kind == pointerType)
+                     {
+                        Type t = templatedType.type;
+                        while(t.kind == pointerType) t = t.type;
+                        if(constant) t.constant = constant;
+                     }
+
                      e.destType = templatedType;
                      if(templatedType)
                      {
@@ -9019,7 +9708,19 @@ void ProcessExpressionType(Expression exp)
       {
          Type type;
          Location oldyylloc = yylloc;
-         bool thisPtr = (exp.member.exp && exp.member.exp.type == identifierExp && !strcmp(exp.member.exp.identifier.string, "this"));
+         bool thisPtr;
+         Expression checkExp = exp.member.exp;
+         while(checkExp)
+         {
+            if(checkExp.type == castExp)
+               checkExp = checkExp.cast.exp;
+            else if(checkExp.type == bracketsExp)
+               checkExp = checkExp.list ? checkExp.list->first : null;
+            else
+               break;
+         }
+
+         thisPtr = (checkExp && checkExp.type == identifierExp && !strcmp(checkExp.identifier.string, "this"));
          exp.thisPtr = thisPtr;
 
          // DOING THIS LATER NOW...
@@ -9033,7 +9734,7 @@ void ProcessExpressionType(Expression exp)
          }
 
          ProcessExpressionType(exp.member.exp);
-         if(exp.member.exp.expType && exp.member.exp.expType.kind == classType && exp.member.exp.expType._class && 
+         if(exp.member.exp.expType && exp.member.exp.expType.kind == classType && exp.member.exp.expType._class &&
             exp.member.exp.expType._class.registered && exp.member.exp.expType._class.registered.type == normalClass)
          {
             exp.isConstant = false;
@@ -9094,7 +9795,7 @@ void ProcessExpressionType(Expression exp)
                      int c;
                      int paramCount = 0;
                      int lastParam = -1;
-                     
+
                      char templateString[1024];
                      ClassTemplateParameter param;
                      sprintf(templateString, "%s<", expClass.templateClass.fullName);
@@ -9116,7 +9817,7 @@ void ProcessExpressionType(Expression exp)
                               int p = 0;
                               Class nextClass;
                               for(nextClass = sClass.base; nextClass; nextClass = nextClass.base) p += nextClass.templateParams.count;
-                              
+
                               for(cParam = sClass.templateParams.first; cParam; cParam = cParam.next, p++)
                               {
                                  if(cParam.type == TemplateParameterType::type && arg.dataTypeString && !strcmp(cParam.name, arg.dataTypeString))
@@ -9150,6 +9851,7 @@ void ProcessExpressionType(Expression exp)
                                     Expression exp;
                                     char * string = PrintHexUInt64(arg.expression.ui64);
                                     exp = MkExpCast(MkTypeName(specs, decl), MkExpConstant(string));
+                                    delete string;
 
                                     ProcessExpressionType(exp);
                                     ComputeExpression(exp);
@@ -9190,7 +9892,7 @@ void ProcessExpressionType(Expression exp)
                                  lastParam = p;
                               }
                               p++;
-                           }               
+                           }
                         }
                      }
                      {
@@ -9204,7 +9906,7 @@ void ProcessExpressionType(Expression exp)
                         FreeType(exp.expType);
                         exp.expType = ProcessTypeString(templateString, false);
                         FinishTemplatesContext(context);
-                     }                     
+                     }
                   }
 
                   // *([expType] *)(((byte *)[exp.member.exp]) + [argExp].member.offset)
@@ -9217,15 +9919,15 @@ void ProcessExpressionType(Expression exp)
                   MkExpCast(MkTypeName(specs, MkDeclaratorPointer(MkPointer(null, null), decl)), MkExpBrackets(MkListOne(MkExpOp(
                      MkExpBrackets(MkListOne(
                         MkExpCast(MkTypeName(MkListOne(MkSpecifierName("byte")), MkDeclaratorPointer(MkPointer(null, null), null)), expMember))),
-                           '+',  
-                           MkExpOp(MkExpMember(MkExpMember(argExp, MkIdentifier("member")), MkIdentifier("offset")), 
+                           '+',
+                           MkExpOp(MkExpMember(MkExpMember(argExp, MkIdentifier("member")), MkIdentifier("offset")),
                            '+',
                            MkExpMember(MkExpMember(MkExpMember(CopyExpression(argExp), MkIdentifier("member")), MkIdentifier("_class")), MkIdentifier("offset")))))))
-                           
+
                            ));
                }
             }
-            else if(type.templateParameter && type.templateParameter.type == TemplateParameterType::type && 
+            else if(type.templateParameter && type.templateParameter.type == TemplateParameterType::type &&
                (type.templateParameter.dataType || type.templateParameter.dataTypeString))
             {
                type = ProcessTemplateParameterType(type.templateParameter);
@@ -9234,8 +9936,9 @@ void ProcessExpressionType(Expression exp)
          // TODO: *** This seems to be where we should add method support for all basic types ***
          if(type && (type.kind == templateType));
          else if(type && (type.kind == classType || type.kind == subClassType || type.kind == intType || type.kind == enumType ||
-                          type.kind == int64Type || type.kind == shortType || type.kind == longType || type.kind == charType ||
-                          type.kind == intPtrType || type.kind == intSizeType || type.kind == floatType || type.kind == doubleType))
+                          type.kind == int64Type || type.kind == shortType || type.kind == longType || type.kind == charType || type.kind == _BoolType ||
+                          type.kind == intPtrType || type.kind == intSizeType || type.kind == floatType || type.kind == doubleType ||
+                          (type.kind == pointerType && type.type.kind == charType)))
          {
             Identifier id = exp.member.member;
             TypeKind typeKind = type.kind;
@@ -9265,7 +9968,7 @@ void ProcessExpressionType(Expression exp)
                      _class = eSystem_FindClass(privateModule, "uintptr");
                      FreeType(exp.expType);
                      exp.expType = ProcessTypeString("uintptr", false);
-                     exp.byReference = false;
+                     exp.byReference = true;
                   }
                   else
                   {
@@ -9280,8 +9983,8 @@ void ProcessExpressionType(Expression exp)
 
             if(_class && id)
             {
-               /*bool thisPtr = 
-                  (exp.member.exp.type == identifierExp && 
+               /*bool thisPtr =
+                  (exp.member.exp.type == identifierExp &&
                   !strcmp(exp.member.exp.identifier.string, "this"));*/
                Property prop = null;
                Method method = null;
@@ -9316,28 +10019,39 @@ void ProcessExpressionType(Expression exp)
                   // Prioritize properties over data members otherwise
                   else
                   {
+                     bool useMemberForNonConst = false;
                      // First look for Public Members (Unless class specifier is provided, which skips public priority)
                      if(!id.classSym)
                      {
                         prop = eClass_FindProperty(_class, id.string, null);
-                        if(!id._class || !id._class.name || strcmp(id._class.name, "property"))
+
+                        useMemberForNonConst = prop && exp.destType &&
+                           ( (exp.destType.kind == classType && !exp.destType.constant) || ((exp.destType.kind == pointerType || exp.destType.kind == arrayType) && exp.destType.type && !exp.destType.type.constant) ) &&
+                              !strncmp(prop.dataTypeString, "const ", 6);
+
+                        if(useMemberForNonConst || !id._class || !id._class.name || strcmp(id._class.name, "property"))
                            member = eClass_FindDataMember(_class, id.string, null, null, null);
                      }
 
-                     if(!prop && !member)
+                     if((!prop || useMemberForNonConst) && !member)
                      {
-                        method = eClass_FindMethod(_class, id.string, null);
+                        method = useMemberForNonConst ? null : eClass_FindMethod(_class, id.string, null);
                         if(!method)
                         {
                            prop = eClass_FindProperty(_class, id.string, privateModule);
-                           if(!id._class || !id._class.name || strcmp(id._class.name, "property"))
+
+                           useMemberForNonConst |= prop && exp.destType &&
+                              ( (exp.destType.kind == classType && !exp.destType.constant) || ((exp.destType.kind == pointerType || exp.destType.kind == arrayType) && exp.destType.type && !exp.destType.type.constant) ) &&
+                                 !strncmp(prop.dataTypeString, "const ", 6);
+
+                           if(useMemberForNonConst || !id._class || !id._class.name || strcmp(id._class.name, "property"))
                               member = eClass_FindDataMember(_class, id.string, privateModule, null, null);
                         }
                      }
 
                      if(member && prop)
                      {
-                        if(member._class != prop._class && !id._class && eClass_IsDerived(member._class, prop._class))
+                        if(useMemberForNonConst || (member._class != prop._class && !id._class && eClass_IsDerived(member._class, prop._class)))
                            prop = null;
                         else
                            member = null;
@@ -9366,16 +10080,16 @@ void ProcessExpressionType(Expression exp)
 
                         FreeType(classExp.expType);
                         classExp.expType = ProcessTypeString("ecere::com::Class", false);
-                     
+
                         strcpy(structName, "__ecereClassData_");
                         FullClassNameCat(structName, type._class.string, false);
                         exp.type = pointerExp;
                         exp.member.member = id;
 
                         exp.member.exp = MkExpBrackets(MkListOne(MkExpCast(
-                           MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)), MkDeclaratorPointer(MkPointer(null, null), null)), 
+                           MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)), MkDeclaratorPointer(MkPointer(null, null), null)),
                               MkExpBrackets(MkListOne(MkExpOp(
-                                 MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null,null), null)), 
+                                 MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null,null), null)),
                                     MkExpMember(classExp, MkIdentifier("data"))), '+',
                                        MkExpMember(MkExpClass(MkListOne(MkSpecifierName(type._class.string)), null), MkIdentifier("offsetClass")))))
                                  )));
@@ -9400,13 +10114,13 @@ void ProcessExpressionType(Expression exp)
                      }
                   }
                }
-      
+
                if(prop)
                {
                   exp.member.memberType = propertyMember;
                   if(!prop.dataType)
                      ProcessPropertyType(prop);
-                  exp.expType = prop.dataType;                     
+                  exp.expType = prop.dataType;
                   if(prop.dataType) prop.dataType.refCount++;
                }
                else if(member)
@@ -9438,7 +10152,7 @@ void ProcessExpressionType(Expression exp)
                }
                else if(method)
                {
-                  if(inCompiler)
+                  //if(inCompiler)
                   {
                      /*if(id._class)
                      {
@@ -9475,7 +10189,8 @@ void ProcessExpressionType(Expression 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;
@@ -9518,10 +10233,19 @@ void ProcessExpressionType(Expression exp)
                      {
                         ClassTemplateArgument arg = tClass.templateArgs[id];
                         Context context = SetupTemplatesContext(tClass);
+                        bool constant = exp.expType.constant;
                         /*if(!arg.dataType)
                            arg.dataType = ProcessTypeString(arg.dataTypeString, false);*/
                         FreeType(exp.expType);
+
                         exp.expType = ProcessTypeString(arg.dataTypeString, false);
+                        if(exp.expType.kind == classType && constant) exp.expType.constant = true;
+                        else if(exp.expType.kind == pointerType)
+                        {
+                           Type t = exp.expType.type;
+                           while(t.kind == pointerType) t = t.type;
+                           if(constant) t.constant = constant;
+                        }
                         if(exp.expType)
                         {
                            if(exp.expType.kind == thisClassType)
@@ -9536,6 +10260,14 @@ void ProcessExpressionType(Expression exp)
                            if(!exp.destType)
                            {
                               exp.destType = ProcessTypeString(arg.dataTypeString, false);
+                              if(exp.destType.kind == classType && constant) exp.destType.constant = true;
+                              else if(exp.destType.kind == pointerType)
+                              {
+                                 Type t = exp.destType.type;
+                                 while(t.kind == pointerType) t = t.type;
+                                 if(constant) t.constant = constant;
+                              }
+
                               //exp.destType.refCount++;
 
                               if(exp.destType.kind == thisClassType)
@@ -9561,7 +10293,7 @@ void ProcessExpressionType(Expression exp)
                         if(sClass.templateClass) sClass = sClass.templateClass;
                         for(curParam = sClass.templateParams.first; curParam; curParam = curParam.next)
                         {
-                           if(curParam.type == TemplateParameterType::type && 
+                           if(curParam.type == TemplateParameterType::type &&
                               !strcmp(exp.expType.type.templateParameter.identifier.string, curParam.name))
                            {
                               for(sClass = sClass.base; sClass; sClass = sClass.base)
@@ -9580,7 +10312,7 @@ void ProcessExpressionType(Expression exp)
                         Type basicType;
                         /*if(!arg.dataType)
                            arg.dataType = ProcessTypeString(arg.dataTypeString, false);*/
-                        
+
                         basicType = ProcessTypeString(arg.dataTypeString, false);
                         if(basicType)
                         {
@@ -9594,7 +10326,7 @@ void ProcessExpressionType(Expression exp)
                            if(tClass.templateClass)
                               basicType.passAsTemplate = true;
                            */
-                           
+
                            FreeType(exp.expType);
 
                            exp.expType = Type { refCount = 1, kind = pointerType, type = basicType };
@@ -9660,7 +10392,7 @@ void ProcessExpressionType(Expression exp)
                                  {
                                     if(!strcmp(paramCur.name, param.name))
                                     {
-                                       
+
                                        break;
                                     }
                                     cp++;
@@ -9690,6 +10422,7 @@ void ProcessExpressionType(Expression exp)
                                        Expression exp;
                                        char * string = PrintHexUInt64(arg.expression.ui64);
                                        exp = MkExpCast(MkTypeName(specs, decl), MkExpConstant(string));
+                                       delete string;
 
                                        ProcessExpressionType(exp);
                                        ComputeExpression(exp);
@@ -9719,7 +10452,7 @@ void ProcessExpressionType(Expression exp)
                                     {
                                        strcat(templateString, param.name);
                                        strcat(templateString, " = ");
-                                    }                                       
+                                    }
                                     strcat(templateString, argument);
                                     paramCount++;
                                     lastParam = p;
@@ -9758,7 +10491,7 @@ void ProcessExpressionType(Expression exp)
                   memberType.refCount++;
             }
          }
-         else 
+         else
          {
             char expString[10240];
             expString[0] = '\0';
@@ -9778,7 +10511,7 @@ void ProcessExpressionType(Expression exp)
                   exp.expType = ReplaceThisClassType(_class);
                }
             }
-         }         
+         }
          yylloc = oldyylloc;
          break;
       }
@@ -9851,7 +10584,7 @@ void ProcessExpressionType(Expression exp)
          exp.expType = Type
          {
             refCount = 1;
-            kind = intType;
+            kind = intSizeType;
          };
          // exp.isConstant = true;
          break;
@@ -9863,7 +10596,7 @@ void ProcessExpressionType(Expression exp)
          exp.expType = Type
          {
             refCount = 1;
-            kind = intType;
+            kind = intSizeType;
          };
          exp.isConstant = true;
 
@@ -9878,11 +10611,13 @@ void ProcessExpressionType(Expression exp)
          FreeType(exp.cast.exp.destType);
          exp.cast.exp.destType = type;
          type.refCount++;
+         type.casted = true;
          ProcessExpressionType(exp.cast.exp);
+         type.casted = false;
          type.count = 0;
          exp.expType = type;
          //type.refCount++;
-         
+
          // if(!NeedCast(exp.cast.exp.expType, exp.cast.exp.destType))
          if(!exp.cast.exp.needCast && !NeedCast(exp.cast.exp.expType, type))
          {
@@ -9896,7 +10631,7 @@ void ProcessExpressionType(Expression exp)
             //FreeType(exp.destType);
             FreeType(exp.expType);
             FreeTypeName(exp.cast.typeName);
-            
+
             *exp = *castExp;
             FreeType(exp.expType);
             FreeType(exp.destType);
@@ -10029,9 +10764,9 @@ void ProcessExpressionType(Expression exp)
                classExp = MkExpIdentifier(MkIdentifier("class"));
 
             exp.member.exp = MkExpBrackets(MkListOne(MkExpCast(
-               MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)), MkDeclaratorPointer(MkPointer(null, null), null)), 
+               MkTypeName(MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier(structName), null)), MkDeclaratorPointer(MkPointer(null, null), null)),
                   MkExpBrackets(MkListOne(MkExpOp(
-                     MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null,null), null)), 
+                     MkExpCast(MkTypeName(MkListOne(MkSpecifier(CHAR)), MkDeclaratorPointer(MkPointer(null,null), null)),
                         MkExpMember(classExp, MkIdentifier("data"))), '+',
                            MkExpMember(MkExpClass(MkListOne(MkSpecifierName(_class.fullName)), null), MkIdentifier("offsetClass")))))
                      )));
@@ -10044,7 +10779,7 @@ void ProcessExpressionType(Expression exp)
       case arrayExp:
       {
          Type type = null;
-         char * typeString = null;
+         const char * typeString = null;
          char typeStringBuf[1024];
          if(exp.destType && exp.destType.kind == classType && exp.destType._class && exp.destType._class.registered &&
             exp.destType._class.registered != containerClass && eClass_IsDerived(exp.destType._class.registered, containerClass))
@@ -10065,25 +10800,25 @@ void ProcessExpressionType(Expression exp)
                   else
                   {
                      // if(!MatchType(e.expType, type, null, null, null, false, false, false))
-                     if(!MatchTypeExpression(e, type, null, false))
+                     if(!MatchTypeExpression(e, type, null, false, true))
                      {
                         FreeType(type);
                         type = e.expType;
                         e.expType = null;
-                        
+
                         e = exp.list->first;
                         ProcessExpressionType(e);
                         if(e.expType)
                         {
                            //if(!MatchTypes(e.expType, type, null, null, null, false, false, false))
-                           if(!MatchTypeExpression(e, type, null, false))
+                           if(!MatchTypeExpression(e, type, null, false, true))
                            {
                               FreeType(e.expType);
                               e.expType = null;
                               FreeType(type);
                               type = null;
                               break;
-                           }                           
+                           }
                         }
                      }
                   }
@@ -10139,7 +10874,7 @@ void ProcessExpressionType(Expression exp)
                FreeType(type);
                delete exp.list;
             }
-            
+
             DeclareStruct("ecere::com::BuiltInContainer", false);
 
             ListAdd(structInitializers, /*MkIdentifier("_vTbl")*/    MkInitializerAssignment(MkExpMember(MkExpClass(MkListOne(MkSpecifierName("BuiltInContainer")), null), MkIdentifier("_vTbl"))));
@@ -10220,7 +10955,7 @@ void ProcessExpressionType(Expression exp)
    if(exp.destType && (exp.destType.kind == voidType || exp.destType.kind == dummyType) );
    else if(exp.destType && !exp.destType.keepCast)
    {
-      if(!CheckExpressionType(exp, exp.destType, false))
+      if(!CheckExpressionType(exp, exp.destType, false, !exp.destType.casted))
       {
          if(!exp.destType.count || unresolved)
          {
@@ -10272,7 +11007,7 @@ void ProcessExpressionType(Expression exp)
                //CheckExpressionType(exp, exp.destType, false);
 
                if(exp.destType.truth && exp.destType._class && exp.destType._class.registered && !strcmp(exp.destType._class.registered.name, "bool") &&
-                  exp.expType.kind != voidType && exp.expType.kind != structType && exp.expType.kind != unionType && 
+                  exp.expType.kind != voidType && exp.expType.kind != structType && exp.expType.kind != unionType &&
                   (exp.expType.kind != classType || exp.expType.classObjectType || (exp.expType._class && exp.expType._class.registered && exp.expType._class.registered.type != structClass)));
                else
                {
@@ -10281,7 +11016,7 @@ void ProcessExpressionType(Expression exp)
                   if(inCompiler) { PrintExpression(exp, expString); ChangeCh(expString, '\n', ' '); }
 
 #ifdef _DEBUG
-                  CheckExpressionType(exp, exp.destType, false);
+                  CheckExpressionType(exp, exp.destType, false, true);
 #endif
                   // Flex & Bison generate code that triggers this, so we ignore it for a quiet sdk build:
                   if(!sourceFile || (strcmp(sourceFile, "src\\lexer.ec") && strcmp(sourceFile, "src/lexer.ec") && strcmp(sourceFile, "src\\grammar.ec") && strcmp(sourceFile, "src/grammar.ec")))
@@ -10313,7 +11048,7 @@ void ProcessExpressionType(Expression exp)
 
          PrintType(exp.expType, typeString, false, false);
          decl = SpecDeclFromString(typeString, specs, null);
-         
+
          exp.cast.typeName = MkTypeName(specs, decl);
          exp.cast.exp = newExp;
       }
@@ -10334,13 +11069,14 @@ void ProcessExpressionType(Expression exp)
    }
 
    // Let's try to support any_object & typed_object here:
-   ApplyAnyObjectLogic(exp);
+   if(inCompiler)
+      ApplyAnyObjectLogic(exp);
 
    // Mark nohead classes as by reference, unless we're casting them to an integral type
    if(!notByReference && exp.expType && exp.expType.kind == classType && exp.expType._class && exp.expType._class.registered &&
-      exp.expType._class.registered.type == noHeadClass && (!exp.destType || 
-         (exp.destType.kind != intType && exp.destType.kind != int64Type && exp.destType.kind != intPtrType && exp.destType.kind != intSizeType && 
-          exp.destType.kind != longType && exp.destType.kind != shortType && exp.destType.kind != charType)))
+      exp.expType._class.registered.type == noHeadClass && (!exp.destType ||
+         (exp.destType.kind != intType && exp.destType.kind != int64Type && exp.destType.kind != intPtrType && exp.destType.kind != intSizeType &&
+          exp.destType.kind != longType && exp.destType.kind != shortType && exp.destType.kind != charType && exp.destType.kind != _BoolType)))
    {
       exp.byReference = true;
    }
@@ -10350,7 +11086,7 @@ void ProcessExpressionType(Expression exp)
 static void FindNextDataMember(Class _class, Class * curClass, DataMember * curMember, DataMember * subMemberStack, int * subMemberStackPos)
 {
    // THIS CODE WILL FIND NEXT MEMBER...
-   if(*curMember) 
+   if(*curMember)
    {
       *curMember = (*curMember).next;
 
@@ -10372,7 +11108,7 @@ static void FindNextDataMember(Class _class, Class * curClass, DataMember * curM
 
             *curMember = (*curMember).members.first;
             while(*curMember && (*curMember).isProperty)
-               *curMember = (*curMember).next;                     
+               *curMember = (*curMember).next;
          }
       }
    }
@@ -10405,7 +11141,7 @@ static void FindNextDataMember(Class _class, Class * curClass, DataMember * curM
 
                *curMember = (*curMember).members.first;
                while(*curMember && (*curMember).isProperty)
-                  *curMember = (*curMember).next;                     
+                  *curMember = (*curMember).next;
             }
          }
       }
@@ -10614,14 +11350,14 @@ static void ProcessDeclarator(Declarator decl)
                   declarator = null;
                };
                if(!decl.function.parameters)
-                  decl.function.parameters = MkList();               
+                  decl.function.parameters = MkList();
                decl.function.parameters->Insert(null, param);
                id._class = null;
             }
             if(decl.function.parameters)
             {
                TypeName param;
-               
+
                for(param = decl.function.parameters->first; param; param = param.next)
                {
                   if(param.qualifiers && param.qualifiers->first)
@@ -10635,7 +11371,9 @@ static void ProcessDeclarator(Declarator decl)
                            qualifiers = MkListOne(MkSpecifier(VOID));
                            declarator = MkDeclaratorPointer(MkPointer(null,null), d);
                         };
-                        
+                        if(d.type != pointerDeclarator)
+                           newParam.qualifiers->Insert(null, MkSpecifier(CONST));
+
                         FreeList(param.qualifiers, FreeSpecifier);
 
                         param.qualifiers = MkListOne(MkStructOrUnion(structSpecifier, MkIdentifier("__ecereNameSpace__ecere__com__Class"), null));
@@ -10647,11 +11385,13 @@ static void ProcessDeclarator(Declarator decl)
                      else if(spec && spec.specifier == ANY_OBJECT)
                      {
                         Declarator d = param.declarator;
-                        
+
                         FreeList(param.qualifiers, FreeSpecifier);
 
                         param.qualifiers = MkListOne(MkSpecifier(VOID));
-                        param.declarator = MkDeclaratorPointer(MkPointer(null,null), d);                        
+                        if(d.type != pointerDeclarator)
+                           param.qualifiers->Insert(null, MkSpecifier(CONST));
+                        param.declarator = MkDeclaratorPointer(MkPointer(null,null), d);
                      }
                      else if(spec.specifier == THISCLASS)
                      {
@@ -10690,7 +11430,7 @@ static void ProcessDeclaration(Declaration decl)
          if(decl.declarators)
          {
             InitDeclarator d;
-         
+
             for(d = decl.declarators->first; d; d = d.next)
             {
                Type type, subType;
@@ -10702,17 +11442,17 @@ static void ProcessDeclaration(Declaration decl)
                {
                   ProcessInitializer(d.initializer, type);
 
-                  // Change "ColorRGB a = ColorRGB { 1,2,3 } => ColorRGB a { 1,2,3 }                  
-                  
+                  // Change "ColorRGB a = ColorRGB { 1,2,3 } => ColorRGB a { 1,2,3 }
+
                   if(decl.declarators->count == 1 && d.initializer.type == expInitializer &&
                      d.initializer.exp.type == instanceExp)
                   {
-                     if(type.kind == classType && type._class == 
+                     if(type.kind == classType && type._class ==
                         d.initializer.exp.expType._class)
                      {
                         Instantiation inst = d.initializer.exp.instance;
                         inst.exp = MkExpIdentifier(CopyIdentifier(GetDeclId(d.declarator)));
-                        
+
                         d.initializer.exp.instance = null;
                         if(decl.specifiers)
                            FreeList(decl.specifiers, FreeSpecifier);
@@ -10838,7 +11578,7 @@ static void CreateFireWatcher(Property prop, Expression object, Statement stmt)
       ListAdd(stmt.expressions, MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eInstance_FireWatchers")), args));
    }
 
-   
+
    {
       args = MkList();
       ListAdd(args, object ? CopyExpression(object) : MkExpIdentifier(MkIdentifier("this")));
@@ -10850,8 +11590,8 @@ static void CreateFireWatcher(Property prop, Expression object, Statement stmt)
       ListAdd(args, MkExpIdentifier(MkIdentifier(propNameM)));
       ListAdd(stmt.expressions, MkExpCall(MkExpIdentifier(MkIdentifier("ecere::com::eInstance_FireSelfWatchers")), args));
    }
-   
-   if(curFunction.propSet && !strcmp(curFunction.propSet.string, prop.name) && 
+
+   if(curFunction.propSet && !strcmp(curFunction.propSet.string, prop.name) &&
       (!object || (object.type == identifierExp && !strcmp(object.identifier.string, "this"))))
       curFunction.propSet.fireWatchersDone = true;
 }
@@ -10892,10 +11632,8 @@ static void ProcessStatement(Statement stmt)
             Context prevContext = curContext;
 
             if(!stmt.compound.isSwitch)
-            {
                curCompound = stmt;
-               curContext = stmt.compound.context;
-            }
+            curContext = stmt.compound.context;
 
             if(stmt.compound.declarations)
             {
@@ -11042,11 +11780,11 @@ static void ProcessStatement(Statement stmt)
          char iteratorType[1024];
          Type source;
          Expression e;
-         bool isBuiltin = exp && exp->last && 
-            (((Expression)exp->last).type == ExpressionType::arrayExp || 
+         bool isBuiltin = exp && exp->last &&
+            (((Expression)exp->last).type == ExpressionType::arrayExp ||
               (((Expression)exp->last).type == castExp && ((Expression)exp->last).cast.exp.type == ExpressionType::arrayExp));
          Expression arrayExp;
-         char * typeString = null;
+         const char * typeString = null;
          int builtinCount = 0;
 
          for(e = exp ? exp->first : null; e; e = e.next)
@@ -11067,12 +11805,12 @@ static void ProcessStatement(Statement stmt)
             Class _class = source ? source._class.registered : null;
             Symbol symbol;
             Expression expIt = null;
-            bool isMap = false, isArray = false, isLinkList = false, isList = false, isCustomAVLTree = false, isAVLTree = false;
+            bool isMap = false, isArray = false, isLinkList = false, isList = false, isCustomAVLTree = false; //, isAVLTree = false;
             Class arrayClass = eSystem_FindClass(privateModule, "Array");
             Class linkListClass = eSystem_FindClass(privateModule, "LinkList");
             Class customAVLTreeClass = eSystem_FindClass(privateModule, "CustomAVLTree");
             stmt.type = compoundStmt;
-            
+
             stmt.compound.context = Context { };
             stmt.compound.context.parent = curContext;
             curContext = stmt.compound.context;
@@ -11080,15 +11818,15 @@ static void ProcessStatement(Statement stmt)
             if(source && eClass_IsDerived(source._class.registered, customAVLTreeClass))
             {
                Class mapClass = eSystem_FindClass(privateModule, "Map");
-               Class avlTreeClass = eSystem_FindClass(privateModule, "AVLTree");
+               //Class avlTreeClass = eSystem_FindClass(privateModule, "AVLTree");
                isCustomAVLTree = true;
-               if(eClass_IsDerived(source._class.registered, avlTreeClass))
+               /*if(eClass_IsDerived(source._class.registered, avlTreeClass))
                   isAVLTree = true;
-               else if(eClass_IsDerived(source._class.registered, mapClass))
+               else */if(eClass_IsDerived(source._class.registered, mapClass))
                   isMap = true;
             }
             else if(source && eClass_IsDerived(source._class.registered, arrayClass)) isArray = true;
-            else if(source && eClass_IsDerived(source._class.registered, linkListClass)) 
+            else if(source && eClass_IsDerived(source._class.registered, linkListClass))
             {
                Class listClass = eSystem_FindClass(privateModule, "List");
                isLinkList = true;
@@ -11099,19 +11837,19 @@ static void ProcessStatement(Statement stmt)
             {
                Declarator decl;
                OldList * specs = MkList();
-               decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, 
+               decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs,
                   MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(id)));
                stmt.compound.declarations = MkListOne(
                   MkDeclaration(specs, MkListOne(MkInitDeclarator(decl, null))));
                ListAdd(stmt.compound.declarations, MkDeclaration(MkListOne(MkSpecifierName(source._class.registered.fullName)),
-                  MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalArray")), 
+                  MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalArray")),
                      MkInitializerAssignment(MkExpBrackets(exp))))));
             }
             else if(isBuiltin)
             {
                Type type = null;
                char typeStringBuf[1024];
-               
+
                // TODO: Merge this code?
                arrayExp = (((Expression)exp->last).type == ExpressionType::arrayExp) ? (Expression)exp->last : ((Expression)exp->last).cast.exp;
                if(((Expression)exp->last).type == castExp)
@@ -11141,25 +11879,25 @@ static void ProcessStatement(Statement stmt)
                         else
                         {
                            // if(!MatchType(e.expType, type, null, null, null, false, false, false))
-                           if(!MatchTypeExpression(e, type, null, false))
+                           if(!MatchTypeExpression(e, type, null, false, true))
                            {
                               FreeType(type);
                               type = e.expType;
                               e.expType = null;
-                              
+
                               e = arrayExp.list->first;
                               ProcessExpressionType(e);
                               if(e.expType)
                               {
                                  //if(!MatchTypes(e.expType, type, null, null, null, false, false, false, false))
-                                 if(!MatchTypeExpression(e, type, null, false))
+                                 if(!MatchTypeExpression(e, type, null, false, true))
                                  {
                                     FreeType(e.expType);
                                     e.expType = null;
                                     FreeType(type);
                                     type = null;
                                     break;
-                                 }                           
+                                 }
                               }
                            }
                         }
@@ -11201,7 +11939,7 @@ static void ProcessStatement(Statement stmt)
                      delete arrayExp.list;
                   }
                   decl = SpecDeclFromString(typeString, specs, MkDeclaratorIdentifier(id));
-                  stmt.compound.declarations = MkListOne(MkDeclaration(CopyList(specs, CopySpecifier), 
+                  stmt.compound.declarations = MkListOne(MkDeclaration(CopyList(specs, CopySpecifier),
                      MkListOne(MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null), /*CopyDeclarator(*/decl/*)*/), null))));
 
                   ListAdd(stmt.compound.declarations, MkDeclaration(specs, MkListOne(MkInitDeclarator(
@@ -11220,12 +11958,12 @@ static void ProcessStatement(Statement stmt)
                Declarator decl;
                OldList * specs = MkList();
 
-               decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, 
+               decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs,
                   MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(id)));
                stmt.compound.declarations = MkListOne(
                   MkDeclaration(specs, MkListOne(MkInitDeclarator(decl, null))));
                ListAdd(stmt.compound.declarations, MkDeclaration(MkListOne(MkSpecifierName("BuiltInContainer")),
-                  MkListOne(MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier("__internalArray"))), 
+                  MkListOne(MkInitDeclarator(MkDeclaratorPointer(MkPointer(null, null), MkDeclaratorIdentifier(MkIdentifier("__internalArray"))),
                      MkInitializerAssignment(MkExpBrackets(exp))))));
                */
             }
@@ -11236,7 +11974,7 @@ static void ProcessStatement(Statement stmt)
                decl = SpecDeclFromString(_class.templateArgs[3].dataTypeString, specs, MkDeclaratorIdentifier(id));
                stmt.compound.declarations = MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(decl, null))));
                ListAdd(stmt.compound.declarations, MkDeclaration(MkListOne(MkSpecifierName(source._class.registered.fullName)),
-                  MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalLinkList")), 
+                  MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalLinkList")),
                      MkInitializerAssignment(MkExpBrackets(exp))))));
             }
             /*else if(isCustomAVLTree)
@@ -11246,7 +11984,7 @@ static void ProcessStatement(Statement stmt)
                decl = SpecDeclFromString(_class.templateArgs[3].dataTypeString, specs, MkDeclaratorIdentifier(id));
                stmt.compound.declarations = MkListOne(MkDeclaration(specs, MkListOne(MkInitDeclarator(decl, null))));
                ListAdd(stmt.compound.declarations, MkDeclaration(MkListOne(MkSpecifierName(source._class.registered.fullName)),
-                  MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalTree")), 
+                  MkListOne(MkInitDeclarator(MkDeclaratorIdentifier(MkIdentifier("__internalTree")),
                      MkInitializerAssignment(MkExpBrackets(exp))))));
             }*/
             else if(_class.templateArgs)
@@ -11258,14 +11996,61 @@ static void ProcessStatement(Statement stmt)
 
                stmt.compound.declarations = MkListOne(
                   MkDeclarationInst(MkInstantiationNamed(MkListOne(MkSpecifierName(iteratorType)),
-                  MkExpIdentifier(id), MkListOne(MkMembersInitList(MkListOne(MkMemberInit(isMap ? MkListOne(MkIdentifier("map")) : null, 
+                  MkExpIdentifier(id), MkListOne(MkMembersInitList(MkListOne(MkMemberInit(isMap ? MkListOne(MkIdentifier("map")) : null,
                   MkInitializerAssignment(MkExpBrackets(exp)))))))));
             }
             symbol = FindSymbol(id.string, curContext, curContext, false, false);
 
-            if(block && block.type == compoundStmt && block.compound.context)
+            if(block)
             {
-               block.compound.context.parent = stmt.compound.context;
+               // Reparent sub-contexts in this statement
+               switch(block.type)
+               {
+                  case compoundStmt:
+                     if(block.compound.context)
+                        block.compound.context.parent = stmt.compound.context;
+                     break;
+                  case ifStmt:
+                     if(block.ifStmt.stmt && block.ifStmt.stmt.type == compoundStmt && block.ifStmt.stmt.compound.context)
+                        block.ifStmt.stmt.compound.context.parent = stmt.compound.context;
+                     if(block.ifStmt.elseStmt && block.ifStmt.elseStmt.type == compoundStmt && block.ifStmt.elseStmt.compound.context)
+                        block.ifStmt.elseStmt.compound.context.parent = stmt.compound.context;
+                     break;
+                  case switchStmt:
+                     if(block.switchStmt.stmt && block.switchStmt.stmt.type == compoundStmt && block.switchStmt.stmt.compound.context)
+                        block.switchStmt.stmt.compound.context.parent = stmt.compound.context;
+                     break;
+                  case whileStmt:
+                     if(block.whileStmt.stmt && block.whileStmt.stmt.type == compoundStmt && block.whileStmt.stmt.compound.context)
+                        block.whileStmt.stmt.compound.context.parent = stmt.compound.context;
+                     break;
+                  case doWhileStmt:
+                     if(block.doWhile.stmt && block.doWhile.stmt.type == compoundStmt && block.doWhile.stmt.compound.context)
+                        block.doWhile.stmt.compound.context.parent = stmt.compound.context;
+                     break;
+                  case forStmt:
+                     if(block.forStmt.stmt && block.forStmt.stmt.type == compoundStmt && block.forStmt.stmt.compound.context)
+                        block.forStmt.stmt.compound.context.parent = stmt.compound.context;
+                     break;
+                  case forEachStmt:
+                     if(block.forEachStmt.stmt && block.forEachStmt.stmt.type == compoundStmt && block.forEachStmt.stmt.compound.context)
+                        block.forEachStmt.stmt.compound.context.parent = stmt.compound.context;
+                     break;
+                  /* Only handle those with compound blocks for now... (Potential limitation on compound statements within expressions)
+                  case labeledStmt:
+                  case caseStmt
+                  case expressionStmt:
+                  case gotoStmt:
+                  case continueStmt:
+                  case breakStmt
+                  case returnStmt:
+                  case asmStmt:
+                  case badDeclarationStmt:
+                  case fireWatchersStmt:
+                  case stopWatchingStmt:
+                  case watchStmt:
+                  */
+               }
             }
             if(filter)
             {
@@ -11275,7 +12060,7 @@ static void ProcessStatement(Statement stmt)
             {
                stmt.compound.statements = MkListOne(MkForStmt(
                   MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpMember(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("array"))))),
-                  MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '<', 
+                  MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '<',
                      MkExpOp(MkExpMember(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("array")), '+', MkExpMember(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("count")))))),
                   MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), INC_OP, null)),
                   block));
@@ -11293,7 +12078,7 @@ static void ProcessStatement(Statement stmt)
 
                stmt.compound.statements = MkListOne(MkForStmt(
                   MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpIdentifier(MkIdentifier("__internalArray"))))),
-                  MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '<', 
+                  MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '<',
                      MkExpOp(MkExpIdentifier(MkIdentifier("__internalArray")), '+', MkExpConstant(count))))),
                   MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), INC_OP, null)),
                   block));
@@ -11302,7 +12087,7 @@ static void ProcessStatement(Statement stmt)
                Declarator decl = SpecDeclFromString(_class.templateArgs[2].dataTypeString, specs, MkDeclaratorPointer(MkPointer(null, null), null));
                stmt.compound.statements = MkListOne(MkForStmt(
                   MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '=', MkExpPointer(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("data"))))),
-                  MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '<', 
+                  MkExpressionStmt(MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), '<',
                      MkExpOp(MkExpCast(MkTypeName(specs, decl), MkExpPointer(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("data"))), '+', MkExpPointer(MkExpIdentifier(MkIdentifier("__internalArray")), MkIdentifier("count")))))),
                   MkListOne(MkExpOp(MkExpIdentifier(CopyIdentifier(id)), INC_OP, null)),
                   block));
@@ -11315,7 +12100,7 @@ static void ProcessStatement(Statement stmt)
             {
                Class typeClass = eSystem_FindClass(_class.module, _class.templateArgs[3].dataTypeString);
                Class listItemClass = eSystem_FindClass(_class.module, "ListItem");
-               if(typeClass && eClass_IsDerived(typeClass, listItemClass) && _class.templateArgs[5].dataTypeString && 
+               if(typeClass && eClass_IsDerived(typeClass, listItemClass) && _class.templateArgs[5].dataTypeString &&
                   !strcmp(_class.templateArgs[5].dataTypeString, "LT::link"))
                {
                   stmt.compound.statements = MkListOne(MkForStmt(
@@ -11362,7 +12147,7 @@ static void ProcessStatement(Statement stmt)
             if(stmt.compound.declarations->first)
                ProcessDeclaration(stmt.compound.declarations->first);
 
-            if(symbol) 
+            if(symbol)
                symbol.isIterator = isMap ? 2 : ((isArray || isBuiltin) ? 3 : (isLinkList ? (isList ? 5 : 4) : (isCustomAVLTree ? 6 : 1)));
 
             ProcessStatement(stmt);
@@ -11459,7 +12244,7 @@ static void ProcessStatement(Statement stmt)
                {
                   ClassFunction func;
                   char watcherName[1024];
-                  Class watcherClass = watcher ? 
+                  Class watcherClass = watcher ?
                      ((watcher.expType && watcher.expType.kind == classType && watcher.expType._class) ? watcher.expType._class.registered : null) : thisClass;
                   External createdExternal;
 
@@ -11502,7 +12287,7 @@ static void ProcessStatement(Statement stmt)
 
                      // Create a declaration above
                      {
-                        Declaration decl = MkDeclaration(CopyList(createdExternal.function.specifiers, CopySpecifier), 
+                        Declaration decl = MkDeclaration(CopyList(createdExternal.function.specifiers, CopySpecifier),
                            MkListOne(MkInitDeclarator(CopyDeclarator(createdExternal.function.declarator), null)));
                         externalDecl.declaration = decl;
                         if(decl.symbol && !decl.symbol.pointerExternal)
@@ -11531,8 +12316,8 @@ static void ProcessStatement(Statement stmt)
                               char getName[1024], setName[1024];
                               OldList * args = MkList();
 
-                              DeclareProperty(prop, setName, getName);                              
-                              
+                              DeclareProperty(prop, setName, getName);
+
                               // eInstance_Watch(stmt.watch.object, prop, stmt.watch.watcher, callback);
                               strcpy(propName, "__ecereProp_");
                               FullClassNameCat(propName, prop._class.fullName, false);
@@ -11548,7 +12333,7 @@ static void ProcessStatement(Statement stmt)
                               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);
                         }
                      }
                   }
@@ -11591,7 +12376,7 @@ static void ProcessStatement(Statement stmt)
 
          if(inCompiler)
          {
-            _class = object ? 
+            _class = object ?
                   ((object.expType && object.expType.kind == classType && object.expType._class) ? object.expType._class.registered : null) : thisClass;
 
             if(_class)
@@ -11675,7 +12460,7 @@ static void ProcessStatement(Statement stmt)
                   if(!watches)
                   {
                      OldList * args;
-                     // eInstance_StopWatching(object, null, watcher); 
+                     // eInstance_StopWatching(object, null, watcher);
                      args = MkList();
                      ListAdd(args, CopyExpression(object));
                      ListAdd(args, MkExpConstant("0"));
@@ -11694,8 +12479,8 @@ static void ProcessStatement(Statement stmt)
                            OldList * args = MkList();
 
                            DeclareProperty(prop, setName, getName);
-         
-                           // eInstance_StopWatching(object, prop, watcher); 
+
+                           // eInstance_StopWatching(object, prop, watcher);
                            strcpy(propName, "__ecereProp_");
                            FullClassNameCat(propName, prop._class.fullName, false);
                            strcat(propName, "_");
@@ -11709,7 +12494,7 @@ static void ProcessStatement(Statement stmt)
                            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);
                      }
                   }
 
@@ -11740,7 +12525,7 @@ static void ProcessFunction(FunctionDefinition function)
 
    yylloc = function.loc;
    // Process thisClass
-   
+
    if(type && type.thisClass)
    {
       Symbol classSym = type.thisClass;
@@ -11795,7 +12580,7 @@ static void ProcessFunction(FunctionDefinition function)
          FullClassNameCat(structName, _class.fullName, false);
 
          // [class] this
-         
+
 
          funcDecl = GetFuncDecl(function.declarator);
          if(funcDecl)
@@ -11812,12 +12597,12 @@ static void ProcessFunction(FunctionDefinition function)
 
             // DANGER: Watch for this... Check if it's a Conversion?
             // if((_class.type != bitClass && _class.type != unitClass && _class.type != enumClass) || function != (FunctionDefinition)symbol.externalSet)
-            
+
             // WAS TRYING THIS FOR CONVERSION PROPERTIES ON NOHEAD CLASSES: if((_class.type == structClass) || function != (FunctionDefinition)symbol.externalSet)
             if(!function.propertyNoThis)
             {
                TypeName thisParam;
-               
+
                if(type.classObjectType != classPointer)
                {
                   thisParam = QMkClass(_class.fullName, MkDeclaratorIdentifier(MkIdentifier("this")));
@@ -11872,10 +12657,10 @@ static void ProcessFunction(FunctionDefinition function)
                      funcDecl.function.parameters->Insert(null, thisParam);
                   }
                }
-            }         
+            }
          }
       }
-      
+
       // Add this to the context
       if(function.body)
       {
@@ -11892,6 +12677,7 @@ static void ProcessFunction(FunctionDefinition function)
             {
                thisSymbol.type.classObjectType = ClassObjectType::typedObject;
                thisSymbol.type.byReference = type.byReference;
+               thisSymbol.type.typedByReference = type.byReference;
                /*
                thisSymbol = Symbol { string = CopyString("class") };
                function.body.compound.context.symbols.Add(thisSymbol);
@@ -11901,7 +12687,7 @@ static void ProcessFunction(FunctionDefinition function)
       }
 
       // Pointer to class data
-      
+
       if(inCompiler && _class && (_class.type == normalClass /*|| _class.type == noHeadClass*/) && type.classObjectType != classPointer)
       {
          DataMember member = null;
@@ -11922,11 +12708,11 @@ static void ProcessFunction(FunctionDefinition function)
          if(member)
          {
             char pointerName[1024];
-   
+
             Declaration decl;
             Initializer initializer;
             Expression exp, bytePtr;
-   
+
             strcpy(pointerName, "__ecerePointer_");
             FullClassNameCat(pointerName, _class.fullName, false);
             {
@@ -11963,7 +12749,7 @@ static void ProcessFunction(FunctionDefinition function)
                kind = pointerType;
                type = Type { refCount = 1, kind = voidType };
             };
-   
+
             if(function.body)
             {
                yylloc = function.body.loc;
@@ -11994,7 +12780,7 @@ static void ProcessFunction(FunctionDefinition function)
             }
          }
       }
-      
+
 
       // Loop through the function and replace undeclared identifiers
       // which are a member of the class (methods, properties or data)
@@ -12104,7 +12890,7 @@ static void ProcessClass(OldList definitions, Symbol symbol)
             type = regClass ? MkClassType(regClass.fullName) : null;
          };
          globalContext.symbols.Add((BTNode)thisSymbol);
-         
+
          for(defProperty = def.defProperties->first; defProperty; defProperty = defProperty.next)
          {
             thisClass = regClass;
@@ -12124,7 +12910,7 @@ static void ProcessClass(OldList definitions, Symbol symbol)
          Symbol thisSymbol = Symbol { string = CopyString("this"), type = MkClassType(regClass.fullName) };
          globalContext.symbols.Add(thisSymbol);
          */
-         
+
          thisClass = regClass;
          if(prop.setStmt)
          {
@@ -12182,7 +12968,7 @@ static void ProcessClass(OldList definitions, Symbol symbol)
       else if(def.type == propertyWatchClassDef && def.propertyWatch)
       {
          PropertyWatch propertyWatch = def.propertyWatch;
-        
+
          thisClass = regClass;
          if(propertyWatch.compound)
          {
@@ -12202,7 +12988,7 @@ static void ProcessClass(OldList definitions, Symbol symbol)
    }
 }
 
-void DeclareFunctionUtil(String s)
+void DeclareFunctionUtil(const String s)
 {
    GlobalFunction function = eSystem_FindFunction(privateModule, s);
    if(function)
@@ -12266,7 +13052,15 @@ void ComputeDataTypes()
    DeclareFunctionUtil("eSystem_New0");
    DeclareFunctionUtil("eSystem_Renew");
    DeclareFunctionUtil("eSystem_Renew0");
+   DeclareFunctionUtil("eSystem_Delete");
    DeclareFunctionUtil("eClass_GetProperty");
+   DeclareFunctionUtil("eClass_SetProperty");
+   DeclareFunctionUtil("eInstance_FireSelfWatchers");
+   DeclareFunctionUtil("eInstance_SetMethod");
+   DeclareFunctionUtil("eInstance_IncRef");
+   DeclareFunctionUtil("eInstance_StopWatching");
+   DeclareFunctionUtil("eInstance_Watch");
+   DeclareFunctionUtil("eInstance_FireWatchers");
 
    DeclareStruct("ecere::com::Class", false);
    DeclareStruct("ecere::com::Instance", false);
@@ -12290,7 +13084,8 @@ void ComputeDataTypes()
       else if(external.type == declarationExternal)
       {
          currentClass = null;
-         ProcessDeclaration(external.declaration);
+         if(external.declaration)
+            ProcessDeclaration(external.declaration);
       }
       else if(external.type == classExternal)
       {
@@ -12314,6 +13109,7 @@ void ComputeDataTypes()
    }
    currentClass = null;
    thisNameSpace = null;
+   curExternal = null;
 
    delete temp.symbol;
    delete temp;