a small fix for the floating point problem
[fw/sdcc] / src / SDCCval.c
1 /*----------------------------------------------------------------------
2     SDCCval.c :- has routine to do all kinds of fun stuff with the
3                 value wrapper & with initialiser lists.
4
5     Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6
7     This program is free software; you can redistribute it and/or modify it
8     under the terms of the GNU General Public License as published by the
9     Free Software Foundation; either version 2, or (at your option) any
10     later version.
11
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
21     In other words, you are welcome to use, share and improve this program.
22     You are forbidden to forbid anyone else to use, share and improve
23     what you give them.   Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
25
26 #include "common.h"
27 #include <math.h>
28 #include <stdlib.h>
29 #include <limits.h>
30 #include "newalloc.h"
31
32 int cNestLevel;
33
34 /*-----------------------------------------------------------------*/
35 /* newValue - allocates and returns a new value        */
36 /*-----------------------------------------------------------------*/
37 value *
38 newValue ()
39 {
40   value *val;
41
42   val = Safe_alloc (sizeof (value));
43
44   return val;
45 }
46
47 /*-----------------------------------------------------------------*/
48 /* newiList - new initializer list                                 */
49 /*-----------------------------------------------------------------*/
50 initList *
51 newiList (int type, void *ilist)
52 {
53   initList *nilist;
54
55
56   nilist = Safe_alloc (sizeof (initList));
57
58   nilist->type = type;
59   nilist->lineno = yylineno;
60
61   switch (type)
62     {
63     case INIT_NODE:
64       nilist->init.node = (struct ast *) ilist;
65       break;
66
67     case INIT_DEEP:
68       nilist->init.deep = (struct initList *) ilist;
69       break;
70     }
71
72   return nilist;
73 }
74
75 /*------------------------------------------------------------------*/
76 /* revinit   - reverses the initial values for a value  chain        */
77 /*------------------------------------------------------------------*/
78 initList *
79 revinit (initList * val)
80 {
81   initList *prev, *curr, *next;
82
83   if (!val)
84     return NULL;
85
86   prev = val;
87   curr = val->next;
88
89   while (curr)
90     {
91       next = curr->next;
92       curr->next = prev;
93       prev = curr;
94       curr = next;
95     }
96   val->next = (void *) NULL;
97   return prev;
98 }
99
100 bool
101 convertIListToConstList(initList *src, literalList **lList)
102 {
103     initList    *iLoop;
104     literalList *head, *last, *newL;
105     
106     head = last = NULL;
107     
108     if (!src || src->type != INIT_DEEP)
109     {
110         return FALSE;
111     }
112     
113     iLoop =  src->init.deep;
114     
115     while (iLoop)
116     {
117         if (iLoop->type != INIT_NODE)
118         {
119             return FALSE;
120         }
121         
122         if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node))))
123         {
124             return FALSE;
125         }
126         iLoop = iLoop->next;
127     }
128     
129     // We've now established that the initializer list contains only literal values.
130     
131     iLoop = src->init.deep;
132     while (iLoop)
133     {
134         double val = AST_LIT_VALUE(iLoop->init.node);
135         
136         if (last && last->literalValue == val)
137         {
138             last->count++;
139         }
140         else
141         {
142             newL = Safe_alloc(sizeof(literalList));
143             newL->literalValue = val;
144             newL->count = 1;
145             newL->next = NULL;
146             
147             if (last)
148             {
149                 last->next = newL;
150             }
151             else
152             {
153                 head = newL;
154             }
155             last = newL;
156         }
157         iLoop = iLoop->next;
158     }
159     
160     if (!head)    
161     {
162         return FALSE;
163     }
164     
165     *lList = head;
166     return TRUE;
167 }
168
169 literalList *
170 copyLiteralList(literalList *src)
171 {
172     literalList *head, *prev, *newL;
173     
174     head = prev = NULL;
175     
176     while (src)
177     {
178         newL = Safe_alloc(sizeof(literalList));
179         
180         newL->literalValue = src->literalValue;
181         newL->count = src->count;
182         newL->next = NULL;
183         
184         if (prev)
185         {
186             prev->next = newL;
187         }
188         else
189         {
190             head = newL;
191         }
192         prev = newL;
193         src = src->next;
194     }
195     
196     return head;
197 }
198
199
200
201 /*------------------------------------------------------------------*/
202 /* copyIlist - copy initializer list            */
203 /*------------------------------------------------------------------*/
204 initList *
205 copyIlist (initList * src)
206 {
207   initList *dest = NULL;
208
209   if (!src)
210     return NULL;
211
212   switch (src->type)
213     {
214     case INIT_DEEP:
215       dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
216       break;
217     case INIT_NODE:
218       dest = newiList (INIT_NODE, copyAst (src->init.node));
219       break;
220     }
221
222   if (src->next)
223     dest->next = copyIlist (src->next);
224
225   return dest;
226 }
227
228 /*------------------------------------------------------------------*/
229 /* list2int - converts the first element of the list to value       */
230 /*------------------------------------------------------------------*/
231 double 
232 list2int (initList * val)
233 {
234   initList *i = val;
235
236   if (i->type == INIT_DEEP)
237     return list2int (val->init.deep);
238
239   return floatFromVal (constExprValue (val->init.node, TRUE));
240 }
241
242 /*------------------------------------------------------------------*/
243 /* list2val - converts the first element of the list to value       */
244 /*------------------------------------------------------------------*/
245 value *
246 list2val (initList * val)
247 {
248   if (!val)
249     return NULL;
250
251   if (val->type == INIT_DEEP)
252     return list2val (val->init.deep);
253
254   return constExprValue (val->init.node, TRUE);
255 }
256
257 /*------------------------------------------------------------------*/
258 /* list2expr - returns the first expression in the initializer list */
259 /*------------------------------------------------------------------*/
260 ast *
261 list2expr (initList * ilist)
262 {
263   if (ilist->type == INIT_DEEP)
264     return list2expr (ilist->init.deep);
265   return ilist->init.node;
266 }
267
268 /*------------------------------------------------------------------*/
269 /* resolveIvalSym - resolve symbols in initial values               */
270 /*------------------------------------------------------------------*/
271 void 
272 resolveIvalSym (initList * ilist)
273 {
274   if (!ilist)
275     return;
276
277   if (ilist->type == INIT_NODE)
278     ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
279
280   if (ilist->type == INIT_DEEP)
281     resolveIvalSym (ilist->init.deep);
282
283   resolveIvalSym (ilist->next);
284 }
285
286 /*-----------------------------------------------------------------*/
287 /* symbolVal - creates a value for a symbol              */
288 /*-----------------------------------------------------------------*/
289 value *
290 symbolVal (symbol * sym)
291 {
292   value *val;
293
294   if (!sym)
295     return NULL;
296
297   val = newValue ();
298   val->sym = sym;
299
300   if (sym->type)
301     {
302       val->type = sym->type;
303       val->etype = getSpec (val->type);
304     }
305
306   if (*sym->rname)
307     sprintf (val->name, "%s", sym->rname);
308   else
309     sprintf (val->name, "_%s", sym->name);
310
311
312   return val;
313 }
314
315 /*--------------------------------------------------------------------*/
316 /* cheapestVal - convert a val to the cheapest as possible value      */
317 /*--------------------------------------------------------------------*/
318 value *cheapestVal (value *val) {
319   long sval=0;
320   unsigned long uval=0;
321
322   if (IS_FLOAT(val->type) || IS_CHAR(val->type))
323     return val;
324
325   if (SPEC_LONG(val->type)) {
326     if (SPEC_USIGN(val->type)) {
327       uval=SPEC_CVAL(val->type).v_ulong;
328     } else {
329       sval=SPEC_CVAL(val->type).v_long;
330     }
331   } else {
332     if (SPEC_USIGN(val->type)) {
333       uval=SPEC_CVAL(val->type).v_uint;
334     } else {
335       sval=SPEC_CVAL(val->type).v_int;
336     }
337   }
338
339   if (SPEC_USIGN(val->type)) {
340     if (uval<=0xffff) {
341       SPEC_LONG(val->type)=0;
342       SPEC_CVAL(val->type).v_uint = uval;
343     }
344     if (uval<=0xff) {
345       SPEC_NOUN(val->type)=V_CHAR;
346     }
347   } else { // not unsigned
348     if (sval<0) {
349       if (sval>=-32768) {
350         SPEC_LONG(val->type)=0;
351         SPEC_CVAL(val->type).v_int = sval & 0xffff;
352       }
353       if (sval>=-128) {
354         SPEC_NOUN(val->type)=V_CHAR;
355         SPEC_CVAL(val->type).v_int &= 0xff;
356       }
357     } else { // sval>=0
358       SPEC_USIGN(val->type)=1;
359       if (sval<=65535) {
360         SPEC_LONG(val->type)=0;
361         SPEC_CVAL(val->type).v_int = sval;
362       }
363       if (sval<=255) {
364         SPEC_NOUN(val->type)=V_CHAR;
365       }
366     }
367   }
368   return val;
369 }
370
371 /*-----------------------------------------------------------------*/
372 /* valueFromLit - creates a value from a literal                   */
373 /*-----------------------------------------------------------------*/
374 value *
375 valueFromLit (double lit)
376 {
377   char buffer[50];
378
379   if ((((long) lit) - lit) == 0)
380     {
381       sprintf (buffer, "%ld", (long) lit);
382       return constVal (buffer);
383     }
384
385   sprintf (buffer, "%f", lit);
386   return constFloatVal (buffer);
387 }
388
389 /*-----------------------------------------------------------------*/
390 /* constFloatVal - converts a FLOAT constant to value              */
391 /*-----------------------------------------------------------------*/
392 value *
393 constFloatVal (char *s)
394 {
395   value *val = newValue ();
396   double sval;
397
398   if (sscanf (s, "%lf", &sval) != 1)
399     {
400       werror (E_INVALID_FLOAT_CONST, s);
401       return constVal ("0");
402     }
403
404   val->type = val->etype = newLink ();
405   val->type->class = SPECIFIER;
406   SPEC_NOUN (val->type) = V_FLOAT;
407   SPEC_SCLS (val->type) = S_LITERAL;
408   SPEC_CVAL (val->type).v_float = sval;
409
410   return val;
411 }
412
413 /*-----------------------------------------------------------------*/
414 /* constVal - converts an INTEGER constant into a cheapest value   */
415 /*-----------------------------------------------------------------*/
416 value *constVal (char *s)
417 {
418   value *val;
419   short hex = 0, octal = 0;
420   char scanFmt[10];
421   int scI = 0;
422   double dval;
423
424   val = newValue ();            /* alloc space for value   */
425
426   val->type = val->etype = newLink ();  /* create the spcifier */
427   val->type->class = SPECIFIER;
428   SPEC_SCLS (val->type) = S_LITERAL;
429   // let's start with an unsigned char
430   SPEC_NOUN (val->type) = V_CHAR;
431   SPEC_USIGN (val->type) = 1;
432
433   hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
434
435   /* set the octal flag   */
436   if (!hex && *s == '0' && *(s + 1))
437     octal = 1;
438
439   /* create the scan string */
440   scanFmt[scI++] = '%';
441
442   scanFmt[scI++] = 'l';
443
444   if (octal)
445     scanFmt[scI++] = 'o';
446   else if (hex)
447     scanFmt[scI++] = 'x';
448   else
449     scanFmt[scI++] = 'f';
450
451   scanFmt[scI++] = '\0';
452
453   if (octal || hex) {
454     unsigned long sval;
455     sscanf (s, scanFmt, &sval);
456     dval=sval;
457   } else {
458     sscanf (s, scanFmt, &dval);
459   }
460
461   /* Setup the flags first */
462   /* set the _long flag if 'lL' is found */
463   if (strchr (s, 'l') || strchr (s, 'L')) {
464     SPEC_NOUN (val->type) = V_INT;
465     SPEC_LONG (val->type) = 1;
466   }
467
468   if (dval<0) { // "-28u" will still be signed and negative
469     SPEC_USIGN (val->type) = 0;
470     if (dval<-128) { // check if we have to promote to int
471       SPEC_NOUN (val->type) = V_INT;
472     }
473     if (dval<-32768) { // check if we have to promote to long int
474       SPEC_LONG (val->type) = 1;
475     }
476   } else { // >=0
477     if (dval>0xff) { // check if we have to promote to int
478       SPEC_NOUN (val->type) = V_INT;
479     }
480     if (dval>0xffff) { // check if we have to promote to long int
481       SPEC_LONG (val->type) = 1;
482     }
483   }
484
485   if (SPEC_LONG (val->type))
486     {
487       if (SPEC_USIGN (val->type))
488         {
489           SPEC_CVAL (val->type).v_ulong = dval;
490         }
491       else
492         {
493           SPEC_CVAL (val->type).v_long = dval;
494         }
495     }
496   else
497     {
498       if (SPEC_USIGN (val->type))
499         {
500           SPEC_CVAL (val->type).v_uint = dval;
501         }
502       else
503         {
504           SPEC_CVAL (val->type).v_int = dval;
505         }
506     }
507
508   return val;
509 }
510
511 /*! /fn char hexEscape(char **src)
512
513     /param src Pointer to 'x' from start of hex character value
514 */
515
516 unsigned char hexEscape(char **src)
517 {
518   char *s ;
519   unsigned long value ;
520   
521   (*src)++ ;    /* Skip over the 'x' */
522   s = *src ;    /* Save for error detection */
523   
524   value = strtol (*src, src, 16);
525   
526   if (s == *src) {
527       // no valid hex found
528       werror(E_INVALID_HEX);
529   } else {
530     if (value > 255) {
531       werror(W_ESC_SEQ_OOR_FOR_CHAR);
532     }
533   }
534   return (char) value;
535 }
536
537 /*------------------------------------------------------------------*/
538 /* octalEscape - process an octal constant of max three digits      */
539 /* return the octal value, throw a warning for illegal octal        */
540 /* adjust src to point at the last proccesed char                   */
541 /*------------------------------------------------------------------*/
542
543 unsigned char octalEscape (char **str) {
544   int digits;
545   unsigned value=0;
546
547   for (digits=0; digits<3; digits++) {
548     if (**str>='0' && **str<='7') {
549       value = value*8 + (**str-'0');
550       (*str)++;
551     } else {
552       break;
553     }
554   }
555   if (digits) {
556     if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
557       werror (W_ESC_SEQ_OOR_FOR_CHAR);
558     }
559   }
560   return value;
561 }
562
563 /*! 
564   /fn int copyStr (char *dest, char *src)
565   
566   Copies a source string to a dest buffer interpreting escape sequences
567   and special characters
568
569   /param dest Buffer to receive the resultant string
570   /param src  Buffer containing the source string with escape sequecnes
571   /return Number of characters in output string
572
573 */
574
575 int 
576 copyStr (char *dest, char *src)
577
578 {
579   char *OriginalDest = dest ;
580
581   while (*src)
582     {
583       if (*src == '\"')
584         src++;
585       else if (*src == '\\')
586         {
587           src++;
588           switch (*src)
589             {
590             case 'n':
591               *dest++ = '\n';
592               break;
593             case 't':
594               *dest++ = '\t';
595               break;
596             case 'v':
597               *dest++ = '\v';
598               break;
599             case 'b':
600               *dest++ = '\b';
601               break;
602             case 'r':
603               *dest++ = '\r';
604               break;
605             case 'f':
606               *dest++ = '\f';
607               break;
608             case 'a':
609               *dest++ = '\a';
610               break;
611
612             case '0':
613             case '1':
614             case '2':
615             case '3':
616             case '4':
617             case '5':
618             case '6':
619             case '7':
620               *dest++ = octalEscape(&src);
621               src-- ;
622               break;
623
624             case 'x': 
625               *dest++ = hexEscape(&src) ;
626               src-- ;
627               break ;
628
629             case '\\':
630               *dest++ = '\\';
631               break;
632             case '\?':
633               *dest++ = '\?';
634               break;
635             case '\'':
636               *dest++ = '\'';
637               break;
638             case '\"':
639               *dest++ = '\"';
640               break;
641             default:
642               *dest++ = *src;
643             }
644           src++;
645         }
646       else
647         *dest++ = *src++;
648     }
649
650   *dest++ = '\0';
651
652   return dest - OriginalDest ;
653 }
654
655 /*------------------------------------------------------------------*/
656 /* strVal - converts a string constant to a value       */
657 /*------------------------------------------------------------------*/
658 value *
659 strVal (char *s)
660 {
661   value *val;
662
663   val = newValue ();            /* get a new one */
664
665   /* get a declarator */
666   val->type = newLink ();
667   DCL_TYPE (val->type) = ARRAY;
668   val->type->next = val->etype = newLink ();
669   val->etype->class = SPECIFIER;
670   SPEC_NOUN (val->etype) = V_CHAR;
671   SPEC_SCLS (val->etype) = S_LITERAL;
672
673   SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
674   DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
675
676   return val;
677 }
678
679
680 /*------------------------------------------------------------------*/
681 /* reverseValWithType - reverses value chain with type & etype      */
682 /*------------------------------------------------------------------*/
683 value *
684 reverseValWithType (value * val)
685 {
686   sym_link *type;
687   sym_link *etype;
688
689   if (!val)
690     return NULL;
691
692   /* save the type * etype chains */
693   type = val->type;
694   etype = val->etype;
695
696   /* set the current one 2b null */
697   val->type = val->etype = NULL;
698   val = reverseVal (val);
699
700   /* restore type & etype */
701   val->type = type;
702   val->etype = etype;
703
704   return val;
705 }
706
707 /*------------------------------------------------------------------*/
708 /* reverseVal - reverses the values for a value  chain        */
709 /*------------------------------------------------------------------*/
710 value *
711 reverseVal (value * val)
712 {
713   value *prev, *curr, *next;
714
715   if (!val)
716     return NULL;
717
718   prev = val;
719   curr = val->next;
720
721   while (curr)
722     {
723       next = curr->next;
724       curr->next = prev;
725       prev = curr;
726       curr = next;
727     }
728   val->next = (void *) NULL;
729   return prev;
730 }
731
732 /*------------------------------------------------------------------*/
733 /* copyValueChain - will copy a chain of values                     */
734 /*------------------------------------------------------------------*/
735 value *
736 copyValueChain (value * src)
737 {
738   value *dest;
739
740   if (!src)
741     return NULL;
742
743   dest = copyValue (src);
744   dest->next = copyValueChain (src->next);
745
746   return dest;
747 }
748
749 /*------------------------------------------------------------------*/
750 /* copyValue - copies contents of a value to a fresh one            */
751 /*------------------------------------------------------------------*/
752 value *
753 copyValue (value * src)
754 {
755   value *dest;
756
757   dest = newValue ();
758   dest->sym = copySymbol (src->sym);
759   strcpy (dest->name, src->name);
760   dest->type = (src->type ? copyLinkChain (src->type) : NULL);
761   dest->etype = (src->type ? getSpec (dest->type) : NULL);
762
763   return dest;
764 }
765
766 /*------------------------------------------------------------------*/
767 /* charVal - converts a character constant to a value       */
768 /*------------------------------------------------------------------*/
769 value *
770 charVal (char *s)
771 {
772   value *val;
773 //  unsigned uValue ;
774
775   val = newValue ();
776
777   val->type = val->etype = newLink ();
778   val->type->class = SPECIFIER;
779   SPEC_NOUN (val->type) = V_CHAR;
780   SPEC_USIGN(val->type) = 1;
781   SPEC_SCLS (val->type) = S_LITERAL;
782
783   s++;                          /* get rid of quotation */
784   /* if \ then special processing */
785   if (*s == '\\')
786     {
787       s++;                      /* go beyond the backslash  */
788       switch (*s)
789         {
790         case 'n':
791           SPEC_CVAL (val->type).v_int = '\n';
792           break;
793         case 't':
794           SPEC_CVAL (val->type).v_int = '\t';
795           break;
796         case 'v':
797           SPEC_CVAL (val->type).v_int = '\v';
798           break;
799         case 'b':
800           SPEC_CVAL (val->type).v_int = '\b';
801           break;
802         case 'r':
803           SPEC_CVAL (val->type).v_int = '\r';
804           break;
805         case 'f':
806           SPEC_CVAL (val->type).v_int = '\f';
807           break;
808         case 'a':
809           SPEC_CVAL (val->type).v_int = '\a';
810           break;
811         case '\\':
812           SPEC_CVAL (val->type).v_int = '\\';
813           break;
814         case '\?':
815           SPEC_CVAL (val->type).v_int = '\?';
816           break;
817         case '\'':
818           SPEC_CVAL (val->type).v_int = '\'';
819           break;
820         case '\"':
821           SPEC_CVAL (val->type).v_int = '\"';
822           break;
823
824         case '0' :
825         case '1' :
826         case '2' :
827         case '3' :
828         case '4' :
829         case '5' :
830         case '6' :
831         case '7' :
832           SPEC_CVAL (val->type).v_uint = octalEscape(&s);
833           break;
834
835         case 'x':
836           SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
837           break;
838
839         default:
840           SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
841           break;
842         }
843     }
844   else                          /* not a backslash */
845     SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
846
847   return val;
848 }
849
850 /*------------------------------------------------------------------*/
851 /* valFromType - creates a value from type given                    */
852 /*------------------------------------------------------------------*/
853 value *
854 valFromType (sym_link * type)
855 {
856   value *val = newValue ();
857   val->type = copyLinkChain (type);
858   val->etype = getSpec (val->type);
859   return val;
860 }
861
862 /*------------------------------------------------------------------*/
863 /* floatFromVal - value to unsinged integer conversion        */
864 /*------------------------------------------------------------------*/
865 double 
866 floatFromVal (value * val)
867 {
868   if (!val)
869     return 0;
870
871   if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
872     {
873       werror (E_CONST_EXPECTED, val->name);
874       return 0;
875     }
876
877   /* if it is not a specifier then we can assume that */
878   /* it will be an unsigned long                      */
879   if (!IS_SPEC (val->type))
880     return (double) SPEC_CVAL (val->etype).v_ulong;
881
882   if (SPEC_NOUN (val->etype) == V_FLOAT)
883     return (double) SPEC_CVAL (val->etype).v_float;
884
885   if (SPEC_LONG (val->etype))
886     {
887       if (SPEC_USIGN (val->etype))
888         return (double) SPEC_CVAL (val->etype).v_ulong;
889       else
890         return (double) SPEC_CVAL (val->etype).v_long;
891     }
892   
893   if (SPEC_NOUN(val->etype)==V_INT) {
894     if (SPEC_USIGN (val->etype))
895       return (double) SPEC_CVAL (val->etype).v_uint;
896     else
897       return (double) SPEC_CVAL (val->etype).v_int;
898   } else { // SPEC_NOUN==V_CHAR
899     if (SPEC_USIGN (val->etype))
900       return (double) ((unsigned char)SPEC_CVAL (val->etype).v_uint);
901     else
902       return (double) ((signed char)SPEC_CVAL (val->etype).v_int);
903   }
904 }
905
906
907 /*------------------------------------------------------------------*/
908 /* valUnaryPM - does the unary +/- operation on a constant          */
909 /*------------------------------------------------------------------*/
910 value *
911 valUnaryPM (value * val)
912 {
913   /* depending on type */
914   if (SPEC_NOUN (val->etype) == V_FLOAT)
915     SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
916   else
917     {
918       if (SPEC_LONG (val->etype))
919         {
920           if (SPEC_USIGN (val->etype))
921             SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
922           else
923             SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
924         }
925       else
926         {
927           if (SPEC_USIGN (val->etype))
928             SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
929           else
930             SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
931           if (SPEC_NOUN (val->etype)==V_CHAR) {
932             SPEC_CVAL (val->etype).v_uint &= 0xff;
933           }
934         }
935     }
936   // -(unsigned 3) now really is signed
937   SPEC_USIGN(val->etype)=0;
938   return val;
939 }
940
941 /*------------------------------------------------------------------*/
942 /* valueComplement - complements a constant                         */
943 /*------------------------------------------------------------------*/
944 value *
945 valComplement (value * val)
946 {
947   /* depending on type */
948   if (SPEC_LONG (val->etype))
949     {
950       if (SPEC_USIGN (val->etype))
951         SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
952       else
953         SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
954     }
955   else
956     {
957       if (SPEC_USIGN (val->etype))
958         SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
959       else
960         SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
961       if (SPEC_NOUN (val->etype)==V_CHAR) {
962         SPEC_CVAL (val->etype).v_uint &= 0xff;
963       }
964     }
965   return val;
966 }
967
968 /*------------------------------------------------------------------*/
969 /* valueNot - complements a constant                                */
970 /*------------------------------------------------------------------*/
971 value *
972 valNot (value * val)
973 {
974   /* depending on type */
975   if (SPEC_LONG (val->etype))
976     {
977       if (SPEC_USIGN (val->etype))
978         SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
979       else
980         SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
981     }
982   else
983     {
984       if (SPEC_USIGN (val->etype))
985         SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
986       else
987         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
988       if (SPEC_NOUN (val->etype)==V_CHAR) {
989         SPEC_CVAL (val->etype).v_uint &= 0xff;
990       }
991     }
992   return val;
993 }
994
995 /*------------------------------------------------------------------*/
996 /* valMult - multiply constants                                     */
997 /*------------------------------------------------------------------*/
998 value *
999 valMult (value * lval, value * rval)
1000 {
1001   value *val;
1002
1003   /* create a new value */
1004   val = newValue ();
1005   val->type = val->etype = newLink ();
1006   val->type->class = SPECIFIER;
1007   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1008                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1009   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1010   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1011   SPEC_LONG (val->type) = 1;
1012
1013   if (IS_FLOAT (val->type))
1014     SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1015   else
1016     {
1017       if (SPEC_LONG (val->type))
1018         {
1019           if (SPEC_USIGN (val->type))
1020             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
1021               (unsigned long) floatFromVal (rval);
1022           else
1023             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
1024               (long) floatFromVal (rval);
1025         }
1026     }
1027   return cheapestVal(val);
1028 }
1029
1030 /*------------------------------------------------------------------*/
1031 /* valDiv  - Divide   constants                                     */
1032 /*------------------------------------------------------------------*/
1033 value *
1034 valDiv (value * lval, value * rval)
1035 {
1036   value *val;
1037
1038   if (floatFromVal (rval) == 0)
1039     {
1040       werror (E_DIVIDE_BY_ZERO);
1041       return rval;
1042     }
1043
1044   /* create a new value */
1045   val = newValue ();
1046   val->type = val->etype = newLink();
1047   val->type->class = SPECIFIER;
1048   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1049                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1050   SPEC_SCLS (val->etype) = S_LITERAL;
1051   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1052   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1053
1054   if (IS_FLOAT (val->type))
1055     SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1056   else
1057     {
1058       if (SPEC_LONG (val->type))
1059         {
1060           if (SPEC_USIGN (val->type))
1061             SPEC_CVAL (val->type).v_ulong = 
1062               (unsigned long) floatFromVal (lval) /
1063               (unsigned long) floatFromVal (rval);
1064           else
1065             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1066               (long) floatFromVal (rval);
1067         }
1068       else
1069         {
1070           if (SPEC_USIGN (val->type)) {
1071             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1072               (unsigned) floatFromVal (rval);
1073           } else {
1074             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1075               (int) floatFromVal (rval);
1076           }
1077         }
1078     }
1079   return cheapestVal(val);
1080 }
1081
1082 /*------------------------------------------------------------------*/
1083 /* valMod  - Modulus  constants                                     */
1084 /*------------------------------------------------------------------*/
1085 value *
1086 valMod (value * lval, value * rval)
1087 {
1088   value *val;
1089
1090   /* create a new value */
1091   val = newValue ();
1092   val->type = val->etype = newLink ();
1093   val->type->class = SPECIFIER;
1094   SPEC_NOUN (val->type) = V_INT;        /* type is int */
1095   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1096   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1097   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1098
1099   if (SPEC_LONG (val->type))
1100     {
1101       if (SPEC_USIGN (val->type))
1102         SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1103           (unsigned long) floatFromVal (rval);
1104       else
1105         SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1106           (unsigned long) floatFromVal (rval);
1107     }
1108   else
1109     {
1110       if (SPEC_USIGN (val->type)) {
1111         SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1112           (unsigned) floatFromVal (rval);
1113       } else {
1114         SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1115           (unsigned) floatFromVal (rval);
1116       }
1117     }
1118
1119   return cheapestVal(val);
1120 }
1121
1122 /*------------------------------------------------------------------*/
1123 /* valPlus - Addition constants                                     */
1124 /*------------------------------------------------------------------*/
1125 value *
1126 valPlus (value * lval, value * rval)
1127 {
1128   value *val;
1129
1130   /* create a new value */
1131   val = newValue ();
1132   val->type = val->etype = newLink ();
1133   val->type->class = SPECIFIER;
1134   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1135                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1136   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1137   SPEC_USIGN (val->type) = 
1138     SPEC_USIGN (lval->etype) &&
1139     SPEC_USIGN (rval->etype) &&
1140     (floatFromVal(lval)+floatFromVal(rval))>=0;
1141     
1142   SPEC_LONG (val->type) = 1;
1143
1144   if (IS_FLOAT (val->type))
1145     SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1146   else
1147     {
1148       if (SPEC_LONG (val->type))
1149         {
1150           if (SPEC_USIGN (val->type))
1151             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1152               (unsigned long) floatFromVal (rval);
1153           else
1154             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1155               (long) floatFromVal (rval);
1156         }
1157     }
1158   return cheapestVal(val);
1159 }
1160
1161 /*------------------------------------------------------------------*/
1162 /* valMinus - Addition constants                                    */
1163 /*------------------------------------------------------------------*/
1164 value *
1165 valMinus (value * lval, value * rval)
1166 {
1167   value *val;
1168
1169   /* create a new value */
1170   val = newValue ();
1171   val->type = val->etype = newLink ();
1172   val->type->class = SPECIFIER;
1173   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1174                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1175   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1176   SPEC_USIGN (val->type) = 
1177     SPEC_USIGN (lval->etype) &&
1178     SPEC_USIGN (rval->etype) &&
1179     (floatFromVal(lval)-floatFromVal(rval))>=0;
1180
1181   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1182
1183   if (IS_FLOAT (val->type))
1184     SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1185   else
1186     {
1187       if (SPEC_LONG (val->type))
1188         {
1189           if (SPEC_USIGN (val->type)) {
1190             SPEC_CVAL (val->type).v_ulong = 
1191               (unsigned long) floatFromVal (lval) -
1192               (unsigned long) floatFromVal (rval);
1193           } else {
1194             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1195               (long) floatFromVal (rval);
1196           }
1197         }
1198       else
1199         {
1200           if (SPEC_USIGN (val->type)) {
1201             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1202               (unsigned) floatFromVal (rval);
1203           } else {
1204             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - 
1205               (int) floatFromVal (rval);
1206           }
1207         }
1208     }
1209   return cheapestVal(val);
1210 }
1211
1212 /*------------------------------------------------------------------*/
1213 /* valShift - Shift left or right                                   */
1214 /*------------------------------------------------------------------*/
1215 value *
1216 valShift (value * lval, value * rval, int lr)
1217 {
1218   value *val;
1219
1220   /* create a new value */
1221   val = newValue ();
1222   val->type = val->etype = newIntLink ();
1223   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1224   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1225   SPEC_LONG (val->type) = 1;
1226
1227   if (SPEC_LONG (val->type))
1228     {
1229       if (SPEC_USIGN (val->type))
1230         SPEC_CVAL (val->type).v_ulong = lr ? 
1231           (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1232           (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1233       else
1234         SPEC_CVAL (val->type).v_long = lr ?
1235           (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1236           (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1237     }
1238
1239   return cheapestVal(val);
1240 }
1241
1242 /*------------------------------------------------------------------*/
1243 /* valCompare- Compares two literal                                 */
1244 /*------------------------------------------------------------------*/
1245 value *
1246 valCompare (value * lval, value * rval, int ctype)
1247 {
1248   value *val;
1249
1250   /* create a new value */
1251   val = newValue ();
1252   val->type = val->etype = newCharLink ();
1253   val->type->class = SPECIFIER;
1254   SPEC_NOUN (val->type) = V_CHAR;       /* type is char */
1255   SPEC_USIGN (val->type) = 1;
1256   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1257
1258   switch (ctype)
1259     {
1260     case '<':
1261       SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1262       break;
1263
1264     case '>':
1265       SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1266       break;
1267
1268     case LE_OP:
1269       SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1270       break;
1271
1272     case GE_OP:
1273       SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1274       break;
1275
1276     case EQ_OP:
1277       SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1278       break;
1279
1280     case NE_OP:
1281       SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1282       break;
1283
1284     }
1285
1286   return val;
1287 }
1288
1289 /*------------------------------------------------------------------*/
1290 /* valBitwise - Bitwise operation                                   */
1291 /*------------------------------------------------------------------*/
1292 value *
1293 valBitwise (value * lval, value * rval, int op)
1294 {
1295   value *val;
1296
1297   /* create a new value */
1298   val = newValue ();
1299   val->type = copyLinkChain (lval->type);
1300   val->etype = getSpec (val->type);
1301
1302   switch (op)
1303     {
1304     case '&':
1305       if (SPEC_LONG (val->type))
1306         {
1307           if (SPEC_USIGN (val->type))
1308             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1309               (unsigned long) floatFromVal (rval);
1310           else
1311             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1312               (long) floatFromVal (rval);
1313         }
1314       else
1315         {
1316           if (SPEC_USIGN (val->type))
1317             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1318               (unsigned) floatFromVal (rval);
1319           else
1320             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1321         }
1322       break;
1323
1324     case '|':
1325       if (SPEC_LONG (val->type))
1326         {
1327           if (SPEC_USIGN (val->type))
1328             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1329               (unsigned long) floatFromVal (rval);
1330           else
1331             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1332               (long) floatFromVal (rval);
1333         }
1334       else
1335         {
1336           if (SPEC_USIGN (val->type))
1337             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1338               (unsigned) floatFromVal (rval);
1339           else
1340             SPEC_CVAL (val->type).v_int =
1341               (int) floatFromVal (lval) | (int) floatFromVal (rval);
1342         }
1343
1344       break;
1345
1346     case '^':
1347       if (SPEC_LONG (val->type))
1348         {
1349           if (SPEC_USIGN (val->type))
1350             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1351               (unsigned long) floatFromVal (rval);
1352           else
1353             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1354               (long) floatFromVal (rval);
1355         }
1356       else
1357         {
1358           if (SPEC_USIGN (val->type))
1359             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1360               (unsigned) floatFromVal (rval);
1361           else
1362             SPEC_CVAL (val->type).v_int =
1363               (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1364         }
1365       break;
1366     }
1367
1368   return cheapestVal(val);
1369 }
1370
1371 /*------------------------------------------------------------------*/
1372 /* valAndOr   - Generates code for and / or operation               */
1373 /*------------------------------------------------------------------*/
1374 value *
1375 valLogicAndOr (value * lval, value * rval, int op)
1376 {
1377   value *val;
1378
1379   /* create a new value */
1380   val = newValue ();
1381   val->type = val->etype = newCharLink ();
1382   val->type->class = SPECIFIER;
1383   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1384   SPEC_USIGN (val->type) = 0;
1385
1386   switch (op)
1387     {
1388     case AND_OP:
1389       SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1390       break;
1391
1392     case OR_OP:
1393       SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1394       break;
1395     }
1396
1397
1398   return val;
1399 }
1400
1401 /*------------------------------------------------------------------*/
1402 /* valCastLiteral - casts a literal value to another type           */
1403 /*------------------------------------------------------------------*/
1404 value *
1405 valCastLiteral (sym_link * dtype, double fval)
1406 {
1407   value *val;
1408
1409   if (!dtype)
1410     return NULL;
1411
1412   val = newValue ();
1413   val->etype = getSpec (val->type = copyLinkChain (dtype));
1414   SPEC_SCLS (val->etype) = S_LITERAL;
1415   /* if it is not a specifier then we can assume that */
1416   /* it will be an unsigned long                      */
1417   if (!IS_SPEC (val->type))
1418     {
1419       SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1420       return val;
1421     }
1422
1423   if (SPEC_NOUN (val->etype) == V_FLOAT)
1424     SPEC_CVAL (val->etype).v_float = fval;
1425   else
1426     {
1427       if (SPEC_LONG (val->etype))
1428         {
1429           if (SPEC_USIGN (val->etype))
1430             SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1431           else
1432             SPEC_CVAL (val->etype).v_long = (long) fval;
1433         }
1434       else
1435         {
1436           if (SPEC_USIGN (val->etype))
1437             SPEC_CVAL (val->etype).v_uint = (unsigned short)fval;
1438           else
1439             SPEC_CVAL (val->etype).v_int = (short)fval;
1440           if (SPEC_NOUN (val->etype)==V_CHAR) {
1441             SPEC_CVAL (val->etype).v_uint &= 0xff; 
1442           }
1443         }
1444     }
1445   return val;
1446 }
1447
1448 /*------------------------------------------------------------------*/
1449 /* getNelements - determines # of elements from init list           */
1450 /*------------------------------------------------------------------*/
1451 int 
1452 getNelements (sym_link * type, initList * ilist)
1453 {
1454   sym_link *etype = getSpec (type);
1455   int i;
1456
1457   if (!ilist)
1458     return 0;
1459
1460   if (ilist->type == INIT_DEEP)
1461     ilist = ilist->init.deep;
1462
1463   /* if type is a character array and there is only one
1464      (string) initialiser then get the length of the string */
1465   if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1466     {
1467       ast *iast = ilist->init.node;
1468       value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1469       if (!v)
1470         {
1471           werror (W_INIT_WRONG);
1472           return 0;
1473         }
1474
1475       if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1476         // yep, it's a string
1477         {
1478           return DCL_ELEM (v->type);
1479         }
1480     }
1481
1482   i = 0;
1483   while (ilist)
1484     {
1485       i++;
1486       ilist = ilist->next;
1487     }
1488
1489   return i;
1490 }
1491
1492 /*-----------------------------------------------------------------*/
1493 /* valForArray - returns a value with name of array index          */
1494 /*-----------------------------------------------------------------*/
1495 value *
1496 valForArray (ast * arrExpr)
1497 {
1498   value *val, *lval = NULL;
1499   char buffer[128];
1500   int size = getSize (arrExpr->left->ftype->next);
1501   /* if the right or left is an array
1502      resolve it first */
1503   if (IS_AST_OP (arrExpr->left))
1504     {
1505       if (arrExpr->left->opval.op == '[')
1506         lval = valForArray (arrExpr->left);
1507       else if (arrExpr->left->opval.op == '.')
1508         lval = valForStructElem (arrExpr->left->left,
1509                                  arrExpr->left->right);
1510       else if (arrExpr->left->opval.op == PTR_OP &&
1511                IS_ADDRESS_OF_OP (arrExpr->left->left))
1512         lval = valForStructElem (arrExpr->left->left->left,
1513                                  arrExpr->left->right);
1514       else
1515         return NULL;
1516
1517     }
1518   else if (!IS_AST_SYM_VALUE (arrExpr->left))
1519     return NULL;
1520
1521   if (!IS_AST_LIT_VALUE (arrExpr->right))
1522     return NULL;
1523
1524   val = newValue ();
1525   if (!lval)
1526     sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1527   else
1528     sprintf (buffer, "%s", lval->name);
1529
1530   sprintf (val->name, "(%s + %d)", buffer,
1531            (int) AST_LIT_VALUE (arrExpr->right) * size);
1532
1533   val->type = newLink ();
1534   if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1535     {
1536       DCL_TYPE (val->type) = CPOINTER;
1537       DCL_PTR_CONST (val->type) = port->mem.code_ro;
1538     }
1539   else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1540     DCL_TYPE (val->type) = FPOINTER;
1541   else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1542     DCL_TYPE (val->type) = PPOINTER;
1543   else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1544     DCL_TYPE (val->type) = IPOINTER;
1545   else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1546     DCL_TYPE (val->type) = EEPPOINTER;
1547   else
1548     DCL_TYPE (val->type) = POINTER;
1549   val->type->next = arrExpr->left->ftype;
1550   val->etype = getSpec (val->type);
1551   return val;
1552 }
1553
1554 /*-----------------------------------------------------------------*/
1555 /* valForStructElem - returns value with name of struct element    */
1556 /*-----------------------------------------------------------------*/
1557 value *
1558 valForStructElem (ast * structT, ast * elemT)
1559 {
1560   value *val, *lval = NULL;
1561   char buffer[128];
1562   symbol *sym;
1563
1564   /* left could be furthur derefed */
1565   if (IS_AST_OP (structT))
1566     {
1567       if (structT->opval.op == '[')
1568         lval = valForArray (structT);
1569       else if (structT->opval.op == '.')
1570         lval = valForStructElem (structT->left, structT->right);
1571       else if (structT->opval.op == PTR_OP &&
1572                IS_ADDRESS_OF_OP (structT->left))
1573         lval = valForStructElem (structT->left->left,
1574                                  structT->right);
1575       else
1576         return NULL;
1577     }
1578
1579   if (!IS_AST_SYM_VALUE (elemT))
1580     return NULL;
1581
1582   if (!IS_STRUCT (structT->etype))
1583     return NULL;
1584
1585   if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1586                                AST_SYMBOL (elemT))) == NULL)
1587     {
1588       return NULL;
1589     }
1590
1591   val = newValue ();
1592   if (!lval)
1593     sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1594   else
1595     sprintf (buffer, "%s", lval->name);
1596
1597   sprintf (val->name, "(%s + %d)", buffer,
1598            (int) sym->offset);
1599
1600   val->type = newLink ();
1601   if (SPEC_SCLS (structT->etype) == S_CODE)
1602     {
1603       DCL_TYPE (val->type) = CPOINTER;
1604       DCL_PTR_CONST (val->type) = port->mem.code_ro;
1605     }
1606   else if (SPEC_SCLS (structT->etype) == S_XDATA)
1607     DCL_TYPE (val->type) = FPOINTER;
1608   else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1609     DCL_TYPE (val->type) = PPOINTER;
1610   else if (SPEC_SCLS (structT->etype) == S_IDATA)
1611     DCL_TYPE (val->type) = IPOINTER;
1612   else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1613     DCL_TYPE (val->type) = EEPPOINTER;
1614   else
1615     DCL_TYPE (val->type) = POINTER;
1616   val->type->next = sym->type;
1617   val->etype = getSpec (val->type);
1618   return val;
1619 }
1620
1621 /*-----------------------------------------------------------------*/
1622 /* valForCastAggr - will return value for a cast of an aggregate   */
1623 /*                  plus minus a constant                          */
1624 /*-----------------------------------------------------------------*/
1625 value *
1626 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1627 {
1628   value *val;
1629
1630   if (!IS_AST_SYM_VALUE (aexpr))
1631     return NULL;
1632   if (!IS_AST_LIT_VALUE (cnst))
1633     return NULL;
1634
1635   val = newValue ();
1636
1637   sprintf (val->name, "(%s %c %d)",
1638            AST_SYMBOL (aexpr)->rname, op,
1639            getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1640
1641   val->type = type;
1642   val->etype = getSpec (val->type);
1643   return val;
1644 }
1645
1646 /*-----------------------------------------------------------------*/
1647 /* valForCastAggr - will return value for a cast of an aggregate   */
1648 /*                  with no constant                               */
1649 /*-----------------------------------------------------------------*/
1650 value *
1651 valForCastArr (ast * aexpr, sym_link * type)
1652 {
1653   value *val;
1654
1655   if (!IS_AST_SYM_VALUE (aexpr))
1656     return NULL;
1657
1658   val = newValue ();
1659
1660   sprintf (val->name, "(%s)",
1661            AST_SYMBOL (aexpr)->rname);
1662
1663   val->type = type;
1664   val->etype = getSpec (val->type);
1665   return val;
1666 }