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