src/SDCCval.c (valMinus): fixed bug #826041
[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 no 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   /* both signed char and unsigned char are promoted to signed int */
1092   if (IS_CHAR (lval->etype))
1093     {
1094       SPEC_USIGN (lval->etype) = 0;
1095       SPEC_NOUN  (lval->etype) = V_INT;
1096     }
1097   if (IS_CHAR (rval->etype))
1098     {
1099       SPEC_USIGN (rval->etype) = 0;
1100       SPEC_NOUN  (rval->etype) = V_INT;
1101     }
1102   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1103   if (IS_FLOAT (val->type))
1104     SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1105       /* signed and unsigned mul are the same, as long as the precision of the
1106          result isn't bigger than the precision of the operands. */
1107   else if (SPEC_LONG (val->type))
1108     SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1109                                     (TYPE_UDWORD) floatFromVal (rval);
1110   else if (SPEC_USIGN (val->type)) /* unsigned */
1111     {
1112       TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1113                        (TYPE_UWORD) floatFromVal (rval);
1114
1115       SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1116       if (ul != (TYPE_UWORD) ul)
1117         werror (W_INT_OVL);
1118     }
1119   else /* int */
1120     {
1121       TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
1122                      (TYPE_WORD) floatFromVal (rval);
1123
1124       SPEC_CVAL (val->type).v_int = (TYPE_WORD) l;
1125       if (l != (TYPE_WORD) l)
1126         werror (W_INT_OVL);
1127     }
1128   return cheapestVal(val);
1129 }
1130
1131 /*------------------------------------------------------------------*/
1132 /* valDiv  - Divide   constants                                     */
1133 /*------------------------------------------------------------------*/
1134 value *
1135 valDiv (value * lval, value * rval)
1136 {
1137   value *val;
1138
1139   if (floatFromVal (rval) == 0)
1140     {
1141       werror (E_DIVIDE_BY_ZERO);
1142       return rval;
1143     }
1144
1145   /* create a new value */
1146   val = newValue ();
1147   val->type = val->etype = newLink(SPECIFIER);
1148   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1149                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1150   SPEC_SCLS (val->etype) = S_LITERAL;
1151   /* both signed char and unsigned char are promoted to signed int */
1152   if (IS_CHAR (lval->etype))
1153     {
1154       SPEC_USIGN (lval->etype) = 0;
1155       SPEC_NOUN  (lval->etype) = V_INT;
1156     }
1157   if (IS_CHAR (rval->etype))
1158     {
1159       SPEC_USIGN (rval->etype) = 0;
1160       SPEC_NOUN  (rval->etype) = V_INT;
1161     }
1162   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1163   SPEC_LONG  (val->type) = (SPEC_LONG  (lval->etype) | SPEC_LONG  (rval->etype));
1164
1165   if (IS_FLOAT (val->type))
1166     SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1167   else
1168     {
1169       if (SPEC_LONG (val->type))
1170         {
1171           if (SPEC_USIGN (val->type))
1172             SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
1173               (TYPE_UDWORD) floatFromVal (rval);
1174           else
1175             SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
1176               (TYPE_DWORD) floatFromVal (rval);
1177         }
1178       else
1179         {
1180           if (SPEC_USIGN (val->type)) {
1181             SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
1182               (TYPE_UWORD) floatFromVal (rval);
1183           } else {
1184             SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
1185               (TYPE_WORD) floatFromVal (rval);
1186           }
1187         }
1188     }
1189   return cheapestVal(val);
1190 }
1191
1192 /*------------------------------------------------------------------*/
1193 /* valMod  - Modulus  constants                                     */
1194 /*------------------------------------------------------------------*/
1195 value *
1196 valMod (value * lval, value * rval)
1197 {
1198   value *val;
1199
1200   /* create a new value */
1201   val = newValue ();
1202   val->type = val->etype = newLink (SPECIFIER);
1203   SPEC_NOUN (val->type) = V_INT;        /* type is int */
1204   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1205   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1206   SPEC_LONG  (val->type) = (SPEC_LONG  (lval->etype) | SPEC_LONG  (rval->etype));
1207
1208   if (SPEC_LONG (val->type))
1209     {
1210       if (SPEC_USIGN (val->type))
1211         SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) %
1212           (TYPE_UDWORD) floatFromVal (rval);
1213       else
1214         SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) %
1215           (TYPE_DWORD) floatFromVal (rval);
1216     }
1217   else
1218     {
1219       if (SPEC_USIGN (val->type)) {
1220         SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) %
1221           (TYPE_UWORD) floatFromVal (rval);
1222       } else {
1223         SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) %
1224           (TYPE_WORD) floatFromVal (rval);
1225       }
1226     }
1227
1228   return cheapestVal(val);
1229 }
1230
1231 /*------------------------------------------------------------------*/
1232 /* valPlus - Addition constants                                     */
1233 /*------------------------------------------------------------------*/
1234 value *
1235 valPlus (value * lval, value * rval)
1236 {
1237   value *val;
1238
1239   /* create a new value */
1240   val = newValue ();
1241   val->type = val->etype = newLink (SPECIFIER);
1242   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1243                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1244   SPEC_SCLS  (val->type) = S_LITERAL;   /* will remain literal */
1245   SPEC_LONG  (val->type) = (SPEC_LONG  (lval->etype) | SPEC_LONG  (rval->etype));
1246   /* both signed char and unsigned char are promoted to signed int */
1247   if (IS_CHAR (lval->etype))
1248     {
1249       SPEC_USIGN (lval->etype) = 0;
1250       SPEC_NOUN  (lval->etype) = V_INT;
1251     }
1252   if (IS_CHAR (rval->etype))
1253     {
1254       SPEC_USIGN (rval->etype) = 0;
1255       SPEC_NOUN  (rval->etype) = V_INT;
1256     }
1257   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1258   if (IS_FLOAT (val->type))
1259     SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1260   else
1261     {
1262       if (SPEC_USIGN (val->type))
1263         SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) +
1264           (TYPE_UDWORD) floatFromVal (rval);
1265       else
1266         SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) +
1267           (TYPE_DWORD) floatFromVal (rval);
1268     }
1269   return cheapestVal(val);
1270 }
1271
1272 /*------------------------------------------------------------------*/
1273 /* valMinus - Addition constants                                    */
1274 /*------------------------------------------------------------------*/
1275 value *
1276 valMinus (value * lval, value * rval)
1277 {
1278   value *val;
1279
1280   /* create a new value */
1281   val = newValue ();
1282   val->type = val->etype = newLink (SPECIFIER);
1283   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1284                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1285   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1286   SPEC_LONG  (val->type) = (SPEC_LONG  (lval->etype) | SPEC_LONG  (rval->etype));
1287   /* both signed char and unsigned char are promoted to signed int */
1288   if (IS_CHAR (lval->etype))
1289     {
1290       SPEC_USIGN (lval->etype) = 0;
1291       SPEC_NOUN  (lval->etype) = V_INT;
1292     }
1293   if (IS_CHAR (rval->etype))
1294     {
1295       SPEC_USIGN (rval->etype) = 0;
1296       SPEC_NOUN  (rval->etype) = V_INT;
1297     }
1298   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1299   if (IS_FLOAT (val->type))
1300     SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1301   else
1302     {
1303       if (SPEC_USIGN (val->type))
1304         SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) -
1305           (TYPE_UDWORD) floatFromVal (rval);
1306       else
1307         SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
1308           (TYPE_DWORD) floatFromVal (rval);
1309     }
1310   return cheapestVal(val);
1311 }
1312
1313 /*------------------------------------------------------------------*/
1314 /* valShift - Shift left or right                                   */
1315 /*------------------------------------------------------------------*/
1316 value *
1317 valShift (value * lval, value * rval, int lr)
1318 {
1319   value *val;
1320
1321   /* create a new value */
1322   val = newValue ();
1323   val->type = val->etype = newIntLink ();
1324   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1325   SPEC_NOUN  (val->etype) = V_INT;
1326   /* 'unsigned char' promotes to 'signed int' */
1327   if (!IS_CHAR (lval->etype))
1328     SPEC_USIGN (val->type) = SPEC_USIGN (lval->etype);
1329   SPEC_LONG (val->type) = SPEC_LONG (lval->etype);
1330
1331   if (SPEC_USIGN (val->type))
1332     {
1333       SPEC_CVAL (val->type).v_ulong = lr ?
1334         (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UWORD) floatFromVal (rval) : \
1335         (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UWORD) floatFromVal (rval);
1336     }
1337   else
1338     {
1339       SPEC_CVAL (val->type).v_long = lr ?
1340         (TYPE_DWORD) floatFromVal (lval) << (TYPE_UWORD) floatFromVal (rval) : \
1341         (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UWORD) floatFromVal (rval);
1342     }
1343   return cheapestVal(val);
1344 }
1345
1346 /*------------------------------------------------------------------*/
1347 /* valCompare- Compares two literal                                 */
1348 /*------------------------------------------------------------------*/
1349 value *
1350 valCompare (value * lval, value * rval, int ctype)
1351 {
1352   value *val;
1353
1354   /* create a new value */
1355   val = newValue ();
1356   val->type = val->etype = newCharLink ();
1357   val->type->class = SPECIFIER;
1358   SPEC_NOUN (val->type) = V_CHAR;       /* type is char */
1359   SPEC_USIGN (val->type) = 1;
1360   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1361
1362   switch (ctype)
1363     {
1364     case '<':
1365       SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1366       break;
1367
1368     case '>':
1369       SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1370       break;
1371
1372     case LE_OP:
1373       SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1374       break;
1375
1376     case GE_OP:
1377       SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1378       break;
1379
1380     case EQ_OP:
1381       if (SPEC_NOUN(lval->type) == V_FLOAT ||
1382           SPEC_NOUN(rval->type) == V_FLOAT)
1383         {
1384           SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1385         }
1386       else
1387         {
1388           /* integrals: ignore signedness */
1389           TYPE_UDWORD l, r;
1390
1391           l = (TYPE_UDWORD) floatFromVal (lval);
1392           if (SPEC_NOUN(lval->type) == V_CHAR)
1393             l &= 0xffff; /* promote to int */
1394           else if (!SPEC_LONG (lval->type))
1395             l &= 0xffff;
1396
1397           r = (TYPE_UDWORD) floatFromVal (rval);
1398           if (SPEC_NOUN(rval->type) == V_CHAR)
1399             r &= 0xffff; /* promote to int */
1400           else if (!SPEC_LONG (rval->type))
1401             r &= 0xffff;
1402
1403           SPEC_CVAL (val->type).v_int = l == r;
1404         }
1405       break;
1406     case NE_OP:
1407       if (SPEC_NOUN(lval->type) == V_FLOAT ||
1408           SPEC_NOUN(rval->type) == V_FLOAT)
1409         {
1410           SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1411         }
1412       else
1413         {
1414           /* integrals: ignore signedness */
1415           TYPE_UDWORD l, r;
1416
1417           l = (TYPE_UDWORD) floatFromVal (lval);
1418           if (SPEC_NOUN(lval->type) == V_CHAR)
1419             l &= 0xffff; /* promote to int */
1420           else if (!SPEC_LONG (lval->type))
1421             l &= 0xffff;
1422
1423           r = (TYPE_UDWORD) floatFromVal (rval);
1424           if (SPEC_NOUN(rval->type) == V_CHAR)
1425             r &= 0xffff; /* promote to int */
1426           else if (!SPEC_LONG (rval->type))
1427             r &= 0xffff;
1428
1429           SPEC_CVAL (val->type).v_int = l != r;
1430         }
1431       break;
1432
1433     }
1434
1435   return val;
1436 }
1437
1438 /*------------------------------------------------------------------*/
1439 /* valBitwise - Bitwise operation                                   */
1440 /*------------------------------------------------------------------*/
1441 value *
1442 valBitwise (value * lval, value * rval, int op)
1443 {
1444   value *val;
1445
1446   /* create a new value */
1447   val = newValue ();
1448   val->type = copyLinkChain (getSize(rval->type) > getSize(lval->type) ?
1449                              rval->type : lval->type);
1450   val->etype = getSpec (val->type);
1451
1452   switch (op)
1453     {
1454     case '&':
1455       if (SPEC_LONG (val->type))
1456         {
1457           if (SPEC_USIGN (val->type))
1458             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1459               (unsigned long) floatFromVal (rval);
1460           else
1461             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1462               (long) floatFromVal (rval);
1463         }
1464       else
1465         {
1466           if (SPEC_USIGN (val->type))
1467             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1468               (unsigned) floatFromVal (rval);
1469           else
1470             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1471         }
1472       break;
1473
1474     case '|':
1475       if (SPEC_LONG (val->type))
1476         {
1477           if (SPEC_USIGN (val->type))
1478             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1479               (unsigned long) floatFromVal (rval);
1480           else
1481             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1482               (long) floatFromVal (rval);
1483         }
1484       else
1485         {
1486           if (SPEC_USIGN (val->type))
1487             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1488               (unsigned) floatFromVal (rval);
1489           else
1490             SPEC_CVAL (val->type).v_int =
1491               (int) floatFromVal (lval) | (int) floatFromVal (rval);
1492         }
1493
1494       break;
1495
1496     case '^':
1497       if (SPEC_LONG (val->type))
1498         {
1499           if (SPEC_USIGN (val->type))
1500             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1501               (unsigned long) floatFromVal (rval);
1502           else
1503             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1504               (long) floatFromVal (rval);
1505         }
1506       else
1507         {
1508           if (SPEC_USIGN (val->type))
1509             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1510               (unsigned) floatFromVal (rval);
1511           else
1512             SPEC_CVAL (val->type).v_int =
1513               (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1514         }
1515       break;
1516     }
1517
1518   return cheapestVal(val);
1519 }
1520
1521 /*------------------------------------------------------------------*/
1522 /* valAndOr   - Generates code for and / or operation               */
1523 /*------------------------------------------------------------------*/
1524 value *
1525 valLogicAndOr (value * lval, value * rval, int op)
1526 {
1527   value *val;
1528
1529   /* create a new value */
1530   val = newValue ();
1531   val->type = val->etype = newCharLink ();
1532   val->type->class = SPECIFIER;
1533   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1534   SPEC_USIGN (val->type) = 0;
1535
1536   switch (op)
1537     {
1538     case AND_OP:
1539       SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1540       break;
1541
1542     case OR_OP:
1543       SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1544       break;
1545     }
1546
1547
1548   return val;
1549 }
1550
1551 /*------------------------------------------------------------------*/
1552 /* valCastLiteral - casts a literal value to another type           */
1553 /*------------------------------------------------------------------*/
1554 value *
1555 valCastLiteral (sym_link * dtype, double fval)
1556 {
1557   value *val;
1558   TYPE_UDWORD l = (TYPE_UDWORD)fval;
1559
1560   if (!dtype)
1561     return NULL;
1562
1563   val = newValue ();
1564   val->etype = getSpec (val->type = copyLinkChain (dtype));
1565   SPEC_SCLS (val->etype) = S_LITERAL;
1566
1567   /* if it is not a specifier then we can assume that */
1568   /* it will be an unsigned long                      */
1569   if (!IS_SPEC (val->type)) {
1570       SPEC_CVAL (val->etype).v_ulong = l;
1571       return val;
1572   }
1573
1574   if (SPEC_NOUN (val->etype) == V_FLOAT)
1575       SPEC_CVAL (val->etype).v_float = fval;
1576   else if (SPEC_NOUN (val->etype) == V_CHAR) {
1577       if (SPEC_USIGN (val->etype))
1578           SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1579       else
1580           SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1581   } else {
1582       if (SPEC_LONG (val->etype)) {
1583           if (SPEC_USIGN (val->etype))
1584               SPEC_CVAL (val->etype).v_ulong = (TYPE_UDWORD) l;
1585           else
1586               SPEC_CVAL (val->etype).v_long = (TYPE_DWORD) l;
1587       } else {
1588           if (SPEC_USIGN (val->etype))
1589               SPEC_CVAL (val->etype).v_uint = (TYPE_UWORD)l;
1590           else
1591               SPEC_CVAL (val->etype).v_int = (TYPE_WORD)l;
1592       }
1593   }
1594   return val;
1595 }
1596
1597 /*------------------------------------------------------------------*/
1598 /* getNelements - determines # of elements from init list           */
1599 /*------------------------------------------------------------------*/
1600 int
1601 getNelements (sym_link * type, initList * ilist)
1602 {
1603   int i;
1604
1605   if (!ilist)
1606     return 0;
1607
1608   if (ilist->type == INIT_DEEP)
1609     ilist = ilist->init.deep;
1610
1611   /* if type is a character array and there is only one
1612      (string) initialiser then get the length of the string */
1613   if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1614     {
1615       ast *iast = ilist->init.node;
1616       value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1617       if (!v)
1618         {
1619           werror (E_CONST_EXPECTED);
1620           return 0;
1621         }
1622
1623       if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1624         // yep, it's a string
1625         {
1626           return DCL_ELEM (v->type);
1627         }
1628     }
1629
1630   i = 0;
1631   while (ilist)
1632     {
1633       i++;
1634       ilist = ilist->next;
1635     }
1636   return i;
1637 }
1638
1639 /*-----------------------------------------------------------------*/
1640 /* valForArray - returns a value with name of array index          */
1641 /*-----------------------------------------------------------------*/
1642 value *
1643 valForArray (ast * arrExpr)
1644 {
1645   value *val, *lval = NULL;
1646   char buffer[128];
1647   int size = getSize (arrExpr->left->ftype->next);
1648   /* if the right or left is an array
1649      resolve it first */
1650   if (IS_AST_OP (arrExpr->left))
1651     {
1652       if (arrExpr->left->opval.op == '[')
1653         lval = valForArray (arrExpr->left);
1654       else if (arrExpr->left->opval.op == '.')
1655         lval = valForStructElem (arrExpr->left->left,
1656                                  arrExpr->left->right);
1657       else if (arrExpr->left->opval.op == PTR_OP &&
1658                IS_ADDRESS_OF_OP (arrExpr->left->left))
1659         lval = valForStructElem (arrExpr->left->left->left,
1660                                  arrExpr->left->right);
1661       else
1662         return NULL;
1663
1664     }
1665   else if (!IS_AST_SYM_VALUE (arrExpr->left))
1666     return NULL;
1667
1668   if (!IS_AST_LIT_VALUE (arrExpr->right))
1669     return NULL;
1670
1671   val = newValue ();
1672   if (!lval)
1673     {
1674         SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1675     }
1676   else
1677     {
1678         SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1679     }
1680
1681   SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1682            (int) AST_LIT_VALUE (arrExpr->right) * size);
1683
1684   val->type = newLink (DECLARATOR);
1685   if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1686     DCL_TYPE (val->type) = CPOINTER;
1687   else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1688     DCL_TYPE (val->type) = FPOINTER;
1689   else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1690     DCL_TYPE (val->type) = PPOINTER;
1691   else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1692     DCL_TYPE (val->type) = IPOINTER;
1693   else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1694     DCL_TYPE (val->type) = EEPPOINTER;
1695   else
1696     DCL_TYPE (val->type) = POINTER;
1697   val->type->next = arrExpr->left->ftype;
1698   val->etype = getSpec (val->type);
1699   return val;
1700 }
1701
1702 /*-----------------------------------------------------------------*/
1703 /* valForStructElem - returns value with name of struct element    */
1704 /*-----------------------------------------------------------------*/
1705 value *
1706 valForStructElem (ast * structT, ast * elemT)
1707 {
1708   value *val, *lval = NULL;
1709   char buffer[128];
1710   symbol *sym;
1711
1712   /* left could be furthur derefed */
1713   if (IS_AST_OP (structT))
1714     {
1715       if (structT->opval.op == '[')
1716         lval = valForArray (structT);
1717       else if (structT->opval.op == '.')
1718         lval = valForStructElem (structT->left, structT->right);
1719       else if (structT->opval.op == PTR_OP &&
1720                IS_ADDRESS_OF_OP (structT->left))
1721         lval = valForStructElem (structT->left->left,
1722                                  structT->right);
1723       else
1724         return NULL;
1725     }
1726
1727   if (!IS_AST_SYM_VALUE (elemT))
1728     return NULL;
1729
1730   if (!IS_STRUCT (structT->etype))
1731     return NULL;
1732
1733   if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1734                                AST_SYMBOL (elemT))) == NULL)
1735     {
1736       return NULL;
1737     }
1738
1739   val = newValue ();
1740   if (!lval)
1741     {
1742         SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1743     }
1744   else
1745     {
1746         SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1747     }
1748
1749   SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1750            (int) sym->offset);
1751
1752   val->type = newLink (DECLARATOR);
1753   if (SPEC_SCLS (structT->etype) == S_CODE)
1754     DCL_TYPE (val->type) = CPOINTER;
1755   else if (SPEC_SCLS (structT->etype) == S_XDATA)
1756     DCL_TYPE (val->type) = FPOINTER;
1757   else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1758     DCL_TYPE (val->type) = PPOINTER;
1759   else if (SPEC_SCLS (structT->etype) == S_IDATA)
1760     DCL_TYPE (val->type) = IPOINTER;
1761   else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1762     DCL_TYPE (val->type) = EEPPOINTER;
1763   else
1764     DCL_TYPE (val->type) = POINTER;
1765   val->type->next = sym->type;
1766   val->etype = getSpec (val->type);
1767   return val;
1768 }
1769
1770 /*-----------------------------------------------------------------*/
1771 /* valForCastAggr - will return value for a cast of an aggregate   */
1772 /*                  plus minus a constant                          */
1773 /*-----------------------------------------------------------------*/
1774 value *
1775 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1776 {
1777   value *val;
1778
1779   if (!IS_AST_SYM_VALUE (aexpr))
1780     return NULL;
1781   if (!IS_AST_LIT_VALUE (cnst))
1782     return NULL;
1783
1784   val = newValue ();
1785
1786   SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1787            AST_SYMBOL (aexpr)->rname, op,
1788            getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1789
1790   val->type = type;
1791   val->etype = getSpec (val->type);
1792   return val;
1793 }
1794
1795 /*-----------------------------------------------------------------*/
1796 /* valForCastAggr - will return value for a cast of an aggregate   */
1797 /*                  with no constant                               */
1798 /*-----------------------------------------------------------------*/
1799 value *
1800 valForCastArr (ast * aexpr, sym_link * type)
1801 {
1802   value *val;
1803
1804   if (!IS_AST_SYM_VALUE (aexpr))
1805     return NULL;
1806
1807   val = newValue ();
1808
1809   SNPRINTF (val->name, sizeof(val->name), "(%s)",
1810            AST_SYMBOL (aexpr)->rname);
1811
1812   val->type = type;
1813   val->etype = getSpec (val->type);
1814   return val;
1815 }