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