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