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