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