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