* src/SDCCast.c (decorateType),
[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_alloc (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_alloc (sizeof (initList));
57
58   nilist->type = type;
59   nilist->lineno = mylineno;
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 bool
101 convertIListToConstList(initList *src, literalList **lList)
102 {
103     initList    *iLoop;
104     literalList *head, *last, *newL;
105     
106     head = last = NULL;
107     
108     if (!src || src->type != INIT_DEEP)
109     {
110         return FALSE;
111     }
112     
113     iLoop =  src->init.deep;
114     
115     while (iLoop)
116     {
117         if (iLoop->type != INIT_NODE)
118         {
119             return FALSE;
120         }
121
122         if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node))))
123         {
124             return FALSE;
125         }
126         iLoop = iLoop->next;
127     }
128
129     // We've now established that the initializer list contains only literal values.
130
131     iLoop = src->init.deep;
132     while (iLoop)
133     {
134         double val = AST_LIT_VALUE(iLoop->init.node);
135
136         if (last && last->literalValue == val)
137         {
138             last->count++;
139         }
140         else
141         {
142             newL = Safe_alloc(sizeof(literalList));
143             newL->literalValue = val;
144             newL->count = 1;
145             newL->next = NULL;
146             
147             if (last)
148             {
149                 last->next = newL;
150             }
151             else
152             {
153                 head = newL;
154             }
155             last = newL;
156         }
157         iLoop = iLoop->next;
158     }
159     
160     if (!head)    
161     {
162         return FALSE;
163     }
164     
165     *lList = head;
166     return TRUE;
167 }
168
169 literalList *
170 copyLiteralList(literalList *src)
171 {
172     literalList *head, *prev, *newL;
173     
174     head = prev = NULL;
175     
176     while (src)
177     {
178         newL = Safe_alloc(sizeof(literalList));
179         
180         newL->literalValue = src->literalValue;
181         newL->count = src->count;
182         newL->next = NULL;
183         
184         if (prev)
185         {
186             prev->next = newL;
187         }
188         else
189         {
190             head = newL;
191         }
192         prev = newL;
193         src = src->next;
194     }
195     
196     return head;
197 }
198
199
200
201 /*------------------------------------------------------------------*/
202 /* copyIlist - copy initializer list            */
203 /*------------------------------------------------------------------*/
204 initList *
205 copyIlist (initList * src)
206 {
207   initList *dest = NULL;
208
209   if (!src)
210     return NULL;
211
212   switch (src->type)
213     {
214     case INIT_DEEP:
215       dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
216       break;
217     case INIT_NODE:
218       dest = newiList (INIT_NODE, copyAst (src->init.node));
219       break;
220     }
221
222   if (src->next)
223     dest->next = copyIlist (src->next);
224
225   return dest;
226 }
227
228 /*------------------------------------------------------------------*/
229 /* list2int - converts the first element of the list to value       */
230 /*------------------------------------------------------------------*/
231 double
232 list2int (initList * val)
233 {
234   initList *i = val;
235
236   if (i->type == INIT_DEEP)
237     return list2int (val->init.deep);
238
239   return floatFromVal (constExprValue (val->init.node, TRUE));
240 }
241
242 /*------------------------------------------------------------------*/
243 /* list2val - converts the first element of the list to value       */
244 /*------------------------------------------------------------------*/
245 value *
246 list2val (initList * val)
247 {
248   if (!val)
249     return NULL;
250
251   if (val->type == INIT_DEEP)
252     return list2val (val->init.deep);
253
254   return constExprValue (val->init.node, TRUE);
255 }
256
257 /*------------------------------------------------------------------*/
258 /* list2expr - returns the first expression in the initializer list */
259 /*------------------------------------------------------------------*/
260 ast *
261 list2expr (initList * ilist)
262 {
263   if (ilist->type == INIT_DEEP)
264     return list2expr (ilist->init.deep);
265   return ilist->init.node;
266 }
267
268 /*------------------------------------------------------------------*/
269 /* resolveIvalSym - resolve symbols in initial values               */
270 /*------------------------------------------------------------------*/
271 void
272 resolveIvalSym (initList * ilist)
273 {
274   if (!ilist)
275     return;
276
277   if (ilist->type == INIT_NODE)
278     ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
279
280   if (ilist->type == INIT_DEEP)
281     resolveIvalSym (ilist->init.deep);
282
283   resolveIvalSym (ilist->next);
284 }
285
286 /*-----------------------------------------------------------------*/
287 /* symbolVal - creates a value for a symbol              */
288 /*-----------------------------------------------------------------*/
289 value *
290 symbolVal (symbol * sym)
291 {
292   value *val;
293
294   if (!sym)
295     return NULL;
296
297   val = newValue ();
298   val->sym = sym;
299
300   if (sym->type)
301     {
302       val->type = sym->type;
303       val->etype = getSpec (val->type);
304     }
305
306   if (*sym->rname)
307     {
308         SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
309     }
310   else
311     {
312         SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
313     }
314
315   return val;
316 }
317
318 #if defined(REDUCE_LITERALS)
319 /*--------------------------------------------------------------------*/
320 /* cheapestVal - convert a val to the cheapest as possible value      */
321 /*--------------------------------------------------------------------*/
322 static value *cheapestVal (value *val) {
323   TYPE_DWORD  sval=0;
324   TYPE_UDWORD uval=0;
325
326   if (IS_FLOAT(val->type) || IS_CHAR(val->type))
327     return val;
328
329   if (SPEC_LONG(val->type)) {
330     if (SPEC_USIGN(val->type)) {
331       uval=SPEC_CVAL(val->type).v_ulong;
332     } else {
333       sval=SPEC_CVAL(val->type).v_long;
334     }
335   } else {
336     if (SPEC_USIGN(val->type)) {
337       uval=SPEC_CVAL(val->type).v_uint;
338     } else {
339       sval=SPEC_CVAL(val->type).v_int;
340     }
341   }
342
343   if (SPEC_USIGN(val->type)) {
344     if (uval<=0xffff) {
345       SPEC_LONG(val->type)=0;
346       SPEC_CVAL(val->type).v_uint = (TYPE_UWORD)uval;
347       if (uval<=0xff) {
348         SPEC_NOUN(val->type)=V_CHAR;
349       }
350     }
351   } else { // not unsigned
352     if (sval<0) {
353       if (sval>=-32768) {
354         SPEC_LONG(val->type)=0;
355         SPEC_CVAL(val->type).v_int = (TYPE_WORD)sval;
356         if (sval>=-128) {
357           SPEC_NOUN(val->type)=V_CHAR;
358         }
359       }
360     } else { // sval>=0
361       if (sval<=32767) {
362         SPEC_LONG(val->type)=0;
363         SPEC_CVAL(val->type).v_int = (TYPE_WORD)sval;
364         if (sval<=127) {
365           SPEC_NOUN(val->type)=V_CHAR;
366         }
367       }
368     }
369   }
370   return val;
371 }
372
373 #else
374
375 static value *cheapestVal (value *val)
376 {
377   /* - signed/unsigned must not be changed.
378      - long must not be changed.
379
380      the only possible reduction is from signed int to signed char,
381      because it's automatically promoted back to signed int.
382
383      a reduction from unsigned int to unsigned char is a bug,
384      because an _unsigned_ char is promoted to _signed_ int! */
385   if (IS_INT(val->type) &&
386       !SPEC_USIGN(val->type) &&
387       !SPEC_LONG(val->type) &&
388       SPEC_CVAL(val->type).v_int >= -128 &&
389       SPEC_CVAL(val->type).v_int <=  127)
390
391     {
392       SPEC_NOUN(val->type) = V_CHAR;
393     }
394   /* this could be too aggressive:
395      'unsigned char' promotes to 'signed int', so that we can
396      reduce it the other way */
397   if (IS_INT(val->type) &&
398       !SPEC_USIGN(val->type) &&
399       !SPEC_LONG(val->type) &&
400       SPEC_CVAL(val->type).v_int >= 128 &&
401       SPEC_CVAL(val->type).v_int <= 255)
402
403     {
404       SPEC_NOUN(val->type) = V_CHAR;
405       SPEC_USIGN(val->type) = 1;
406     }
407   return (val);
408 }
409 #endif
410
411 /*-----------------------------------------------------------------*/
412 /* valueFromLit - creates a value from a literal                   */
413 /*-----------------------------------------------------------------*/
414 value *
415 valueFromLit (double lit)
416 {
417   char buffer[50];
418
419   if ((((TYPE_DWORD) lit) - lit) == 0)
420     {
421       SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_DWORD) lit);
422       return constVal (buffer);
423     }
424
425   SNPRINTF (buffer, sizeof(buffer), "%f", lit);
426   return constFloatVal (buffer);
427 }
428
429 /*-----------------------------------------------------------------*/
430 /* constFloatVal - converts a FLOAT constant to value              */
431 /*-----------------------------------------------------------------*/
432 value *
433 constFloatVal (char *s)
434 {
435   value *val = newValue ();
436   double sval;
437
438   if (sscanf (s, "%lf", &sval) != 1)
439     {
440       werror (E_INVALID_FLOAT_CONST, s);
441       return constVal ("0");
442     }
443
444   val->type = val->etype = newLink (SPECIFIER);
445   SPEC_NOUN (val->type) = V_FLOAT;
446   SPEC_SCLS (val->type) = S_LITERAL;
447   SPEC_CVAL (val->type).v_float = sval;
448
449   return val;
450 }
451
452 /*-----------------------------------------------------------------*/
453 /* constVal - converts an INTEGER constant into a cheapest value   */
454 /*-----------------------------------------------------------------*/
455 value *constVal (char *s)
456 {
457   value *val;
458   short hex = 0, octal = 0;
459   char scanFmt[10];
460   int scI = 0;
461   double dval;
462
463   val = newValue ();            /* alloc space for value   */
464
465   val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
466   SPEC_SCLS (val->type) = S_LITERAL;
467   // let's start with a signed char
468   SPEC_NOUN (val->type) = V_CHAR;
469   SPEC_USIGN (val->type) = 0;
470
471   hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
472
473   /* set the octal flag   */
474   if (!hex && *s == '0' && *(s + 1))
475     octal = 1;
476
477   /* create the scan string */
478   scanFmt[scI++] = '%';
479
480   scanFmt[scI++] = 'l';
481
482   if (octal)
483     scanFmt[scI++] = 'o';
484   else if (hex)
485     scanFmt[scI++] = 'x';
486   else
487     scanFmt[scI++] = 'f';
488
489   scanFmt[scI++] = '\0';
490
491   if (octal || hex) {
492     unsigned long sval;
493     sscanf (s, scanFmt, &sval);
494     dval=sval;
495   } else {
496     sscanf (s, scanFmt, &dval);
497   }
498
499   /* Setup the flags first */
500   /* set the _long flag if 'lL' is found */
501   if (strchr (s, 'l') || strchr (s, 'L')) {
502     SPEC_NOUN (val->type) = V_INT;
503     SPEC_LONG (val->type) = 1;
504   }
505
506   /* set the unsigned flag if 'uU' is found */
507   if (strchr (s, 'u') || strchr (s, 'U')) {
508     SPEC_USIGN (val->type) = 1;
509   }
510
511   if (dval<0) { // "-28u" will still be signed and negative
512     if (dval<-128) { // check if we have to promote to int
513       SPEC_NOUN (val->type) = V_INT;
514     }
515     if (dval<-32768) { // check if we have to promote to long int
516       SPEC_LONG (val->type) = 1;
517     }
518   } else { // >=0
519     if (dval>0xff ||    /* check if we have to promote to int */
520         SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
521                                      char. After an integral promotion it will
522                                      be a signed int; this certainly isn't what
523                                      the programer wants */
524       SPEC_NOUN (val->type) = V_INT;
525     }
526     else if (dval>0x7f && !SPEC_USIGN (val->type)) { // check if we have to promote to int
527 #if 0
528       if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
529           dval<=0xff) {
530         SPEC_USIGN (val->type) = 1;
531       } else {
532         SPEC_NOUN (val->type) = V_INT;
533       }
534 #else
535       /* this is quite agressive: 'unsigned char' will be promoted to 'signed int',
536          so that the signedness of a char shouldn't matter */
537       SPEC_USIGN (val->type) = 1;
538 #endif
539     }
540     if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
541       SPEC_LONG (val->type) = 1;
542     }
543     else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
544       if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
545           dval<=0xffff) {
546         SPEC_USIGN (val->type) = 1;
547       } else {
548         SPEC_LONG (val->type) = 1;
549         if (dval>0x7fffffff) {
550           SPEC_USIGN (val->type) = 1;
551         }
552       }
553     }
554   }
555
556   if (SPEC_LONG (val->type))
557     {
558       if (SPEC_USIGN (val->type))
559         {
560           SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD)dval;
561         }
562       else
563         {
564           SPEC_CVAL (val->type).v_long = (TYPE_DWORD)dval;
565         }
566     }
567   else
568     {
569       if (SPEC_USIGN (val->type))
570         {
571           SPEC_CVAL (val->type).v_uint = (TYPE_UWORD)dval;
572         }
573       else
574         {
575           SPEC_CVAL (val->type).v_int = (TYPE_WORD)dval;
576         }
577     }
578
579   return val;
580 }
581
582 /*! /fn char hexEscape(char **src)
583
584     /param src Pointer to 'x' from start of hex character value
585 */
586
587 unsigned char hexEscape(char **src)
588 {
589   char *s ;
590   unsigned long value ;
591
592   (*src)++ ;    /* Skip over the 'x' */
593   s = *src ;    /* Save for error detection */
594   
595   value = strtol (*src, src, 16);
596   
597   if (s == *src) {
598       // no valid hex found
599       werror(E_INVALID_HEX);
600   } else {
601     if (value > 255) {
602       werror(W_ESC_SEQ_OOR_FOR_CHAR);
603     }
604   }
605   return (char) value;
606 }
607
608 /*------------------------------------------------------------------*/
609 /* octalEscape - process an octal constant of max three digits      */
610 /* return the octal value, throw a warning for illegal octal        */
611 /* adjust src to point at the last proccesed char                   */
612 /*------------------------------------------------------------------*/
613
614 unsigned char octalEscape (char **str) {
615   int digits;
616   unsigned value=0;
617
618   for (digits=0; digits<3; digits++) {
619     if (**str>='0' && **str<='7') {
620       value = value*8 + (**str-'0');
621       (*str)++;
622     } else {
623       break;
624     }
625   }
626   if (digits) {
627     if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
628       werror (W_ESC_SEQ_OOR_FOR_CHAR);
629     }
630   }
631   return value;
632 }
633
634 /*! 
635   /fn int copyStr (char *dest, char *src)
636   
637   Copies a source string to a dest buffer interpreting escape sequences
638   and special characters
639
640   /param dest Buffer to receive the resultant string
641   /param src  Buffer containing the source string with escape sequecnes
642   /return Number of characters in output string
643
644 */
645
646 int 
647 copyStr (char *dest, char *src)
648
649 {
650   char *OriginalDest = dest ;
651
652   while (*src)
653     {
654       if (*src == '\"')
655         src++;
656       else if (*src == '\\')
657         {
658           src++;
659           switch (*src)
660             {
661             case 'n':
662               *dest++ = '\n';
663               break;
664             case 't':
665               *dest++ = '\t';
666               break;
667             case 'v':
668               *dest++ = '\v';
669               break;
670             case 'b':
671               *dest++ = '\b';
672               break;
673             case 'r':
674               *dest++ = '\r';
675               break;
676             case 'f':
677               *dest++ = '\f';
678               break;
679             case 'a':
680               *dest++ = '\a';
681               break;
682
683             case '0':
684             case '1':
685             case '2':
686             case '3':
687             case '4':
688             case '5':
689             case '6':
690             case '7':
691               *dest++ = octalEscape(&src);
692               src-- ;
693               break;
694
695             case 'x': 
696               *dest++ = hexEscape(&src) ;
697               src-- ;
698               break ;
699
700             case '\\':
701               *dest++ = '\\';
702               break;
703             case '\?':
704               *dest++ = '\?';
705               break;
706             case '\'':
707               *dest++ = '\'';
708               break;
709             case '\"':
710               *dest++ = '\"';
711               break;
712             default:
713               *dest++ = *src;
714             }
715           src++;
716         }
717       else
718         *dest++ = *src++;
719     }
720
721   *dest++ = '\0';
722
723   return dest - OriginalDest ;
724 }
725
726 /*------------------------------------------------------------------*/
727 /* strVal - converts a string constant to a value       */
728 /*------------------------------------------------------------------*/
729 value *
730 strVal (char *s)
731 {
732   value *val;
733
734   val = newValue ();            /* get a new one */
735
736   /* get a declarator */
737   val->type = newLink (DECLARATOR);
738   DCL_TYPE (val->type) = ARRAY;
739   val->type->next = val->etype = newLink (SPECIFIER);
740   SPEC_NOUN (val->etype) = V_CHAR;
741   SPEC_SCLS (val->etype) = S_LITERAL;
742
743   SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
744   DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
745
746   return val;
747 }
748
749
750 /*------------------------------------------------------------------*/
751 /* reverseValWithType - reverses value chain with type & etype      */
752 /*------------------------------------------------------------------*/
753 value *
754 reverseValWithType (value * val)
755 {
756   sym_link *type;
757   sym_link *etype;
758
759   if (!val)
760     return NULL;
761
762   /* save the type * etype chains */
763   type = val->type;
764   etype = val->etype;
765
766   /* set the current one 2b null */
767   val->type = val->etype = NULL;
768   val = reverseVal (val);
769
770   /* restore type & etype */
771   val->type = type;
772   val->etype = etype;
773
774   return val;
775 }
776
777 /*------------------------------------------------------------------*/
778 /* reverseVal - reverses the values for a value  chain        */
779 /*------------------------------------------------------------------*/
780 value *
781 reverseVal (value * val)
782 {
783   value *prev, *curr, *next;
784
785   if (!val)
786     return NULL;
787
788   prev = val;
789   curr = val->next;
790
791   while (curr)
792     {
793       next = curr->next;
794       curr->next = prev;
795       prev = curr;
796       curr = next;
797     }
798   val->next = (void *) NULL;
799   return prev;
800 }
801
802 /*------------------------------------------------------------------*/
803 /* copyValueChain - will copy a chain of values                     */
804 /*------------------------------------------------------------------*/
805 value *
806 copyValueChain (value * src)
807 {
808   value *dest;
809
810   if (!src)
811     return NULL;
812
813   dest = copyValue (src);
814   dest->next = copyValueChain (src->next);
815
816   return dest;
817 }
818
819 /*------------------------------------------------------------------*/
820 /* copyValue - copies contents of a value to a fresh one            */
821 /*------------------------------------------------------------------*/
822 value *
823 copyValue (value * src)
824 {
825   value *dest;
826
827   dest = newValue ();
828   dest->sym = copySymbol (src->sym);
829   strncpyz (dest->name, src->name, SDCC_NAME_MAX);
830   dest->type = (src->type ? copyLinkChain (src->type) : NULL);
831   dest->etype = (src->type ? getSpec (dest->type) : NULL);
832
833   return dest;
834 }
835
836 /*------------------------------------------------------------------*/
837 /* charVal - converts a character constant to a value       */
838 /*------------------------------------------------------------------*/
839 value *
840 charVal (char *s)
841 {
842   value *val;
843
844   val = newValue ();
845
846   val->type = val->etype = newLink (SPECIFIER);
847   SPEC_NOUN (val->type) = V_CHAR;
848   SPEC_USIGN(val->type) = 1;
849   SPEC_SCLS (val->type) = S_LITERAL;
850
851   s++;                          /* get rid of quotation */
852   /* if \ then special processing */
853   if (*s == '\\')
854     {
855       s++;                      /* go beyond the backslash  */
856       switch (*s)
857         {
858         case 'n':
859           SPEC_CVAL (val->type).v_uint = '\n';
860           break;
861         case 't':
862           SPEC_CVAL (val->type).v_uint = '\t';
863           break;
864         case 'v':
865           SPEC_CVAL (val->type).v_uint = '\v';
866           break;
867         case 'b':
868           SPEC_CVAL (val->type).v_uint = '\b';
869           break;
870         case 'r':
871           SPEC_CVAL (val->type).v_uint = '\r';
872           break;
873         case 'f':
874           SPEC_CVAL (val->type).v_uint = '\f';
875           break;
876         case 'a':
877           SPEC_CVAL (val->type).v_uint = '\a';
878           break;
879         case '\\':
880           SPEC_CVAL (val->type).v_uint = '\\';
881           break;
882         case '\?':
883           SPEC_CVAL (val->type).v_uint = '\?';
884           break;
885         case '\'':
886           SPEC_CVAL (val->type).v_uint = '\'';
887           break;
888         case '\"':
889           SPEC_CVAL (val->type).v_uint = '\"';
890           break;
891
892         case '0' :
893         case '1' :
894         case '2' :
895         case '3' :
896         case '4' :
897         case '5' :
898         case '6' :
899         case '7' :
900           SPEC_CVAL (val->type).v_uint = octalEscape(&s);
901           break;
902
903         case 'x':
904           SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
905           break;
906
907         default:
908           SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
909           break;
910         }
911     }
912   else                          /* not a backslash */
913     SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
914
915   return val;
916 }
917
918 /*------------------------------------------------------------------*/
919 /* valFromType - creates a value from type given                    */
920 /*------------------------------------------------------------------*/
921 value *
922 valFromType (sym_link * type)
923 {
924   value *val = newValue ();
925   val->type = copyLinkChain (type);
926   val->etype = getSpec (val->type);
927   return val;
928 }
929
930 /*------------------------------------------------------------------*/
931 /* floatFromVal - value to double float conversion                  */
932 /*------------------------------------------------------------------*/
933 double
934 floatFromVal (value * val)
935 {
936   if (!val)
937     return 0;
938
939   if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
940     {
941       werror (E_CONST_EXPECTED, val->name);
942       return 0;
943     }
944
945   /* if it is not a specifier then we can assume that */
946   /* it will be an unsigned long                      */
947   if (!IS_SPEC (val->type))
948     return (double) SPEC_CVAL (val->etype).v_ulong;
949
950   if (SPEC_NOUN (val->etype) == V_FLOAT)
951     return (double) SPEC_CVAL (val->etype).v_float;
952
953   if (SPEC_LONG (val->etype))
954     {
955       if (SPEC_USIGN (val->etype))
956         return (double) SPEC_CVAL (val->etype).v_ulong;
957       else
958         return (double) SPEC_CVAL (val->etype).v_long;
959     }
960
961   if (SPEC_NOUN (val->etype) == V_INT) {
962     if (SPEC_USIGN (val->etype))
963       return (double) SPEC_CVAL (val->etype).v_uint;
964     else
965       return (double) SPEC_CVAL (val->etype).v_int;
966   }
967
968   if (SPEC_NOUN (val->etype) == V_CHAR) {
969     if (SPEC_USIGN (val->etype))
970       return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
971     else
972       return (double) (signed char)SPEC_CVAL (val->etype).v_int;
973   }
974
975   if (IS_BITVAR(val->etype)) {
976     return (double) SPEC_CVAL (val->etype).v_uint;
977   }
978
979   if (SPEC_NOUN (val->etype) == V_VOID) {
980     return (double) SPEC_CVAL (val->etype).v_ulong;
981   }
982
983   // we are lost !
984   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
985           "floatFromVal: unknown value");
986   return 0;
987 }
988
989 /*------------------------------------------------------------------*/
990 /* valUnaryPM - does the unary +/- operation on a constant          */
991 /*------------------------------------------------------------------*/
992 value *
993 valUnaryPM (value * val)
994 {
995   /* depending on type */
996   if (SPEC_NOUN (val->etype) == V_FLOAT)
997     SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
998   else
999     {
1000       if (SPEC_LONG (val->etype))
1001         {
1002           if (SPEC_USIGN (val->etype))
1003             SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1004           else
1005             SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1006         }
1007       else
1008         {
1009           if (SPEC_USIGN (val->etype))
1010             SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1011           else
1012             SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1013         }
1014     }
1015   // -(unsigned 3) now really is signed
1016   SPEC_USIGN(val->etype)=0;
1017   // -(unsigned char)135 now really is an int
1018   if (SPEC_NOUN(val->etype) == V_CHAR) {
1019     if (SPEC_CVAL(val->etype).v_int < -128) {
1020       SPEC_NOUN(val->etype) = V_INT;
1021     }
1022   }
1023   return val;
1024 }
1025
1026 /*------------------------------------------------------------------*/
1027 /* valueComplement - complements a constant                         */
1028 /*------------------------------------------------------------------*/
1029 value *
1030 valComplement (value * val)
1031 {
1032   /* depending on type */
1033   if (SPEC_LONG (val->etype))
1034     {
1035       if (SPEC_USIGN (val->etype))
1036         SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1037       else
1038         SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1039     }
1040   else
1041     {
1042       if (SPEC_USIGN (val->etype))
1043         SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1044       else
1045         SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1046     }
1047   // ~(unsigned 3) now really is signed
1048   SPEC_USIGN(val->etype)=0;
1049   return val;
1050 }
1051
1052 /*------------------------------------------------------------------*/
1053 /* valueNot - complements a constant                                */
1054 /*------------------------------------------------------------------*/
1055 value *
1056 valNot (value * val)
1057 {
1058   /* depending on type */
1059   if (SPEC_LONG (val->etype))
1060     {
1061       if (SPEC_USIGN (val->etype))
1062         SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
1063       else
1064         SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1065     }
1066   else
1067     {
1068       if (SPEC_USIGN (val->etype))
1069         SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1070       else
1071         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1072     }
1073   return val;
1074 }
1075
1076 /*------------------------------------------------------------------*/
1077 /* valMult - multiply constants                                     */
1078 /*------------------------------------------------------------------*/
1079 value *
1080 valMult (value * lval, value * rval)
1081 {
1082   value *val;
1083
1084   /* create a new value */
1085   val = newValue ();
1086   val->type = val->etype = newLink (SPECIFIER);
1087   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1088                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1089   SPEC_SCLS  (val->type) = S_LITERAL;   /* will remain literal */
1090   SPEC_LONG  (val->type) = (SPEC_LONG  (lval->etype) | SPEC_LONG  (rval->etype));
1091   SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1092                                                     rval->etype,
1093                                                     TRUE));
1094   if (IS_FLOAT (val->type))
1095     SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1096       /* signed and unsigned mul are the same, as long as the precision of the
1097          result isn't bigger than the precision of the operands. */
1098   else if (SPEC_LONG (val->type))
1099     SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1100                                     (TYPE_UDWORD) floatFromVal (rval);
1101   else if (SPEC_USIGN (val->type)) /* unsigned int */
1102     {
1103       TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1104                        (TYPE_UWORD) floatFromVal (rval);
1105
1106       SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1107       if (ul != (TYPE_UWORD) ul)
1108         werror (W_INT_OVL);
1109     }
1110   else /* signed int */
1111     {
1112       TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
1113                      (TYPE_WORD) floatFromVal (rval);
1114
1115       SPEC_CVAL (val->type).v_int = (TYPE_WORD) l;
1116       if (l != (TYPE_WORD) l)
1117         werror (W_INT_OVL);
1118     }
1119   return cheapestVal (val);
1120 }
1121
1122 /*------------------------------------------------------------------*/
1123 /* valDiv  - Divide   constants                                     */
1124 /*------------------------------------------------------------------*/
1125 value *
1126 valDiv (value * lval, value * rval)
1127 {
1128   value *val;
1129
1130   if (floatFromVal (rval) == 0)
1131     {
1132       werror (E_DIVIDE_BY_ZERO);
1133       return rval;
1134     }
1135
1136   /* create a new value */
1137   val = newValue ();
1138   val->type = val->etype = newLink(SPECIFIER);
1139   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1140                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1141   SPEC_SCLS (val->etype) = S_LITERAL;
1142   SPEC_LONG  (val->type) = (SPEC_LONG  (lval->etype) | SPEC_LONG  (rval->etype));
1143   SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1144                                                     rval->etype,
1145                                                     TRUE));
1146
1147   if (IS_FLOAT (val->type))
1148     SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1149   else if (SPEC_LONG (val->type))
1150     {
1151       if (SPEC_USIGN (val->type))
1152         SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
1153           (TYPE_UDWORD) floatFromVal (rval);
1154       else
1155         SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
1156           (TYPE_DWORD) floatFromVal (rval);
1157     }
1158   else
1159     {
1160       if (SPEC_USIGN (val->type))
1161         SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
1162           (TYPE_UWORD) floatFromVal (rval);
1163       else
1164         SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
1165           (TYPE_WORD) floatFromVal (rval);
1166     }
1167   return cheapestVal (val);
1168 }
1169
1170 /*------------------------------------------------------------------*/
1171 /* valMod  - Modulus  constants                                     */
1172 /*------------------------------------------------------------------*/
1173 value *
1174 valMod (value * lval, value * rval)
1175 {
1176   value *val;
1177
1178   /* create a new value */
1179   val = newValue ();
1180   val->type = val->etype = newLink (SPECIFIER);
1181   SPEC_NOUN (val->type) = V_INT;        /* type is int */
1182   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1183   SPEC_LONG  (val->type) = (SPEC_LONG  (lval->etype) | SPEC_LONG  (rval->etype));
1184   SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1185                                                     rval->etype,
1186                                                     TRUE));
1187
1188   if (SPEC_LONG (val->type))
1189     {
1190       if (SPEC_USIGN (val->type))
1191         SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) %
1192           (TYPE_UDWORD) floatFromVal (rval);
1193       else
1194         SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) %
1195           (TYPE_DWORD) floatFromVal (rval);
1196     }
1197   else
1198     {
1199       if (SPEC_USIGN (val->type))
1200         SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) %
1201           (TYPE_UWORD) floatFromVal (rval);
1202       else
1203         SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) %
1204           (TYPE_WORD) floatFromVal (rval);
1205     }
1206   return cheapestVal (val);
1207 }
1208
1209 /*------------------------------------------------------------------*/
1210 /* valPlus - Addition constants                                     */
1211 /*------------------------------------------------------------------*/
1212 value *
1213 valPlus (value * lval, value * rval)
1214 {
1215   value *val;
1216
1217   /* create a new value */
1218   val = newValue ();
1219   val->type = val->etype = newLink (SPECIFIER);
1220   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1221                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1222   SPEC_SCLS  (val->type) = S_LITERAL;   /* will remain literal */
1223   SPEC_LONG  (val->type) = (SPEC_LONG  (lval->etype) | SPEC_LONG  (rval->etype));
1224   SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1225                                                     rval->etype,
1226                                                     TRUE));
1227   if (IS_FLOAT (val->type))
1228     SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1229   else  if (SPEC_LONG (val->type))
1230     {
1231       if (SPEC_USIGN (val->type))
1232         SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) +
1233          (TYPE_UDWORD) floatFromVal (rval);
1234       else
1235         SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) +
1236           (TYPE_DWORD) floatFromVal (rval);
1237     }
1238   else
1239     {
1240       if (SPEC_USIGN (val->type))
1241         SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) +
1242           (TYPE_UWORD) floatFromVal (rval);
1243       else
1244         SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) +
1245           (TYPE_WORD) floatFromVal (rval);
1246     }
1247   return cheapestVal (val);
1248 }
1249
1250 /*------------------------------------------------------------------*/
1251 /* valMinus - Addition constants                                    */
1252 /*------------------------------------------------------------------*/
1253 value *
1254 valMinus (value * lval, value * rval)
1255 {
1256   value *val;
1257
1258   /* create a new value */
1259   val = newValue ();
1260   val->type = val->etype = newLink (SPECIFIER);
1261   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1262                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1263   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1264   SPEC_LONG  (val->type) = (SPEC_LONG  (lval->etype) | SPEC_LONG  (rval->etype));
1265   SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1266                                                     rval->etype,
1267                                                     FALSE));
1268   if (IS_FLOAT (val->type))
1269     SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1270   else  if (SPEC_LONG (val->type))
1271     {
1272       if (SPEC_USIGN (val->type))
1273         SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) -
1274           (TYPE_UDWORD) floatFromVal (rval);
1275       else
1276         SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
1277           (TYPE_DWORD) floatFromVal (rval);
1278     }
1279   else
1280    {
1281      if (SPEC_USIGN (val->type))
1282        SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) -
1283          (TYPE_UWORD) floatFromVal (rval);
1284      else
1285        SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) -
1286          (TYPE_WORD) floatFromVal (rval);
1287     }
1288   return cheapestVal (val);
1289 }
1290
1291 /*------------------------------------------------------------------*/
1292 /* valShift - Shift left or right                                   */
1293 /*------------------------------------------------------------------*/
1294 value *
1295 valShift (value * lval, value * rval, int lr)
1296 {
1297   value *val;
1298
1299   /* create a new value */
1300   val = newValue ();
1301   val->type = val->etype = newIntLink ();
1302   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1303   SPEC_NOUN  (val->etype) = V_INT;
1304   /* 'unsigned char' promotes to 'signed int' */
1305   if (!IS_CHAR (lval->etype))
1306     SPEC_USIGN (val->type) = SPEC_USIGN (lval->etype);
1307   SPEC_LONG (val->type) = SPEC_LONG (lval->etype);
1308
1309   if (getSize (val->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) &&
1310        /* left shift */
1311       (lr ||
1312         /* right shift and unsigned */
1313        (!lr && SPEC_USIGN (rval->type))))
1314     {
1315       werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1316     }
1317
1318   if (SPEC_LONG (val->type))
1319     {
1320       if (SPEC_USIGN (val->type))
1321         {
1322           SPEC_CVAL (val->type).v_ulong = lr ?
1323             (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1324             (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1325         }
1326       else
1327         {
1328           SPEC_CVAL (val->type).v_long = lr ?
1329             (TYPE_DWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1330             (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1331         }
1332     }
1333   else
1334     {
1335       if (SPEC_USIGN (val->type))
1336         {
1337           SPEC_CVAL (val->type).v_uint = lr ?
1338             (TYPE_UWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1339             (TYPE_UWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1340         }
1341       else
1342         {
1343           SPEC_CVAL (val->type).v_int = lr ?
1344             (TYPE_WORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1345             (TYPE_WORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1346         }
1347     }
1348   return cheapestVal (val);
1349 }
1350
1351 /*------------------------------------------------------------------*/
1352 /* valCompare- Compares two literal                                 */
1353 /*------------------------------------------------------------------*/
1354 value *
1355 valCompare (value * lval, value * rval, int ctype)
1356 {
1357   value *val;
1358
1359   /* create a new value */
1360   val = newValue ();
1361   val->type = val->etype = newCharLink ();
1362   val->type->class = SPECIFIER;
1363   SPEC_NOUN (val->type) = V_CHAR;       /* type is char */
1364   SPEC_USIGN (val->type) = 1;
1365   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1366
1367   switch (ctype)
1368     {
1369     case '<':
1370       SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1371       break;
1372
1373     case '>':
1374       SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1375       break;
1376
1377     case LE_OP:
1378       SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1379       break;
1380
1381     case GE_OP:
1382       SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1383       break;
1384
1385     case EQ_OP:
1386       if (SPEC_NOUN(lval->type) == V_FLOAT ||
1387           SPEC_NOUN(rval->type) == V_FLOAT)
1388         {
1389           SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1390         }
1391       else
1392         {
1393           /* integrals: ignore signedness */
1394           TYPE_UDWORD l, r;
1395
1396           l = (TYPE_UDWORD) floatFromVal (lval);
1397           r = (TYPE_UDWORD) floatFromVal (rval);
1398           /* In order to correctly compare 'signed int' and 'unsigned int' it's
1399              neccessary to strip them to 16 bit.
1400              Literals are reduced to their cheapest type, therefore left and
1401              right might have different types. It's neccessary to find a
1402              common type: int (used for char too) or long */
1403           if (!IS_LONG (lval->etype) &&
1404               !IS_LONG (rval->etype))
1405             {
1406               r = (TYPE_UWORD) r;
1407               l = (TYPE_UWORD) l;
1408             }
1409           SPEC_CVAL (val->type).v_int = l == r;
1410         }
1411       break;
1412     case NE_OP:
1413       if (SPEC_NOUN(lval->type) == V_FLOAT ||
1414           SPEC_NOUN(rval->type) == V_FLOAT)
1415         {
1416           SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1417         }
1418       else
1419         {
1420           /* integrals: ignore signedness */
1421           TYPE_UDWORD l, r;
1422
1423           l = (TYPE_UDWORD) floatFromVal (lval);
1424           r = (TYPE_UDWORD) floatFromVal (rval);
1425           /* In order to correctly compare 'signed int' and 'unsigned int' it's
1426              neccessary to strip them to 16 bit.
1427              Literals are reduced to their cheapest type, therefore left and
1428              right might have different types. It's neccessary to find a
1429              common type: int (used for char too) or long */
1430           if (!IS_LONG (lval->etype) &&
1431               !IS_LONG (rval->etype))
1432             {
1433               r = (TYPE_UWORD) r;
1434               l = (TYPE_UWORD) l;
1435             }
1436           SPEC_CVAL (val->type).v_int = l != r;
1437         }
1438       break;
1439
1440     }
1441
1442   return val;
1443 }
1444
1445 /*------------------------------------------------------------------*/
1446 /* valBitwise - Bitwise operation                                   */
1447 /*------------------------------------------------------------------*/
1448 value *
1449 valBitwise (value * lval, value * rval, int op)
1450 {
1451   value *val;
1452
1453   /* create a new value */
1454   val = newValue ();
1455   val->type = copyLinkChain (getSize(rval->type) > getSize(lval->type) ?
1456                              rval->type : lval->type);
1457   val->etype = getSpec (val->type);
1458
1459   switch (op)
1460     {
1461     case '&':
1462       if (SPEC_LONG (val->type))
1463         {
1464           if (SPEC_USIGN (val->type))
1465             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1466               (unsigned long) floatFromVal (rval);
1467           else
1468             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1469               (long) floatFromVal (rval);
1470         }
1471       else
1472         {
1473           if (SPEC_USIGN (val->type))
1474             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1475               (unsigned) floatFromVal (rval);
1476           else
1477             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1478         }
1479       break;
1480
1481     case '|':
1482       if (SPEC_LONG (val->type))
1483         {
1484           if (SPEC_USIGN (val->type))
1485             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1486               (unsigned long) floatFromVal (rval);
1487           else
1488             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1489               (long) floatFromVal (rval);
1490         }
1491       else
1492         {
1493           if (SPEC_USIGN (val->type))
1494             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1495               (unsigned) floatFromVal (rval);
1496           else
1497             SPEC_CVAL (val->type).v_int =
1498               (int) floatFromVal (lval) | (int) floatFromVal (rval);
1499         }
1500
1501       break;
1502
1503     case '^':
1504       if (SPEC_LONG (val->type))
1505         {
1506           if (SPEC_USIGN (val->type))
1507             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1508               (unsigned long) floatFromVal (rval);
1509           else
1510             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1511               (long) floatFromVal (rval);
1512         }
1513       else
1514         {
1515           if (SPEC_USIGN (val->type))
1516             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1517               (unsigned) floatFromVal (rval);
1518           else
1519             SPEC_CVAL (val->type).v_int =
1520               (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1521         }
1522       break;
1523     }
1524
1525   return cheapestVal(val);
1526 }
1527
1528 /*------------------------------------------------------------------*/
1529 /* valAndOr   - Generates code for and / or operation               */
1530 /*------------------------------------------------------------------*/
1531 value *
1532 valLogicAndOr (value * lval, value * rval, int op)
1533 {
1534   value *val;
1535
1536   /* create a new value */
1537   val = newValue ();
1538   val->type = val->etype = newCharLink ();
1539   val->type->class = SPECIFIER;
1540   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1541   SPEC_USIGN (val->type) = 0;
1542
1543   switch (op)
1544     {
1545     case AND_OP:
1546       SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1547       break;
1548
1549     case OR_OP:
1550       SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1551       break;
1552     }
1553
1554
1555   return val;
1556 }
1557
1558 /*------------------------------------------------------------------*/
1559 /* valCastLiteral - casts a literal value to another type           */
1560 /*------------------------------------------------------------------*/
1561 value *
1562 valCastLiteral (sym_link * dtype, double fval)
1563 {
1564   value *val;
1565   TYPE_UDWORD l = (TYPE_UDWORD)fval;
1566
1567   if (!dtype)
1568     return NULL;
1569
1570   val = newValue ();
1571   val->etype = getSpec (val->type = copyLinkChain (dtype));
1572   SPEC_SCLS (val->etype) = S_LITERAL;
1573
1574   /* if it is not a specifier then we can assume that */
1575   /* it will be an unsigned long                      */
1576   if (!IS_SPEC (val->type)) {
1577       SPEC_CVAL (val->etype).v_ulong = l;
1578       return val;
1579   }
1580
1581   if (SPEC_NOUN (val->etype) == V_FLOAT)
1582       SPEC_CVAL (val->etype).v_float = fval;
1583   else if (SPEC_NOUN (val->etype) == V_CHAR) {
1584       if (SPEC_USIGN (val->etype))
1585           SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1586       else
1587           SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1588   } else {
1589       if (SPEC_LONG (val->etype)) {
1590           if (SPEC_USIGN (val->etype))
1591               SPEC_CVAL (val->etype).v_ulong = (TYPE_UDWORD) l;
1592           else
1593               SPEC_CVAL (val->etype).v_long = (TYPE_DWORD) l;
1594       } else {
1595           if (SPEC_USIGN (val->etype))
1596               SPEC_CVAL (val->etype).v_uint = (TYPE_UWORD)l;
1597           else
1598               SPEC_CVAL (val->etype).v_int = (TYPE_WORD)l;
1599       }
1600   }
1601   return val;
1602 }
1603
1604 /*------------------------------------------------------------------*/
1605 /* getNelements - determines # of elements from init list           */
1606 /*------------------------------------------------------------------*/
1607 int
1608 getNelements (sym_link * type, initList * ilist)
1609 {
1610   int i;
1611
1612   if (!ilist)
1613     return 0;
1614
1615   if (ilist->type == INIT_DEEP)
1616     ilist = ilist->init.deep;
1617
1618   /* if type is a character array and there is only one
1619      (string) initialiser then get the length of the string */
1620   if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1621     {
1622       ast *iast = ilist->init.node;
1623       value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1624       if (!v)
1625         {
1626           werror (E_CONST_EXPECTED);
1627           return 0;
1628         }
1629
1630       if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1631         // yep, it's a string
1632         {
1633           return DCL_ELEM (v->type);
1634         }
1635     }
1636
1637   i = 0;
1638   while (ilist)
1639     {
1640       i++;
1641       ilist = ilist->next;
1642     }
1643   return i;
1644 }
1645
1646 /*-----------------------------------------------------------------*/
1647 /* valForArray - returns a value with name of array index          */
1648 /*-----------------------------------------------------------------*/
1649 value *
1650 valForArray (ast * arrExpr)
1651 {
1652   value *val, *lval = NULL;
1653   char buffer[128];
1654   int size = getSize (arrExpr->left->ftype->next);
1655   /* if the right or left is an array
1656      resolve it first */
1657   if (IS_AST_OP (arrExpr->left))
1658     {
1659       if (arrExpr->left->opval.op == '[')
1660         lval = valForArray (arrExpr->left);
1661       else if (arrExpr->left->opval.op == '.')
1662         lval = valForStructElem (arrExpr->left->left,
1663                                  arrExpr->left->right);
1664       else if (arrExpr->left->opval.op == PTR_OP &&
1665                IS_ADDRESS_OF_OP (arrExpr->left->left))
1666         lval = valForStructElem (arrExpr->left->left->left,
1667                                  arrExpr->left->right);
1668       else
1669         return NULL;
1670
1671     }
1672   else if (!IS_AST_SYM_VALUE (arrExpr->left))
1673     return NULL;
1674
1675   if (!IS_AST_LIT_VALUE (arrExpr->right))
1676     return NULL;
1677
1678   val = newValue ();
1679   if (!lval)
1680     {
1681         SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1682     }
1683   else
1684     {
1685         SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1686     }
1687
1688   SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1689            (int) AST_LIT_VALUE (arrExpr->right) * size);
1690
1691   val->type = newLink (DECLARATOR);
1692   if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1693     DCL_TYPE (val->type) = CPOINTER;
1694   else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1695     DCL_TYPE (val->type) = FPOINTER;
1696   else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1697     DCL_TYPE (val->type) = PPOINTER;
1698   else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1699     DCL_TYPE (val->type) = IPOINTER;
1700   else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1701     DCL_TYPE (val->type) = EEPPOINTER;
1702   else
1703     DCL_TYPE (val->type) = POINTER;
1704   val->type->next = arrExpr->left->ftype;
1705   val->etype = getSpec (val->type);
1706   return val;
1707 }
1708
1709 /*-----------------------------------------------------------------*/
1710 /* valForStructElem - returns value with name of struct element    */
1711 /*-----------------------------------------------------------------*/
1712 value *
1713 valForStructElem (ast * structT, ast * elemT)
1714 {
1715   value *val, *lval = NULL;
1716   char buffer[128];
1717   symbol *sym;
1718
1719   /* left could be furthur derefed */
1720   if (IS_AST_OP (structT))
1721     {
1722       if (structT->opval.op == '[')
1723         lval = valForArray (structT);
1724       else if (structT->opval.op == '.')
1725         lval = valForStructElem (structT->left, structT->right);
1726       else if (structT->opval.op == PTR_OP &&
1727                IS_ADDRESS_OF_OP (structT->left))
1728         lval = valForStructElem (structT->left->left,
1729                                  structT->right);
1730       else
1731         return NULL;
1732     }
1733
1734   if (!IS_AST_SYM_VALUE (elemT))
1735     return NULL;
1736
1737   if (!IS_STRUCT (structT->etype))
1738     return NULL;
1739
1740   if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1741                                AST_SYMBOL (elemT))) == NULL)
1742     {
1743       return NULL;
1744     }
1745
1746   val = newValue ();
1747   if (!lval)
1748     {
1749         SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1750     }
1751   else
1752     {
1753         SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1754     }
1755
1756   SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1757            (int) sym->offset);
1758
1759   val->type = newLink (DECLARATOR);
1760   if (SPEC_SCLS (structT->etype) == S_CODE)
1761     DCL_TYPE (val->type) = CPOINTER;
1762   else if (SPEC_SCLS (structT->etype) == S_XDATA)
1763     DCL_TYPE (val->type) = FPOINTER;
1764   else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1765     DCL_TYPE (val->type) = PPOINTER;
1766   else if (SPEC_SCLS (structT->etype) == S_IDATA)
1767     DCL_TYPE (val->type) = IPOINTER;
1768   else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1769     DCL_TYPE (val->type) = EEPPOINTER;
1770   else
1771     DCL_TYPE (val->type) = POINTER;
1772   val->type->next = sym->type;
1773   val->etype = getSpec (val->type);
1774   return val;
1775 }
1776
1777 /*-----------------------------------------------------------------*/
1778 /* valForCastAggr - will return value for a cast of an aggregate   */
1779 /*                  plus minus a constant                          */
1780 /*-----------------------------------------------------------------*/
1781 value *
1782 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1783 {
1784   value *val;
1785
1786   if (!IS_AST_SYM_VALUE (aexpr))
1787     return NULL;
1788   if (!IS_AST_LIT_VALUE (cnst))
1789     return NULL;
1790
1791   val = newValue ();
1792
1793   SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1794            AST_SYMBOL (aexpr)->rname, op,
1795            getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1796
1797   val->type = type;
1798   val->etype = getSpec (val->type);
1799   return val;
1800 }
1801
1802 /*-----------------------------------------------------------------*/
1803 /* valForCastAggr - will return value for a cast of an aggregate   */
1804 /*                  with no constant                               */
1805 /*-----------------------------------------------------------------*/
1806 value *
1807 valForCastArr (ast * aexpr, sym_link * type)
1808 {
1809   value *val;
1810
1811   if (!IS_AST_SYM_VALUE (aexpr))
1812     return NULL;
1813
1814   val = newValue ();
1815
1816   SNPRINTF (val->name, sizeof(val->name), "(%s)",
1817            AST_SYMBOL (aexpr)->rname);
1818
1819   val->type = type;
1820   val->etype = getSpec (val->type);
1821   return val;
1822 }