Changed Safe_calloc to use 2 arguements to mimic teh standard calloc function
[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(1,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(1,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(1,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 }