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