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