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