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