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