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