Fix inconsistent handling of bit variables
[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     {
308         SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
309     }
310   else
311     {
312         SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
313     }
314
315   return val;
316 }
317
318 /*--------------------------------------------------------------------*/
319 /* cheapestVal - convert a val to the cheapest as possible value      */
320 /*--------------------------------------------------------------------*/
321 value *cheapestVal (value *val) {
322   long sval=0;
323   unsigned long uval=0;
324
325   if (IS_FLOAT(val->type) || IS_CHAR(val->type))
326     return val;
327
328   if (SPEC_LONG(val->type)) {
329     if (SPEC_USIGN(val->type)) {
330       uval=SPEC_CVAL(val->type).v_ulong;
331     } else {
332       sval=SPEC_CVAL(val->type).v_long;
333     }
334   } else {
335     if (SPEC_USIGN(val->type)) {
336       uval=SPEC_CVAL(val->type).v_uint;
337     } else {
338       sval=SPEC_CVAL(val->type).v_int;
339     }
340   }
341
342   if (SPEC_USIGN(val->type)) {
343     if (uval<=0xffff) {
344       SPEC_LONG(val->type)=0;
345       SPEC_CVAL(val->type).v_uint = uval;
346       if (uval<=0xff) {
347         SPEC_NOUN(val->type)=V_CHAR;
348       }
349     }
350   } else { // not unsigned
351     if (sval<0) {
352       if (sval>=-32768) {
353         SPEC_LONG(val->type)=0;
354         SPEC_CVAL(val->type).v_int = sval;
355         if (sval>=-128) {
356           SPEC_NOUN(val->type)=V_CHAR;
357         }
358       }
359     } else { // sval>=0
360       SPEC_USIGN(val->type)=1;
361       if (sval<=65535) {
362         SPEC_LONG(val->type)=0;
363         SPEC_CVAL(val->type).v_int = sval;
364         if (sval<=255) {
365           SPEC_NOUN(val->type)=V_CHAR;
366         }
367       }
368     }
369   }
370   return val;
371 }
372
373 /*-----------------------------------------------------------------*/
374 /* valueFromLit - creates a value from a literal                   */
375 /*-----------------------------------------------------------------*/
376 value *
377 valueFromLit (double lit)
378 {
379   char buffer[50];
380
381   if ((((long) lit) - lit) == 0)
382     {
383       SNPRINTF (buffer, sizeof(buffer), "%ld", (long) lit);
384       return constVal (buffer);
385     }
386
387   SNPRINTF (buffer, sizeof(buffer), "%f", lit);
388   return constFloatVal (buffer);
389 }
390
391 /*-----------------------------------------------------------------*/
392 /* constFloatVal - converts a FLOAT constant to value              */
393 /*-----------------------------------------------------------------*/
394 value *
395 constFloatVal (char *s)
396 {
397   value *val = newValue ();
398   double sval;
399
400   if (sscanf (s, "%lf", &sval) != 1)
401     {
402       werror (E_INVALID_FLOAT_CONST, s);
403       return constVal ("0");
404     }
405
406   val->type = val->etype = newLink ();
407   val->type->class = SPECIFIER;
408   SPEC_NOUN (val->type) = V_FLOAT;
409   SPEC_SCLS (val->type) = S_LITERAL;
410   SPEC_CVAL (val->type).v_float = sval;
411
412   return val;
413 }
414
415 /*-----------------------------------------------------------------*/
416 /* constVal - converts an INTEGER constant into a cheapest value   */
417 /*-----------------------------------------------------------------*/
418 value *constVal (char *s)
419 {
420   value *val;
421   short hex = 0, octal = 0;
422   char scanFmt[10];
423   int scI = 0;
424   double dval;
425
426   val = newValue ();            /* alloc space for value   */
427
428   val->type = val->etype = newLink ();  /* create the spcifier */
429   val->type->class = SPECIFIER;
430   SPEC_SCLS (val->type) = S_LITERAL;
431   // let's start with an unsigned char
432   SPEC_NOUN (val->type) = V_CHAR;
433   SPEC_USIGN (val->type) = 1;
434
435   hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
436
437   /* set the octal flag   */
438   if (!hex && *s == '0' && *(s + 1))
439     octal = 1;
440
441   /* create the scan string */
442   scanFmt[scI++] = '%';
443
444   scanFmt[scI++] = 'l';
445
446   if (octal)
447     scanFmt[scI++] = 'o';
448   else if (hex)
449     scanFmt[scI++] = 'x';
450   else
451     scanFmt[scI++] = 'f';
452
453   scanFmt[scI++] = '\0';
454
455   if (octal || hex) {
456     unsigned long sval;
457     sscanf (s, scanFmt, &sval);
458     dval=sval;
459   } else {
460     sscanf (s, scanFmt, &dval);
461   }
462
463   /* Setup the flags first */
464   /* set the _long flag if 'lL' is found */
465   if (strchr (s, 'l') || strchr (s, 'L')) {
466     SPEC_NOUN (val->type) = V_INT;
467     SPEC_LONG (val->type) = 1;
468   }
469
470   if (dval<0) { // "-28u" will still be signed and negative
471     SPEC_USIGN (val->type) = 0;
472     if (dval<-128) { // check if we have to promote to int
473       SPEC_NOUN (val->type) = V_INT;
474     }
475     if (dval<-32768) { // check if we have to promote to long int
476       SPEC_LONG (val->type) = 1;
477     }
478   } else { // >=0
479     if (dval>0xff) { // check if we have to promote to int
480       SPEC_NOUN (val->type) = V_INT;
481     }
482     if (dval>0xffff) { // check if we have to promote to long int
483       SPEC_LONG (val->type) = 1;
484     }
485   }
486
487   if (SPEC_LONG (val->type))
488     {
489       if (SPEC_USIGN (val->type))
490         {
491           SPEC_CVAL (val->type).v_ulong = dval;
492         }
493       else
494         {
495           SPEC_CVAL (val->type).v_long = dval;
496         }
497     }
498   else
499     {
500       if (SPEC_USIGN (val->type))
501         {
502           SPEC_CVAL (val->type).v_uint = dval;
503         }
504       else
505         {
506           SPEC_CVAL (val->type).v_int = dval;
507         }
508     }
509
510   return val;
511 }
512
513 /*! /fn char hexEscape(char **src)
514
515     /param src Pointer to 'x' from start of hex character value
516 */
517
518 unsigned char hexEscape(char **src)
519 {
520   char *s ;
521   unsigned long value ;
522   
523   (*src)++ ;    /* Skip over the 'x' */
524   s = *src ;    /* Save for error detection */
525   
526   value = strtol (*src, src, 16);
527   
528   if (s == *src) {
529       // no valid hex found
530       werror(E_INVALID_HEX);
531   } else {
532     if (value > 255) {
533       werror(W_ESC_SEQ_OOR_FOR_CHAR);
534     }
535   }
536   return (char) value;
537 }
538
539 /*------------------------------------------------------------------*/
540 /* octalEscape - process an octal constant of max three digits      */
541 /* return the octal value, throw a warning for illegal octal        */
542 /* adjust src to point at the last proccesed char                   */
543 /*------------------------------------------------------------------*/
544
545 unsigned char octalEscape (char **str) {
546   int digits;
547   unsigned value=0;
548
549   for (digits=0; digits<3; digits++) {
550     if (**str>='0' && **str<='7') {
551       value = value*8 + (**str-'0');
552       (*str)++;
553     } else {
554       break;
555     }
556   }
557   if (digits) {
558     if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
559       werror (W_ESC_SEQ_OOR_FOR_CHAR);
560     }
561   }
562   return value;
563 }
564
565 /*! 
566   /fn int copyStr (char *dest, char *src)
567   
568   Copies a source string to a dest buffer interpreting escape sequences
569   and special characters
570
571   /param dest Buffer to receive the resultant string
572   /param src  Buffer containing the source string with escape sequecnes
573   /return Number of characters in output string
574
575 */
576
577 int 
578 copyStr (char *dest, char *src)
579
580 {
581   char *OriginalDest = dest ;
582
583   while (*src)
584     {
585       if (*src == '\"')
586         src++;
587       else if (*src == '\\')
588         {
589           src++;
590           switch (*src)
591             {
592             case 'n':
593               *dest++ = '\n';
594               break;
595             case 't':
596               *dest++ = '\t';
597               break;
598             case 'v':
599               *dest++ = '\v';
600               break;
601             case 'b':
602               *dest++ = '\b';
603               break;
604             case 'r':
605               *dest++ = '\r';
606               break;
607             case 'f':
608               *dest++ = '\f';
609               break;
610             case 'a':
611               *dest++ = '\a';
612               break;
613
614             case '0':
615             case '1':
616             case '2':
617             case '3':
618             case '4':
619             case '5':
620             case '6':
621             case '7':
622               *dest++ = octalEscape(&src);
623               src-- ;
624               break;
625
626             case 'x': 
627               *dest++ = hexEscape(&src) ;
628               src-- ;
629               break ;
630
631             case '\\':
632               *dest++ = '\\';
633               break;
634             case '\?':
635               *dest++ = '\?';
636               break;
637             case '\'':
638               *dest++ = '\'';
639               break;
640             case '\"':
641               *dest++ = '\"';
642               break;
643             default:
644               *dest++ = *src;
645             }
646           src++;
647         }
648       else
649         *dest++ = *src++;
650     }
651
652   *dest++ = '\0';
653
654   return dest - OriginalDest ;
655 }
656
657 /*------------------------------------------------------------------*/
658 /* strVal - converts a string constant to a value       */
659 /*------------------------------------------------------------------*/
660 value *
661 strVal (char *s)
662 {
663   value *val;
664
665   val = newValue ();            /* get a new one */
666
667   /* get a declarator */
668   val->type = newLink ();
669   DCL_TYPE (val->type) = ARRAY;
670   val->type->next = val->etype = newLink ();
671   val->etype->class = SPECIFIER;
672   SPEC_NOUN (val->etype) = V_CHAR;
673   SPEC_SCLS (val->etype) = S_LITERAL;
674
675   SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
676   DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
677
678   return val;
679 }
680
681
682 /*------------------------------------------------------------------*/
683 /* reverseValWithType - reverses value chain with type & etype      */
684 /*------------------------------------------------------------------*/
685 value *
686 reverseValWithType (value * val)
687 {
688   sym_link *type;
689   sym_link *etype;
690
691   if (!val)
692     return NULL;
693
694   /* save the type * etype chains */
695   type = val->type;
696   etype = val->etype;
697
698   /* set the current one 2b null */
699   val->type = val->etype = NULL;
700   val = reverseVal (val);
701
702   /* restore type & etype */
703   val->type = type;
704   val->etype = etype;
705
706   return val;
707 }
708
709 /*------------------------------------------------------------------*/
710 /* reverseVal - reverses the values for a value  chain        */
711 /*------------------------------------------------------------------*/
712 value *
713 reverseVal (value * val)
714 {
715   value *prev, *curr, *next;
716
717   if (!val)
718     return NULL;
719
720   prev = val;
721   curr = val->next;
722
723   while (curr)
724     {
725       next = curr->next;
726       curr->next = prev;
727       prev = curr;
728       curr = next;
729     }
730   val->next = (void *) NULL;
731   return prev;
732 }
733
734 /*------------------------------------------------------------------*/
735 /* copyValueChain - will copy a chain of values                     */
736 /*------------------------------------------------------------------*/
737 value *
738 copyValueChain (value * src)
739 {
740   value *dest;
741
742   if (!src)
743     return NULL;
744
745   dest = copyValue (src);
746   dest->next = copyValueChain (src->next);
747
748   return dest;
749 }
750
751 /*------------------------------------------------------------------*/
752 /* copyValue - copies contents of a value to a fresh one            */
753 /*------------------------------------------------------------------*/
754 value *
755 copyValue (value * src)
756 {
757   value *dest;
758
759   dest = newValue ();
760   dest->sym = copySymbol (src->sym);
761   strncpyz (dest->name, src->name, SDCC_NAME_MAX);
762   dest->type = (src->type ? copyLinkChain (src->type) : NULL);
763   dest->etype = (src->type ? getSpec (dest->type) : NULL);
764
765   return dest;
766 }
767
768 /*------------------------------------------------------------------*/
769 /* charVal - converts a character constant to a value       */
770 /*------------------------------------------------------------------*/
771 value *
772 charVal (char *s)
773 {
774   value *val;
775 //  unsigned uValue ;
776
777   val = newValue ();
778
779   val->type = val->etype = newLink ();
780   val->type->class = SPECIFIER;
781   SPEC_NOUN (val->type) = V_CHAR;
782   SPEC_USIGN(val->type) = 1;
783   SPEC_SCLS (val->type) = S_LITERAL;
784
785   s++;                          /* get rid of quotation */
786   /* if \ then special processing */
787   if (*s == '\\')
788     {
789       s++;                      /* go beyond the backslash  */
790       switch (*s)
791         {
792         case 'n':
793           SPEC_CVAL (val->type).v_int = '\n';
794           break;
795         case 't':
796           SPEC_CVAL (val->type).v_int = '\t';
797           break;
798         case 'v':
799           SPEC_CVAL (val->type).v_int = '\v';
800           break;
801         case 'b':
802           SPEC_CVAL (val->type).v_int = '\b';
803           break;
804         case 'r':
805           SPEC_CVAL (val->type).v_int = '\r';
806           break;
807         case 'f':
808           SPEC_CVAL (val->type).v_int = '\f';
809           break;
810         case 'a':
811           SPEC_CVAL (val->type).v_int = '\a';
812           break;
813         case '\\':
814           SPEC_CVAL (val->type).v_int = '\\';
815           break;
816         case '\?':
817           SPEC_CVAL (val->type).v_int = '\?';
818           break;
819         case '\'':
820           SPEC_CVAL (val->type).v_int = '\'';
821           break;
822         case '\"':
823           SPEC_CVAL (val->type).v_int = '\"';
824           break;
825
826         case '0' :
827         case '1' :
828         case '2' :
829         case '3' :
830         case '4' :
831         case '5' :
832         case '6' :
833         case '7' :
834           SPEC_CVAL (val->type).v_uint = octalEscape(&s);
835           break;
836
837         case 'x':
838           SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
839           break;
840
841         default:
842           SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
843           break;
844         }
845     }
846   else                          /* not a backslash */
847     SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
848
849   return val;
850 }
851
852 /*------------------------------------------------------------------*/
853 /* valFromType - creates a value from type given                    */
854 /*------------------------------------------------------------------*/
855 value *
856 valFromType (sym_link * type)
857 {
858   value *val = newValue ();
859   val->type = copyLinkChain (type);
860   val->etype = getSpec (val->type);
861   return val;
862 }
863
864 /*------------------------------------------------------------------*/
865 /* floatFromVal - value to double float conversion                  */
866 /*------------------------------------------------------------------*/
867 double 
868 floatFromVal (value * val)
869 {
870   if (!val)
871     return 0;
872
873   if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
874     {
875       werror (E_CONST_EXPECTED, val->name);
876       return 0;
877     }
878
879   /* if it is not a specifier then we can assume that */
880   /* it will be an unsigned long                      */
881   if (!IS_SPEC (val->type))
882     return (double) SPEC_CVAL (val->etype).v_ulong;
883
884   if (SPEC_NOUN (val->etype) == V_FLOAT)
885     return (double) SPEC_CVAL (val->etype).v_float;
886
887   if (SPEC_LONG (val->etype))
888     {
889       if (SPEC_USIGN (val->etype))
890         return (double) SPEC_CVAL (val->etype).v_ulong;
891       else
892         return (double) SPEC_CVAL (val->etype).v_long;
893     }
894   
895   if (SPEC_NOUN (val->etype) == V_INT) {
896     if (SPEC_USIGN (val->etype))
897       return (double) SPEC_CVAL (val->etype).v_uint;
898     else
899       return (double) SPEC_CVAL (val->etype).v_int;
900   }
901
902   if (SPEC_NOUN (val->etype) == V_CHAR) {
903     if (SPEC_USIGN (val->etype))
904       return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
905     else
906       return (double) (signed char)SPEC_CVAL (val->etype).v_int;
907   }
908
909   if (IS_BITVAR(val->etype)) {
910     return (double) SPEC_CVAL (val->etype).v_uint;
911   }
912
913   if (SPEC_NOUN (val->etype) == V_VOID) {
914     return (double) SPEC_CVAL (val->etype).v_ulong;
915   }
916
917   // we are lost !
918   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
919           "floatFromVal: unknown value");
920   return 0;
921 }
922
923
924 /*------------------------------------------------------------------*/
925 /* valUnaryPM - does the unary +/- operation on a constant          */
926 /*------------------------------------------------------------------*/
927 value *
928 valUnaryPM (value * val)
929 {
930   /* depending on type */
931   if (SPEC_NOUN (val->etype) == V_FLOAT)
932     SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
933   else
934     {
935       if (SPEC_LONG (val->etype))
936         {
937           if (SPEC_USIGN (val->etype))
938             SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
939           else
940             SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
941         }
942       else
943         {
944           if (SPEC_USIGN (val->etype))
945             SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
946           else
947             SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
948         }
949     }
950   // -(unsigned 3) now really is signed
951   SPEC_USIGN(val->etype)=0;
952   // -(unsigned char)135 now really is an int
953   if (SPEC_NOUN(val->etype) == V_CHAR) {
954     if (SPEC_CVAL(val->etype).v_int < -128) {
955       SPEC_NOUN(val->etype) = V_INT;
956     }
957   }
958   return val;
959 }
960
961 /*------------------------------------------------------------------*/
962 /* valueComplement - complements a constant                         */
963 /*------------------------------------------------------------------*/
964 value *
965 valComplement (value * val)
966 {
967   /* depending on type */
968   if (SPEC_LONG (val->etype))
969     {
970       if (SPEC_USIGN (val->etype))
971         SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
972       else
973         SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
974     }
975   else
976     {
977       if (SPEC_USIGN (val->etype))
978         SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
979       else
980         SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
981     }
982   // ~(unsigned 3) now really is signed
983   SPEC_USIGN(val->etype)=0;
984   return val;
985 }
986
987 /*------------------------------------------------------------------*/
988 /* valueNot - complements a constant                                */
989 /*------------------------------------------------------------------*/
990 value *
991 valNot (value * val)
992 {
993   /* depending on type */
994   if (SPEC_LONG (val->etype))
995     {
996       if (SPEC_USIGN (val->etype))
997         SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
998       else
999         SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1000     }
1001   else
1002     {
1003       if (SPEC_USIGN (val->etype))
1004         SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1005       else
1006         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1007     }
1008   return val;
1009 }
1010
1011 /*------------------------------------------------------------------*/
1012 /* valMult - multiply constants                                     */
1013 /*------------------------------------------------------------------*/
1014 value *
1015 valMult (value * lval, value * rval)
1016 {
1017   value *val;
1018
1019   /* create a new value */
1020   val = newValue ();
1021   val->type = val->etype = newLink ();
1022   val->type->class = SPECIFIER;
1023   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1024                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1025   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1026   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1027   SPEC_LONG (val->type) = 1;
1028
1029   if (IS_FLOAT (val->type))
1030     SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1031   else
1032     {
1033       if (SPEC_LONG (val->type))
1034         {
1035           if (SPEC_USIGN (val->type))
1036             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
1037               (unsigned long) floatFromVal (rval);
1038           else
1039             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
1040               (long) floatFromVal (rval);
1041         }
1042     }
1043   return cheapestVal(val);
1044 }
1045
1046 /*------------------------------------------------------------------*/
1047 /* valDiv  - Divide   constants                                     */
1048 /*------------------------------------------------------------------*/
1049 value *
1050 valDiv (value * lval, value * rval)
1051 {
1052   value *val;
1053
1054   if (floatFromVal (rval) == 0)
1055     {
1056       werror (E_DIVIDE_BY_ZERO);
1057       return rval;
1058     }
1059
1060   /* create a new value */
1061   val = newValue ();
1062   val->type = val->etype = newLink();
1063   val->type->class = SPECIFIER;
1064   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1065                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1066   SPEC_SCLS (val->etype) = S_LITERAL;
1067   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1068   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1069
1070   if (IS_FLOAT (val->type))
1071     SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1072   else
1073     {
1074       if (SPEC_LONG (val->type))
1075         {
1076           if (SPEC_USIGN (val->type))
1077             SPEC_CVAL (val->type).v_ulong = 
1078               (unsigned long) floatFromVal (lval) /
1079               (unsigned long) floatFromVal (rval);
1080           else
1081             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1082               (long) floatFromVal (rval);
1083         }
1084       else
1085         {
1086           if (SPEC_USIGN (val->type)) {
1087             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1088               (unsigned) floatFromVal (rval);
1089           } else {
1090             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1091               (int) floatFromVal (rval);
1092           }
1093         }
1094     }
1095   return cheapestVal(val);
1096 }
1097
1098 /*------------------------------------------------------------------*/
1099 /* valMod  - Modulus  constants                                     */
1100 /*------------------------------------------------------------------*/
1101 value *
1102 valMod (value * lval, value * rval)
1103 {
1104   value *val;
1105
1106   /* create a new value */
1107   val = newValue ();
1108   val->type = val->etype = newLink ();
1109   val->type->class = SPECIFIER;
1110   SPEC_NOUN (val->type) = V_INT;        /* type is int */
1111   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1112   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1113   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1114
1115   if (SPEC_LONG (val->type))
1116     {
1117       if (SPEC_USIGN (val->type))
1118         SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1119           (unsigned long) floatFromVal (rval);
1120       else
1121         SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1122           (unsigned long) floatFromVal (rval);
1123     }
1124   else
1125     {
1126       if (SPEC_USIGN (val->type)) {
1127         SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1128           (unsigned) floatFromVal (rval);
1129       } else {
1130         SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1131           (unsigned) floatFromVal (rval);
1132       }
1133     }
1134
1135   return cheapestVal(val);
1136 }
1137
1138 /*------------------------------------------------------------------*/
1139 /* valPlus - Addition constants                                     */
1140 /*------------------------------------------------------------------*/
1141 value *
1142 valPlus (value * lval, value * rval)
1143 {
1144   value *val;
1145
1146   /* create a new value */
1147   val = newValue ();
1148   val->type = val->etype = newLink ();
1149   val->type->class = SPECIFIER;
1150   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1151                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1152   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1153   SPEC_USIGN (val->type) = 
1154     SPEC_USIGN (lval->etype) &&
1155     SPEC_USIGN (rval->etype) &&
1156     (floatFromVal(lval)+floatFromVal(rval))>=0;
1157     
1158   SPEC_LONG (val->type) = 1;
1159
1160   if (IS_FLOAT (val->type))
1161     SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1162   else
1163     {
1164       if (SPEC_LONG (val->type))
1165         {
1166           if (SPEC_USIGN (val->type))
1167             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1168               (unsigned long) floatFromVal (rval);
1169           else
1170             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1171               (long) floatFromVal (rval);
1172         }
1173     }
1174   return cheapestVal(val);
1175 }
1176
1177 /*------------------------------------------------------------------*/
1178 /* valMinus - Addition constants                                    */
1179 /*------------------------------------------------------------------*/
1180 value *
1181 valMinus (value * lval, value * rval)
1182 {
1183   value *val;
1184
1185   /* create a new value */
1186   val = newValue ();
1187   val->type = val->etype = newLink ();
1188   val->type->class = SPECIFIER;
1189   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1190                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1191   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1192   SPEC_USIGN (val->type) = 
1193     SPEC_USIGN (lval->etype) &&
1194     SPEC_USIGN (rval->etype) &&
1195     (floatFromVal(lval)-floatFromVal(rval))>=0;
1196
1197   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1198
1199   if (IS_FLOAT (val->type))
1200     SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1201   else
1202     {
1203       if (SPEC_LONG (val->type))
1204         {
1205           if (SPEC_USIGN (val->type)) {
1206             SPEC_CVAL (val->type).v_ulong = 
1207               (unsigned long) floatFromVal (lval) -
1208               (unsigned long) floatFromVal (rval);
1209           } else {
1210             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1211               (long) floatFromVal (rval);
1212           }
1213         }
1214       else
1215         {
1216           if (SPEC_USIGN (val->type)) {
1217             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1218               (unsigned) floatFromVal (rval);
1219           } else {
1220             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - 
1221               (int) floatFromVal (rval);
1222           }
1223         }
1224     }
1225   return cheapestVal(val);
1226 }
1227
1228 /*------------------------------------------------------------------*/
1229 /* valShift - Shift left or right                                   */
1230 /*------------------------------------------------------------------*/
1231 value *
1232 valShift (value * lval, value * rval, int lr)
1233 {
1234   value *val;
1235
1236   /* create a new value */
1237   val = newValue ();
1238   val->type = val->etype = newIntLink ();
1239   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1240   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1241   SPEC_LONG (val->type) = 1;
1242
1243   if (SPEC_LONG (val->type))
1244     {
1245       if (SPEC_USIGN (val->type))
1246         SPEC_CVAL (val->type).v_ulong = lr ? 
1247           (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1248           (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1249       else
1250         SPEC_CVAL (val->type).v_long = lr ?
1251           (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1252           (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1253     }
1254
1255   return cheapestVal(val);
1256 }
1257
1258 /*------------------------------------------------------------------*/
1259 /* valCompare- Compares two literal                                 */
1260 /*------------------------------------------------------------------*/
1261 value *
1262 valCompare (value * lval, value * rval, int ctype)
1263 {
1264   value *val;
1265
1266   /* create a new value */
1267   val = newValue ();
1268   val->type = val->etype = newCharLink ();
1269   val->type->class = SPECIFIER;
1270   SPEC_NOUN (val->type) = V_CHAR;       /* type is char */
1271   SPEC_USIGN (val->type) = 1;
1272   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1273
1274   switch (ctype)
1275     {
1276     case '<':
1277       SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1278       break;
1279
1280     case '>':
1281       SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1282       break;
1283
1284     case LE_OP:
1285       SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1286       break;
1287
1288     case GE_OP:
1289       SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1290       break;
1291
1292     case EQ_OP:
1293       SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1294       break;
1295
1296     case NE_OP:
1297       SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1298       break;
1299
1300     }
1301
1302   return val;
1303 }
1304
1305 /*------------------------------------------------------------------*/
1306 /* valBitwise - Bitwise operation                                   */
1307 /*------------------------------------------------------------------*/
1308 value *
1309 valBitwise (value * lval, value * rval, int op)
1310 {
1311   value *val;
1312
1313   /* create a new value */
1314   val = newValue ();
1315   val->type = copyLinkChain (getSize(rval->type) > getSize(lval->type) ?
1316                              rval->type : lval->type);
1317   val->etype = getSpec (val->type);
1318
1319   switch (op)
1320     {
1321     case '&':
1322       if (SPEC_LONG (val->type))
1323         {
1324           if (SPEC_USIGN (val->type))
1325             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1326               (unsigned long) floatFromVal (rval);
1327           else
1328             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1329               (long) floatFromVal (rval);
1330         }
1331       else
1332         {
1333           if (SPEC_USIGN (val->type))
1334             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1335               (unsigned) floatFromVal (rval);
1336           else
1337             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1338         }
1339       break;
1340
1341     case '|':
1342       if (SPEC_LONG (val->type))
1343         {
1344           if (SPEC_USIGN (val->type))
1345             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1346               (unsigned long) floatFromVal (rval);
1347           else
1348             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1349               (long) floatFromVal (rval);
1350         }
1351       else
1352         {
1353           if (SPEC_USIGN (val->type))
1354             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1355               (unsigned) floatFromVal (rval);
1356           else
1357             SPEC_CVAL (val->type).v_int =
1358               (int) floatFromVal (lval) | (int) floatFromVal (rval);
1359         }
1360
1361       break;
1362
1363     case '^':
1364       if (SPEC_LONG (val->type))
1365         {
1366           if (SPEC_USIGN (val->type))
1367             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1368               (unsigned long) floatFromVal (rval);
1369           else
1370             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1371               (long) floatFromVal (rval);
1372         }
1373       else
1374         {
1375           if (SPEC_USIGN (val->type))
1376             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1377               (unsigned) floatFromVal (rval);
1378           else
1379             SPEC_CVAL (val->type).v_int =
1380               (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1381         }
1382       break;
1383     }
1384
1385   return cheapestVal(val);
1386 }
1387
1388 /*------------------------------------------------------------------*/
1389 /* valAndOr   - Generates code for and / or operation               */
1390 /*------------------------------------------------------------------*/
1391 value *
1392 valLogicAndOr (value * lval, value * rval, int op)
1393 {
1394   value *val;
1395
1396   /* create a new value */
1397   val = newValue ();
1398   val->type = val->etype = newCharLink ();
1399   val->type->class = SPECIFIER;
1400   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1401   SPEC_USIGN (val->type) = 0;
1402
1403   switch (op)
1404     {
1405     case AND_OP:
1406       SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1407       break;
1408
1409     case OR_OP:
1410       SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1411       break;
1412     }
1413
1414
1415   return val;
1416 }
1417
1418 /*------------------------------------------------------------------*/
1419 /* valCastLiteral - casts a literal value to another type           */
1420 /*------------------------------------------------------------------*/
1421 value *
1422 valCastLiteral (sym_link * dtype, double fval)
1423 {
1424   value *val;
1425
1426   if (!dtype)
1427     return NULL;
1428
1429   val = newValue ();
1430   val->etype = getSpec (val->type = copyLinkChain (dtype));
1431   SPEC_SCLS (val->etype) = S_LITERAL;
1432   /* if it is not a specifier then we can assume that */
1433   /* it will be an unsigned long                      */
1434   if (!IS_SPEC (val->type)) {
1435       SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1436       return val;
1437   }
1438
1439   if (SPEC_NOUN (val->etype) == V_FLOAT)
1440       SPEC_CVAL (val->etype).v_float = fval;
1441   else {
1442       unsigned long l = fval;
1443       if (SPEC_LONG (val->etype)) {
1444           if (SPEC_USIGN (val->etype))
1445               SPEC_CVAL (val->etype).v_ulong = (unsigned long) l;
1446           else
1447               SPEC_CVAL (val->etype).v_long = (long) l;
1448       } else {
1449           if (SPEC_USIGN (val->etype))
1450               SPEC_CVAL (val->etype).v_uint = (unsigned short)l;
1451           else
1452               SPEC_CVAL (val->etype).v_int = (short)l;
1453       }
1454   }
1455   return val;
1456 }
1457
1458 /*------------------------------------------------------------------*/
1459 /* getNelements - determines # of elements from init list           */
1460 /*------------------------------------------------------------------*/
1461 int 
1462 getNelements (sym_link * type, initList * ilist)
1463 {
1464   int i;
1465
1466   if (!ilist)
1467     return 0;
1468
1469   if (ilist->type == INIT_DEEP)
1470     ilist = ilist->init.deep;
1471
1472   /* if type is a character array and there is only one
1473      (string) initialiser then get the length of the string */
1474   if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1475     {
1476       ast *iast = ilist->init.node;
1477       value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1478       if (!v)
1479         {
1480           werror (E_CONST_EXPECTED);
1481           return 0;
1482         }
1483
1484       if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1485         // yep, it's a string
1486         {
1487           return DCL_ELEM (v->type);
1488         }
1489     }
1490
1491   i = 0;
1492   while (ilist)
1493     {
1494       i++;
1495       ilist = ilist->next;
1496     }
1497   return i;
1498 }
1499
1500 /*-----------------------------------------------------------------*/
1501 /* valForArray - returns a value with name of array index          */
1502 /*-----------------------------------------------------------------*/
1503 value *
1504 valForArray (ast * arrExpr)
1505 {
1506   value *val, *lval = NULL;
1507   char buffer[128];
1508   int size = getSize (arrExpr->left->ftype->next);
1509   /* if the right or left is an array
1510      resolve it first */
1511   if (IS_AST_OP (arrExpr->left))
1512     {
1513       if (arrExpr->left->opval.op == '[')
1514         lval = valForArray (arrExpr->left);
1515       else if (arrExpr->left->opval.op == '.')
1516         lval = valForStructElem (arrExpr->left->left,
1517                                  arrExpr->left->right);
1518       else if (arrExpr->left->opval.op == PTR_OP &&
1519                IS_ADDRESS_OF_OP (arrExpr->left->left))
1520         lval = valForStructElem (arrExpr->left->left->left,
1521                                  arrExpr->left->right);
1522       else
1523         return NULL;
1524
1525     }
1526   else if (!IS_AST_SYM_VALUE (arrExpr->left))
1527     return NULL;
1528
1529   if (!IS_AST_LIT_VALUE (arrExpr->right))
1530     return NULL;
1531
1532   val = newValue ();
1533   if (!lval)
1534     {
1535         SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1536     }
1537   else
1538     {
1539         SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1540     }
1541
1542   SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1543            (int) AST_LIT_VALUE (arrExpr->right) * size);
1544
1545   val->type = newLink ();
1546   if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1547     {
1548       DCL_TYPE (val->type) = CPOINTER;
1549       DCL_PTR_CONST (val->type) = port->mem.code_ro;
1550     }
1551   else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1552     DCL_TYPE (val->type) = FPOINTER;
1553   else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1554     DCL_TYPE (val->type) = PPOINTER;
1555   else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1556     DCL_TYPE (val->type) = IPOINTER;
1557   else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1558     DCL_TYPE (val->type) = EEPPOINTER;
1559   else
1560     DCL_TYPE (val->type) = POINTER;
1561   val->type->next = arrExpr->left->ftype;
1562   val->etype = getSpec (val->type);
1563   return val;
1564 }
1565
1566 /*-----------------------------------------------------------------*/
1567 /* valForStructElem - returns value with name of struct element    */
1568 /*-----------------------------------------------------------------*/
1569 value *
1570 valForStructElem (ast * structT, ast * elemT)
1571 {
1572   value *val, *lval = NULL;
1573   char buffer[128];
1574   symbol *sym;
1575
1576   /* left could be furthur derefed */
1577   if (IS_AST_OP (structT))
1578     {
1579       if (structT->opval.op == '[')
1580         lval = valForArray (structT);
1581       else if (structT->opval.op == '.')
1582         lval = valForStructElem (structT->left, structT->right);
1583       else if (structT->opval.op == PTR_OP &&
1584                IS_ADDRESS_OF_OP (structT->left))
1585         lval = valForStructElem (structT->left->left,
1586                                  structT->right);
1587       else
1588         return NULL;
1589     }
1590
1591   if (!IS_AST_SYM_VALUE (elemT))
1592     return NULL;
1593
1594   if (!IS_STRUCT (structT->etype))
1595     return NULL;
1596
1597   if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1598                                AST_SYMBOL (elemT))) == NULL)
1599     {
1600       return NULL;
1601     }
1602
1603   val = newValue ();
1604   if (!lval)
1605     {
1606         SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1607     }
1608   else
1609     {
1610         SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1611     }
1612
1613   SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1614            (int) sym->offset);
1615
1616   val->type = newLink ();
1617   if (SPEC_SCLS (structT->etype) == S_CODE)
1618     {
1619       DCL_TYPE (val->type) = CPOINTER;
1620       DCL_PTR_CONST (val->type) = port->mem.code_ro;
1621     }
1622   else if (SPEC_SCLS (structT->etype) == S_XDATA)
1623     DCL_TYPE (val->type) = FPOINTER;
1624   else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1625     DCL_TYPE (val->type) = PPOINTER;
1626   else if (SPEC_SCLS (structT->etype) == S_IDATA)
1627     DCL_TYPE (val->type) = IPOINTER;
1628   else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1629     DCL_TYPE (val->type) = EEPPOINTER;
1630   else
1631     DCL_TYPE (val->type) = POINTER;
1632   val->type->next = sym->type;
1633   val->etype = getSpec (val->type);
1634   return val;
1635 }
1636
1637 /*-----------------------------------------------------------------*/
1638 /* valForCastAggr - will return value for a cast of an aggregate   */
1639 /*                  plus minus a constant                          */
1640 /*-----------------------------------------------------------------*/
1641 value *
1642 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1643 {
1644   value *val;
1645
1646   if (!IS_AST_SYM_VALUE (aexpr))
1647     return NULL;
1648   if (!IS_AST_LIT_VALUE (cnst))
1649     return NULL;
1650
1651   val = newValue ();
1652
1653   SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1654            AST_SYMBOL (aexpr)->rname, op,
1655            getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1656
1657   val->type = type;
1658   val->etype = getSpec (val->type);
1659   return val;
1660 }
1661
1662 /*-----------------------------------------------------------------*/
1663 /* valForCastAggr - will return value for a cast of an aggregate   */
1664 /*                  with no constant                               */
1665 /*-----------------------------------------------------------------*/
1666 value *
1667 valForCastArr (ast * aexpr, sym_link * type)
1668 {
1669   value *val;
1670
1671   if (!IS_AST_SYM_VALUE (aexpr))
1672     return NULL;
1673
1674   val = newValue ();
1675
1676   SNPRINTF (val->name, sizeof(val->name), "(%s)",
1677            AST_SYMBOL (aexpr)->rname);
1678
1679   val->type = type;
1680   val->etype = getSpec (val->type);
1681   return val;
1682 }