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 -------------------------------------------------------------------------*/
30 #include "SDCCglobl.h"
38 /*-----------------------------------------------------------------*/
39 /* newValue - allocates and returns a new value */
40 /*-----------------------------------------------------------------*/
45 ALLOC(val,sizeof(value));
50 /*-----------------------------------------------------------------*/
51 /* newiList - new initializer list */
52 /*-----------------------------------------------------------------*/
53 initList *newiList ( int type, void *ilist)
58 ALLOC(nilist,sizeof(initList));
61 nilist->lineno = yylineno ;
65 nilist->init.node = (struct ast *) ilist ;
69 nilist->init.deep = (struct initList *) ilist ;
76 /*------------------------------------------------------------------*/
77 /* revinit - reverses the initial values for a value chain */
78 /*------------------------------------------------------------------*/
79 initList *revinit ( initList *val)
81 initList *prev , *curr, *next ;
95 val->next = (void *) NULL ;
99 /*------------------------------------------------------------------*/
100 /* copyIlist - copy initializer list */
101 /*------------------------------------------------------------------*/
102 initList *copyIlist (initList *src)
104 initList *dest = NULL;
111 dest = newiList (INIT_DEEP,copyIlist (src->init.deep));
114 dest = newiList (INIT_NODE,copyAst (src->init.node)) ;
119 dest->next = copyIlist(src->next);
124 /*------------------------------------------------------------------*/
125 /* list2int - converts the first element of the list to value */
126 /*------------------------------------------------------------------*/
127 double list2int (initList *val)
131 if ( i->type == INIT_DEEP )
132 return list2int (val->init.deep) ;
134 return floatFromVal(constExprValue(val->init.node,TRUE));
137 /*------------------------------------------------------------------*/
138 /* list2val - converts the first element of the list to value */
139 /*------------------------------------------------------------------*/
140 value *list2val (initList *val)
145 if ( val->type == INIT_DEEP )
146 return list2val (val->init.deep) ;
148 return constExprValue(val->init.node,TRUE);
151 /*------------------------------------------------------------------*/
152 /* list2expr - returns the first expression in the initializer list */
153 /*------------------------------------------------------------------*/
154 ast *list2expr ( initList *ilist)
156 if ( ilist->type == INIT_DEEP )
157 return list2expr (ilist->init.deep) ;
158 return ilist->init.node ;
161 /*------------------------------------------------------------------*/
162 /* resolveIvalSym - resolve symbols in initial values */
163 /*------------------------------------------------------------------*/
164 void resolveIvalSym ( initList *ilist)
169 if ( ilist->type == INIT_NODE )
170 ilist->init.node = decorateType(resolveSymbols (ilist->init.node));
172 if ( ilist->type == INIT_DEEP )
173 resolveIvalSym (ilist->init.deep);
175 resolveIvalSym (ilist->next);
178 /*-----------------------------------------------------------------*/
179 /* symbolVal - creates a value for a symbol */
180 /*-----------------------------------------------------------------*/
181 value *symbolVal ( symbol *sym )
192 val->type = sym->type;
193 val->etype= getSpec(val->type);
197 sprintf (val->name,"%s",sym->rname);
199 sprintf(val->name,"_%s",sym->name);
205 /*-----------------------------------------------------------------*/
206 /* valueFromLit - creates a value from a literal */
207 /*-----------------------------------------------------------------*/
208 value *valueFromLit (float lit)
212 if ( ( ((long) lit ) - lit ) == 0 ) {
213 sprintf(buffer,"%ld",(long) lit);
214 return constVal (buffer);
217 sprintf(buffer,"%f",lit);
218 return constFloatVal (buffer);
221 /*-----------------------------------------------------------------*/
222 /* constFloatVal - converts a FLOAT constant to value */
223 /*-----------------------------------------------------------------*/
224 value *constFloatVal ( char *s )
226 value *val = newValue();
229 if(sscanf (s,"%f",&sval) != 1) {
230 werror(E_INVALID_FLOAT_CONST,s);
231 return constVal("0");
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;
243 /*-----------------------------------------------------------------*/
244 /* constVal - converts a INTEGER constant into a value */
245 /*-----------------------------------------------------------------*/
246 value *constVal (char *s)
249 short hex = 0 , octal = 0 ;
254 val = newValue() ; /* alloc space for value */
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 ;
261 /* set the _unsigned flag if 'uU' found */
262 if (strchr(s,'u') || strchr(s,'U'))
263 SPEC_USIGN(val->type) = 1;
265 /* set the _long flag if 'lL' is found */
266 if (strchr(s,'l') || strchr(s,'L'))
267 SPEC_LONG(val->type) = 1;
269 hex = ((strchr(s,'x') || strchr(s,'X')) ? 1 : 0) ;
271 /* set the octal flag */
272 if (!hex && *s == '0' && *(s+1) )
275 /* create the scan string */
276 scanFmt[scI++] = '%' ;
279 scanFmt[scI++] = 'o' ;
282 scanFmt[scI++] = 'x' ;
284 if (SPEC_USIGN(val->type))
285 scanFmt[scI++] = 'u' ;
287 scanFmt[scI++] = 'd' ;
289 scanFmt[scI++] = '\0' ;
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);
299 if (SPEC_LONG(val->type) || sval > 32768) {
300 if (SPEC_USIGN(val->type))
301 SPEC_CVAL(val->type).v_ulong = sval ;
303 SPEC_CVAL(val->type).v_long = sval ;
304 SPEC_LONG(val->type) = 1;
307 if (SPEC_USIGN(val->type))
308 SPEC_CVAL(val->type).v_uint = sval ;
310 SPEC_CVAL(val->type).v_int = sval ;
313 // check the size and make it a short if required
315 SPEC_SHORT(val->etype) = 1;
321 /*------------------------------------------------------------------*/
322 /* copyStr - copies src to dest ignoring leading & trailing \"s */
323 /*------------------------------------------------------------------*/
324 void copyStr (char *dest, char *src )
331 if ( *src == '\\' ) {
356 /* embedded octal or hex constant */
357 if (*(src+1) == 'x' ||
359 x = strtol(src,&src,16);
363 x = strtol(src,&src,8);
392 /*------------------------------------------------------------------*/
393 /* strVal - converts a string constant to a value */
394 /*------------------------------------------------------------------*/
395 value *strVal ( char *s )
399 val = newValue() ; /* get a new one */
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;
410 ALLOC_ATOMIC(SPEC_CVAL(val->etype).v_char,strlen(s)+1);
411 copyStr (SPEC_CVAL(val->etype).v_char,s);
416 /*------------------------------------------------------------------*/
417 /* reverseValWithType - reverses value chain with type & etype */
418 /*------------------------------------------------------------------*/
419 value *reverseValWithType ( value *val )
427 /* save the type * etype chains */
431 /* set the current one 2b null */
432 val->type = val->etype = NULL;
433 val = reverseVal (val);
435 /* restore type & etype */
442 /*------------------------------------------------------------------*/
443 /* reverseVal - reverses the values for a value chain */
444 /*------------------------------------------------------------------*/
445 value *reverseVal ( value *val)
447 value *prev , *curr, *next ;
461 val->next = (void *) NULL ;
465 /*------------------------------------------------------------------*/
466 /* copyValueChain - will copy a chain of values */
467 /*------------------------------------------------------------------*/
468 value *copyValueChain ( value *src )
475 dest = copyValue (src);
476 dest->next = copyValueChain (src->next);
481 /*------------------------------------------------------------------*/
482 /* copyValue - copies contents of a vlue to a fresh one */
483 /*------------------------------------------------------------------*/
484 value *copyValue (value *src)
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);
497 /*------------------------------------------------------------------*/
498 /* charVal - converts a character constant to a value */
499 /*------------------------------------------------------------------*/
500 value *charVal ( char *s )
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 ;
511 s++ ; /* get rid of quotation */
512 /* if \ then special processing */
514 s++ ; /* go beyond the backslash */
517 SPEC_CVAL(val->type).v_int = '\n';
520 SPEC_CVAL(val->type).v_int = '\t';
523 SPEC_CVAL(val->type).v_int = '\v';
526 SPEC_CVAL(val->type).v_int = '\b';
529 SPEC_CVAL(val->type).v_int = '\r';
532 SPEC_CVAL(val->type).v_int = '\f';
535 SPEC_CVAL(val->type).v_int = '\a';
538 SPEC_CVAL(val->type).v_int = '\\';
541 SPEC_CVAL(val->type).v_int = '\?';
544 SPEC_CVAL(val->type).v_int = '\'';
547 SPEC_CVAL(val->type).v_int = '\"';
550 sscanf(s,"%o",&SPEC_CVAL(val->type).v_int);
553 s++ ; /* go behond the 'x' */
554 sscanf(s,"%x",&SPEC_CVAL(val->type).v_int);
557 SPEC_CVAL(val->type).v_int = *s;
561 else /* not a backslash */
562 SPEC_CVAL(val->type).v_int = *s;
567 /*------------------------------------------------------------------*/
568 /* valFromType - creates a value from type given */
569 /*------------------------------------------------------------------*/
570 value *valFromType ( link *type)
572 value *val = newValue();
573 val->type = copyLinkChain(type);
574 val->etype = getSpec(val->type);
578 /*------------------------------------------------------------------*/
579 /* floatFromVal - value to unsinged integer conversion */
580 /*------------------------------------------------------------------*/
581 double floatFromVal ( value *val )
586 if (SPEC_SCLS(val->etype) != S_LITERAL) {
587 werror(E_CONST_EXPECTED,val->name);
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;
596 if (SPEC_NOUN(val->etype) == V_FLOAT )
597 return (double) SPEC_CVAL(val->etype).v_float ;
599 if (SPEC_LONG(val->etype)) {
600 if (SPEC_USIGN(val->etype))
601 return (double) SPEC_CVAL(val->etype).v_ulong ;
603 return (double) SPEC_CVAL(val->etype).v_long ;
606 if (SPEC_USIGN(val->etype))
607 return (double) SPEC_CVAL(val->etype).v_uint ;
609 return (double) SPEC_CVAL(val->etype).v_int ;
615 /*------------------------------------------------------------------*/
616 /* valUnaryPM - dones the unary +/- operation on a constant */
617 /*------------------------------------------------------------------*/
618 value *valUnaryPM (value *val)
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;
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 ;
628 SPEC_CVAL(val->etype).v_long = - SPEC_CVAL(val->etype).v_long;
631 if (SPEC_USIGN(val->etype))
632 SPEC_CVAL(val->etype).v_uint = - SPEC_CVAL(val->etype).v_uint ;
634 SPEC_CVAL(val->etype).v_int = - SPEC_CVAL(val->etype).v_int ;
641 /*------------------------------------------------------------------*/
642 /* valueComplement - complements a constant */
643 /*------------------------------------------------------------------*/
644 value *valComplement ( value *val)
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 ;
651 SPEC_CVAL(val->etype).v_long = ~SPEC_CVAL(val->etype).v_long;
654 if (SPEC_USIGN(val->etype))
655 SPEC_CVAL(val->etype).v_uint = ~SPEC_CVAL(val->etype).v_uint ;
657 SPEC_CVAL(val->etype).v_int = ~SPEC_CVAL(val->etype).v_int ;
662 /*------------------------------------------------------------------*/
663 /* valueNot - complements a constant */
664 /*------------------------------------------------------------------*/
665 value *valNot ( value *val)
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 ;
672 SPEC_CVAL(val->etype).v_long = !SPEC_CVAL(val->etype).v_long;
675 if (SPEC_USIGN(val->etype))
676 SPEC_CVAL(val->etype).v_uint = !SPEC_CVAL(val->etype).v_uint ;
678 SPEC_CVAL(val->etype).v_int = !SPEC_CVAL(val->etype).v_int ;
683 /*------------------------------------------------------------------*/
684 /* valMult - multiply constants */
685 /*------------------------------------------------------------------*/
686 value *valMult (value *lval, value *rval)
690 /* create a new value */
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));
700 if (IS_FLOAT(val->type))
701 SPEC_CVAL(val->type).v_float = floatFromVal(lval) * floatFromVal(rval);
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);
708 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) *
709 (long) floatFromVal(rval);
712 if (SPEC_USIGN(val->type))
713 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) *
714 (unsigned) floatFromVal(rval);
716 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) *
717 (int) floatFromVal(rval);
723 /*------------------------------------------------------------------*/
724 /* valDiv - Divide constants */
725 /*------------------------------------------------------------------*/
726 value *valDiv (value *lval, value *rval)
730 if (floatFromVal(rval) == 0) {
731 werror(E_DIVIDE_BY_ZERO);
735 /* create a new value */
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));
745 if (IS_FLOAT(val->type))
746 SPEC_CVAL(val->type).v_float = floatFromVal(lval) / floatFromVal(rval);
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);
753 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) /
754 (long) floatFromVal(rval);
757 if (SPEC_USIGN(val->type))
758 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) /
759 (unsigned) floatFromVal(rval);
761 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) /
762 (int) floatFromVal(rval);
768 /*------------------------------------------------------------------*/
769 /* valMod - Modulus constants */
770 /*------------------------------------------------------------------*/
771 value *valMod (value *lval, value *rval)
775 /* create a new value */
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));
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);
789 SPEC_CVAL(val->type).v_long = (unsigned long) floatFromVal(lval) %
790 (unsigned long) floatFromVal(rval);
793 if (SPEC_USIGN(val->type))
794 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) %
795 (unsigned) floatFromVal(rval);
797 SPEC_CVAL(val->type).v_int = (unsigned) floatFromVal(lval) %
798 (unsigned) floatFromVal(rval);
804 /*------------------------------------------------------------------*/
805 /* valPlus - Addition constants */
806 /*------------------------------------------------------------------*/
807 value *valPlus (value *lval, value *rval)
811 /* create a new value */
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));
821 if (IS_FLOAT(val->type))
822 SPEC_CVAL(val->type).v_float = floatFromVal(lval) + floatFromVal(rval);
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);
829 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) +
830 (long) floatFromVal(rval);
833 if (SPEC_USIGN(val->type))
834 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) +
835 (unsigned) floatFromVal(rval);
837 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) +
838 (int) floatFromVal(rval);
844 /*------------------------------------------------------------------*/
845 /* valMinus - Addition constants */
846 /*------------------------------------------------------------------*/
847 value *valMinus (value *lval, value *rval)
851 /* create a new value */
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));
861 if (IS_FLOAT(val->type))
862 SPEC_CVAL(val->type).v_float = floatFromVal(lval) - floatFromVal(rval);
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);
869 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) -
870 (long) floatFromVal(rval);
873 if (SPEC_USIGN(val->type))
874 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) -
875 (unsigned) floatFromVal(rval);
877 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) - (int) floatFromVal(rval);
883 /*------------------------------------------------------------------*/
884 /* valShift - Shift left or right */
885 /*------------------------------------------------------------------*/
886 value *valShift (value *lval, value *rval, int lr)
890 /* create a new value */
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));
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);
905 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) <<
906 (long) floatFromVal(rval);
909 if (SPEC_USIGN(val->type))
910 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) <<
911 (unsigned) floatFromVal(rval);
913 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) <<
914 (int) floatFromVal(rval);
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);
923 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) >>
924 (long) floatFromVal(rval);
927 if (SPEC_USIGN(val->type))
928 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) >>
929 (unsigned) floatFromVal(rval);
931 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) >>
932 (int) floatFromVal(rval);
939 /*------------------------------------------------------------------*/
940 /* valCompare- Compares two literal */
941 /*------------------------------------------------------------------*/
942 value *valCompare (value *lval, value *rval, int ctype)
946 /* create a new value */
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 */
956 SPEC_CVAL(val->type).v_int = floatFromVal(lval) < floatFromVal(rval);
960 SPEC_CVAL(val->type).v_int = floatFromVal(lval) > floatFromVal(rval);
964 SPEC_CVAL(val->type).v_int = floatFromVal(lval) <= floatFromVal(rval);
968 SPEC_CVAL(val->type).v_int = floatFromVal(lval) >= floatFromVal(rval);
972 SPEC_CVAL(val->type).v_int = floatFromVal(lval) == floatFromVal(rval);
976 SPEC_CVAL(val->type).v_int = floatFromVal(lval) != floatFromVal(rval);
984 /*------------------------------------------------------------------*/
985 /* valBitwise - Bitwise operation */
986 /*------------------------------------------------------------------*/
987 value *valBitwise (value *lval, value *rval, int op)
991 /* create a new value */
993 val->type = copyLinkChain (lval->type);
994 val->etype = getSpec(val->type);
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);
1004 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) &
1005 (long) floatFromVal(rval);
1008 if (SPEC_USIGN(val->type))
1009 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) &
1010 (unsigned) floatFromVal(rval);
1012 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) & (int) floatFromVal(rval);
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);
1022 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) |
1023 (long) floatFromVal(rval);
1026 if (SPEC_USIGN(val->type))
1027 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) |
1028 (unsigned) floatFromVal(rval);
1030 SPEC_CVAL(val->type).v_int =
1031 (int) floatFromVal(lval) | (int) floatFromVal(rval);
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);
1042 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) ^
1043 (long) floatFromVal(rval);
1046 if (SPEC_USIGN(val->type))
1047 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) ^
1048 (unsigned) floatFromVal(rval);
1050 SPEC_CVAL(val->type).v_int =
1051 (int) floatFromVal(lval) ^ (int) floatFromVal(rval);
1059 /*------------------------------------------------------------------*/
1060 /* valAndOr - Generates code for and / or operation */
1061 /*------------------------------------------------------------------*/
1062 value *valLogicAndOr (value *lval, value *rval, int op)
1066 /* create a new value */
1068 val->type = val->etype = newCharLink();
1069 val->type->class = SPECIFIER ;
1070 SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
1075 SPEC_CVAL(val->type).v_int = floatFromVal(lval) && floatFromVal(rval);
1079 SPEC_CVAL(val->type).v_int = floatFromVal(lval) || floatFromVal(rval);
1087 /*------------------------------------------------------------------*/
1088 /* valCastLiteral - casts a literal value to another type */
1089 /*------------------------------------------------------------------*/
1090 value *valCastLiteral (link *dtype, double fval)
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;
1107 if (SPEC_NOUN(val->etype) == V_FLOAT )
1108 SPEC_CVAL(val->etype).v_float = fval;
1110 if (SPEC_LONG(val->etype)) {
1111 if (SPEC_USIGN(val->etype))
1112 SPEC_CVAL(val->etype).v_ulong = (unsigned long) fval;
1114 SPEC_CVAL(val->etype).v_long = (long) fval;
1117 if (SPEC_USIGN(val->etype))
1118 SPEC_CVAL(val->etype).v_uint = (unsigned int) fval;
1120 SPEC_CVAL(val->etype).v_int = (int) fval;
1126 /*------------------------------------------------------------------*/
1127 /* getNelements - determines # of elements from init list */
1128 /*------------------------------------------------------------------*/
1129 int getNelements (link *type,initList *ilist)
1131 link *etype = getSpec(type);
1137 if (ilist->type == INIT_DEEP)
1138 ilist = ilist->init.deep;
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);
1146 werror(E_INIT_WRONG);
1149 if (!IS_ARRAY(v->type) || !IS_CHAR(v->etype)) {
1150 werror(E_INIT_WRONG);
1153 return DCL_ELEM(v->type);
1159 ilist = ilist->next;
1165 /*-----------------------------------------------------------------*/
1166 /* valForArray - returns a value with name of array index */
1167 /*-----------------------------------------------------------------*/
1168 value *valForArray (ast *arrExpr)
1170 value *val, *lval = NULL ;
1172 int size = getSize(arrExpr->left->ftype->next);
1173 /* if the right or left is an array
1175 if (IS_AST_OP(arrExpr->left)) {
1176 if (arrExpr->left->opval.op == '[')
1177 lval = valForArray(arrExpr->left);
1179 if (arrExpr->left->opval.op == '.')
1180 lval = valForStructElem(arrExpr->left->left,
1181 arrExpr->left->right);
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);
1191 if (!IS_AST_SYM_VALUE(arrExpr->left))
1194 if (!IS_AST_LIT_VALUE(arrExpr->right))
1199 sprintf(buffer,"%s",AST_SYMBOL(arrExpr->left)->rname);
1201 sprintf(buffer,"%s",lval->name);
1203 sprintf(val->name,"(%s + %d)",buffer,
1204 (int)AST_LIT_VALUE(arrExpr->right)*size);
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;
1212 if (SPEC_SCLS(arrExpr->left->etype) == S_XDATA)
1213 DCL_TYPE(val->type) = FPOINTER;
1215 if (SPEC_SCLS(arrExpr->left->etype) == S_XSTACK )
1216 DCL_TYPE(val->type) = PPOINTER ;
1218 if (SPEC_SCLS(arrExpr->left->etype) == S_IDATA)
1219 DCL_TYPE(val->type) = IPOINTER ;
1221 DCL_TYPE(val->type) = POINTER ;
1222 val->type->next = arrExpr->left->ftype;
1223 val->etype = getSpec(val->type);
1227 /*-----------------------------------------------------------------*/
1228 /* valForStructElem - returns value with name of struct element */
1229 /*-----------------------------------------------------------------*/
1230 value *valForStructElem(ast *structT, ast *elemT)
1232 value *val, *lval = NULL;
1236 /* left could be furthur derefed */
1237 if (IS_AST_OP(structT)) {
1238 if (structT->opval.op == '[')
1239 lval = valForArray(structT);
1241 if (structT->opval.op == '.')
1242 lval = valForStructElem(structT->left,structT->right);
1244 if (structT->opval.op == PTR_OP &&
1245 IS_ADDRESS_OF_OP(structT->left))
1246 lval = valForStructElem(structT->left->left,
1252 if (!IS_AST_SYM_VALUE(elemT))
1255 if (!IS_STRUCT(structT->etype))
1258 if ((sym = getStructElement(SPEC_STRUCT(structT->etype),
1259 AST_SYMBOL(elemT))) == NULL) {
1265 sprintf(buffer,"%s",AST_SYMBOL(structT)->rname);
1267 sprintf(buffer,"%s",lval->name);
1269 sprintf(val->name,"(%s + %d)",buffer,
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;
1278 if (SPEC_SCLS(structT->etype) == S_XDATA)
1279 DCL_TYPE(val->type) = FPOINTER;
1281 if (SPEC_SCLS(structT->etype) == S_XSTACK )
1282 DCL_TYPE(val->type) = PPOINTER ;
1284 if (SPEC_SCLS(structT->etype) == S_IDATA)
1285 DCL_TYPE(val->type) = IPOINTER ;
1287 DCL_TYPE(val->type) = POINTER ;
1288 val->type->next = sym->type;
1289 val->etype = getSpec(val->type);