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