c439f550f8e5d06d84b2237374ea45ea4460da66
[sdk] / ide / src / debugger / debugTools.ec
1 import "ide"
2
3 static Map<String, uintptr> oneArgFns
4 { [
5    { "sqrt", (uintptr)sqrt },
6    { "log", (uintptr)log },
7    { "log10", (uintptr)log10 },
8    { "sin", (uintptr)sin },
9    { "cos", (uintptr)cos },
10    { "tan", (uintptr)tan },
11    { "asin", (uintptr)asin },
12    { "acos", (uintptr)acos },
13    { "atan", (uintptr)atan },
14    { "sinh", (uintptr)sinh },
15    { "cosh", (uintptr)cosh },
16    { "tanh", (uintptr)tanh },
17    { "asinh", (uintptr)asinh },
18    { "acosh", (uintptr)acosh },
19    { "atanh", (uintptr)atanh },
20    { "exp", (uintptr)exp },
21    { "floor", (uintptr)floor },
22    { "ceil", (uintptr)ceil },
23    { "fabs", (uintptr)sqrt }
24 ] };
25
26 static Map<String, uintptr> twoArgFns
27 { [
28    { "pow", (uintptr)pow },
29    { "atan2", (uintptr)atan2 },
30    { "fmod", (uintptr)fmod }
31 ] };
32
33 static void CarryExpressionError(Expression exp, Expression expError)
34 {
35    Expression temp { };
36
37    // This function assumes that expError is contained within exp,
38    // and therefore these types will be freed when freeing the old contents
39    // of the expression we're carying into.
40
41    if(expError.destType) expError.destType.refCount++;
42    if(expError.expType) expError.expType.refCount++;
43
44    *temp = *expError;
45
46    // -- Careful: this could be problematic as FreeExpContents will free the contents of expError
47    // Nulling things that may be freed now, but this is all overly messy/complex
48    switch(expError.type)
49    {
50       case functionCallErrorExp:
51          expError.call.exp = null;
52          expError.call.arguments = null;
53          break;
54       case symbolErrorExp:
55          expError.identifier = null;
56          break;
57       case memoryErrorExp:
58          expError.constant = null;
59          break;
60       case memberPropertyErrorExp:
61       case memberSymbolErrorExp:
62          expError.member.exp = null;
63          expError.member.member = null;
64          break;
65    }
66
67    /*
68    Identifier identifier = expError.identifier;
69    expError.identifier = null;
70    FreeExpContents(exp);
71    exp.identifier = identifier;
72    exp.type = expError.type;
73    */
74    if(exp.expType) FreeType(exp.expType);
75    if(exp.destType) FreeType(exp.destType);
76    FreeExpContents(exp);
77    *exp = *temp; //*expError;
78    delete temp;
79    // memset(expError, 0, sizeof(class Expression));
80 }
81
82 static char GetGdbFormatChar(Type type)
83 {
84 //          x : Regard the bits of the value as an integer, and print the integer in hexadecimal.
85 //          d : Print as integer in signed decimal.
86 //          u : Print as integer in unsigned decimal.
87 //          o : Print as integer in octal.
88 //          t : Print as integer in binary. The letter `t' stands for "two". (4)
89 //          a : Print as an address, both absolute in hexadecimal and as an offset from the nearest preceding symbol. You can use this format used to discover where (in what function) an unknown address is located:
90 //          c : Regard as an integer and print it as a character constant. This prints both the numerical value and its character representation. The character representation is replaced with the octal escape `\nnn' for characters outside the 7-bit ASCII range.
91 //          f : Regard the bits of the value as a floating point number and print using typical floating point syntax.
92    if(!type)
93       return 'x';
94
95    switch(type.kind)
96    {
97       case charType:
98          //return 'c';
99       case shortType:
100       case intType:
101       case longType:
102       case int64Type:
103          if(type.isSigned)
104             return 'd';
105          else
106             return 'u';
107       case floatType:
108          return 'f';
109       case doubleType:
110          return 'f';
111       case structType:
112       case unionType:
113       case functionType:
114       case arrayType:
115          // return 'u';
116          return 0;
117       case ellipsisType:
118       case enumType:
119       case methodType:
120       case vaListType:
121       // case TypeTypedObject, TypeAnyObject, TypeClassPointer:
122       case dummyType:
123          break;
124       case classType:
125       case pointerType:
126          return 'x';
127    }
128    return 'x';
129 }
130
131 /*static */bool ExpressionIsError(Expression exp)
132 {
133    return (exp.type == dereferenceErrorExp || exp.type == symbolErrorExp ||
134          exp.type == memberSymbolErrorExp || exp.type == memoryErrorExp || exp.type == unknownErrorExp ||
135          exp.type == noDebuggerErrorExp || exp.type == memberPropertyErrorExp || exp.type == functionCallErrorExp || exp.type == divideBy0ErrorExp);
136 }
137
138 void DebugComputeExpression(Expression exp)
139 {
140 #ifdef _DEBUG
141    char expString[1024] = "";
142    //char temp[1024];
143    //if(inCompiler)
144       PrintExpression(exp, expString);
145    // printf("%s (exp.type = %s)\n", expString, exp.type.OnGetString(temp, null, null));
146 #endif
147    switch(exp.type)
148    {
149       case identifierExp:
150       {
151          Expression prev = exp.prev, next = exp.next;
152          char * evaluation = null;
153          ExpressionType evalError = dummyExp;
154          Expression expNew;
155          TypeKind kind = dummyType;
156          Type dataType = exp.expType;
157          uint64 address = 0;
158          bool hasAddress;
159          bool isPointer = false;
160          bool evaluate = false;
161          bool evaluateAddress = false;
162          String idString = null;
163          if(exp.identifier.string)
164          {
165             const String start = (exp.identifier.string[0] == ':' && exp.identifier.string[1] == ':') ? exp.identifier.string + 2 : exp.identifier.string;
166             if(strstr(start, "::"))
167             {
168                char prefix[] = "__ecereNameSpace__";
169                int len = strlen(start);
170                idString = new char[len + sizeof(prefix)];
171                memcpy(idString, prefix, sizeof(prefix) - 1);
172                memcpy(idString + sizeof(prefix) - 1, start, len + 1);
173                ChangeCh(idString + sizeof(prefix) - 1, ':', '_');
174             }
175             else
176                idString = CopyString(exp.identifier.string);
177          }
178
179          if(dataType && dataType.kind == classType && dataType._class.registered)
180          {
181             Class _class = dataType._class.registered;
182             if(_class.type == bitClass || _class.type == unitClass || _class.type == enumClass)
183             {
184                if(!_class.dataType)
185                   _class.dataType = ProcessTypeString(_class.dataTypeString, false);
186                dataType = _class.dataType;
187             }
188             else if(_class.type == normalClass || _class.type == noHeadClass || _class.type == systemClass) // Added systemClass here for Instance
189             {
190                isPointer = true;
191             }
192          }
193          else if(dataType && dataType.kind == classType && !dataType._class.registered)
194             isPointer = true;
195          if(dataType)
196             kind = dataType.kind;
197          else
198          {
199             exp.type = symbolErrorExp;
200             evalError = symbolErrorExp;
201          }
202          switch(kind)
203          {
204             case intPtrType: case intSizeType: case _BoolType:
205             case charType: case shortType: case intType: case int64Type: case longType: case floatType: case doubleType:
206             case enumType:
207             case arrayType:
208             case structType:
209             case pointerType:
210             case unionType:
211                evaluate = true;
212                evaluateAddress = true;
213                break;
214             case classType:
215                if(exp.byReference && dataType._class && dataType._class.registered && dataType._class.registered.type == structClass)
216                // if(!dataType._class || !dataType._class.registered || dataType._class.registered.type != structClass || exp.byReference)
217                   evaluateAddress = false;
218                else
219                   evaluateAddress = true;
220                evaluate = true;
221                break;
222             case functionType:
223             case ellipsisType:
224             case methodType:
225             case vaListType:
226             // case TypeTypedObject, TypeAnyObject, TypeClassPointer:
227             case dummyType:
228                break;
229          }
230          if(evaluate)
231          {
232             char temp[1024];
233             if(evaluateAddress)
234             {
235                temp[0] = '&';
236                strcpy(temp + 1, idString);
237             }
238             else
239                strcpy(temp, idString);
240
241             evaluation = Debugger::EvaluateExpression(temp, &evalError);
242             if(evaluation)
243             {
244                address = _strtoui64(evaluation, null, 0);
245                //delete evaluation;
246                //evaluation = null;
247             }
248             else
249                address = 0;
250             hasAddress = true;
251          }
252          else
253             hasAddress = false;
254
255          if(evalError == dummyExp)
256          {
257             switch(kind)
258             {
259                case charType:
260                   delete evaluation;
261                   evaluation = Debugger::EvaluateExpression(idString, &evalError);
262                   if(evaluation)
263                   {
264                      //int c, len;
265                      char * temp;
266                      temp = strstr(evaluation, " '");
267                      //len = strlen(temp);
268                      if(temp)
269                         temp[0] = '\0';
270                      {/*
271                         for(c = 0; c < len; c++)
272                            temp[c] = ' ';
273                         eString_TrimRSpaces(evaluation, evaluation);
274                      */}
275                   }
276                   break;
277                case shortType:
278                case intType:
279                case longType:
280                case intPtrType:
281                case intSizeType:
282                case _BoolType:
283                case int64Type:
284                case floatType:
285                case doubleType:
286                case enumType:
287                case pointerType:
288                   delete evaluation;
289                   evaluation = Debugger::EvaluateExpression(idString, &evalError);
290                   if(evaluation)
291                   {
292                      if(kind == pointerType)
293                      {
294                         uint64 value;
295                         value = _strtoui64(evaluation, null, 0);
296                         delete evaluation;
297                         evaluation = PrintHexUInt64(value);
298                      }
299                   }
300                   break;
301                case classType:
302                   if(isPointer)
303                   {
304                      int size;
305                      char format;
306                      delete evaluation;
307                      //evaluation = Debugger::EvaluateExpression(idString, &evalError);
308                      size = ComputeTypeSize(exp.expType); //exp.expType.arrayType.size;
309                      format = GetGdbFormatChar(exp.expType);
310                      evaluation = Debugger::ReadMemory(address, size, format, &evalError);
311                      if(evaluation)
312                         StripQuotes(evaluation, evaluation);
313                   }
314                   break;
315                case structType:
316                case unionType:
317                case functionType:
318                   //evaluation = Debugger::EvaluateExpression(idString, &evalError);
319                   delete evaluation;
320                   break;
321                case arrayType:
322                {
323                   // for classType  --> if(_class.type == structClass) ?
324                   //char temp[1024];
325                   //sprintf(temp, "&%s", idString);
326                   //evaluation = Debugger::EvaluateExpression(temp, &evalError);
327                   break;
328                }
329                case ellipsisType:
330                case methodType:
331                case vaListType:
332                // case TypeTypedObject, TypeAnyObject, TypeClassPointer:
333                case dummyType:
334                   delete evaluation;
335                   evaluation = Debugger::EvaluateExpression(idString, &evalError);
336                   break;
337             }
338          }
339          switch(evalError)
340          {
341             case dummyExp:
342                if(evaluation && (exp.type != symbolErrorExp || !exp.identifier || !idString || strcmp(evaluation, idString)))
343                {
344                   char * lt = strchr(evaluation, '<');
345                   if(lt) *lt = 0;
346
347                   // Going back to parsing the expression string so as to catch inf/-inf/nan/-nan etc.
348                   expNew = ParseExpressionString(evaluation);
349                   //expNew = MkExpConstant(evaluation);
350                   //printf("Evaluation = %s\n", evaluation);
351                   delete evaluation;
352                   expNew.destType = exp.expType;
353
354                   // WHY EXACTLY MUST WE PROCESS THIS EXPRESSION TYPE AGAIN ? ADDED THIS FOR 0x00000000
355                   if(exp.expType && (exp.expType.kind == pointerType || exp.expType.kind == classType) && expNew.destType)
356                   {
357                      expNew.expType = expNew.destType;
358                      expNew.destType.refCount++;
359                      // For negative values parsed as opExp
360                      if(expNew.type == opExp && expNew.op.op == '-' && !expNew.op.exp1 && expNew.op.exp2)
361                      {
362                         expNew.op.exp2.expType = expNew.destType;
363                         expNew.destType.refCount++;
364                         expNew.op.exp2.isConstant = true;
365                      }
366                   }
367                   else
368                      ProcessExpressionType(expNew);
369                   FreeType(exp.destType);
370                   FreeExpContents(exp);
371
372                   DebugComputeExpression(expNew);
373                   expNew.prev = prev;
374                   expNew.next = next;
375                   expNew.isConstant = true;
376                   expNew.address = address;
377                   expNew.hasAddress = hasAddress;
378                   *exp = *expNew;
379                   delete expNew;
380                }
381                else
382                {
383                   // Unhandled code path, evaluation is null
384                   FreeExpContents(exp);
385                   exp.type = unknownErrorExp;
386                }
387                break;
388             case symbolErrorExp:
389                // Keep the identifier
390                exp.type = evalError;
391                break;
392             default:
393                FreeExpContents(exp);
394                exp.type = evalError;
395                break;
396          }
397          break;
398       }
399       case instanceExp:
400       {
401          Instantiation inst = exp.instance;
402          MembersInit members;
403          Symbol classSym = inst._class ? inst._class.symbol : null; // FindClass(inst._class.name);
404          Class _class = classSym ? classSym.registered : null;
405          DataMember curMember = null;
406          Class curClass = null;
407          DataMember subMemberStack[256];
408          int subMemberStackPos = 0;
409          uint64 bits = 0;
410
411          if(_class && (_class.type == structClass || _class.type == normalClass || _class.type == noHeadClass ))
412          {
413             // Don't recompute the instantiation...
414             // Non Simple classes will have become constants by now
415             if(inst.data)
416                return;
417
418             if(_class.type == normalClass || _class.type == noHeadClass)
419             {
420                inst.data = (byte *)eInstance_New(_class);
421                if(_class.type == normalClass)
422                   ((Instance)inst.data)._refCount++;
423             }
424             else
425                inst.data = new0 byte[_class.structSize];
426          }
427
428          if(inst.members)
429          {
430             for(members = inst.members->first; members; members = members.next)
431             {
432                switch(members.type)
433                {
434                   case dataMembersInit:
435                   {
436                      if(members.dataMembers)
437                      {
438                         MemberInit member;
439                         for(member = members.dataMembers->first; member; member = member.next)
440                         {
441                            Identifier ident = member.identifiers ? member.identifiers->first : null;
442                            bool found = false;
443
444                            Property prop = null;
445                            DataMember dataMember = null;
446                            uint dataMemberOffset;
447
448                            if(!ident)
449                            {
450                               eClass_FindNextMember(_class, &curClass, &curMember, subMemberStack, &subMemberStackPos);
451                               if(curMember)
452                               {
453                                  if(curMember.isProperty)
454                                  {
455                                     prop = (Property)curMember; // TOFIX: (eC II ? THe mss
456                                  }
457                                  else
458                                  {
459                                     dataMember = curMember;
460
461                                     // CHANGED THIS HERE
462                                     eClass_FindDataMemberAndOffset(_class, dataMember.name, &dataMemberOffset, GetPrivateModule(), null, null);
463
464                                     // 2013/17/29 -- It seems that this was missing here!
465                                     if(_class.type == normalClass)
466                                        dataMemberOffset += _class.base.structSize;
467                                     // dataMemberOffset = dataMember.offset;
468                                  }
469                                  found = true;
470                               }
471                            }
472                            else
473                            {
474                               prop = eClass_FindProperty(_class, ident.string, GetPrivateModule());
475                               if(prop)
476                               {
477                                  found = true;
478                                  if(prop.memberAccess == publicAccess)
479                                  {
480                                     curMember = (DataMember)prop;
481                                     curClass = prop._class;
482                                  }
483                               }
484                               else
485                               {
486                                  DataMember _subMemberStack[256];
487                                  int _subMemberStackPos = 0;
488
489                                  // FILL MEMBER STACK
490                                  dataMember = eClass_FindDataMemberAndOffset(_class, ident.string, &dataMemberOffset, GetPrivateModule(), _subMemberStack, &_subMemberStackPos);
491
492                                  if(dataMember)
493                                  {
494                                     found = true;
495                                     if(dataMember.memberAccess == publicAccess)
496                                     {
497                                        curMember = dataMember;
498                                        curClass = dataMember._class;
499                                        memcpy(subMemberStack, _subMemberStack, sizeof(DataMember) * _subMemberStackPos);
500                                        subMemberStackPos = _subMemberStackPos;
501                                     }
502                                  }
503                               }
504                            }
505
506                            if(found && member.initializer && member.initializer.type == expInitializer)
507                            {
508                               Expression value = member.initializer.exp;
509                               Type type = null;
510                               bool deepMember = false;
511                               if(prop)
512                               {
513                                  type = prop.dataType;
514                               }
515                               else if(dataMember)
516                               {
517                                  if(!dataMember.dataType)
518                                     dataMember.dataType = ProcessTypeString(dataMember.dataTypeString, false);
519
520                                  type = dataMember.dataType;
521                               }
522
523                               if(ident && ident.next)
524                               {
525                                  deepMember = true;
526
527                                  // for(; ident && type; ident = ident.next)
528                                  for(ident = ident.next; ident && type; ident = ident.next)
529                                  {
530                                     if(type.kind == classType)
531                                     {
532                                        prop = eClass_FindProperty(type._class.registered,
533                                           ident.string, GetPrivateModule());
534                                        if(prop)
535                                           type = prop.dataType;
536                                        else
537                                        {
538                                           dataMember = eClass_FindDataMemberAndOffset(type._class.registered,
539                                              ident.string, &dataMemberOffset, GetPrivateModule(), null, null);
540                                           if(dataMember)
541                                              type = dataMember.dataType;
542                                        }
543                                     }
544                                     else if(type.kind == structType || type.kind == unionType)
545                                     {
546                                        Type memberType;
547                                        for(memberType = type.members.first; memberType; memberType = memberType.next)
548                                        {
549                                           if(!strcmp(memberType.name, ident.string))
550                                           {
551                                              type = memberType;
552                                              break;
553                                           }
554                                        }
555                                     }
556                                  }
557                               }
558                               if(value)
559                               {
560                                  FreeType(value.destType);
561                                  value.destType = type;
562                                  if(type) type.refCount++;
563                                  DebugComputeExpression(value);
564                               }
565                               if(!deepMember && type && value && (_class.type == structClass || _class.type == normalClass || _class.type == noHeadClass /*&& value.expType.kind == type.kind*/))
566                               {
567                                  if(type.kind == classType)
568                                  {
569                                     Class _class = type._class.registered;
570                                     if(_class.type == bitClass || _class.type == unitClass ||
571                                        _class.type == enumClass)
572                                     {
573                                        if(!_class.dataType)
574                                           _class.dataType = ProcessTypeString(_class.dataTypeString, false);
575                                        type = _class.dataType;
576                                     }
577                                  }
578
579                                  if(dataMember)
580                                  {
581                                     void * ptr = inst.data + dataMemberOffset;
582
583                                     if(value.type == constantExp)
584                                     {
585                                        switch(type.kind)
586                                        {
587                                           case intType:
588                                           {
589                                              GetInt(value, (int*)ptr);
590                                              break;
591                                           }
592                                           case int64Type:
593                                           {
594                                              GetInt64(value, (int64*)ptr);
595                                              break;
596                                           }
597                                           case intPtrType:
598                                           {
599                                              GetIntPtr(value, (intptr*)ptr);
600                                              break;
601                                           }
602                                           case intSizeType:
603                                           {
604                                              GetIntSize(value, (intsize*)ptr);
605                                              break;
606                                           }
607                                           case floatType:
608                                           {
609                                              GetFloat(value, (float*)ptr);
610                                              break;
611                                           }
612                                           case doubleType:
613                                           {
614                                              GetDouble(value, (double *)ptr);
615                                              break;
616                                           }
617                                        }
618                                     }
619                                     else if(value.type == instanceExp)
620                                     {
621                                        if(type.kind == classType)
622                                        {
623                                           Class _class = type._class.registered;
624                                           if(_class.type == structClass)
625                                           {
626                                              ComputeTypeSize(type);
627                                              if(value.instance.data)
628                                                 memcpy(ptr, value.instance.data, type.size);
629                                           }
630                                        }
631                                     }
632                                  }
633                                  else if(prop)
634                                  {
635                                     if(value.type == instanceExp && value.instance.data)
636                                     {
637                                        if(type.kind == classType)
638                                        {
639                                           Class _class = type._class.registered;
640                                           if(_class && (_class.type != normalClass || eClass_IsDerived(((Instance)value.instance.data)._class, _class)))
641                                           {
642                                              void (*Set)(void *, void *) = (void *)prop.Set;
643                                              Set(inst.data, value.instance.data);
644                                              PopulateInstance(inst);
645                                           }
646                                        }
647                                     }
648                                     else if(value.type == constantExp)
649                                     {
650                                        switch(type.kind)
651                                        {
652                                           case doubleType:
653                                           {
654                                              void (*Set)(void *, double) = (void *)prop.Set;
655                                              Set(inst.data, strtod(value.constant, null) );
656                                              break;
657                                           }
658                                           case floatType:
659                                           {
660                                              void (*Set)(void *, float) = (void *)prop.Set;
661                                              Set(inst.data, (float)(strtod(value.constant, null)));
662                                              break;
663                                           }
664                                           case intType:
665                                           {
666                                              void (*Set)(void *, int) = (void *)prop.Set;
667                                              Set(inst.data, (int)strtol(value.constant, null, 0));
668                                              break;
669                                           }
670                                           case int64Type:
671                                           {
672                                              void (*Set)(void *, int64) = (void *)prop.Set;
673                                              Set(inst.data, _strtoi64(value.constant, null, 0));
674                                              break;
675                                           }
676                                           case intPtrType:
677                                           {
678                                              void (*Set)(void *, intptr) = (void *)prop.Set;
679                                              Set(inst.data, (intptr)_strtoi64(value.constant, null, 0));
680                                              break;
681                                           }
682                                           case intSizeType:
683                                           {
684                                              void (*Set)(void *, intsize) = (void *)prop.Set;
685                                              Set(inst.data, (intsize)_strtoi64(value.constant, null, 0));
686                                              break;
687                                           }
688                                        }
689                                     }
690                                     else if(value.type == stringExp)
691                                     {
692                                        char temp[1024];
693                                        ReadString(temp, value.string);
694                                        ((void (*)(void *, void *))(void *)prop.Set)(inst.data, temp);
695                                     }
696                                  }
697                               }
698                               else if(!deepMember && type && _class.type == unitClass)
699                               {
700                                  if(prop)
701                                  {
702                                     // Only support converting units to units for now...
703                                     if(value.type == constantExp)
704                                     {
705                                        if(type.kind == classType)
706                                        {
707                                           Class _class = type._class.registered;
708                                           if(_class.type == unitClass)
709                                           {
710                                              if(!_class.dataType)
711                                                 _class.dataType = ProcessTypeString(_class.dataTypeString, false);
712                                              type = _class.dataType;
713                                           }
714                                        }
715                                        // TODO: Assuming same base type for units...
716                                        switch(type.kind)
717                                        {
718                                           case floatType:
719                                           {
720                                              float fValue;
721                                              float (*Set)(float) = (void *)prop.Set;
722                                              GetFloat(member.initializer.exp, &fValue);
723                                              exp.constant = PrintFloat(Set(fValue));
724                                              exp.type = constantExp;
725                                              break;
726                                           }
727                                           case doubleType:
728                                           {
729                                              double dValue;
730                                              double (*Set)(double) = (void *)prop.Set;
731                                              GetDouble(member.initializer.exp, &dValue);
732                                              exp.constant = PrintDouble(Set(dValue));
733                                              exp.type = constantExp;
734                                              break;
735                                           }
736                                        }
737                                     }
738                                  }
739                               }
740                               else if(!deepMember && type && _class.type == bitClass)
741                               {
742                                  if(prop)
743                                  {
744                                     if(value.type == instanceExp && value.instance.data)
745                                     {
746                                        unsigned int (*Set)(void *) = (void *)prop.Set;
747                                        bits = Set(value.instance.data);
748                                     }
749                                     else if(value.type == constantExp)
750                                     {
751                                     }
752                                  }
753                                  else if(dataMember)
754                                  {
755                                     BitMember bitMember = (BitMember) dataMember;
756                                     Type type;
757                                     int part = 0;
758                                     GetInt(value, &part);
759                                     bits = (bits & ~bitMember.mask);
760                                     if(!bitMember.dataType)
761                                        bitMember.dataType = ProcessTypeString(bitMember.dataTypeString, false);
762
763                                     type = bitMember.dataType;
764
765                                     if(type.kind == classType && type._class && type._class.registered)
766                                     {
767                                        if(!type._class.registered.dataType)
768                                           type._class.registered.dataType = ProcessTypeString(type._class.registered.dataTypeString, false);
769                                        type = type._class.registered.dataType;
770                                     }
771
772                                     switch(type.kind)
773                                     {
774                                        case _BoolType:
775                                        case charType:
776                                           if(type.isSigned)
777                                              bits |= ((char)part << bitMember.pos);
778                                           else
779                                              bits |= ((unsigned char)part << bitMember.pos);
780                                           break;
781                                        case shortType:
782                                           if(type.isSigned)
783                                              bits |= ((short)part << bitMember.pos);
784                                           else
785                                              bits |= ((unsigned short)part << bitMember.pos);
786                                           break;
787                                        case intType:
788                                        case longType:
789                                           if(type.isSigned)
790                                              bits |= ((int)part << bitMember.pos);
791                                           else
792                                              bits |= ((unsigned int)part << bitMember.pos);
793                                           break;
794                                        case int64Type:
795                                           if(type.isSigned)
796                                              bits |= ((int64)part << bitMember.pos);
797                                           else
798                                              bits |= ((uint64)part << bitMember.pos);
799                                           break;
800                                        case intPtrType:
801                                           if(type.isSigned)
802                                           {
803                                              bits |= ((intptr)part << bitMember.pos);
804                                           }
805                                           else
806                                           {
807                                              bits |= ((uintptr)part << bitMember.pos);
808                                           }
809                                           break;
810                                        case intSizeType:
811                                           if(type.isSigned)
812                                           {
813                                              bits |= ((ssize_t)(intsize)part << bitMember.pos);
814                                           }
815                                           else
816                                           {
817                                              bits |= ((size_t) (uintsize)part << bitMember.pos);
818                                           }
819                                           break;
820                                     }
821                                  }
822                               }
823                            }
824                            else
825                            {
826                               if(_class && _class.type == unitClass)
827                               {
828                                  DebugComputeExpression(member.initializer.exp);
829                                  exp.constant = member.initializer.exp.constant;
830                                  exp.type = constantExp;
831
832                                  member.initializer.exp.constant = null;
833                               }
834                            }
835                         }
836                      }
837                      break;
838                   }
839                }
840             }
841          }
842          if(_class && _class.type == bitClass)
843          {
844             exp.constant = PrintHexUInt(bits);
845             exp.type = constantExp;
846          }
847          if(exp.type != instanceExp)
848          {
849             FreeInstance(inst);
850          }
851          break;
852       }
853       /*
854       case constantExp:
855          break;
856       */
857       case opExp:
858       {
859          Expression expError = null;
860          Expression exp1 = null, exp2 = null;
861          Operand op1 = { 0 }, op2 = { 0 };
862
863          /*
864          if(exp.op.op == '&' || exp.op.op == '*')
865          {
866             if(!exp.op.exp1 && exp.op.exp2)
867             {
868                if(exp.op.exp2.type == identifierExp)
869                {
870                   Expression prev = exp.prev, next = exp.next;
871                   char * evaluation = null;
872                   ExpressionType evalError = dummyExp;
873                   Expression expNew;
874                   char temp[1024];
875                   sprintf(temp, "%c%s", exp.op.op, exp.op.exp2.identifier.string);
876                   evaluation = Debugger::EvaluateExpression(temp, &evalError);
877                   if(evalError != dummyExp)
878                   {
879                      exp.type = evalError;
880                      exp.constant = CopyString("");
881                   }
882                   else if(evaluation)
883                   {
884                      expNew = ParseExpressionString(evaluation);
885                      delete evaluation;
886                      expNew.destType = exp.expType;
887                      FreeType(exp.destType);
888                      FreeExpContents(exp);
889                      ProcessExpressionType(expNew);
890                      DebugComputeExpression(expNew);
891                      expNew.prev = prev;
892                      expNew.next = next;
893                      expNew.isConstant = true;
894                      *exp = *expNew;
895                      delete expNew;
896                   }
897                   else
898                      exp.type = ExpUnknownError;
899                   break;
900                }
901                //else
902                {
903                   uint64 address;
904                   int size;
905                   char format;
906                   if(exp.op.op == '*')
907                   {
908                   DebugComputeExpression(exp.op.exp2);
909                   size = ComputeTypeSize(exp.op.exp2.expType);
910                   format = GetGdbFormatChar(exp.op.exp2.expType);
911                   GetInt(exp.op.exp2, &address);
912                   //sprintf(temp, "%c%s", exp.op.op, exp.op.exp2.constant);
913                   evaluation = Debug_ReadMemory(address, size, format, &evalError);
914                   }
915                   else
916                      evalError = ExpUnknownError;
917                }
918             }
919          }
920          */
921
922          // We don't care about operations with only exp2 (INC_OP, DEC_OP...)
923          if(exp.op.exp2)
924          {
925             Expression e = exp.op.exp2;
926
927             while((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list)
928             {
929                if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
930                {
931                   if(e.type == extensionCompoundExp)
932                      e = ((Statement)e.compound.compound.statements->last).expressions->last;
933                   else
934                      e = e.list->last;
935                }
936             }
937             if(exp.op.op == TokenType::sizeOf && e && e.expType)
938             {
939                if(e.type == stringExp && e.string)
940                {
941                   char * string = e.string;
942                   int len = strlen(string);
943                   char * tmp = new char[len-2+1];
944                   len = UnescapeString(tmp, string + 1, len - 2);
945                   delete tmp;
946                   FreeExpContents(exp);
947                   exp.type = constantExp;
948                   exp.constant = PrintUInt(len + 1);
949                }
950                else
951                {
952                   Type type = e.expType;
953                   type.refCount++;
954                   FreeExpContents(exp);
955                   exp.type = constantExp;
956                   exp.constant = PrintUInt(ComputeTypeSize(type));
957                   FreeType(type);
958                }
959                break;
960             }
961             else
962             {
963                DebugComputeExpression(exp.op.exp2);
964                if(ExpressionIsError(exp.op.exp2))
965                   expError = exp.op.exp2;
966             }
967          }
968          if(!expError)
969          {
970             if(exp.op.exp1)
971             {
972                DebugComputeExpression(exp.op.exp1);
973                if(ExpressionIsError(exp.op.exp1))
974                   expError = exp.op.exp1;
975                else
976                {
977                   if(exp.op.exp2)
978                   {
979                      if(ExpressionIsError(exp.op.exp2))
980                         expError = exp.op.exp2;
981                      else
982                      {
983                         exp1 = exp.op.exp1;
984                         exp2 = exp.op.exp2;
985                         op1 = GetOperand(exp1);
986                         if(op1.type) op1.type.refCount++;
987                         op2 = GetOperand(exp2);
988                         if(op2.type) op2.type.refCount++;
989                      }
990                   }
991                   else
992                   {
993                      exp1 = exp.op.exp1;
994                      op1 = GetOperand(exp1);
995                      if(op1.type) op1.type.refCount++;
996                   }
997                }
998             }
999             else if(exp.op.exp2)
1000             {
1001                if(ExpressionIsError(exp.op.exp2))
1002                   expError = exp.op.exp2;
1003                else
1004                {
1005                   exp1 = exp.op.exp2;
1006                   if(exp.op.op == '&' || exp.op.op == '*')
1007                   {
1008                      Expression prev = exp1.prev, next = exp1.next;
1009                      Expression expNew;
1010                      ExpressionType evalError = dummyExp;
1011                      char * evaluation = null;
1012                      if(exp.op.op == '&')
1013                      {
1014                         if(exp1.hasAddress)
1015                         {
1016                            char * temp;
1017                            //sprintf(temp, "%u", exp1.address);
1018                            temp = PrintHexUInt64(exp1.address);
1019                            expNew = ParseExpressionString(temp);
1020                            delete temp;
1021                            //expNew.address = exp1.address;
1022                            expNew.expType = exp.expType;
1023                            /*
1024                            expNew.destType = exp.expType;
1025                            expNew.destType.refCount++;
1026                            */
1027                            FreeType(exp.destType);
1028                            FreeExpContents(exp);
1029                            ProcessExpressionType(expNew);
1030                            DebugComputeExpression(expNew);
1031                            expNew.prev = prev;
1032                            expNew.next = next;
1033                            expNew.isConstant = true;
1034                            *exp = *expNew;
1035                            delete expNew;
1036                         }
1037                         else
1038                            exp1.address = 0;
1039                      }
1040                      else if(exp.op.op == '*')
1041                      {
1042                         // TODO: Common pathway for * and [ ]
1043                         if(!exp.expType)
1044                         {
1045                            delete evaluation;
1046                            FreeExpContents(exp1);
1047                            exp1.type = dereferenceErrorExp;
1048                            expError = exp1;
1049                         }
1050                         else
1051                         {
1052                            uint64 address = 0;
1053                            int size;
1054                            char format;
1055                            Expression e = exp1;
1056                            uint offset = 0;
1057                            bool gotAddress = false;
1058
1059                            while(((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list) || e.type == castExp)
1060                            {
1061                               if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
1062                               {
1063                                  if(e.type == extensionCompoundExp)
1064                                     e = ((Statement)e.compound.compound.statements->last).expressions->last;
1065                                  else
1066                                     e = e.list->last;
1067                               }
1068                               else if(e.type == castExp)
1069                                  e = e.cast.exp;
1070                            }
1071
1072                            if(e.expType.kind == structType)
1073                            {
1074                               address = exp1.address;
1075                               gotAddress = true;
1076                            }
1077                            else
1078                               gotAddress = GetUInt64(e, &address);
1079                            size = ComputeTypeSize(exp.expType); //exp.expType.arrayType.size;
1080                            if(exp.expType && exp.expType.type && exp.expType.kind == arrayType)
1081                               // For multilevels arrays
1082                               format = 'x';
1083                            else
1084                               format = GetGdbFormatChar(exp.expType);
1085                            while(e.type == opExp && e.op.op == '+' && e.op.exp1 && e.op.exp2)
1086                            {
1087                               Expression e1 = e.op.exp1, e2 = e.op.exp2;
1088                               while(((e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp) && e1.list) || e1.type == castExp)
1089                               {
1090                                  if(e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp)
1091                                  {
1092                                     if(e1.type == extensionCompoundExp)
1093                                        e1 = ((Statement)e1.compound.compound.statements->last).expressions->last;
1094                                     else
1095                                        e1 = e1.list->last;
1096                                  }
1097                                  else if(e1.type == castExp)
1098                                     e1 = e1.cast.exp;
1099                               }
1100                               while(((e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp) && e2.list) || e2.type == castExp)
1101                               {
1102                                  if(e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp)
1103                                  {
1104                                     if(e2.type == extensionCompoundExp)
1105                                        e2 = ((Statement)e2.compound.compound.statements->last).expressions->last;
1106                                     else
1107                                        e2 = e2.list->last;
1108                                  }
1109                                  else if(e2.type == castExp)
1110                                     e2 = e2.cast.exp;
1111                               }
1112
1113                               if((e1.type == stringExp || e1.type == opExp) && e.op.exp2.isConstant && e.op.exp2.expType && e.op.exp2.expType.kind == intType)
1114                               {
1115                                  offset += strtol(e.op.exp2.constant, null, 0);
1116                                  e = e1;
1117                               }
1118                               else if((e2.type == stringExp || e2.type == opExp) && e.op.exp1.isConstant && e.op.exp1.expType && e.op.exp1.expType.kind == intType)
1119                               {
1120                                  offset += strtol(e.op.exp1.constant, null, 0);
1121                                  e = e2;
1122                               }
1123                               else
1124                                   break;
1125                            }
1126
1127                            if(e.type == stringExp)
1128                            {
1129                               char * tmp = null;
1130                               String string = e.string;
1131                               bool valid = false;
1132                               Type expType = exp1.expType.type;
1133                               if(expType) expType.refCount++;
1134
1135                               if(string)
1136                               {
1137                                  int len = string ? strlen(string) : 0;
1138                                  tmp = new char[len-2+1];
1139                                  len = UnescapeString(tmp, string + 1, len - 2);
1140                                  if(len >= 0 && offset * size + size-1 <= len)
1141                                     valid = true;
1142                               }
1143
1144                               FreeExpContents(exp);
1145                               if(!valid)
1146                                  exp.type = dereferenceErrorExp;
1147                               else if(expType)
1148                               {
1149                                  exp.type = constantExp;
1150                                  exp.isConstant = true;
1151                                  switch(expType.kind)
1152                                  {
1153                                     case charType:   exp.constant = expType.isSigned ? PrintChar(((char *)tmp)[offset]) : PrintUChar(((byte *)tmp)[offset]); break;
1154                                     case shortType:  exp.constant = expType.isSigned ? PrintShort(((short *)tmp)[offset]) : PrintUShort(((uint16 *)tmp)[offset]); break;
1155                                     case intType:    exp.constant = expType.isSigned ? PrintInt(((int *)tmp)[offset]) : PrintUInt(((uint *)tmp)[offset]); break;
1156                                     case int64Type:  exp.constant = expType.isSigned ? PrintInt64(((int64 *)tmp)[offset]) : PrintUInt64(((uint64 *)tmp)[offset]); break;
1157                                     case floatType:  exp.constant = PrintFloat(((float *)tmp)[offset]); break;
1158                                     case doubleType: exp.constant = PrintDouble(((double *)tmp)[offset]); break;
1159                                     default:
1160                                        exp.type = unknownErrorExp;
1161                                  }
1162                               }
1163                               else
1164                                  exp.type = unknownErrorExp;
1165                               FreeType(expType);
1166                               delete tmp;
1167                            }
1168                            else if(gotAddress && exp.expType.kind == arrayType)
1169                            {
1170                               FreeExpContents(exp);
1171                               exp.type = constantExp;
1172                               exp.isConstant = true;
1173                               exp.constant = PrintHexUInt64(address);
1174                               exp.address = address;
1175                               exp.hasAddress = true;
1176                            }
1177                            else if(gotAddress && format)
1178                            {
1179                               evaluation = Debugger::ReadMemory(address, size, format, &evalError);
1180                               switch(evalError)
1181                               {
1182                                  case dummyExp:
1183                                     if(evaluation)
1184                                     {
1185                                        expNew = ParseExpressionString(evaluation);
1186                                        expNew.address = address;
1187                                        expNew.hasAddress = true;
1188                                        delete evaluation;
1189                                        expNew.destType = exp.expType;
1190                                        FreeType(exp.destType);
1191                                        FreeExpContents(exp);
1192                                        ProcessExpressionType(expNew);
1193                                        DebugComputeExpression(expNew);
1194                                        expNew.prev = prev;
1195                                        expNew.next = next;
1196                                        expNew.isConstant = true;
1197                                        *exp = *expNew;
1198                                        delete expNew;
1199                                     }
1200                                     else
1201                                     {
1202                                        // Unhandled code path, evaluation is null
1203                                        FreeExpContents(exp);
1204                                        exp.type = unknownErrorExp;
1205                                     }
1206                                     break;
1207                                  case memoryErrorExp:
1208                                     delete evaluation;
1209                                     FreeExpContents(exp1);
1210                                     exp1.type = evalError;
1211                                     exp1.constant = PrintHexUInt64(address);
1212                                     expError = exp1;
1213                                     break;
1214                                  default:
1215                                     delete evaluation;
1216                                     FreeExpContents(exp1);
1217                                     exp1.type = evalError;
1218                                     expError = exp1;
1219                                     break;
1220                               }
1221                            }
1222                            else
1223                            {
1224                               FreeExpContents(exp1);
1225                               exp1.type = unknownErrorExp;  // Not supported yet, generate error to fallback to GDB printout
1226                               expError = exp1;
1227                            }
1228                         }
1229                      }
1230                   }
1231                   else
1232                      op1 = GetOperand(exp1);
1233                   if(op1.type) op1.type.refCount++;
1234                }
1235             }
1236          }
1237          if(expError)
1238             CarryExpressionError(exp, expError);
1239          else if(exp.type == opExp)
1240          {
1241             if(exp1 && exp2 && exp1.expType && exp2.expType &&
1242                ((exp1.expType.kind == pointerType || exp1.expType.kind == arrayType) ||
1243                 (exp2.expType.kind == pointerType || exp2.expType.kind == arrayType)))
1244             {
1245                bool valid = false;
1246                if((exp.op.op == '+' || exp.op.op == '-') && (op2.type || op1.type))
1247                {
1248                   Expression e1 = exp1, e2 = exp2;
1249                   while(((e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp) && e1.list) || e1.type == castExp)
1250                   {
1251                      if(e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp)
1252                      {
1253                         if(e1.type == extensionCompoundExp)
1254                            e1 = ((Statement)e1.compound.compound.statements->last).expressions->last;
1255                         else
1256                            e1 = e1.list->last;
1257                      }
1258                      else if(e1.type == castExp)
1259                         e1 = e1.cast.exp;
1260                   }
1261                   while(((e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp) && e2.list) || e2.type == castExp)
1262                   {
1263                      if(e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp)
1264                      {
1265                         if(e2.type == extensionCompoundExp)
1266                            e2 = ((Statement)e2.compound.compound.statements->last).expressions->last;
1267                         else
1268                            e2 = e2.list->last;
1269                      }
1270                      else if(e2.type == castExp)
1271                         e2 = e2.cast.exp;
1272                   }
1273
1274                   if((e1.type == stringExp && op2.type && op2.type.kind == intType) || (e2.type == stringExp && op1.type && op1.type.kind == intType))
1275                   {
1276                      uint64 offset = ((exp.op.op == '+') ? 1 : -1) * (e1.type == stringExp ? op2.i64 : op1.i64);
1277                      String newString = null;
1278                      Expression e = e1.type == stringExp ? e1 : e2;
1279                      if(e.string)
1280                      {
1281                         int len = strlen(e.string) - 2;
1282                         char * tmp = OffsetEscapedString(e.string + 1, len, (int)offset);
1283                         if(tmp)
1284                         {
1285                            len -= tmp - (e.string + 1);
1286                            newString = new char[2 + len + 1];
1287                            newString[0] = '\"';
1288                            memcpy(newString + 1, tmp, len);
1289                            newString[1 + len] = '\"';
1290                            newString[1 + len + 1] = 0;
1291                         }
1292                      }
1293                      valid = true;
1294                      FreeExpContents(exp);
1295                      if(newString)
1296                      {
1297                         exp.type = stringExp;
1298                         exp.string = newString;
1299                      }
1300                      else
1301                         exp.type = dereferenceErrorExp;
1302                   }
1303                   // Can't add 2 pointers...
1304                   else if(exp.op.op != '+' ||
1305                      !((exp1.expType.kind == pointerType || exp1.expType.kind == arrayType) &&
1306                        (exp2.expType.kind == pointerType || exp2.expType.kind == arrayType)))
1307                   {
1308                      bool op1IsPointer = exp1.expType.kind == pointerType || exp1.expType.kind == arrayType;
1309                      bool op2IsPointer = exp2.expType.kind == pointerType || exp2.expType.kind == arrayType;
1310                      bool addressResult = !op1IsPointer || !op2IsPointer;
1311                      uint size = 0;
1312                      valid = true;
1313                      if(op1IsPointer)
1314                         size = ComputeTypeSize(exp1.expType.type);
1315                      else if(op2IsPointer)
1316                         size = ComputeTypeSize(exp2.expType.type);
1317
1318                      if(addressResult && size)
1319                      {
1320                        if(op1IsPointer) op2.ui64 *= size;
1321                        else if(op1IsPointer) op1.ui64 *= size;
1322                      }
1323
1324                      CallOperator(exp, exp1, exp2, op1, op2);
1325                      if(exp.type == constantExp)
1326                      {
1327                         if(addressResult)
1328                         {
1329                            exp.address = _strtoui64(exp.constant, null, 0);
1330                            delete exp.constant;
1331                            exp.constant = PrintHexUInt64(exp.address);
1332                            if(op1.type.kind == arrayType || op2.type.kind == arrayType)
1333                               exp.hasAddress = true;
1334                         }
1335                         else
1336                         {
1337                            int64 v = _strtoi64(exp.constant, null, 0);
1338                            if(size) v /= size;
1339                            delete exp.constant;
1340                            exp.constant = PrintInt(v);
1341                         }
1342                      }
1343                   }
1344                }
1345                if(!valid)
1346                {
1347                   FreeExpContents(exp);
1348                   exp.type = unknownErrorExp;   // We should have an invalid operands error
1349                }
1350             }
1351             else
1352             {
1353                if(!exp2 && exp1 && exp1.type == constantExp && exp1.constant && !strcmp(exp1.constant, "nan") && exp.op.op == '-')
1354                {
1355                   FreeExpContents(exp);
1356                   exp.constant = CopyString("-nan");
1357                   exp.type = constantExp;
1358                }
1359                else
1360                {
1361                   if((exp.op.op == '/' || exp.op.op == '%') && op2.kind != doubleType && op1.kind != doubleType && op2.kind != floatType && op1.kind != floatType &&
1362                      (((op2.kind == int64Type || op2.kind == intPtrType || op2.kind == intSizeType) && !op2.i64) ||
1363                      (op2.kind == intType && !op2.i) || (op2.kind == shortType && !op2.s) || (op2.kind == charType && !op2.c)))
1364                   {
1365                      FreeExpContents(exp);
1366                      exp.type = divideBy0ErrorExp;
1367                   }
1368                   else
1369                      CallOperator(exp, exp1, exp2, op1, op2);
1370                }
1371             }
1372             FreeType(op1.type);
1373             FreeType(op2.type);
1374             if(exp.type == constantExp)
1375                exp.isConstant = true;
1376          }
1377          break;
1378       }
1379       case bracketsExp:
1380       {
1381          Expression e, n;
1382          //for(
1383          //   e = (*exp.list).first, n = e ? e.next : null;
1384          //   e;
1385          //   e = n, n = n?(n.next) : null)
1386
1387          for(e = exp.list->first; e; e = n)
1388          {
1389             n = e.next;
1390             if(!n)
1391             {
1392                OldList * list = exp.list;
1393                DebugComputeExpression(e);
1394                //if(ExpressionIsError(e)) //.type == ExpSymbolError
1395                //   CarryExpressionError(exp, e);
1396                //FreeExpContents(exp);
1397                FreeType(exp.expType);
1398                FreeType(exp.destType);
1399                *exp = *e;
1400                delete e;
1401                delete list;
1402             }
1403             else
1404             {
1405                FreeExpression(e);
1406             }
1407          }
1408          break;
1409       }
1410       case indexExp:
1411       {
1412          int size;
1413          char format;
1414          Expression e;
1415          exp.isConstant = true;
1416
1417          DebugComputeExpression(exp.index.exp);
1418          if(ExpressionIsError(exp.index.exp)) //.type == ExpSymbolError
1419             CarryExpressionError(exp, exp.index.exp);
1420          else
1421          {
1422             Expression prev = exp.prev, next = exp.next;
1423             char * evaluation = null;
1424             ExpressionType evalError = dummyExp;
1425             Type dataType = exp.index.exp.expType ? exp.index.exp.expType.type : null;
1426
1427             if(!exp.index.exp.isConstant)
1428                exp.isConstant = false;
1429
1430             // int r[0]
1431             // 4 == size = ComputeTypeSize(exp.expType);
1432             // 0 == size = ComputeTypeSize(exp.expType.arrayType);
1433             // 4 == size = ComputeTypeSize(exp.index.exp.expType);
1434             // 0 == size = ComputeTypeSize(exp.index.exp.expType.arrayType);
1435
1436             size = ComputeTypeSize(dataType);
1437             if(dataType && dataType.type && dataType.kind == arrayType)
1438                // For multilevels arrays
1439                format = 'x';
1440             else
1441                format = GetGdbFormatChar(dataType);
1442
1443             for(e = exp.index.index->first; e; e = e.next)
1444             {
1445                DebugComputeExpression(e);
1446                if(ExpressionIsError(e)) //.type == ExpSymbolError
1447                {
1448                   CarryExpressionError(exp, e);
1449                   break;
1450                }
1451                if(!e.next)
1452                {
1453                   // Check if this type is int
1454                }
1455                if(!e.isConstant)
1456                   exp.isConstant = false;
1457             }
1458             if(!ExpressionIsError(exp))
1459             {
1460                // Is this necessary here? pass15 had done this already...
1461                if(exp.expType) FreeType(exp.expType);
1462                exp.expType = Dereference(exp.index.exp.expType);
1463
1464                if(!exp.expType)
1465                {
1466                   delete evaluation;
1467                   FreeExpContents(exp);
1468                   exp.type = dereferenceErrorExp;
1469                }
1470                else if(exp.index.index && exp.index.index->last && ((Expression)exp.index.index->last) && ((Expression)exp.index.index->last).expType)
1471                {
1472                   Type type = ((Expression)exp.index.index->last).expType;
1473                   if(type.kind == intType || type.kind == charType || type.kind == shortType || type.kind == int64Type || type.kind == intPtrType ||
1474                      type.kind == intSizeType || type.kind == longType || type.kind == _BoolType || type.kind == enumType ||
1475                         (type.kind == classType && type._class && type._class.registered &&
1476                            type._class.registered.type == enumClass))
1477                   {
1478                      bool gotAddress = false;
1479                      uint64 address = 0, offset = 0;
1480                      Expression expNew, last = (Expression)exp.index.index->last;
1481                      Expression e = exp.index.exp;
1482
1483                      while(((e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp) && e.list) || e.type == castExp)
1484                      {
1485                         if(e.type == bracketsExp || e.type == extensionExpressionExp || e.type == extensionCompoundExp)
1486                         {
1487                            if(e.type == extensionCompoundExp)
1488                               e = ((Statement)e.compound.compound.statements->last).expressions->last;
1489                            else
1490                               e = e.list->last;
1491                         }
1492                         else if(e.type == castExp)
1493                            e = e.cast.exp;
1494                      }
1495
1496                      //GetUInt(exp.index.exp, &address);
1497
1498                      GetUInt64(last, &offset);
1499
1500                      // TOFIX: Check if it has address: TESTING
1501                      if(exp.index.exp.hasAddress && exp.index.exp.expType.kind == arrayType)
1502                      {
1503                         address = exp.index.exp.address;
1504                         gotAddress = true;
1505                      }
1506                      else if(exp.index.exp.type == constantExp)
1507                         gotAddress = GetUInt64(exp.index.exp, &address);
1508
1509                      while(e.type == opExp && e.op.op == '+' && e.op.exp1 && e.op.exp2)
1510                      {
1511                         Expression e1 = e.op.exp1, e2 = e.op.exp2;
1512                         while(((e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp) && e1.list) || e1.type == castExp)
1513                         {
1514                            if(e1.type == bracketsExp || e1.type == extensionExpressionExp || e1.type == extensionCompoundExp)
1515                            {
1516                               if(e1.type == extensionCompoundExp)
1517                                  e1 = ((Statement)e1.compound.compound.statements->last).expressions->last;
1518                               else
1519                                  e1 = e1.list->last;
1520                            }
1521                            else if(e1.type == castExp)
1522                               e1 = e1.cast.exp;
1523                         }
1524                         while(((e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp) && e2.list) || e2.type == castExp)
1525                         {
1526                            if(e2.type == bracketsExp || e2.type == extensionExpressionExp || e2.type == extensionCompoundExp)
1527                            {
1528                               if(e2.type == extensionCompoundExp)
1529                                  e2 = ((Statement)e2.compound.compound.statements->last).expressions->last;
1530                               else
1531                                  e2 = e2.list->last;
1532                            }
1533                            else if(e2.type == castExp)
1534                               e2 = e2.cast.exp;
1535                         }
1536
1537                         if((e1.type == stringExp || e1.type == opExp) && e.op.exp2.isConstant && e.op.exp2.expType && e.op.exp2.expType.kind == intType)
1538                         {
1539                            offset += strtol(e.op.exp2.constant, null, 0);
1540                            e = e1;
1541                         }
1542                         else if((e2.type == stringExp || e2.type == opExp) && e.op.exp1.isConstant && e.op.exp1.expType && e.op.exp1.expType.kind == intType)
1543                         {
1544                            offset += strtol(e.op.exp1.constant, null, 0);
1545                            e = e2;
1546                         }
1547                         else
1548                             break;
1549                      }
1550
1551                      //size = ComputeTypeSize(exp.expType.arrayType); //exp.expType.arrayType.size;
1552                      address += offset * size;
1553
1554                      if(e.type == stringExp)
1555                      {
1556                         char * tmp = null;
1557                         String string = e.string;
1558                         bool valid = false;
1559                         Type expType = exp.index.exp.expType.type;
1560                         if(expType) expType.refCount++;
1561
1562                         if(string)
1563                         {
1564                            int len = string ? strlen(string) : 0;
1565                            tmp = new char[len-2+1];
1566                            len = UnescapeString(tmp, string + 1, len - 2);
1567                            if(len >= 0 && offset * size + size-1 <= len)
1568                               valid = true;
1569                         }
1570
1571                         FreeExpContents(exp);
1572                         if(!valid)
1573                            exp.type = dereferenceErrorExp;
1574                         else if(expType)
1575                         {
1576                            exp.type = constantExp;
1577                            exp.isConstant = true;
1578                            switch(expType.kind)
1579                            {
1580                               case charType:   exp.constant = expType.isSigned ? PrintChar(((char *)tmp)[offset]) : PrintUChar(((byte *)tmp)[offset]); break;
1581                               case shortType:  exp.constant = expType.isSigned ? PrintShort(((short *)tmp)[offset]) : PrintUShort(((uint16 *)tmp)[offset]); break;
1582                               case intType:    exp.constant = expType.isSigned ? PrintInt(((int *)tmp)[offset]) : PrintUInt(((uint *)tmp)[offset]); break;
1583                               case int64Type:  exp.constant = expType.isSigned ? PrintInt64(((int64 *)tmp)[offset]) : PrintUInt64(((uint64 *)tmp)[offset]); break;
1584                               case floatType:  exp.constant = PrintFloat(((float *)tmp)[offset]); break;
1585                               case doubleType: exp.constant = PrintDouble(((double *)tmp)[offset]); break;
1586                               default:
1587                                  exp.type = unknownErrorExp;
1588                            }
1589                         }
1590                         else
1591                            exp.type = unknownErrorExp;
1592                         FreeType(expType);
1593                         delete tmp;
1594                      }
1595                      else if(gotAddress && exp.expType.kind == arrayType)
1596                      {
1597                         FreeExpContents(exp);
1598                         exp.type = constantExp;
1599                         exp.isConstant = true;
1600                         exp.constant = PrintHexUInt64(address);
1601                         exp.address = address;
1602                         exp.hasAddress = true;
1603                      }
1604                      else if(gotAddress)
1605                      {
1606                         evaluation = Debugger::ReadMemory(address, size, format, &evalError);
1607                         switch(evalError)
1608                         {
1609                            case dummyExp:
1610                               if(evaluation)
1611                               {
1612                                  expNew = ParseExpressionString(evaluation);
1613                                  delete evaluation;
1614                                  expNew.destType = exp.expType;
1615                                  FreeType(exp.destType);
1616                                  FreeExpContents(exp);
1617                                  ProcessExpressionType(expNew);
1618                                  DebugComputeExpression(expNew);
1619
1620                                  // TOFIX: Only for Array Types
1621                                  expNew.address = address;
1622
1623                                  expNew.hasAddress = true;
1624                                  expNew.prev = prev;
1625                                  expNew.next = next;
1626                                  expNew.isConstant = true;
1627                                  *exp = *expNew;
1628                                  delete expNew;
1629                               }
1630                               else
1631                               {
1632                                  // Unhandled code path, evaluation is null
1633                                  FreeExpContents(exp);
1634                                  exp.type = unknownErrorExp;
1635                               }
1636                               break;
1637                            case memoryErrorExp:
1638                               delete evaluation;
1639                               FreeExpContents(exp);
1640                               exp.type = evalError;
1641                               exp.constant = PrintHexUInt64(address);
1642                               break;
1643                            default:
1644                               delete evaluation;
1645                               FreeExpContents(exp);
1646                               exp.type = evalError;
1647                               break;
1648                         }
1649                      }
1650                      else
1651                      {
1652                         FreeExpContents(exp);
1653                         exp.type = unknownErrorExp;
1654                      }
1655                   }
1656                }
1657             }
1658          }
1659          break;
1660       }
1661       case callExp:
1662       {
1663          Expression callExp = exp.call.exp;
1664          Identifier id = (callExp && callExp.type == identifierExp) ? callExp.identifier : null;
1665          bool resolved = false;
1666          if(id && id.string)
1667          {
1668             if(!strcmp(id.string, "nan") || !strcmp(id.string, "inf"))
1669             {
1670                String s = id.string;
1671                id.string = null;
1672                FreeExpContents(exp);
1673                exp.type = constantExp;
1674                exp.constant = s;
1675                resolved = true;
1676             }
1677             else if(exp.call.arguments)
1678             {
1679                if(exp.call.arguments->count == 1)
1680                {
1681                   double (* fn1)(double) = (void *)oneArgFns[id.string];
1682                   if(fn1)
1683                   {
1684                      Expression arg = exp.call.arguments->first;
1685                      DebugComputeExpression(arg);
1686                      if(ExpressionIsError(arg))
1687                         CarryExpressionError(exp, arg);
1688                      else if(arg.isConstant && arg.type == constantExp)
1689                      {
1690                         double v;
1691                         if(GetDouble(arg, &v))
1692                         {
1693                            FreeExpContents(exp);
1694                            exp.type = constantExp;
1695                            v = fn1(v);
1696                            exp.constant = PrintDouble(v);
1697                            exp.isConstant = true;
1698                            resolved = true;
1699                         }
1700                      }
1701                   }
1702                }
1703                else if(exp.call.arguments->count == 2)
1704                {
1705                   double (* fn2)(double, double) = (void *)twoArgFns[id.string];
1706                   if(fn2)
1707                   {
1708                      Expression arg1 = exp.call.arguments->first;
1709                      Expression arg2 = exp.call.arguments->last;
1710                      DebugComputeExpression(arg1);
1711                      DebugComputeExpression(arg2);
1712                      if(ExpressionIsError(arg1))
1713                         CarryExpressionError(exp, arg1);
1714                      else if(ExpressionIsError(arg2))
1715                         CarryExpressionError(exp, arg2);
1716                      else if(arg1.isConstant && arg1.type == constantExp && arg2.isConstant && arg2.type == constantExp)
1717                      {
1718                         double v1, v2;
1719                         if(GetDouble(arg1, &v1) && GetDouble(arg2, &v2))
1720                         {
1721                            FreeExpContents(exp);
1722                            exp.type = constantExp;
1723                            v1 = fn2(v1, v2);
1724                            exp.constant = PrintDouble(v1);
1725                            exp.isConstant = true;
1726                            resolved = true;
1727                         }
1728                      }
1729                   }
1730                }
1731             }
1732          }
1733          if(!resolved)
1734             exp.type = functionCallErrorExp;
1735          break;
1736       }
1737       case memberExp:
1738       {
1739          Expression memberExp = exp.member.exp;
1740          Identifier memberID = exp.member.member;
1741          //Class _class;
1742          Property prop = null;
1743          DataMember member = null;
1744          Class convertTo = null;
1745          uint offset = 0;  // THIS WASN'T INITIALIZED... IS IT ALWAYS SET?
1746
1747          Type type; // = memberExp.expType;
1748          DebugComputeExpression(memberExp);
1749          type = memberExp.expType;
1750          if(ExpressionIsError(memberExp))
1751             CarryExpressionError(exp, memberExp);
1752          else if(type)
1753          {
1754             // _class = (memberID && memberID.classSym) ? memberID.classSym.registered : ((type.kind == classType && type._class) ? type._class.registered : null);
1755             Class _class = (exp.member.member && exp.member.member.classSym) ? exp.member.member.classSym.registered : (((type.kind == classType || type.kind == subClassType) && type._class) ? type._class.registered : null);
1756             if(!_class)
1757             {
1758                char string[256] = "";
1759                Symbol classSym;
1760                PrintTypeNoConst(type, string, false, true);
1761                classSym = FindClass(string);
1762                _class = classSym ? classSym.registered : null;
1763             }
1764
1765             if(memberID && _class)
1766             {
1767                /*
1768                prop = eClass_FindProperty(_class, memberID.string);
1769                if(!prop)
1770                   member = eClass_FindDataMember(_class, memberID.string);
1771                */
1772                // member = eClass_FindDataMember(_class, memberID.string);
1773                member = eClass_FindDataMemberAndOffset(_class, memberID.string, &offset, _class.module.application, null, null);
1774                if(!member)
1775                   prop = eClass_FindProperty(_class, memberID.string, _class.module.application);
1776             }
1777             if(!prop && !member && _class && memberID)
1778             {
1779                Symbol classSym = FindClass(memberID.string);
1780                convertTo = _class;
1781                _class = classSym ? classSym.registered : null;
1782                if(_class)
1783                   prop = eClass_FindProperty(_class, convertTo.fullName, _class.module.application);
1784             }
1785
1786             //DebugComputeExpression(memberExp);
1787             if(ExpressionIsError(memberExp))
1788                CarryExpressionError(exp, memberExp);
1789             else
1790             {
1791                if(exp.member.memberType == methodMember)
1792                {
1793                   FreeExpContents(exp);
1794                   exp.type = unknownErrorExp;
1795                }
1796                else if(prop)
1797                {
1798                   bool supported = false;
1799                   if(prop.compiled)
1800                   {
1801                      Type type = prop.dataType;
1802                      // TODO: Assuming same base type for units...
1803                      if(_class.type == unitClass)
1804                      {
1805                         if(type.kind == classType)
1806                         {
1807                            Class _class = type._class.registered;
1808                            if(_class.type == unitClass)
1809                            {
1810                               if(!_class.dataType)
1811                                  _class.dataType = ProcessTypeString(_class.dataTypeString, false);
1812                               type = _class.dataType;
1813                            }
1814                         }
1815                         switch(type.kind)
1816                         {
1817                            case floatType:
1818                            {
1819                               float value;
1820                               float (*Get)(float) = (convertTo ? (void *)prop.Set : (void *)prop.Get);
1821                               GetFloat(memberExp, &value);
1822
1823                               FreeExpContents(exp);
1824                               exp.constant = PrintFloat(Get ? Get(value) : value);
1825                               exp.type = constantExp;
1826                               exp.isConstant = true;
1827                               supported = true;
1828                               break;
1829                            }
1830                            case doubleType:
1831                            {
1832                               double value;
1833                               double (*Get)(double) = (convertTo ? (void *)prop.Set : (void *)prop.Get);
1834                               GetDouble(memberExp, &value);
1835
1836                               FreeExpContents(exp);
1837                               exp.constant = PrintDouble(Get ? Get(value) : value);
1838                               exp.isConstant = true;
1839                               exp.type = constantExp;
1840                               supported = true;
1841                               break;
1842                            }
1843                         }
1844                      }
1845                      else
1846                      {
1847                         if(convertTo)
1848                         {
1849                            Expression value = memberExp;
1850                            Type type = prop.dataType;
1851                            exp.member.exp = null;
1852
1853                            if(_class.type == structClass)
1854                            {
1855                               switch(type.kind)
1856                               {
1857                                  case classType:
1858                                  {
1859                                     Class propertyClass = type._class.registered;
1860                                     if(propertyClass.type == structClass && value.type == instanceExp)
1861                                     {
1862                                        void (*Set)(void *, void *) = (void *)prop.Set;
1863                                        FreeExpContents(exp);
1864                                        exp.instance = Instantiation
1865                                        {
1866                                           data = new0 byte[_class.structSize];
1867                                           _class = MkSpecifierName(_class.name);
1868                                           loc = exp.loc;
1869                                        };
1870                                        exp.type = instanceExp;
1871
1872                                        Set(exp.instance.data, value.instance.data);
1873                                        PopulateInstance(exp.instance);
1874                                        supported = true;
1875                                     }
1876                                     break;
1877                                  }
1878                                  case intType:
1879                                  {
1880                                     int intValue;
1881                                     void (*Set)(void *, int) = (void *)prop.Set;
1882
1883                                     GetInt(value, &intValue);
1884                                     FreeExpContents(exp);
1885                                     exp.instance = Instantiation
1886                                     {
1887                                        data = new0 byte[_class.structSize];
1888                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
1889                                        loc = exp.loc;
1890                                     };
1891                                     exp.type = instanceExp;
1892
1893                                     Set(exp.instance.data, intValue);
1894                                     PopulateInstance(exp.instance);
1895                                     supported = true;
1896                                     break;
1897                                  }
1898                                  case int64Type:
1899                                  {
1900                                     int64 intValue;
1901                                     void (*Set)(void *, int64) = (void *)prop.Set;
1902
1903                                     GetInt64(value, &intValue);
1904                                     FreeExpContents(exp);
1905                                     exp.instance = Instantiation
1906                                     {
1907                                        data = new0 byte[_class.structSize];
1908                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
1909                                        loc = exp.loc;
1910                                     };
1911                                     exp.type = instanceExp;
1912
1913                                     Set(exp.instance.data, intValue);
1914                                     PopulateInstance(exp.instance);
1915                                     supported = true;
1916                                     break;
1917                                  }
1918                                  case floatType:
1919                                  {
1920                                     float floatValue;
1921                                     void (*Set)(void *, float) = (void *)prop.Set;
1922
1923                                     GetFloat(value, &floatValue);
1924                                     FreeExpContents(exp);
1925                                     exp.instance = Instantiation
1926                                     {
1927                                        data = new0 byte[_class.structSize];
1928                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
1929                                        loc = exp.loc;
1930                                     };
1931                                     exp.type = instanceExp;
1932
1933                                     Set(exp.instance.data, floatValue);
1934                                     PopulateInstance(exp.instance);
1935                                     supported = true;
1936                                     break;
1937                                  }
1938                                  case doubleType:
1939                                  {
1940                                     double doubleValue;
1941                                     void (*Set)(void *, double) = (void *)prop.Set;
1942
1943                                     GetDouble(value, &doubleValue);
1944                                     FreeExpContents(exp);
1945                                     exp.instance = Instantiation
1946                                     {
1947                                        data = new0 byte[_class.structSize];
1948                                        _class = MkSpecifierName/*MkClassName*/(_class.name);
1949                                        loc = exp.loc;
1950                                     };
1951                                     exp.type = instanceExp;
1952
1953                                     Set(exp.instance.data, doubleValue);
1954                                     PopulateInstance(exp.instance);
1955                                     supported = true;
1956                                     break;
1957                                  }
1958                               }
1959                            }
1960                            else if(_class.type == bitClass)
1961                            {
1962                               switch(type.kind)
1963                               {
1964                                  case classType:
1965                                  {
1966                                     Class propertyClass = type._class.registered;
1967                                     if(propertyClass.type == structClass && value.instance.data)
1968                                     {
1969                                        unsigned int (*Set)(void *) = (void *)prop.Set;
1970                                        unsigned int bits = Set(value.instance.data);
1971                                        FreeExpContents(exp);
1972                                        exp.constant = PrintHexUInt(bits);
1973                                        exp.type = constantExp;
1974                                        supported = true;
1975                                        break;
1976                                     }
1977                                     else if(_class.type == bitClass)
1978                                     {
1979                                        unsigned int value;
1980                                        unsigned int (*Set)(unsigned int) = (void *)prop.Set;
1981                                        unsigned int bits;
1982
1983                                        GetUInt(memberExp, &value);
1984                                        bits = Set(value);
1985                                        FreeExpContents(exp);
1986                                        exp.constant = PrintHexUInt(bits);
1987                                        exp.type = constantExp;
1988                                        supported = true;
1989                                     }
1990                                  }
1991                               }
1992                            }
1993                            FreeExpression(value);
1994                         }
1995                         else
1996                         {
1997                            if(_class.type == bitClass)
1998                            {
1999                               uint value;
2000                               GetUInt(memberExp, &value);
2001
2002                               switch(type.kind)
2003                               {
2004                                  case classType:
2005                                  {
2006                                     Class _class = type._class.registered;
2007                                     if(_class.type == structClass)
2008                                     {
2009                                        void (*Get)(unsigned int, void *) = (void *)prop.Get;
2010
2011                                        FreeExpContents(exp);
2012                                        exp.instance = Instantiation
2013                                        {
2014                                           data = new0 byte[_class.structSize];
2015                                           _class = MkSpecifierName/*MkClassName*/(_class.name);
2016                                           loc = exp.loc;
2017                                        };
2018                                        //exp.instance.fullSet = true;
2019                                        exp.type = instanceExp;
2020                                        Get(value, exp.instance.data);
2021                                        PopulateInstance(exp.instance);
2022                                        supported = true;
2023                                     }
2024                                     else if(_class.type == bitClass)
2025                                     {
2026                                        unsigned int (*Get)(unsigned int) = (void *)prop.Get;
2027                                        uint64 bits = Get(value);
2028                                        exp.constant = PrintHexUInt64(bits);
2029                                        exp.type = constantExp;
2030                                        supported = true;
2031                                     }
2032                                     break;
2033                                  }
2034                               }
2035                            }
2036                            else if(_class.type == structClass)
2037                            {
2038                               byte * value = (memberExp.type == instanceExp ) ? memberExp.instance.data : null;
2039                               if(value)
2040                                  memberExp.instance.data = null;
2041
2042                               switch(type.kind)
2043                               {
2044                                  case classType:
2045                                  {
2046                                     Class _class = type._class.registered;
2047                                     if(_class.type == structClass && value)
2048                                     {
2049                                        void (*Get)(void *, void *) = (void *)prop.Get;
2050
2051                                        FreeExpContents(exp);
2052                                        exp.instance = Instantiation
2053                                        {
2054                                           data = new0 byte[_class.structSize];
2055                                           _class = MkSpecifierName/*MkClassName*/(_class.name);
2056                                           loc = exp.loc;
2057                                        };
2058                                        //exp.instance.fullSet = true;
2059                                        exp.type = instanceExp;
2060                                        Get(value, exp.instance.data);
2061                                        PopulateInstance(exp.instance);
2062                                        supported = true;
2063                                     }
2064                                     break;
2065                                  }
2066                               }
2067
2068                               delete value;
2069                            }
2070                            /*else
2071                            {
2072                               char * value = memberExp.instance.data;
2073                               switch(type.kind)
2074                               {
2075                                  case classType:
2076                                  {
2077                                     Class _class = type._class.registered;
2078                                     if(_class.type == normalClass)
2079                                     {
2080                                        void *(*Get)(void *) = (void *)prop.Get;
2081
2082                                        FreeExpContents(exp);
2083                                        exp.instance = Instantiation
2084                                        {
2085                                           data = Get(value, exp.instance.data);     ?????
2086                                           _class = MkSpecifierName(_class.name); //MkClassName(_class.name);
2087                                           loc = exp.loc;
2088                                        };
2089                                        exp.type = instanceExp;
2090                                     }
2091                                     break;
2092                                  }
2093                               }
2094                            }
2095                            */
2096                         }
2097                      }
2098                   }
2099                   if(!supported)
2100                   {
2101                      exp.type = memberPropertyErrorExp;
2102                      exp.isConstant = false;
2103                   }
2104                }
2105                else if(member)
2106                {
2107                   if(memberExp.hasAddress || memberExp.type == constantExp || (memberExp.type == instanceExp && memberExp.instance && memberExp.instance.data))
2108                   //if(memberExp.expType && memberExp.expType.kind == intType)  // && !exp.index.exp.expType.isSigned
2109                   {
2110                      if(_class.type == bitClass)
2111                      {
2112                         if(memberExp.type == constantExp)
2113                         {
2114                            // Unfinished business...
2115                            BitMember bitMember = (BitMember)member;
2116                            uint64 bits = 0;
2117                            GetUInt64(memberExp, &bits);
2118                            bits &= bitMember.mask;
2119                            bits >>= bitMember.pos;
2120
2121                            FreeExpression(exp.member.exp);
2122                            FreeIdentifier(exp.member.member);
2123
2124                            exp.constant = PrintUInt64(bits);
2125
2126                            exp.isConstant = true;
2127                            exp.type = constantExp;
2128                            exp.hasAddress = false;
2129                         }
2130                      }
2131                      else
2132                      {
2133                         char * evaluation = null;
2134                         ExpressionType evalError = dummyExp;
2135                         bool gotAddress = false;
2136                         uint64 address = 0;
2137                         Expression prev = exp.prev, next = exp.next;
2138                         char format;
2139                         int size;
2140                         Expression expNew;
2141                         Type dataType = member.dataType;
2142
2143                         if(!dataType)
2144                            dataType = member.dataType = ProcessTypeString(member.dataTypeString, false);
2145
2146                         if(dataType.kind == classType && dataType._class.registered &&
2147                               (dataType._class.registered.type == enumClass || dataType._class.registered.type == bitClass || dataType._class.registered.type == unitClass))
2148                         {
2149                            if(dataType._class.registered.dataTypeString)
2150                               dataType._class.registered.dataType = ProcessTypeString(dataType._class.registered.dataTypeString, false);
2151                            dataType = dataType._class.registered.dataType;
2152                            if(!dataType)
2153                               dataType = ProcessTypeString("int", false);
2154                         }
2155
2156                         size = ComputeTypeSize(member.dataType);
2157
2158                         format = GetGdbFormatChar(dataType);
2159                         //if(memberExp.address)
2160                         {
2161                            //GetInt(memberExp, &address);
2162                            //offset = member.offset;
2163
2164                            // TESTING NOHEAD HERE?
2165                            if(_class.type == normalClass || _class.type == noHeadClass || _class.type == systemClass)
2166                               offset += member._class.offset;
2167
2168                            // VERIFY THIS: (trying to fix primitive.type)
2169                            // if(memberExp.type == constantExp)
2170                            if(memberExp.hasAddress && (_class.type != normalClass && _class.type != noHeadClass && _class.type != systemClass))
2171                            {
2172                               address = memberExp.address;
2173                               gotAddress = true;
2174                            }
2175                            else if(memberExp.type == constantExp)
2176                               gotAddress = GetUInt64(memberExp, &address);
2177                            else
2178                            {
2179                               gotAddress = GetUInt64(memberExp, &address);
2180                               //printf("Unhandled !!\n");
2181
2182                               //printf("memberExp.hasAddress = %d\n", memberExp.hasAddress);
2183                               //printf("memberExp.type = %d\n", memberExp.type);
2184                               //printf("_class.name = %s, _class.type = %d\n", _class.name, _class.type);
2185                            }
2186
2187                            address += offset;
2188
2189                            if(memberExp.type == instanceExp)
2190                            {
2191                               String constant = null;
2192                               byte * data = memberExp.instance.data + offset;
2193                               switch(dataType.kind)
2194                               {
2195                                  case charType:
2196                                     if(dataType.isSigned)
2197                                        constant = PrintChar(*(char *)data);
2198                                     else
2199                                        constant = PrintUChar(*(byte *)data);
2200                                     break;
2201                                  case shortType:
2202                                     if(dataType.isSigned)
2203                                        constant = PrintShort(*(short *)data);
2204                                     else
2205                                        constant = PrintUShort(*(uint16 *)data);
2206                                     break;
2207                                  case intType:
2208                                     if(dataType.isSigned)
2209                                        constant = PrintInt(*(int *)data);
2210                                     else
2211                                        constant = PrintUInt(*(uint *)data);
2212                                     break;
2213                                  case longType:
2214                                  case int64Type:
2215                                     if(dataType.isSigned)
2216                                        constant = PrintInt64(*(int64 *)data);
2217                                     else
2218                                        constant = PrintUInt64(*(uint64 *)data);
2219                                     break;
2220                                  case floatType: constant = PrintFloat(*(float *)data); break;
2221                                  case doubleType: constant = PrintDouble(*(double *)data); break;
2222                               }
2223                               if(constant)
2224                               {
2225                                  FreeExpContents(exp);
2226                                  exp.constant = constant;
2227                                  exp.type = constantExp;
2228                                  exp.isConstant = true;
2229                               }
2230                               else
2231                                  exp.type = unknownErrorExp;
2232                            }
2233                            else if(!gotAddress)
2234                            {
2235                               FreeExpContents(exp);
2236                               exp.type = unknownErrorExp;
2237                            }
2238                            else if((dataType.kind == classType && dataType._class &&
2239                                  (!dataType._class.registered || dataType._class.registered.type == normalClass || dataType._class.registered.type == noHeadClass || dataType._class.registered.type == systemClass)) ||
2240                               (dataType.kind != classType && dataType.kind != arrayType && dataType.kind != structType && dataType.kind != unionType))
2241                            {
2242                               evaluation = Debugger::ReadMemory(address, size, format, &evalError);
2243                               if(evalError != dummyExp)
2244                               {
2245                                  exp.type = evalError;
2246                                  exp.constant = PrintHexUInt64(address);
2247                               }
2248                               else if(evaluation)
2249                               {
2250                                  //printf("evaluation = %s\n", evaluation);
2251                                  expNew = ParseExpressionString(evaluation);
2252                                  delete evaluation;
2253                                  expNew.destType = exp.expType;
2254                                  if(exp.expType)
2255                                     exp.expType.refCount++;
2256                                  //FreeType(memberExp.destType);
2257                                  FreeType(exp.expType);
2258                                  FreeType(exp.destType);
2259                                  FreeExpContents(exp);
2260                                  ProcessExpressionType(expNew);
2261                                  DebugComputeExpression(expNew);
2262                                  expNew.prev = prev;
2263                                  expNew.next = next;
2264                                  expNew.isConstant = true;
2265                                  expNew.address = address;
2266                                  expNew.hasAddress = true;
2267                                  *exp = *expNew;
2268                                  delete expNew;
2269                               }
2270                               else
2271                               {
2272                                  FreeExpContents(exp);
2273                                  exp.type = unknownErrorExp;
2274                               }
2275                            }
2276                            else
2277                            {
2278                               // TESTING THIS HERE...
2279                               exp.type = constantExp;
2280                               exp.constant = PrintHexUInt64(address);
2281
2282                               exp.address = address;
2283                               exp.hasAddress = true;
2284                               exp.isConstant = true;
2285                            }
2286                         }
2287                      }
2288                      //else
2289                      //   exp.type = ExpUnknownError;
2290
2291                      //FreeExpContents(exp);
2292                      //exp.constant = PrintUInt64(value);
2293                      //exp.type = constantExp;
2294                   }
2295                }
2296                else
2297                {
2298                   if(type && (type.kind == structType || type.kind == unionType))
2299                   {
2300                      uint offset = 0;
2301                      Type memberType = exp.member.member ? FindMemberAndOffset(type, exp.member.member.string, &offset) : null;
2302                      if(memberType)
2303                      {
2304                         char * evaluation = null;
2305                         ExpressionType evalError = dummyExp;
2306                         uint64 address = 0;
2307                         bool gotAddress = false;
2308                         Expression prev = exp.prev, next = exp.next;
2309                         char format;
2310                         int size = memberType.size;
2311                         Expression expNew;
2312                         Type dataType = memberType;
2313
2314                         if(dataType.kind == classType && dataType._class.registered &&
2315                               (dataType._class.registered.type == enumClass || dataType._class.registered.type == bitClass || dataType._class.registered.type == unitClass))
2316                            dataType = dataType._class.registered.dataType;
2317
2318                         format = GetGdbFormatChar(dataType);
2319
2320                         if(memberExp.hasAddress)
2321                         {
2322                            address = memberExp.address;
2323                            gotAddress = true;
2324                         }
2325                         else if(memberExp.type == constantExp)
2326                            gotAddress = GetUInt64(memberExp, &address);
2327
2328                         address += offset;
2329
2330                         if(!gotAddress)
2331                         {
2332                            FreeExpContents(exp);
2333                            exp.type = unknownErrorExp;
2334                         }
2335                         else if((dataType.kind == classType && dataType._class &&
2336                               (!dataType._class.registered || dataType._class.registered.type == normalClass || dataType._class.registered.type == noHeadClass || dataType._class.registered.type == systemClass)) ||
2337                            (dataType.kind != classType && dataType.kind != arrayType && dataType.kind != structType && dataType.kind != unionType))
2338                         {
2339                            evaluation = Debugger::ReadMemory(address, size, format, &evalError);
2340                            if(evalError != dummyExp)
2341                            {
2342                               exp.type = evalError;
2343                               exp.constant = PrintHexUInt64(address);
2344                            }
2345                            else if(evaluation)
2346                            {
2347                               expNew = ParseExpressionString(evaluation);
2348                               delete evaluation;
2349                               expNew.destType = exp.expType;
2350                               if(exp.expType)
2351                                  exp.expType.refCount++;
2352                               //FreeType(memberExp.destType);
2353                               FreeType(exp.expType);
2354                               FreeType(exp.destType);
2355                               FreeExpContents(exp);
2356                               ProcessExpressionType(expNew);
2357                               DebugComputeExpression(expNew);
2358                               expNew.prev = prev;
2359                               expNew.next = next;
2360                               expNew.isConstant = true;
2361                               expNew.address = address;
2362                               expNew.hasAddress = true;
2363                               *exp = *expNew;
2364                               delete expNew;
2365                            }
2366                            else
2367                            {
2368                               FreeExpContents(exp);
2369                               exp.type = unknownErrorExp;
2370                            }
2371                         }
2372                         else
2373                         {
2374                            FreeExpContents(exp);
2375
2376                            // TESTING THIS HERE...
2377                            exp.type = constantExp;
2378                            exp.constant = PrintHexUInt64(address);
2379
2380                            exp.address = address;
2381                            exp.hasAddress = true;
2382                            exp.isConstant = true;
2383                         }
2384                      }
2385                      else
2386                         exp.type = memberSymbolErrorExp;
2387                   }
2388                   else
2389                      exp.type = memberSymbolErrorExp;
2390                }
2391             }
2392
2393             //if(exp.type != memberExp)
2394             {
2395                //FreeExpression(memberExp);
2396                //FreeIdentifier(memberID);
2397             }
2398          }
2399          else
2400          {
2401             exp.type = memberSymbolErrorExp;
2402          }
2403          break;
2404       }
2405       case typeSizeExp:
2406       {
2407          Type type = ProcessType(exp.typeName.qualifiers, exp.typeName.declarator);
2408          FreeExpContents(exp);
2409          exp.constant = PrintUInt(ComputeTypeSize(type));
2410          exp.type = constantExp;
2411          FreeType(type);
2412          break;
2413       }
2414       case classSizeExp:
2415       {
2416          Symbol classSym = FindClass(exp._class.name);
2417          if(classSym && classSym.registered)
2418          {
2419             //exp.constant = PrintUInt(classSym.registered.size);
2420             //exp.type = constantExp;
2421
2422             char className[1024];
2423             sprintf(className, "__ecereClass_%s", classSym.string);
2424             FreeExpContents(exp);
2425             exp.type = pointerExp;
2426             exp.member.exp = MkExpIdentifier(MkIdentifier(className));
2427             exp.member.member = MkIdentifier("size");
2428          }
2429          break;
2430       }
2431       case castExp:
2432       {
2433          DebugComputeExpression(exp.cast.exp);
2434
2435          if(ExpressionIsError(exp.cast.exp)) //.type == ExpSymbolError
2436             CarryExpressionError(exp, exp.cast.exp);
2437          else
2438          {
2439             exp.hasAddress = exp.cast.exp.hasAddress;
2440             exp.address = exp.cast.exp.address;
2441             if(exp.cast.exp.type == instanceExp && exp.cast.exp.expType && exp.expType && exp.cast.exp.expType.kind == classType && exp.expType.kind == classType &&
2442                exp.cast.exp.expType._class && exp.expType._class && exp.cast.exp.expType._class.registered && exp.expType._class.registered &&
2443                exp.cast.exp.expType._class.registered == exp.expType._class.registered)
2444             {
2445                Instantiation inst = exp.cast.exp.instance;
2446                exp.cast.exp.instance = null;
2447                FreeExpContents(exp);
2448                exp.instance = inst;
2449                exp.type = instanceExp;
2450             }
2451             else if(exp.cast.exp.type == constantExp && exp.expType)
2452             {
2453                Type type = exp.expType;
2454                if(type.kind == classType && type._class && type._class.registered)
2455                {
2456                   Class _class = type._class.registered;
2457                   if(_class.type == unitClass || _class.type == bitClass || _class.type == enumClass)
2458                   {
2459                      if(!_class.dataType)
2460                         _class.dataType = ProcessTypeString(_class.dataTypeString, false);
2461                      type = _class.dataType;
2462                   }
2463                   else if(_class.type == structClass && !type.byReference)
2464                   {
2465                      FreeExpContents(exp);
2466                      exp.type = unknownErrorExp;
2467                      break;
2468                   }
2469                }
2470
2471                switch(type.kind)
2472                {
2473                   case charType:
2474                      if(type.isSigned)
2475                      {
2476                         char value = 0;
2477                         if(GetChar(exp.cast.exp, &value))
2478                         {
2479                            FreeExpContents(exp);
2480                            exp.constant = PrintChar(value);
2481                            exp.type = constantExp;
2482                            exp.isConstant = true;
2483                         }
2484                      }
2485                      else
2486                      {
2487                         unsigned char value = 0;
2488                         if(GetUChar(exp.cast.exp, &value))
2489                         {
2490                            FreeExpContents(exp);
2491                            exp.constant = PrintUChar(value);
2492                            exp.type = constantExp;
2493                            exp.isConstant = true;
2494                         }
2495                      }
2496                      break;
2497                   case shortType:
2498                      if(type.isSigned)
2499                      {
2500                         short value = 0;
2501                         if(GetShort(exp.cast.exp, &value))
2502                         {
2503                            FreeExpContents(exp);
2504                            exp.constant = PrintShort(value);
2505                            exp.type = constantExp;
2506                            exp.isConstant = true;
2507                         }
2508                      }
2509                      else
2510                      {
2511                         unsigned short value = 0;
2512                         if(GetUShort(exp.cast.exp, &value))
2513                         {
2514                            FreeExpContents(exp);
2515                            exp.constant = PrintUShort(value);
2516                            exp.type = constantExp;
2517                            exp.isConstant = true;
2518                         }
2519                      }
2520                      break;
2521                   case intType:
2522                      if(type.isSigned)
2523                      {
2524                         int value = 0;
2525                         if(GetInt(exp.cast.exp, &value))
2526                         {
2527                            FreeExpContents(exp);
2528                            exp.constant = PrintInt(value);
2529                            exp.type = constantExp;
2530                            exp.isConstant = true;
2531                         }
2532                      }
2533                      else
2534                      {
2535                         unsigned int value = 0;
2536                         if(GetUInt(exp.cast.exp, &value))
2537                         {
2538                            FreeExpContents(exp);
2539                            exp.constant = PrintUInt(value);
2540                            exp.type = constantExp;
2541                            exp.isConstant = true;
2542                         }
2543                      }
2544                      break;
2545                   case int64Type:
2546                      if(type.isSigned)
2547                      {
2548                         int64 value = 0;
2549                         if(GetInt64(exp.cast.exp, &value))
2550                         {
2551                            FreeExpContents(exp);
2552                            exp.constant = PrintInt64(value);
2553                            exp.type = constantExp;
2554                            exp.isConstant = true;
2555                         }
2556                      }
2557                      else
2558                      {
2559                         uint64 value = 0;
2560                         if(GetUInt64(exp.cast.exp, &value))
2561                         {
2562                            FreeExpContents(exp);
2563                            exp.constant = PrintUInt64(value);
2564                            exp.type = constantExp;
2565                            exp.isConstant = true;
2566                         }
2567                      }
2568                      break;
2569                   case pointerType:
2570                   case classType:
2571                   {
2572                      uint64 value = 0;
2573                      if(GetUInt64(exp.cast.exp, &value))
2574                      {
2575                         FreeExpContents(exp);
2576                         if(type.kind == pointerType || type.kind == classType)
2577                            exp.constant = PrintHexUInt64(value);
2578                         else
2579                            exp.constant = PrintUInt64(value);
2580                         exp.type = constantExp;
2581                         exp.isConstant = true;
2582                      }
2583                      break;
2584                   }
2585                   case floatType:
2586                   {
2587                      float value = 0;
2588                      if(exp.cast.exp.type == constantExp && exp.cast.exp.constant &&
2589                         (!strcmpi(exp.cast.exp.constant, "nan") ||
2590                         !strcmpi(exp.cast.exp.constant, "-nan") ||
2591                         !strcmpi(exp.cast.exp.constant, "inf") ||
2592                         !strcmpi(exp.cast.exp.constant, "-inf")))
2593                      {
2594                         String constant = exp.cast.exp.constant;
2595                         exp.cast.exp.constant = null;
2596                         FreeExpContents(exp);
2597                         exp.constant = constant;
2598                         exp.type = constantExp;
2599                         exp.isConstant = true;
2600                      }
2601                      else if(GetFloat(exp.cast.exp, &value))
2602                      {
2603                         FreeExpContents(exp);
2604                         exp.constant = PrintFloat(value);
2605                         exp.type = constantExp;
2606                         exp.isConstant = true;
2607                      }
2608                      break;
2609                   }
2610                   case doubleType:
2611                   {
2612                      double value = 0;
2613                      if(exp.cast.exp.type == constantExp && exp.cast.exp.constant &&
2614                         (!strcmpi(exp.cast.exp.constant, "nan") ||
2615                         !strcmpi(exp.cast.exp.constant, "-nan") ||
2616                         !strcmpi(exp.cast.exp.constant, "inf") ||
2617                         !strcmpi(exp.cast.exp.constant, "-inf")))
2618                      {
2619                         String constant = exp.cast.exp.constant;
2620                         exp.cast.exp.constant = null;
2621                         FreeExpContents(exp);
2622                         exp.constant = constant;
2623                         exp.type = constantExp;
2624                         exp.isConstant = true;
2625                      }
2626                      else if(GetDouble(exp.cast.exp, &value))
2627                      {
2628                         FreeExpContents(exp);
2629                         exp.constant = PrintDouble(value);
2630                         exp.type = constantExp;
2631                         exp.isConstant = true;
2632                      }
2633                      break;
2634                   }
2635                }
2636             }
2637          }
2638          break;
2639       }
2640       case conditionExp:
2641       {
2642          if(exp.cond.cond)
2643          {
2644             DebugComputeExpression(exp.cond.cond);
2645
2646             if(ExpressionIsError(exp.cond.cond))
2647                CarryExpressionError(exp, exp.cond.cond);
2648             else if(exp.cond.cond.type == constantExp && exp.cond.cond.constant)
2649             {
2650                Expression e = null;
2651                if(strtol(exp.cond.cond.constant, null, 0))
2652                {
2653                   for(e = exp.cond.exp ? exp.cond.exp->first : null; e; e = e.next)
2654                   {
2655                      DebugComputeExpression(e);
2656                      if(!e.next) break;
2657                   }
2658                   if(e)
2659                   {
2660                      if(ExpressionIsError(e))
2661                      {
2662                         CarryExpressionError(exp, e);
2663                         e = null;
2664                      }
2665                      else
2666                         exp.cond.exp->Remove(e);
2667                   }
2668                }
2669                else
2670                {
2671                   e = exp.cond.elseExp;
2672                   if(e)
2673                   {
2674                      DebugComputeExpression(e);
2675                      if(ExpressionIsError(e))
2676                      {
2677                         CarryExpressionError(exp, e);
2678                         e = null;
2679                      }
2680                      else
2681                         exp.cond.elseExp = null;
2682                   }
2683                }
2684                if(e)
2685                {
2686                   FreeType(exp.expType);
2687                   FreeType(exp.destType);
2688                   e.prev = exp.prev;
2689                   e.next = exp.next;
2690                   FreeExpContents(exp);
2691                   *exp = *e;
2692                   delete e;
2693                }
2694                else if(!ExpressionIsError(exp))
2695                {
2696                   FreeExpContents(exp);
2697                   exp.type = unknownErrorExp;
2698                }
2699             }
2700             else
2701             {
2702                FreeExpContents(exp);
2703                exp.type = unknownErrorExp;
2704             }
2705          }
2706          else
2707          {
2708             FreeExpContents(exp);
2709             exp.type = unknownErrorExp;
2710          }
2711          break;
2712       }
2713    }
2714 }
2715
2716 void ApplyUnitConverters(Expression exp)
2717 {
2718    Property convert = null;
2719    Type type = exp.expType;
2720    bool useGet = false;
2721    if(type.kind == classType && type._class && type._class.registered)
2722    {
2723       Class _class = type._class.registered;
2724       if(_class.type == unitClass || _class.type == bitClass || _class.type == enumClass)
2725       {
2726          if(_class.type == unitClass && _class.base.type == unitClass)
2727          {
2728             Property p;
2729             for(p = _class.conversions.first; p; p = p.next)
2730             {
2731                if(!strcmp(p.name, _class.base.fullName))
2732                {
2733                   convert = p;
2734                   break;
2735                }
2736                else
2737                {
2738                   Class c = eSystem_FindClass(_class.module, p.name);
2739                   if(c)
2740                   {
2741                      Property p2;
2742                      for(p2 = c.conversions.first; p2; p2 = p2.next)
2743                      {
2744                         if(!strcmp(p2.name, _class.base.fullName))
2745                         {
2746                            convert = p;
2747                            break;
2748                         }
2749                      }
2750                   }
2751                   if(convert)
2752                      break;
2753                }
2754             }
2755          }
2756
2757          if(!_class.dataType)
2758             _class.dataType = ProcessTypeString(_class.dataTypeString, false);
2759          type = _class.dataType;
2760       }
2761    }
2762    if(convert)
2763    {
2764       switch(type.kind)
2765       {
2766          case charType:
2767             if(type.isSigned)
2768             {
2769                char value = 0;
2770                if(GetChar(exp, &value))
2771                {
2772                   FreeExpContents(exp);
2773                   exp.constant = PrintChar(value);
2774                   exp.type = constantExp;
2775                   exp.isConstant = true;
2776                }
2777             }
2778             else
2779             {
2780                unsigned char value = 0;
2781                if(GetUChar(exp, &value))
2782                {
2783                   FreeExpContents(exp);
2784                   exp.constant = PrintUChar(value);
2785                   exp.type = constantExp;
2786                   exp.isConstant = true;
2787                }
2788             }
2789             break;
2790          case shortType:
2791             if(type.isSigned)
2792             {
2793                short value = 0;
2794                if(GetShort(exp, &value))
2795                {
2796                   FreeExpContents(exp);
2797                   exp.constant = PrintShort(value);
2798                   exp.type = constantExp;
2799                   exp.isConstant = true;
2800                }
2801             }
2802             else
2803             {
2804                unsigned short value = 0;
2805                if(GetUShort(exp, &value))
2806                {
2807                   FreeExpContents(exp);
2808                   exp.constant = PrintUShort(value);
2809                   exp.type = constantExp;
2810                   exp.isConstant = true;
2811                }
2812             }
2813             break;
2814          case intType:
2815             if(type.isSigned)
2816             {
2817                int value = 0;
2818                if(GetInt(exp, &value))
2819                {
2820                   FreeExpContents(exp);
2821                   exp.constant = PrintInt(value);
2822                   exp.type = constantExp;
2823                   exp.isConstant = true;
2824                }
2825             }
2826             else
2827             {
2828                unsigned int value = 0;
2829                if(GetUInt(exp, &value))
2830                {
2831                   FreeExpContents(exp);
2832                   exp.constant = PrintUInt(value);
2833                   exp.type = constantExp;
2834                   exp.isConstant = true;
2835                }
2836             }
2837             break;
2838          case int64Type:
2839             if(type.isSigned)
2840             {
2841                int64 value = 0;
2842                if(GetInt64(exp, &value))
2843                {
2844                   FreeExpContents(exp);
2845                   exp.constant = PrintInt64(value);
2846                   exp.type = constantExp;
2847                   exp.isConstant = true;
2848                }
2849             }
2850             else
2851             {
2852                uint64 value = 0;
2853                if(GetUInt64(exp, &value))
2854                {
2855                   FreeExpContents(exp);
2856                   exp.constant = PrintUInt64(value);
2857                   exp.type = constantExp;
2858                   exp.isConstant = true;
2859                }
2860             }
2861             break;
2862          case pointerType:
2863          case classType:
2864          {
2865             uint64 value = 0;
2866             if(GetUInt64(exp, &value))
2867             {
2868                FreeExpContents(exp);
2869                if(type.kind == pointerType || type.kind == classType)
2870                   exp.constant = PrintHexUInt64(value);
2871                else
2872                   exp.constant = PrintUInt64(value);
2873                exp.type = constantExp;
2874                exp.isConstant = true;
2875             }
2876             break;
2877          }
2878          case floatType:
2879          {
2880             float value = 0;
2881             if(exp.type == constantExp && exp.constant &&
2882                (!strcmpi(exp.constant, "nan") ||
2883                !strcmpi(exp.constant, "-nan") ||
2884                !strcmpi(exp.constant, "inf") ||
2885                !strcmpi(exp.constant, "-inf")))
2886             {
2887                String constant = exp.constant;
2888                exp.constant = null;
2889                FreeExpContents(exp);
2890                exp.constant = constant;
2891                exp.type = constantExp;
2892                exp.isConstant = true;
2893             }
2894             else if(GetFloat(exp, &value))
2895             {
2896                if(convert)
2897                {
2898                   float (*convertFn)(float) = (useGet ? (void *)convert.Get : (void *)convert.Set);
2899                   if(convertFn)
2900                      value = convertFn(value);
2901                }
2902                FreeExpContents(exp);
2903                exp.constant = PrintFloat(value);
2904                exp.type = constantExp;
2905                exp.isConstant = true;
2906             }
2907             break;
2908          }
2909          case doubleType:
2910          {
2911             double value = 0;
2912             if(exp.type == constantExp && exp.constant &&
2913                (!strcmpi(exp.constant, "nan") ||
2914                !strcmpi(exp.constant, "-nan") ||
2915                !strcmpi(exp.constant, "inf") ||
2916                !strcmpi(exp.constant, "-inf")))
2917             {
2918                String constant = exp.constant;
2919                exp.constant = null;
2920                FreeExpContents(exp);
2921                exp.constant = constant;
2922                exp.type = constantExp;
2923                exp.isConstant = true;
2924             }
2925             else if(GetDouble(exp, &value))
2926             {
2927                if(convert)
2928                {
2929                   double (*convertFn)(double) = (useGet ? (void *)convert.Get : (void *)convert.Set);
2930                   if(convertFn)
2931                      value = convertFn(value);
2932                }
2933                FreeExpContents(exp);
2934                exp.constant = PrintDouble(value);
2935                exp.type = constantExp;
2936                exp.isConstant = true;
2937             }
2938             break;
2939          }
2940       }
2941    }
2942 }