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