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