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