1 /*----------------------------------------------------------------------
2 SDCCval.c :- has routine to do all kinds of fun stuff with the
3 value wrapper & with initialiser lists.
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
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
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.
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.
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 -------------------------------------------------------------------------*/
33 /*-----------------------------------------------------------------*/
34 /* newValue - allocates and returns a new value */
35 /*-----------------------------------------------------------------*/
40 ALLOC(val,sizeof(value));
45 /*-----------------------------------------------------------------*/
46 /* newiList - new initializer list */
47 /*-----------------------------------------------------------------*/
48 initList *newiList ( int type, void *ilist)
53 ALLOC(nilist,sizeof(initList));
56 nilist->lineno = yylineno ;
60 nilist->init.node = (struct ast *) ilist ;
64 nilist->init.deep = (struct initList *) ilist ;
71 /*------------------------------------------------------------------*/
72 /* revinit - reverses the initial values for a value chain */
73 /*------------------------------------------------------------------*/
74 initList *revinit ( initList *val)
76 initList *prev , *curr, *next ;
90 val->next = (void *) NULL ;
94 /*------------------------------------------------------------------*/
95 /* copyIlist - copy initializer list */
96 /*------------------------------------------------------------------*/
97 initList *copyIlist (initList *src)
99 initList *dest = NULL;
106 dest = newiList (INIT_DEEP,copyIlist (src->init.deep));
109 dest = newiList (INIT_NODE,copyAst (src->init.node)) ;
114 dest->next = copyIlist(src->next);
119 /*------------------------------------------------------------------*/
120 /* list2int - converts the first element of the list to value */
121 /*------------------------------------------------------------------*/
122 double list2int (initList *val)
126 if ( i->type == INIT_DEEP )
127 return list2int (val->init.deep) ;
129 return floatFromVal(constExprValue(val->init.node,TRUE));
132 /*------------------------------------------------------------------*/
133 /* list2val - converts the first element of the list to value */
134 /*------------------------------------------------------------------*/
135 value *list2val (initList *val)
140 if ( val->type == INIT_DEEP )
141 return list2val (val->init.deep) ;
143 return constExprValue(val->init.node,TRUE);
146 /*------------------------------------------------------------------*/
147 /* list2expr - returns the first expression in the initializer list */
148 /*------------------------------------------------------------------*/
149 ast *list2expr ( initList *ilist)
151 if ( ilist->type == INIT_DEEP )
152 return list2expr (ilist->init.deep) ;
153 return ilist->init.node ;
156 /*------------------------------------------------------------------*/
157 /* resolveIvalSym - resolve symbols in initial values */
158 /*------------------------------------------------------------------*/
159 void resolveIvalSym ( initList *ilist)
164 if ( ilist->type == INIT_NODE )
165 ilist->init.node = decorateType(resolveSymbols (ilist->init.node));
167 if ( ilist->type == INIT_DEEP )
168 resolveIvalSym (ilist->init.deep);
170 resolveIvalSym (ilist->next);
173 /*-----------------------------------------------------------------*/
174 /* symbolVal - creates a value for a symbol */
175 /*-----------------------------------------------------------------*/
176 value *symbolVal ( symbol *sym )
187 val->type = sym->type;
188 val->etype= getSpec(val->type);
192 sprintf (val->name,"%s",sym->rname);
194 sprintf(val->name,"_%s",sym->name);
200 /*-----------------------------------------------------------------*/
201 /* valueFromLit - creates a value from a literal */
202 /*-----------------------------------------------------------------*/
203 value *valueFromLit (float lit)
207 if ( ( ((long) lit ) - lit ) == 0 ) {
208 sprintf(buffer,"%ld",(long) lit);
209 return constVal (buffer);
212 sprintf(buffer,"%f",lit);
213 return constFloatVal (buffer);
216 /*-----------------------------------------------------------------*/
217 /* constFloatVal - converts a FLOAT constant to value */
218 /*-----------------------------------------------------------------*/
219 value *constFloatVal ( char *s )
221 value *val = newValue();
224 if(sscanf (s,"%f",&sval) != 1) {
225 werror(E_INVALID_FLOAT_CONST,s);
226 return constVal("0");
229 val->type = val->etype = newLink();
230 val->type->class = SPECIFIER ;
231 SPEC_NOUN(val->type) = V_FLOAT ;
232 SPEC_SCLS(val->type) = S_LITERAL;
233 SPEC_CVAL(val->type).v_float = sval;
238 /*-----------------------------------------------------------------*/
239 /* constVal - converts a INTEGER constant into a value */
240 /*-----------------------------------------------------------------*/
241 value *constVal (char *s)
244 short hex = 0 , octal = 0 ;
249 val = newValue() ; /* alloc space for value */
251 val->type = val->etype = newLink() ; /* create the spcifier */
252 val->type->class = SPECIFIER ;
253 SPEC_NOUN(val->type) = V_INT ;
254 SPEC_SCLS(val->type) = S_LITERAL ;
256 /* set the _unsigned flag if 'uU' found */
257 if (strchr(s,'u') || strchr(s,'U'))
258 SPEC_USIGN(val->type) = 1;
260 /* set the _long flag if 'lL' is found */
261 if (strchr(s,'l') || strchr(s,'L'))
262 SPEC_LONG(val->type) = 1;
264 hex = ((strchr(s,'x') || strchr(s,'X')) ? 1 : 0) ;
266 /* set the octal flag */
267 if (!hex && *s == '0' && *(s+1) )
270 /* create the scan string */
271 scanFmt[scI++] = '%' ;
274 scanFmt[scI++] = 'o' ;
277 scanFmt[scI++] = 'x' ;
279 if (SPEC_USIGN(val->type))
280 scanFmt[scI++] = 'u' ;
282 scanFmt[scI++] = 'd' ;
284 scanFmt[scI++] = '\0' ;
286 /* if hex or octal then set the unsigned flag */
287 if ( hex || octal ) {
288 SPEC_USIGN(val->type) = 1 ;
289 sscanf(s,scanFmt,&sval);
294 if (SPEC_LONG(val->type) || sval > 32768) {
295 if (SPEC_USIGN(val->type))
296 SPEC_CVAL(val->type).v_ulong = sval ;
298 SPEC_CVAL(val->type).v_long = sval ;
299 SPEC_LONG(val->type) = 1;
302 if (SPEC_USIGN(val->type))
303 SPEC_CVAL(val->type).v_uint = sval ;
305 SPEC_CVAL(val->type).v_int = sval ;
308 // check the size and make it a short if required
310 SPEC_SHORT(val->etype) = 1;
316 /*------------------------------------------------------------------*/
317 /* copyStr - copies src to dest ignoring leading & trailing \"s */
318 /*------------------------------------------------------------------*/
319 void copyStr (char *dest, char *src )
326 if ( *src == '\\' ) {
351 /* embedded octal or hex constant */
352 if (*(src+1) == 'x' ||
354 x = strtol(src,&src,16);
358 x = strtol(src,&src,8);
387 /*------------------------------------------------------------------*/
388 /* strVal - converts a string constant to a value */
389 /*------------------------------------------------------------------*/
390 value *strVal ( char *s )
394 val = newValue() ; /* get a new one */
396 /* get a declarator */
397 val->type = newLink();
398 DCL_TYPE(val->type) = ARRAY ;
399 DCL_ELEM(val->type) = strlen(s) - 1;
400 val->type->next = val->etype = newLink() ;
401 val->etype->class = SPECIFIER;
402 SPEC_NOUN(val->etype) = V_CHAR ;
403 SPEC_SCLS(val->etype) = S_LITERAL;
405 ALLOC_ATOMIC(SPEC_CVAL(val->etype).v_char,strlen(s)+1);
406 copyStr (SPEC_CVAL(val->etype).v_char,s);
411 /*------------------------------------------------------------------*/
412 /* reverseValWithType - reverses value chain with type & etype */
413 /*------------------------------------------------------------------*/
414 value *reverseValWithType ( value *val )
422 /* save the type * etype chains */
426 /* set the current one 2b null */
427 val->type = val->etype = NULL;
428 val = reverseVal (val);
430 /* restore type & etype */
437 /*------------------------------------------------------------------*/
438 /* reverseVal - reverses the values for a value chain */
439 /*------------------------------------------------------------------*/
440 value *reverseVal ( value *val)
442 value *prev , *curr, *next ;
456 val->next = (void *) NULL ;
460 /*------------------------------------------------------------------*/
461 /* copyValueChain - will copy a chain of values */
462 /*------------------------------------------------------------------*/
463 value *copyValueChain ( value *src )
470 dest = copyValue (src);
471 dest->next = copyValueChain (src->next);
476 /*------------------------------------------------------------------*/
477 /* copyValue - copies contents of a vlue to a fresh one */
478 /*------------------------------------------------------------------*/
479 value *copyValue (value *src)
484 dest->sym = copySymbol(src->sym);
485 strcpy(dest->name,src->name);
486 dest->type = (src->type ? copyLinkChain(src->type) : NULL) ;
487 dest->etype = (src->type ? getSpec(dest->type) : NULL);
492 /*------------------------------------------------------------------*/
493 /* charVal - converts a character constant to a value */
494 /*------------------------------------------------------------------*/
495 value *charVal ( char *s )
501 val->type = val->etype = newLink();
502 val->type->class = SPECIFIER ;
503 SPEC_NOUN(val->type) = V_CHAR ;
504 SPEC_SCLS(val->type) = S_LITERAL ;
506 s++ ; /* get rid of quotation */
507 /* if \ then special processing */
509 s++ ; /* go beyond the backslash */
512 SPEC_CVAL(val->type).v_int = '\n';
515 SPEC_CVAL(val->type).v_int = '\t';
518 SPEC_CVAL(val->type).v_int = '\v';
521 SPEC_CVAL(val->type).v_int = '\b';
524 SPEC_CVAL(val->type).v_int = '\r';
527 SPEC_CVAL(val->type).v_int = '\f';
530 SPEC_CVAL(val->type).v_int = '\a';
533 SPEC_CVAL(val->type).v_int = '\\';
536 SPEC_CVAL(val->type).v_int = '\?';
539 SPEC_CVAL(val->type).v_int = '\'';
542 SPEC_CVAL(val->type).v_int = '\"';
545 sscanf(s,"%o",&SPEC_CVAL(val->type).v_int);
548 s++ ; /* go behond the 'x' */
549 sscanf(s,"%x",&SPEC_CVAL(val->type).v_int);
552 SPEC_CVAL(val->type).v_int = *s;
556 else /* not a backslash */
557 SPEC_CVAL(val->type).v_int = *s;
562 /*------------------------------------------------------------------*/
563 /* valFromType - creates a value from type given */
564 /*------------------------------------------------------------------*/
565 value *valFromType ( link *type)
567 value *val = newValue();
568 val->type = copyLinkChain(type);
569 val->etype = getSpec(val->type);
573 /*------------------------------------------------------------------*/
574 /* floatFromVal - value to unsinged integer conversion */
575 /*------------------------------------------------------------------*/
576 double floatFromVal ( value *val )
581 if (val->etype && SPEC_SCLS(val->etype) != S_LITERAL) {
582 werror(E_CONST_EXPECTED,val->name);
586 /* if it is not a specifier then we can assume that */
587 /* it will be an unsigned long */
588 if (!IS_SPEC(val->type))
589 return (double) SPEC_CVAL(val->etype).v_ulong;
591 if (SPEC_NOUN(val->etype) == V_FLOAT )
592 return (double) SPEC_CVAL(val->etype).v_float ;
594 if (SPEC_LONG(val->etype)) {
595 if (SPEC_USIGN(val->etype))
596 return (double) SPEC_CVAL(val->etype).v_ulong ;
598 return (double) SPEC_CVAL(val->etype).v_long ;
601 if (SPEC_USIGN(val->etype))
602 return (double) SPEC_CVAL(val->etype).v_uint ;
604 return (double) SPEC_CVAL(val->etype).v_int ;
610 /*------------------------------------------------------------------*/
611 /* valUnaryPM - dones the unary +/- operation on a constant */
612 /*------------------------------------------------------------------*/
613 value *valUnaryPM (value *val)
615 /* depending on type */
616 if (SPEC_NOUN(val->etype) == V_FLOAT )
617 SPEC_CVAL(val->etype).v_float = -1.0 * SPEC_CVAL(val->etype).v_float;
619 if ( SPEC_LONG(val->etype)) {
620 if (SPEC_USIGN(val->etype))
621 SPEC_CVAL(val->etype).v_ulong = - SPEC_CVAL(val->etype).v_ulong ;
623 SPEC_CVAL(val->etype).v_long = - SPEC_CVAL(val->etype).v_long;
626 if (SPEC_USIGN(val->etype))
627 SPEC_CVAL(val->etype).v_uint = - SPEC_CVAL(val->etype).v_uint ;
629 SPEC_CVAL(val->etype).v_int = - SPEC_CVAL(val->etype).v_int ;
636 /*------------------------------------------------------------------*/
637 /* valueComplement - complements a constant */
638 /*------------------------------------------------------------------*/
639 value *valComplement ( value *val)
641 /* depending on type */
642 if ( SPEC_LONG(val->etype)) {
643 if (SPEC_USIGN(val->etype))
644 SPEC_CVAL(val->etype).v_ulong = ~SPEC_CVAL(val->etype).v_ulong ;
646 SPEC_CVAL(val->etype).v_long = ~SPEC_CVAL(val->etype).v_long;
649 if (SPEC_USIGN(val->etype))
650 SPEC_CVAL(val->etype).v_uint = ~SPEC_CVAL(val->etype).v_uint ;
652 SPEC_CVAL(val->etype).v_int = ~SPEC_CVAL(val->etype).v_int ;
657 /*------------------------------------------------------------------*/
658 /* valueNot - complements a constant */
659 /*------------------------------------------------------------------*/
660 value *valNot ( value *val)
662 /* depending on type */
663 if ( SPEC_LONG(val->etype)) {
664 if (SPEC_USIGN(val->etype))
665 SPEC_CVAL(val->etype).v_ulong = !SPEC_CVAL(val->etype).v_ulong ;
667 SPEC_CVAL(val->etype).v_long = !SPEC_CVAL(val->etype).v_long;
670 if (SPEC_USIGN(val->etype))
671 SPEC_CVAL(val->etype).v_uint = !SPEC_CVAL(val->etype).v_uint ;
673 SPEC_CVAL(val->etype).v_int = !SPEC_CVAL(val->etype).v_int ;
678 /*------------------------------------------------------------------*/
679 /* valMult - multiply constants */
680 /*------------------------------------------------------------------*/
681 value *valMult (value *lval, value *rval)
685 /* create a new value */
687 val->type = val->etype = newLink();
688 val->type->class = SPECIFIER ;
689 SPEC_NOUN(val->type) = (IS_FLOAT(lval->etype) ||
690 IS_FLOAT(rval->etype) ? V_FLOAT : V_INT );
691 SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
692 SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
693 SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
695 if (IS_FLOAT(val->type))
696 SPEC_CVAL(val->type).v_float = floatFromVal(lval) * floatFromVal(rval);
698 if (SPEC_LONG(val->type)) {
699 if (SPEC_USIGN(val->type))
700 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) *
701 (unsigned long) floatFromVal(rval);
703 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) *
704 (long) floatFromVal(rval);
707 if (SPEC_USIGN(val->type))
708 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) *
709 (unsigned) floatFromVal(rval);
711 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) *
712 (int) floatFromVal(rval);
718 /*------------------------------------------------------------------*/
719 /* valDiv - Divide constants */
720 /*------------------------------------------------------------------*/
721 value *valDiv (value *lval, value *rval)
725 if (floatFromVal(rval) == 0) {
726 werror(E_DIVIDE_BY_ZERO);
730 /* create a new value */
732 val->type = val->etype = ((floatFromVal(lval) / floatFromVal(rval)) < 256 ?
733 newCharLink() : newIntLink());
734 if (IS_FLOAT(lval->etype) || IS_FLOAT(rval->etype))
735 SPEC_NOUN(val->etype) = V_FLOAT ;
736 SPEC_SCLS(val->etype) = S_LITERAL ;
737 SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
738 SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
740 if (IS_FLOAT(val->type))
741 SPEC_CVAL(val->type).v_float = floatFromVal(lval) / floatFromVal(rval);
743 if (SPEC_LONG(val->type)) {
744 if (SPEC_USIGN(val->type))
745 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) /
746 (unsigned long) floatFromVal(rval);
748 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) /
749 (long) floatFromVal(rval);
752 if (SPEC_USIGN(val->type))
753 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) /
754 (unsigned) floatFromVal(rval);
756 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) /
757 (int) floatFromVal(rval);
763 /*------------------------------------------------------------------*/
764 /* valMod - Modulus constants */
765 /*------------------------------------------------------------------*/
766 value *valMod (value *lval, value *rval)
770 /* create a new value */
772 val->type = val->etype = newLink();
773 val->type->class = SPECIFIER ;
774 SPEC_NOUN(val->type) = V_INT ; /* type is int */
775 SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
776 SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
777 SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
779 if (SPEC_LONG(val->type)) {
780 if (SPEC_USIGN(val->type))
781 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) %
782 (unsigned long) floatFromVal(rval);
784 SPEC_CVAL(val->type).v_long = (unsigned long) floatFromVal(lval) %
785 (unsigned long) floatFromVal(rval);
788 if (SPEC_USIGN(val->type))
789 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) %
790 (unsigned) floatFromVal(rval);
792 SPEC_CVAL(val->type).v_int = (unsigned) floatFromVal(lval) %
793 (unsigned) floatFromVal(rval);
799 /*------------------------------------------------------------------*/
800 /* valPlus - Addition constants */
801 /*------------------------------------------------------------------*/
802 value *valPlus (value *lval, value *rval)
806 /* create a new value */
808 val->type = val->etype = newLink();
809 val->type->class = SPECIFIER ;
810 SPEC_NOUN(val->type) = (IS_FLOAT(lval->etype) ||
811 IS_FLOAT(rval->etype) ? V_FLOAT : V_INT );
812 SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
813 SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
814 SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
816 if (IS_FLOAT(val->type))
817 SPEC_CVAL(val->type).v_float = floatFromVal(lval) + floatFromVal(rval);
819 if (SPEC_LONG(val->type)) {
820 if (SPEC_USIGN(val->type))
821 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) +
822 (unsigned long) floatFromVal(rval);
824 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) +
825 (long) floatFromVal(rval);
828 if (SPEC_USIGN(val->type))
829 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) +
830 (unsigned) floatFromVal(rval);
832 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) +
833 (int) floatFromVal(rval);
839 /*------------------------------------------------------------------*/
840 /* valMinus - Addition constants */
841 /*------------------------------------------------------------------*/
842 value *valMinus (value *lval, value *rval)
846 /* create a new value */
848 val->type = val->etype = newLink();
849 val->type->class = SPECIFIER ;
850 SPEC_NOUN(val->type) = (IS_FLOAT(lval->etype) ||
851 IS_FLOAT(rval->etype) ? V_FLOAT : V_INT );
852 SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
853 SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
854 SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
856 if (IS_FLOAT(val->type))
857 SPEC_CVAL(val->type).v_float = floatFromVal(lval) - floatFromVal(rval);
859 if (SPEC_LONG(val->type)) {
860 if (SPEC_USIGN(val->type))
861 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) -
862 (unsigned long) floatFromVal(rval);
864 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) -
865 (long) floatFromVal(rval);
868 if (SPEC_USIGN(val->type))
869 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) -
870 (unsigned) floatFromVal(rval);
872 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) - (int) floatFromVal(rval);
878 /*------------------------------------------------------------------*/
879 /* valShift - Shift left or right */
880 /*------------------------------------------------------------------*/
881 value *valShift (value *lval, value *rval, int lr)
885 /* create a new value */
887 val->type = val->etype = newLink();
888 val->type->class = SPECIFIER ;
889 SPEC_NOUN(val->type) = V_INT ; /* type is int */
890 SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
891 SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
892 SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
895 if (SPEC_LONG(val->type)) {
896 if (SPEC_USIGN(val->type))
897 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) <<
898 (unsigned long) floatFromVal(rval);
900 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) <<
901 (long) floatFromVal(rval);
904 if (SPEC_USIGN(val->type))
905 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) <<
906 (unsigned) floatFromVal(rval);
908 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) <<
909 (int) floatFromVal(rval);
913 if (SPEC_LONG(val->type)) {
914 if (SPEC_USIGN(val->type))
915 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) >>
916 (unsigned long) floatFromVal(rval);
918 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) >>
919 (long) floatFromVal(rval);
922 if (SPEC_USIGN(val->type))
923 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) >>
924 (unsigned) floatFromVal(rval);
926 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) >>
927 (int) floatFromVal(rval);
934 /*------------------------------------------------------------------*/
935 /* valCompare- Compares two literal */
936 /*------------------------------------------------------------------*/
937 value *valCompare (value *lval, value *rval, int ctype)
941 /* create a new value */
943 val->type = val->etype = newCharLink();
944 val->type->class = SPECIFIER ;
945 SPEC_NOUN(val->type) = V_INT ; /* type is int */
946 SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
951 SPEC_CVAL(val->type).v_int = floatFromVal(lval) < floatFromVal(rval);
955 SPEC_CVAL(val->type).v_int = floatFromVal(lval) > floatFromVal(rval);
959 SPEC_CVAL(val->type).v_int = floatFromVal(lval) <= floatFromVal(rval);
963 SPEC_CVAL(val->type).v_int = floatFromVal(lval) >= floatFromVal(rval);
967 SPEC_CVAL(val->type).v_int = floatFromVal(lval) == floatFromVal(rval);
971 SPEC_CVAL(val->type).v_int = floatFromVal(lval) != floatFromVal(rval);
979 /*------------------------------------------------------------------*/
980 /* valBitwise - Bitwise operation */
981 /*------------------------------------------------------------------*/
982 value *valBitwise (value *lval, value *rval, int op)
986 /* create a new value */
988 val->type = copyLinkChain (lval->type);
989 val->etype = getSpec(val->type);
994 if (SPEC_LONG(val->type)) {
995 if (SPEC_USIGN(val->type))
996 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) &
997 (unsigned long) floatFromVal(rval);
999 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) &
1000 (long) floatFromVal(rval);
1003 if (SPEC_USIGN(val->type))
1004 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) &
1005 (unsigned) floatFromVal(rval);
1007 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) & (int) floatFromVal(rval);
1012 if (SPEC_LONG(val->type)) {
1013 if (SPEC_USIGN(val->type))
1014 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) |
1015 (unsigned long) floatFromVal(rval);
1017 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) |
1018 (long) floatFromVal(rval);
1021 if (SPEC_USIGN(val->type))
1022 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) |
1023 (unsigned) floatFromVal(rval);
1025 SPEC_CVAL(val->type).v_int =
1026 (int) floatFromVal(lval) | (int) floatFromVal(rval);
1032 if (SPEC_LONG(val->type)) {
1033 if (SPEC_USIGN(val->type))
1034 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) ^
1035 (unsigned long) floatFromVal(rval);
1037 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) ^
1038 (long) floatFromVal(rval);
1041 if (SPEC_USIGN(val->type))
1042 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) ^
1043 (unsigned) floatFromVal(rval);
1045 SPEC_CVAL(val->type).v_int =
1046 (int) floatFromVal(lval) ^ (int) floatFromVal(rval);
1054 /*------------------------------------------------------------------*/
1055 /* valAndOr - Generates code for and / or operation */
1056 /*------------------------------------------------------------------*/
1057 value *valLogicAndOr (value *lval, value *rval, int op)
1061 /* create a new value */
1063 val->type = val->etype = newCharLink();
1064 val->type->class = SPECIFIER ;
1065 SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
1070 SPEC_CVAL(val->type).v_int = floatFromVal(lval) && floatFromVal(rval);
1074 SPEC_CVAL(val->type).v_int = floatFromVal(lval) || floatFromVal(rval);
1082 /*------------------------------------------------------------------*/
1083 /* valCastLiteral - casts a literal value to another type */
1084 /*------------------------------------------------------------------*/
1085 value *valCastLiteral (link *dtype, double fval)
1093 val->etype = getSpec (val->type = copyLinkChain(dtype));
1094 SPEC_SCLS(val->etype) = S_LITERAL ;
1095 /* if it is not a specifier then we can assume that */
1096 /* it will be an unsigned long */
1097 if (!IS_SPEC(val->type)) {
1098 SPEC_CVAL(val->etype).v_ulong = (unsigned long) fval;
1102 if (SPEC_NOUN(val->etype) == V_FLOAT )
1103 SPEC_CVAL(val->etype).v_float = fval;
1105 if (SPEC_LONG(val->etype)) {
1106 if (SPEC_USIGN(val->etype))
1107 SPEC_CVAL(val->etype).v_ulong = (unsigned long) fval;
1109 SPEC_CVAL(val->etype).v_long = (long) fval;
1112 if (SPEC_USIGN(val->etype))
1113 SPEC_CVAL(val->etype).v_uint = (unsigned int) fval;
1115 SPEC_CVAL(val->etype).v_int = (int) fval;
1121 /*------------------------------------------------------------------*/
1122 /* getNelements - determines # of elements from init list */
1123 /*------------------------------------------------------------------*/
1124 int getNelements (link *type,initList *ilist)
1126 link *etype = getSpec(type);
1132 if (ilist->type == INIT_DEEP)
1133 ilist = ilist->init.deep;
1135 /* if type is a character array and there is only one
1136 initialiser then get the length of the string */
1137 if (IS_ARRAY(type) && IS_CHAR(etype) && !ilist->next) {
1138 ast *iast = ilist->init.node;
1139 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1141 werror(E_INIT_WRONG);
1144 if (!IS_ARRAY(v->type) || !IS_CHAR(v->etype)) {
1145 werror(E_INIT_WRONG);
1148 return DCL_ELEM(v->type);
1154 ilist = ilist->next;
1160 /*-----------------------------------------------------------------*/
1161 /* valForArray - returns a value with name of array index */
1162 /*-----------------------------------------------------------------*/
1163 value *valForArray (ast *arrExpr)
1165 value *val, *lval = NULL ;
1167 int size = getSize(arrExpr->left->ftype->next);
1168 /* if the right or left is an array
1170 if (IS_AST_OP(arrExpr->left)) {
1171 if (arrExpr->left->opval.op == '[')
1172 lval = valForArray(arrExpr->left);
1174 if (arrExpr->left->opval.op == '.')
1175 lval = valForStructElem(arrExpr->left->left,
1176 arrExpr->left->right);
1178 if (arrExpr->left->opval.op == PTR_OP &&
1179 IS_ADDRESS_OF_OP(arrExpr->left->left))
1180 lval = valForStructElem(arrExpr->left->left->left,
1181 arrExpr->left->right);
1186 if (!IS_AST_SYM_VALUE(arrExpr->left))
1189 if (!IS_AST_LIT_VALUE(arrExpr->right))
1194 sprintf(buffer,"%s",AST_SYMBOL(arrExpr->left)->rname);
1196 sprintf(buffer,"%s",lval->name);
1198 sprintf(val->name,"(%s + %d)",buffer,
1199 (int)AST_LIT_VALUE(arrExpr->right)*size);
1201 val->type = newLink();
1202 if (SPEC_SCLS(arrExpr->left->etype) == S_CODE) {
1203 DCL_TYPE(val->type) = CPOINTER ;
1204 DCL_PTR_CONST(val->type) = 1;
1207 if (SPEC_SCLS(arrExpr->left->etype) == S_XDATA)
1208 DCL_TYPE(val->type) = FPOINTER;
1210 if (SPEC_SCLS(arrExpr->left->etype) == S_XSTACK )
1211 DCL_TYPE(val->type) = PPOINTER ;
1213 if (SPEC_SCLS(arrExpr->left->etype) == S_IDATA)
1214 DCL_TYPE(val->type) = IPOINTER ;
1216 if (SPEC_SCLS(arrExpr->left->etype) == S_EEPROM)
1217 DCL_TYPE(val->type) = EEPPOINTER ;
1219 DCL_TYPE(val->type) = POINTER ;
1220 val->type->next = arrExpr->left->ftype;
1221 val->etype = getSpec(val->type);
1225 /*-----------------------------------------------------------------*/
1226 /* valForStructElem - returns value with name of struct element */
1227 /*-----------------------------------------------------------------*/
1228 value *valForStructElem(ast *structT, ast *elemT)
1230 value *val, *lval = NULL;
1234 /* left could be furthur derefed */
1235 if (IS_AST_OP(structT)) {
1236 if (structT->opval.op == '[')
1237 lval = valForArray(structT);
1239 if (structT->opval.op == '.')
1240 lval = valForStructElem(structT->left,structT->right);
1242 if (structT->opval.op == PTR_OP &&
1243 IS_ADDRESS_OF_OP(structT->left))
1244 lval = valForStructElem(structT->left->left,
1250 if (!IS_AST_SYM_VALUE(elemT))
1253 if (!IS_STRUCT(structT->etype))
1256 if ((sym = getStructElement(SPEC_STRUCT(structT->etype),
1257 AST_SYMBOL(elemT))) == NULL) {
1263 sprintf(buffer,"%s",AST_SYMBOL(structT)->rname);
1265 sprintf(buffer,"%s",lval->name);
1267 sprintf(val->name,"(%s + %d)",buffer,
1270 val->type = newLink();
1271 if (SPEC_SCLS(structT->etype) == S_CODE) {
1272 DCL_TYPE(val->type) = CPOINTER ;
1273 DCL_PTR_CONST(val->type) = 1;
1276 if (SPEC_SCLS(structT->etype) == S_XDATA)
1277 DCL_TYPE(val->type) = FPOINTER;
1279 if (SPEC_SCLS(structT->etype) == S_XSTACK )
1280 DCL_TYPE(val->type) = PPOINTER ;
1282 if (SPEC_SCLS(structT->etype) == S_IDATA)
1283 DCL_TYPE(val->type) = IPOINTER ;
1285 if (SPEC_SCLS(structT->etype) == S_EEPROM)
1286 DCL_TYPE(val->type) = EEPPOINTER ;
1288 DCL_TYPE(val->type) = POINTER ;
1289 val->type->next = sym->type;
1290 val->etype = getSpec(val->type);