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