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