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