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