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