Change struct link to struct sym_link to avoid conflict with struct link in unistd.h
[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
31 int             cNestLevel ;
32
33 /*-----------------------------------------------------------------*/
34 /* newValue - allocates and returns a new value                    */
35 /*-----------------------------------------------------------------*/
36 value *newValue ()
37 {
38     value *val ;
39     
40     ALLOC(val,sizeof(value));
41     
42     return val ;
43 }
44
45 /*-----------------------------------------------------------------*/
46 /* newiList - new initializer list                                 */
47 /*-----------------------------------------------------------------*/
48 initList *newiList ( int type, void *ilist)
49 {
50     initList *nilist;
51     
52     
53     ALLOC(nilist,sizeof(initList));     
54     
55     nilist->type = type ;
56     nilist->lineno = yylineno ;
57     
58     switch (type)   {
59     case INIT_NODE :
60         nilist->init.node = (struct ast *) ilist ;
61         break ;
62         
63     case INIT_DEEP :
64         nilist->init.deep = (struct initList *) ilist ;
65         break ;
66     }
67     
68     return nilist ;
69 }
70
71 /*------------------------------------------------------------------*/
72 /* revinit   - reverses the initial values for a value  chain        */
73 /*------------------------------------------------------------------*/
74 initList *revinit   ( initList   *val)
75 {
76     initList  *prev  , *curr, *next ;
77     
78     if (!val)
79         return NULL ;
80     
81     prev = val ;
82     curr = val->next ;
83     
84     while (curr)   {
85         next = curr->next ;
86         curr->next = prev   ;
87         prev = curr ;
88         curr = next ;
89     }
90     val->next = (void *) NULL ;
91     return prev ;
92 }
93
94 /*------------------------------------------------------------------*/
95 /* copyIlist - copy initializer list                                */
96 /*------------------------------------------------------------------*/
97 initList *copyIlist (initList *src)
98 {
99     initList *dest = NULL;
100     
101     if (!src)
102         return NULL ;
103     
104     switch (src->type) {
105     case INIT_DEEP :
106         dest = newiList (INIT_DEEP,copyIlist (src->init.deep));
107         break;
108     case INIT_NODE :
109         dest = newiList (INIT_NODE,copyAst (src->init.node)) ;
110         break;
111     }
112     
113     if ( src->next )
114         dest->next = copyIlist(src->next);
115     
116     return dest ;
117 }
118
119 /*------------------------------------------------------------------*/
120 /* list2int - converts the first element of the list to value       */
121 /*------------------------------------------------------------------*/
122 double list2int (initList   *val)
123 {
124     initList *i = val;
125     
126     if ( i->type == INIT_DEEP )
127         return list2int (val->init.deep) ;
128     
129     return floatFromVal(constExprValue(val->init.node,TRUE));
130 }
131
132 /*------------------------------------------------------------------*/
133 /* list2val - converts the first element of the list to value       */
134 /*------------------------------------------------------------------*/
135 value *list2val (initList   *val)
136 {
137     if (!val)
138         return NULL;
139
140     if ( val->type == INIT_DEEP )
141         return list2val (val->init.deep) ;
142     
143     return constExprValue(val->init.node,TRUE);
144 }
145
146 /*------------------------------------------------------------------*/
147 /* list2expr - returns the first expression in the initializer list */
148 /*------------------------------------------------------------------*/
149 ast     *list2expr ( initList   *ilist)
150 {
151     if ( ilist->type == INIT_DEEP )
152         return list2expr (ilist->init.deep) ;
153     return ilist->init.node ;
154 }
155
156 /*------------------------------------------------------------------*/
157 /* resolveIvalSym - resolve symbols in initial values               */
158 /*------------------------------------------------------------------*/
159 void resolveIvalSym ( initList *ilist)
160 {
161     if ( ! ilist )
162         return ;
163     
164     if ( ilist->type == INIT_NODE )
165         ilist->init.node = decorateType(resolveSymbols (ilist->init.node));
166     
167     if ( ilist->type == INIT_DEEP )
168         resolveIvalSym (ilist->init.deep);
169     
170     resolveIvalSym (ilist->next);
171 }
172
173 /*-----------------------------------------------------------------*/
174 /* symbolVal - creates a value for a symbol                        */
175 /*-----------------------------------------------------------------*/
176 value *symbolVal ( symbol  *sym )
177 {
178     value *val ;
179     
180     if (!sym)
181         return NULL ;
182     
183     val = newValue();
184     val->sym = sym ;
185     
186     if ( sym->type ) {
187         val->type = sym->type;
188         val->etype= getSpec(val->type);
189     }
190     
191     if ( *sym->rname )
192         sprintf (val->name,"%s",sym->rname);
193     else
194         sprintf(val->name,"_%s",sym->name);
195     
196     
197     return val ;
198 }
199
200 /*-----------------------------------------------------------------*/
201 /* valueFromLit - creates a value from a literal                   */
202 /*-----------------------------------------------------------------*/
203 value *valueFromLit (float lit)
204 {
205     char buffer[50];
206     
207     if ( ( ((long) lit ) - lit ) == 0 ) {       
208         sprintf(buffer,"%ld",(long) lit);
209         return constVal (buffer);
210     }
211     
212     sprintf(buffer,"%f",lit);
213     return constFloatVal (buffer);
214 }
215
216 /*-----------------------------------------------------------------*/
217 /* constFloatVal - converts a FLOAT constant to value              */
218 /*-----------------------------------------------------------------*/
219 value *constFloatVal ( char *s )
220 {
221     value *val = newValue();
222     float sval;
223     
224     if(sscanf (s,"%f",&sval) != 1) {
225         werror(E_INVALID_FLOAT_CONST,s);
226         return constVal("0");
227     }
228     
229     val->type = val->etype = newLink();
230     val->type->class = SPECIFIER ;
231     SPEC_NOUN(val->type) = V_FLOAT ;
232     SPEC_SCLS(val->type) = S_LITERAL;
233     SPEC_CVAL(val->type).v_float = sval;
234     
235     return val;
236 }
237
238 /*-----------------------------------------------------------------*/
239 /* constVal - converts a INTEGER constant into a value             */
240 /*-----------------------------------------------------------------*/
241 value *constVal   (char *s)
242 {
243     value *val ;
244     short hex = 0 , octal = 0 ;
245     char  scanFmt[10] ;
246     int  scI = 0 ;
247     unsigned long sval ;
248     
249     val = newValue() ;        /* alloc space for value   */
250     
251     val->type = val->etype = newLink() ; /* create the spcifier */
252     val->type->class    = SPECIFIER ;
253     SPEC_NOUN(val->type) =  V_INT ;
254     SPEC_SCLS(val->type) =  S_LITERAL ;
255     
256     /* set the _unsigned flag if 'uU' found */
257     if (strchr(s,'u') || strchr(s,'U'))
258         SPEC_USIGN(val->type) = 1;
259     
260     /* set the _long flag if 'lL' is found */
261     if (strchr(s,'l') || strchr(s,'L'))
262         SPEC_LONG(val->type) = 1;
263     
264     hex = ((strchr(s,'x') || strchr(s,'X')) ? 1 : 0) ;
265     
266     /* set the octal flag   */
267     if (!hex && *s == '0' && *(s+1) )
268         octal = 1 ;
269     
270     /* create the scan string */
271     scanFmt[scI++] = '%' ;
272     
273     if (octal)
274         scanFmt[scI++] = 'o' ;
275     else
276         if (hex)
277             scanFmt[scI++] = 'x' ;
278         else
279             if (SPEC_USIGN(val->type))
280                 scanFmt[scI++] = 'u' ;
281             else
282                 scanFmt[scI++] = 'd' ;
283     
284     scanFmt[scI++] = '\0' ;
285     
286     /* if hex or octal then set the unsigned flag   */
287     if ( hex || octal ) {
288         SPEC_USIGN(val->type) = 1 ;
289         sscanf(s,scanFmt,&sval);
290     } else
291         sval = atol(s);
292     
293     
294     if (SPEC_LONG(val->type) || sval > 32768) {
295         if (SPEC_USIGN(val->type))
296             SPEC_CVAL(val->type).v_ulong = sval ;
297         else
298             SPEC_CVAL(val->type).v_long = sval ;
299         SPEC_LONG(val->type) = 1;
300     }
301     else {
302         if (SPEC_USIGN(val->type))
303             SPEC_CVAL(val->type).v_uint = sval ;
304         else
305             SPEC_CVAL(val->type).v_int = sval ;
306     }
307
308     // check the size and make it a short if required
309     if (sval < 256 )
310         SPEC_SHORT(val->etype) = 1;                     
311     
312     return val ;
313     
314 }
315
316 /*------------------------------------------------------------------*/
317 /* copyStr - copies src to dest ignoring leading & trailing \"s     */
318 /*------------------------------------------------------------------*/
319 void    copyStr (char *dest, char *src )
320 {
321     unsigned int x;
322     while (*src) {
323         if (*src == '\"' ) 
324             src++ ;
325         else
326             if ( *src == '\\' ) {
327                 src++ ;
328                 switch (*src) {
329                 case 'n'        :
330                     *dest++ = '\n';
331                     break ;
332                 case 't'        :
333                     *dest++ = '\t';
334                     break;
335                 case 'v'        :
336                     *dest++ = '\v';
337                     break;
338                 case 'b'        :
339                     *dest++ = '\b';
340                     break;
341                 case 'r'        :
342                     *dest++ = '\r';
343                     break;
344                 case 'f'        :
345                     *dest++ = '\f';
346                     break;
347                 case 'a' :
348                     *dest++ = '\a';
349                     break;
350                 case '0':
351                     /* embedded octal or hex constant */
352                     if (*(src+1) == 'x' ||
353                         *(src+1) == 'X') {
354                         x = strtol(src,&src,16);
355                         *dest++ = x;
356                     } else {
357                         /* must be octal */
358                         x = strtol(src,&src,8);
359                         *dest++ = x;
360                     }
361                     break;
362                         
363                 case '\\':
364                     *dest++ = '\\';
365                     break;
366                 case '\?':
367                     *dest++ = '\?';
368                     break;
369                 case '\'':
370                     *dest++ = '\'';
371                     break;
372                 case '\"':
373                     *dest++ = '\"';
374                     break;                  
375                 default :
376                     *dest++ = *src ;
377                 }
378                 src++ ;
379             }
380             else
381                 *dest++ = *src++ ;
382     }
383     
384     *dest = '\0' ;
385 }
386
387 /*------------------------------------------------------------------*/
388 /* strVal - converts a string constant to a value                   */
389 /*------------------------------------------------------------------*/
390 value *strVal  ( char   *s )
391 {
392     value *val ;
393     
394     val = newValue() ;        /* get a new one */
395     
396     /* get a declarator */
397     val->type   =  newLink();
398     DCL_TYPE(val->type) = ARRAY ;
399     DCL_ELEM(val->type) = strlen(s) - 1;
400     val->type->next = val->etype = newLink() ;
401     val->etype->class       =  SPECIFIER;
402     SPEC_NOUN(val->etype)   =  V_CHAR   ;
403     SPEC_SCLS(val->etype)   =  S_LITERAL;
404     
405     ALLOC_ATOMIC(SPEC_CVAL(val->etype).v_char,strlen(s)+1);
406     copyStr (SPEC_CVAL(val->etype).v_char,s);
407     return val;
408 }
409
410
411 /*------------------------------------------------------------------*/
412 /* reverseValWithType - reverses value chain with type & etype      */
413 /*------------------------------------------------------------------*/
414 value   *reverseValWithType ( value *val )
415 {
416     sym_link *type ;
417     sym_link *etype;
418     
419     if (!val) 
420         return NULL ;
421     
422     /* save the type * etype chains */
423     type = val->type ;
424     etype = val->etype ;
425     
426     /* set the current one 2b null */
427     val->type = val->etype = NULL;
428     val = reverseVal (val);
429     
430     /* restore type & etype */
431     val->type = type ;
432     val->etype = etype ;
433     
434     return val;
435 }
436
437 /*------------------------------------------------------------------*/
438 /* reverseVal - reverses the values for a value  chain              */
439 /*------------------------------------------------------------------*/
440 value    *reverseVal   ( value  *val)
441 {
442     value  *prev  , *curr, *next ;
443     
444     if (!val)
445         return NULL ;
446     
447     prev = val ;
448     curr = val->next ;
449     
450     while (curr) {
451         next = curr->next ;
452         curr->next = prev   ;
453         prev = curr ;
454         curr = next ;
455     }
456     val->next = (void *) NULL ;
457     return prev ;
458 }
459
460 /*------------------------------------------------------------------*/
461 /* copyValueChain - will copy a chain of values                     */
462 /*------------------------------------------------------------------*/
463 value *copyValueChain ( value *src )
464 {
465     value *dest ;
466     
467     if ( ! src )
468         return NULL ;
469     
470     dest = copyValue (src);
471     dest->next = copyValueChain (src->next);
472     
473     return dest ;
474 }
475
476 /*------------------------------------------------------------------*/
477 /* copyValue - copies contents of a vlue to a fresh one             */
478 /*------------------------------------------------------------------*/
479 value *copyValue  (value   *src)
480 {
481     value *dest ;
482     
483     dest = newValue();
484     dest->sym    = copySymbol(src->sym);
485     strcpy(dest->name,src->name);
486     dest->type   = (src->type ? copyLinkChain(src->type) : NULL) ;
487     dest->etype  = (src->type ? getSpec(dest->type) : NULL);
488     
489     return dest ;
490 }
491
492 /*------------------------------------------------------------------*/
493 /* charVal - converts a character constant to a value               */
494 /*------------------------------------------------------------------*/
495 value *charVal ( char *s )
496 {
497     value *val ;
498     
499     val = newValue ();
500     
501     val->type = val->etype = newLink();
502     val->type->class = SPECIFIER  ;
503     SPEC_NOUN(val->type) = V_CHAR ;
504     SPEC_SCLS(val->type) = S_LITERAL ;
505     
506     s++ ;       /* get rid of quotation */
507     /* if \ then special processing     */
508     if ( *s == '\\' )   {
509         s++ ;   /* go beyond the backslash      */
510         switch (*s)             {
511         case 'n'        :
512             SPEC_CVAL(val->type).v_int = '\n';
513             break ;
514         case 't'        :
515             SPEC_CVAL(val->type).v_int = '\t';
516             break;
517         case 'v'        :
518             SPEC_CVAL(val->type).v_int = '\v';
519             break;
520         case 'b'        :
521             SPEC_CVAL(val->type).v_int = '\b';
522             break;
523         case 'r'        :
524             SPEC_CVAL(val->type).v_int = '\r';
525             break;
526         case 'f'        :
527             SPEC_CVAL(val->type).v_int = '\f';
528             break;
529         case 'a' :
530             SPEC_CVAL(val->type).v_int = '\a';
531             break;
532         case '\\':
533             SPEC_CVAL(val->type).v_int = '\\';
534             break;
535         case '\?':
536             SPEC_CVAL(val->type).v_int = '\?';
537             break;
538         case '\'':
539             SPEC_CVAL(val->type).v_int = '\'';
540             break;
541         case '\"':
542             SPEC_CVAL(val->type).v_int = '\"';
543             break;
544         case '0'        :
545             sscanf(s,"%o",&SPEC_CVAL(val->type).v_int);
546             break;
547         case 'x' :
548             s++ ; /* go behond the 'x' */
549             sscanf(s,"%x",&SPEC_CVAL(val->type).v_int);
550             break;
551         default :
552             SPEC_CVAL(val->type).v_int = *s;
553             break;
554         }
555     }
556     else        /* not a backslash */
557         SPEC_CVAL(val->type).v_int = *s;
558     
559     return val ;
560 }
561
562 /*------------------------------------------------------------------*/
563 /* valFromType - creates a value from type given                    */
564 /*------------------------------------------------------------------*/
565 value *valFromType ( sym_link *type)
566 {
567     value *val = newValue();
568     val->type = copyLinkChain(type);
569     val->etype = getSpec(val->type);
570     return val;
571 }
572
573 /*------------------------------------------------------------------*/
574 /* floatFromVal - value to unsinged integer conversion              */
575 /*------------------------------------------------------------------*/
576 double   floatFromVal ( value *val )
577 {
578     if (!val)
579         return 0;
580
581     if (val->etype && SPEC_SCLS(val->etype) != S_LITERAL) {
582         werror(E_CONST_EXPECTED,val->name);
583         return 0;
584     }
585     
586     /* if it is not a specifier then we can assume that */
587     /* it will be an unsigned long                      */
588     if (!IS_SPEC(val->type))
589         return (double) SPEC_CVAL(val->etype).v_ulong;
590
591     if (SPEC_NOUN(val->etype) == V_FLOAT )
592         return (double) SPEC_CVAL(val->etype).v_float ;
593     else {
594         if (SPEC_LONG(val->etype)) {
595             if (SPEC_USIGN(val->etype))
596                 return (double) SPEC_CVAL(val->etype).v_ulong ;
597             else
598                 return (double) SPEC_CVAL(val->etype).v_long  ;
599         }
600         else {
601             if (SPEC_USIGN(val->etype))
602                 return (double) SPEC_CVAL(val->etype).v_uint ;
603             else
604                 return (double) SPEC_CVAL(val->etype).v_int  ;
605         }
606     }
607 }
608
609
610 /*------------------------------------------------------------------*/
611 /* valUnaryPM - dones the unary +/- operation on a constant         */
612 /*------------------------------------------------------------------*/
613 value *valUnaryPM (value   *val)
614 {
615     /* depending on type */
616     if (SPEC_NOUN(val->etype) == V_FLOAT )
617         SPEC_CVAL(val->etype).v_float = -1.0 * SPEC_CVAL(val->etype).v_float;
618     else {
619         if ( SPEC_LONG(val->etype)) {
620             if (SPEC_USIGN(val->etype))
621                 SPEC_CVAL(val->etype).v_ulong = - SPEC_CVAL(val->etype).v_ulong ;
622             else
623                 SPEC_CVAL(val->etype).v_long  = - SPEC_CVAL(val->etype).v_long;
624         }
625         else {
626             if (SPEC_USIGN(val->etype))
627                 SPEC_CVAL(val->etype).v_uint  = -  SPEC_CVAL(val->etype).v_uint ;
628             else
629                 SPEC_CVAL(val->etype).v_int   = - SPEC_CVAL(val->etype).v_int ; 
630         }
631     }
632     return val ;
633     
634 }
635
636 /*------------------------------------------------------------------*/
637 /* valueComplement - complements a constant                         */
638 /*------------------------------------------------------------------*/
639 value *valComplement ( value  *val)
640 {
641     /* depending on type */
642     if ( SPEC_LONG(val->etype)) {
643         if (SPEC_USIGN(val->etype))
644             SPEC_CVAL(val->etype).v_ulong = ~SPEC_CVAL(val->etype).v_ulong ;
645         else
646             SPEC_CVAL(val->etype).v_long  = ~SPEC_CVAL(val->etype).v_long;
647     }
648     else {
649         if (SPEC_USIGN(val->etype))
650             SPEC_CVAL(val->etype).v_uint  = ~SPEC_CVAL(val->etype).v_uint ;
651         else
652             SPEC_CVAL(val->etype).v_int   = ~SPEC_CVAL(val->etype).v_int ; 
653     }
654     return val ;
655 }
656
657 /*------------------------------------------------------------------*/
658 /* valueNot - complements a constant                                */
659 /*------------------------------------------------------------------*/
660 value *valNot ( value  *val)
661 {
662     /* depending on type */
663     if ( SPEC_LONG(val->etype)) {
664         if (SPEC_USIGN(val->etype))
665             SPEC_CVAL(val->etype).v_ulong = !SPEC_CVAL(val->etype).v_ulong ;
666         else
667             SPEC_CVAL(val->etype).v_long  = !SPEC_CVAL(val->etype).v_long;
668     }
669     else {
670         if (SPEC_USIGN(val->etype))
671             SPEC_CVAL(val->etype).v_uint  = !SPEC_CVAL(val->etype).v_uint ;
672         else
673             SPEC_CVAL(val->etype).v_int   = !SPEC_CVAL(val->etype).v_int ; 
674     }
675     return val ;
676 }
677
678 /*------------------------------------------------------------------*/
679 /* valMult - multiply constants                                     */
680 /*------------------------------------------------------------------*/
681 value *valMult (value  *lval, value *rval)
682 {
683     value *val ;
684     
685     /* create a new value */
686     val = newValue();
687     val->type = val->etype = newLink();
688     val->type->class = SPECIFIER  ;
689     SPEC_NOUN(val->type) = (IS_FLOAT(lval->etype) || 
690                             IS_FLOAT(rval->etype) ? V_FLOAT : V_INT ); 
691     SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
692     SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
693     SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
694     
695     if (IS_FLOAT(val->type))
696         SPEC_CVAL(val->type).v_float = floatFromVal(lval) * floatFromVal(rval);
697     else {
698         if (SPEC_LONG(val->type)) {
699             if (SPEC_USIGN(val->type))
700                 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) * 
701                     (unsigned long) floatFromVal(rval);
702             else
703                 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) * 
704                     (long) floatFromVal(rval);
705         }
706         else {
707             if (SPEC_USIGN(val->type))
708                 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) * 
709                     (unsigned) floatFromVal(rval);
710             else
711                 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) * 
712                     (int) floatFromVal(rval);
713         }
714     }
715     return val ;   
716 }
717
718 /*------------------------------------------------------------------*/
719 /* valDiv  - Divide   constants                                     */
720 /*------------------------------------------------------------------*/
721 value *valDiv  (value  *lval, value *rval)
722 {
723     value *val ;
724
725     if (floatFromVal(rval) == 0) {
726         werror(E_DIVIDE_BY_ZERO);
727         return rval;
728     }
729         
730     /* create a new value */
731     val = newValue();
732     val->type = val->etype = ((floatFromVal(lval) / floatFromVal(rval)) < 256 ?
733                               newCharLink() : newIntLink());
734     if (IS_FLOAT(lval->etype) || IS_FLOAT(rval->etype))
735         SPEC_NOUN(val->etype) = V_FLOAT ;
736     SPEC_SCLS(val->etype) = S_LITERAL ;
737     SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
738     SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
739     
740     if (IS_FLOAT(val->type))
741         SPEC_CVAL(val->type).v_float = floatFromVal(lval) / floatFromVal(rval);
742     else {
743         if (SPEC_LONG(val->type)) {
744             if (SPEC_USIGN(val->type))
745                 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) /
746                     (unsigned long) floatFromVal(rval);
747             else
748                 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) /
749                     (long) floatFromVal(rval);
750         }
751         else {
752             if (SPEC_USIGN(val->type))
753                 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) /
754                     (unsigned) floatFromVal(rval);
755             else
756                 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) / 
757                     (int) floatFromVal(rval);
758         }
759     }
760     return val ;   
761 }
762
763 /*------------------------------------------------------------------*/
764 /* valMod  - Modulus  constants                                     */
765 /*------------------------------------------------------------------*/
766 value *valMod  (value  *lval, value *rval)
767 {
768     value *val ;
769     
770     /* create a new value */
771     val = newValue();
772     val->type = val->etype = newLink();
773     val->type->class = SPECIFIER  ;
774     SPEC_NOUN(val->type) = V_INT ;   /* type is int */
775     SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
776     SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
777     SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
778     
779     if (SPEC_LONG(val->type)) {
780         if (SPEC_USIGN(val->type))
781             SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) % 
782                 (unsigned long) floatFromVal(rval);
783         else
784             SPEC_CVAL(val->type).v_long = (unsigned long) floatFromVal(lval) % 
785                 (unsigned long) floatFromVal(rval);
786     }
787     else {
788         if (SPEC_USIGN(val->type))
789             SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) % 
790                 (unsigned) floatFromVal(rval);
791         else
792             SPEC_CVAL(val->type).v_int = (unsigned) floatFromVal(lval) % 
793                 (unsigned) floatFromVal(rval);
794     }
795     
796     return val ;   
797 }
798
799 /*------------------------------------------------------------------*/
800 /* valPlus - Addition constants                                     */
801 /*------------------------------------------------------------------*/
802 value *valPlus (value  *lval, value *rval)
803 {
804     value *val ;
805     
806     /* create a new value */
807     val = newValue();
808     val->type = val->etype = newLink();
809     val->type->class = SPECIFIER  ;
810     SPEC_NOUN(val->type) = (IS_FLOAT(lval->etype) || 
811                             IS_FLOAT(rval->etype) ? V_FLOAT : V_INT ); 
812     SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
813     SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
814     SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
815     
816     if (IS_FLOAT(val->type))
817         SPEC_CVAL(val->type).v_float = floatFromVal(lval) + floatFromVal(rval);
818     else {
819         if (SPEC_LONG(val->type)) {
820             if (SPEC_USIGN(val->type))
821                 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) +
822                     (unsigned long) floatFromVal(rval);
823             else
824                 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) +
825                     (long) floatFromVal(rval);
826         }
827         else {
828             if (SPEC_USIGN(val->type))
829                 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) +
830                     (unsigned) floatFromVal(rval);
831             else
832                 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) + 
833                     (int) floatFromVal(rval);
834         }
835     }
836     return val ;     
837 }
838
839 /*------------------------------------------------------------------*/
840 /* valMinus - Addition constants                                    */
841 /*------------------------------------------------------------------*/
842 value *valMinus (value  *lval, value *rval)
843 {
844     value *val ;
845     
846     /* create a new value */
847     val = newValue();
848     val->type = val->etype = newLink();
849     val->type->class = SPECIFIER  ;
850     SPEC_NOUN(val->type) = (IS_FLOAT(lval->etype) || 
851                             IS_FLOAT(rval->etype) ? V_FLOAT : V_INT ); 
852     SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
853     SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
854     SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
855     
856     if (IS_FLOAT(val->type))
857         SPEC_CVAL(val->type).v_float = floatFromVal(lval) - floatFromVal(rval);
858     else {
859         if (SPEC_LONG(val->type)) {
860             if (SPEC_USIGN(val->type))
861                 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) -
862                     (unsigned long) floatFromVal(rval);
863             else
864                 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) -
865                     (long) floatFromVal(rval);
866         }
867         else {
868             if (SPEC_USIGN(val->type))
869                 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) -
870                     (unsigned) floatFromVal(rval);
871             else
872                 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) - (int) floatFromVal(rval);
873         }
874     }
875     return val ; 
876 }
877
878 /*------------------------------------------------------------------*/
879 /* valShift - Shift left or right                                   */
880 /*------------------------------------------------------------------*/
881 value *valShift (value  *lval, value *rval, int lr)
882 {
883    value *val ;
884
885    /* create a new value */
886    val = newValue();
887    val->type = val->etype = newLink();
888    val->type->class = SPECIFIER  ;
889    SPEC_NOUN(val->type) = V_INT ;   /* type is int */
890    SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
891    SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
892    SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
893    
894    if (lr) {
895        if (SPEC_LONG(val->type)) {
896            if (SPEC_USIGN(val->type))
897                SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) << 
898                    (unsigned long) floatFromVal(rval);
899            else
900                SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) << 
901                    (long) floatFromVal(rval);
902        }
903        else {
904            if (SPEC_USIGN(val->type))
905                SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) << 
906                    (unsigned) floatFromVal(rval);
907            else
908                SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) << 
909                    (int) floatFromVal(rval);
910        }
911    }
912    else {
913        if (SPEC_LONG(val->type)) {
914            if (SPEC_USIGN(val->type))
915                SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) >>
916                    (unsigned long) floatFromVal(rval);
917            else
918                SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) >>
919                    (long) floatFromVal(rval);
920        }
921        else {
922            if (SPEC_USIGN(val->type))
923                SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) >>
924                    (unsigned) floatFromVal(rval);
925            else
926                SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) >>
927                    (int) floatFromVal(rval);
928        }
929    }
930
931    return val ;   
932 }
933
934 /*------------------------------------------------------------------*/
935 /* valCompare- Compares two literal                                 */
936 /*------------------------------------------------------------------*/
937 value *valCompare (value  *lval, value *rval, int ctype)
938 {
939    value *val ;
940
941    /* create a new value */
942    val = newValue();
943    val->type = val->etype = newCharLink();
944    val->type->class = SPECIFIER  ;
945    SPEC_NOUN(val->type) = V_INT ;   /* type is int */
946    SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */   
947
948    switch (ctype)
949    {
950    case '<' :                 
951        SPEC_CVAL(val->type).v_int = floatFromVal(lval) < floatFromVal(rval);
952        break ;
953
954    case '>' :    
955        SPEC_CVAL(val->type).v_int = floatFromVal(lval) > floatFromVal(rval);
956       break ;
957
958    case LE_OP  :
959        SPEC_CVAL(val->type).v_int = floatFromVal(lval) <= floatFromVal(rval);
960        break ;
961
962    case GE_OP  :
963        SPEC_CVAL(val->type).v_int = floatFromVal(lval) >= floatFromVal(rval);
964        break ;
965
966    case EQ_OP  :
967        SPEC_CVAL(val->type).v_int = floatFromVal(lval) == floatFromVal(rval);
968        break ;
969
970    case NE_OP  :
971        SPEC_CVAL(val->type).v_int = floatFromVal(lval) != floatFromVal(rval);
972        break ;
973        
974    }                            
975
976    return val ;   
977 }
978
979 /*------------------------------------------------------------------*/
980 /* valBitwise - Bitwise operation                                   */
981 /*------------------------------------------------------------------*/
982 value *valBitwise (value  *lval, value *rval, int op)
983 {
984    value *val ;
985
986    /* create a new value */
987    val = newValue();
988    val->type = copyLinkChain (lval->type);
989    val->etype = getSpec(val->type);
990
991    switch (op)
992    {
993    case '&' :
994        if (SPEC_LONG(val->type)) {
995            if (SPEC_USIGN(val->type))
996                SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) &
997                    (unsigned long) floatFromVal(rval);
998            else
999                SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) &
1000                    (long) floatFromVal(rval);
1001        }
1002        else {
1003            if (SPEC_USIGN(val->type))
1004                SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) &
1005                    (unsigned) floatFromVal(rval);
1006            else
1007                SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) & (int) floatFromVal(rval);
1008        }
1009        break ;
1010
1011    case '|' :
1012        if (SPEC_LONG(val->type)) {
1013            if (SPEC_USIGN(val->type))
1014                SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) |
1015                    (unsigned long) floatFromVal(rval);
1016            else
1017                SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) |
1018                    (long) floatFromVal(rval);
1019        }
1020        else {
1021            if (SPEC_USIGN(val->type))
1022                SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) |
1023                    (unsigned) floatFromVal(rval);
1024            else
1025                SPEC_CVAL(val->type).v_int = 
1026                    (int) floatFromVal(lval) | (int) floatFromVal(rval);
1027        }
1028  
1029       break ;
1030
1031    case '^' :
1032        if (SPEC_LONG(val->type)) {
1033            if (SPEC_USIGN(val->type))
1034                SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) ^
1035                    (unsigned long) floatFromVal(rval);
1036            else
1037                SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) ^
1038                    (long) floatFromVal(rval);
1039        }
1040        else {
1041            if (SPEC_USIGN(val->type))
1042                SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) ^
1043                    (unsigned) floatFromVal(rval);
1044            else
1045                SPEC_CVAL(val->type).v_int = 
1046                    (int) floatFromVal(lval) ^ (int) floatFromVal(rval);
1047        }
1048       break ;               
1049    }
1050
1051    return val ;   
1052 }
1053
1054 /*------------------------------------------------------------------*/
1055 /* valAndOr   - Generates code for and / or operation               */
1056 /*------------------------------------------------------------------*/
1057 value *valLogicAndOr (value  *lval, value *rval, int op)
1058 {
1059    value *val ;
1060
1061    /* create a new value */
1062    val = newValue();
1063    val->type = val->etype = newCharLink();
1064    val->type->class = SPECIFIER  ;
1065    SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */  
1066
1067    switch (op)
1068    {
1069    case AND_OP :
1070        SPEC_CVAL(val->type).v_int = floatFromVal(lval)  && floatFromVal(rval);
1071        break ;
1072
1073    case OR_OP :
1074        SPEC_CVAL(val->type).v_int = floatFromVal(lval)  || floatFromVal(rval);
1075        break ;
1076    }
1077   
1078    
1079    return val ;   
1080 }
1081
1082 /*------------------------------------------------------------------*/
1083 /* valCastLiteral - casts a literal value to another type           */
1084 /*------------------------------------------------------------------*/
1085 value *valCastLiteral (sym_link *dtype, double fval)
1086 {
1087     value *val ;
1088
1089     if (!dtype)
1090         return NULL ;
1091
1092     val = newValue();
1093     val->etype = getSpec (val->type = copyLinkChain(dtype));
1094     SPEC_SCLS(val->etype) = S_LITERAL ;
1095     /* if it is not a specifier then we can assume that */
1096     /* it will be an unsigned long                      */
1097     if (!IS_SPEC(val->type)) {
1098         SPEC_CVAL(val->etype).v_ulong = (unsigned long) fval;
1099         return val;
1100     }
1101
1102     if (SPEC_NOUN(val->etype) == V_FLOAT )
1103         SPEC_CVAL(val->etype).v_float = fval;
1104     else {
1105         if (SPEC_LONG(val->etype)) {
1106             if (SPEC_USIGN(val->etype))
1107                 SPEC_CVAL(val->etype).v_ulong = (unsigned long) fval;
1108             else
1109                 SPEC_CVAL(val->etype).v_long  = (long) fval;
1110         }
1111         else {
1112             if (SPEC_USIGN(val->etype))
1113                 SPEC_CVAL(val->etype).v_uint = (unsigned int) fval;
1114             else
1115                 SPEC_CVAL(val->etype).v_int  = (int) fval;   
1116         }
1117     }
1118     return val;
1119 }
1120
1121 /*------------------------------------------------------------------*/
1122 /* getNelements - determines # of elements from init list           */
1123 /*------------------------------------------------------------------*/
1124 int getNelements (sym_link *type,initList *ilist)
1125 {
1126     sym_link *etype = getSpec(type);
1127     int i;
1128
1129     if (! ilist)
1130         return 0;
1131
1132     if (ilist->type == INIT_DEEP)
1133         ilist = ilist->init.deep;
1134
1135     /* if type is a character array and there is only one
1136        initialiser then get the length of the string */
1137     if (IS_ARRAY(type) && IS_CHAR(etype) && !ilist->next) {
1138         ast *iast = ilist->init.node;
1139         value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1140         if (!v) {
1141             werror(E_INIT_WRONG);
1142             return 0;
1143         }
1144         if (!IS_ARRAY(v->type) || !IS_CHAR(v->etype)) {
1145              werror(E_INIT_WRONG);
1146              return 0;
1147         }
1148         return DCL_ELEM(v->type);
1149     }
1150
1151     i = 0 ;
1152     while (ilist) {
1153         i++;
1154         ilist = ilist->next;
1155     }
1156
1157     return i;
1158 }
1159
1160 /*-----------------------------------------------------------------*/
1161 /* valForArray - returns a value with name of array index          */
1162 /*-----------------------------------------------------------------*/
1163 value *valForArray (ast *arrExpr)
1164 {
1165     value *val, *lval = NULL ;
1166     char buffer[128];
1167     int size = getSize(arrExpr->left->ftype->next);
1168     /* if the right or left is an array
1169        resolve it first */
1170     if (IS_AST_OP(arrExpr->left)) {
1171         if (arrExpr->left->opval.op == '[')
1172             lval = valForArray(arrExpr->left);
1173         else
1174             if (arrExpr->left->opval.op == '.')
1175                 lval = valForStructElem(arrExpr->left->left,
1176                                         arrExpr->left->right);
1177             else
1178                 if (arrExpr->left->opval.op == PTR_OP &&
1179                     IS_ADDRESS_OF_OP(arrExpr->left->left))
1180                     lval = valForStructElem(arrExpr->left->left->left,
1181                                             arrExpr->left->right);
1182                 else
1183                     return NULL;
1184                     
1185     } else
1186         if (!IS_AST_SYM_VALUE(arrExpr->left))
1187             return NULL ;
1188     
1189     if (!IS_AST_LIT_VALUE(arrExpr->right))
1190         return NULL;
1191     
1192     val = newValue();
1193     if (!lval)
1194         sprintf(buffer,"%s",AST_SYMBOL(arrExpr->left)->rname);
1195     else
1196         sprintf(buffer,"%s",lval->name);
1197       
1198     sprintf(val->name,"(%s + %d)",buffer,
1199             (int)AST_LIT_VALUE(arrExpr->right)*size);    
1200     
1201     val->type = newLink();    
1202     if (SPEC_SCLS(arrExpr->left->etype) == S_CODE) {
1203         DCL_TYPE(val->type) = CPOINTER ;
1204         DCL_PTR_CONST(val->type) = port->mem.code_ro;
1205     }
1206     else
1207         if (SPEC_SCLS(arrExpr->left->etype) == S_XDATA)
1208             DCL_TYPE(val->type) = FPOINTER;
1209         else
1210             if (SPEC_SCLS(arrExpr->left->etype) == S_XSTACK )
1211                 DCL_TYPE(val->type) = PPOINTER ;
1212             else
1213                 if (SPEC_SCLS(arrExpr->left->etype) == S_IDATA)
1214                     DCL_TYPE(val->type) = IPOINTER ;
1215                 else
1216                     if (SPEC_SCLS(arrExpr->left->etype) == S_EEPROM)
1217                         DCL_TYPE(val->type) = EEPPOINTER ;
1218                     else
1219                         DCL_TYPE(val->type) = POINTER ;
1220     val->type->next = arrExpr->left->ftype;
1221     val->etype = getSpec(val->type);
1222     return val;
1223 }
1224
1225 /*-----------------------------------------------------------------*/
1226 /* valForStructElem - returns value with name of struct element    */
1227 /*-----------------------------------------------------------------*/
1228 value *valForStructElem(ast *structT, ast *elemT)
1229 {
1230     value *val, *lval = NULL;
1231     char buffer[128];
1232     symbol *sym;
1233
1234     /* left could be furthur derefed */
1235     if (IS_AST_OP(structT)) {
1236         if (structT->opval.op == '[')
1237             lval = valForArray(structT);
1238         else
1239             if (structT->opval.op == '.')
1240                 lval = valForStructElem(structT->left,structT->right);
1241             else
1242                 if (structT->opval.op == PTR_OP &&
1243                     IS_ADDRESS_OF_OP(structT->left))
1244                     lval = valForStructElem(structT->left->left,
1245                                             structT->right);
1246                 else
1247                     return NULL;
1248     }
1249
1250     if (!IS_AST_SYM_VALUE(elemT))
1251         return NULL;
1252
1253     if (!IS_STRUCT(structT->etype))
1254         return NULL;
1255
1256     if ((sym = getStructElement(SPEC_STRUCT(structT->etype),
1257                                 AST_SYMBOL(elemT))) == NULL) {
1258         return NULL;
1259     }
1260
1261     val = newValue();
1262     if (!lval)
1263         sprintf(buffer,"%s",AST_SYMBOL(structT)->rname);
1264     else
1265         sprintf(buffer,"%s",lval->name);
1266       
1267     sprintf(val->name,"(%s + %d)",buffer,
1268             (int)sym->offset);   
1269     
1270     val->type = newLink();
1271     if (SPEC_SCLS(structT->etype) == S_CODE) {
1272         DCL_TYPE(val->type) = CPOINTER ;
1273         DCL_PTR_CONST(val->type) = port->mem.code_ro;
1274     }
1275     else
1276         if (SPEC_SCLS(structT->etype) == S_XDATA)
1277             DCL_TYPE(val->type) = FPOINTER;
1278         else
1279             if (SPEC_SCLS(structT->etype) == S_XSTACK )
1280                 DCL_TYPE(val->type) = PPOINTER ;
1281             else
1282                 if (SPEC_SCLS(structT->etype) == S_IDATA)
1283                     DCL_TYPE(val->type) = IPOINTER ;
1284                 else
1285                     if (SPEC_SCLS(structT->etype) == S_EEPROM)
1286                         DCL_TYPE(val->type) = EEPPOINTER ;
1287                     else
1288                         DCL_TYPE(val->type) = POINTER ;
1289     val->type->next = sym->type;
1290     val->etype = getSpec(val->type);
1291     return val; 
1292 }
1293
1294 /*-----------------------------------------------------------------*/
1295 /* valForCastAggr - will return value for a cast of an aggregate   */
1296 /*                  plus minus a constant                          */
1297 /*-----------------------------------------------------------------*/
1298 value *valForCastAggr (ast *aexpr, sym_link *type, ast *cnst, int op)
1299 {
1300     value *val;
1301
1302     if (!IS_AST_SYM_VALUE(aexpr)) return NULL;
1303     if (!IS_AST_LIT_VALUE(cnst)) return NULL;
1304
1305     val = newValue();
1306
1307     sprintf(val->name,"(%s %c %d)",
1308            AST_SYMBOL(aexpr)->rname, op,
1309            getSize(type->next)*(int)AST_LIT_VALUE(cnst));
1310
1311     val->type = type;
1312     val->etype = getSpec(val->type);
1313     return val;
1314 }