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 -------------------------------------------------------------------------*/
34 /*-----------------------------------------------------------------*/
35 /* newValue - allocates and returns a new value */
36 /*-----------------------------------------------------------------*/
41 val = Safe_calloc(1,sizeof(value));
46 /*-----------------------------------------------------------------*/
47 /* newiList - new initializer list */
48 /*-----------------------------------------------------------------*/
49 initList *newiList ( int type, void *ilist)
54 nilist = Safe_calloc(1,sizeof(initList));
57 nilist->lineno = yylineno ;
61 nilist->init.node = (struct ast *) ilist ;
65 nilist->init.deep = (struct initList *) ilist ;
72 /*------------------------------------------------------------------*/
73 /* revinit - reverses the initial values for a value chain */
74 /*------------------------------------------------------------------*/
75 initList *revinit ( initList *val)
77 initList *prev , *curr, *next ;
91 val->next = (void *) NULL ;
95 /*------------------------------------------------------------------*/
96 /* copyIlist - copy initializer list */
97 /*------------------------------------------------------------------*/
98 initList *copyIlist (initList *src)
100 initList *dest = NULL;
107 dest = newiList (INIT_DEEP,copyIlist (src->init.deep));
110 dest = newiList (INIT_NODE,copyAst (src->init.node)) ;
115 dest->next = copyIlist(src->next);
120 /*------------------------------------------------------------------*/
121 /* list2int - converts the first element of the list to value */
122 /*------------------------------------------------------------------*/
123 double list2int (initList *val)
127 if ( i->type == INIT_DEEP )
128 return list2int (val->init.deep) ;
130 return floatFromVal(constExprValue(val->init.node,TRUE));
133 /*------------------------------------------------------------------*/
134 /* list2val - converts the first element of the list to value */
135 /*------------------------------------------------------------------*/
136 value *list2val (initList *val)
141 if ( val->type == INIT_DEEP )
142 return list2val (val->init.deep) ;
144 return constExprValue(val->init.node,TRUE);
147 /*------------------------------------------------------------------*/
148 /* list2expr - returns the first expression in the initializer list */
149 /*------------------------------------------------------------------*/
150 ast *list2expr ( initList *ilist)
152 if ( ilist->type == INIT_DEEP )
153 return list2expr (ilist->init.deep) ;
154 return ilist->init.node ;
157 /*------------------------------------------------------------------*/
158 /* resolveIvalSym - resolve symbols in initial values */
159 /*------------------------------------------------------------------*/
160 void resolveIvalSym ( initList *ilist)
165 if ( ilist->type == INIT_NODE )
166 ilist->init.node = decorateType(resolveSymbols (ilist->init.node));
168 if ( ilist->type == INIT_DEEP )
169 resolveIvalSym (ilist->init.deep);
171 resolveIvalSym (ilist->next);
174 /*-----------------------------------------------------------------*/
175 /* symbolVal - creates a value for a symbol */
176 /*-----------------------------------------------------------------*/
177 value *symbolVal ( symbol *sym )
188 val->type = sym->type;
189 val->etype= getSpec(val->type);
193 sprintf (val->name,"%s",sym->rname);
195 sprintf(val->name,"_%s",sym->name);
201 /*-----------------------------------------------------------------*/
202 /* valueFromLit - creates a value from a literal */
203 /*-----------------------------------------------------------------*/
204 value *valueFromLit (float lit)
208 if ( ( ((long) lit ) - lit ) == 0 ) {
209 sprintf(buffer,"%ld",(long) lit);
210 return constVal (buffer);
213 sprintf(buffer,"%f",lit);
214 return constFloatVal (buffer);
217 /*-----------------------------------------------------------------*/
218 /* constFloatVal - converts a FLOAT constant to value */
219 /*-----------------------------------------------------------------*/
220 value *constFloatVal ( char *s )
222 value *val = newValue();
225 if(sscanf (s,"%f",&sval) != 1) {
226 werror(E_INVALID_FLOAT_CONST,s);
227 return constVal("0");
230 val->type = val->etype = newLink();
231 val->type->class = SPECIFIER ;
232 SPEC_NOUN(val->type) = V_FLOAT ;
233 SPEC_SCLS(val->type) = S_LITERAL;
234 SPEC_CVAL(val->type).v_float = sval;
239 /*-----------------------------------------------------------------*/
240 /* constVal - converts a INTEGER constant into a value */
241 /*-----------------------------------------------------------------*/
242 value *constVal (char *s)
245 short hex = 0 , octal = 0 ;
250 val = newValue() ; /* alloc space for value */
252 val->type = val->etype = newLink() ; /* create the spcifier */
253 val->type->class = SPECIFIER ;
254 SPEC_NOUN(val->type) = V_INT ;
255 SPEC_SCLS(val->type) = S_LITERAL ;
257 /* set the _unsigned flag if 'uU' found */
258 if (strchr(s,'u') || strchr(s,'U'))
259 SPEC_USIGN(val->type) = 1;
261 /* set the _long flag if 'lL' is found */
262 if (strchr(s,'l') || strchr(s,'L'))
263 SPEC_LONG(val->type) = 1;
265 hex = ((strchr(s,'x') || strchr(s,'X')) ? 1 : 0) ;
267 /* set the octal flag */
268 if (!hex && *s == '0' && *(s+1) )
271 /* create the scan string */
272 scanFmt[scI++] = '%' ;
275 scanFmt[scI++] = 'o' ;
278 scanFmt[scI++] = 'x' ;
280 if (SPEC_USIGN(val->type))
281 scanFmt[scI++] = 'u' ;
283 scanFmt[scI++] = 'd' ;
285 scanFmt[scI++] = '\0' ;
287 /* if hex or octal then set the unsigned flag */
288 if ( hex || octal ) {
289 SPEC_USIGN(val->type) = 1 ;
290 sscanf(s,scanFmt,&sval);
295 if (SPEC_LONG(val->type) || sval > 32768) {
296 if (SPEC_USIGN(val->type))
297 SPEC_CVAL(val->type).v_ulong = sval ;
299 SPEC_CVAL(val->type).v_long = sval ;
300 SPEC_LONG(val->type) = 1;
303 if (SPEC_USIGN(val->type))
304 SPEC_CVAL(val->type).v_uint = sval ;
306 SPEC_CVAL(val->type).v_int = sval ;
309 // check the size and make it a short if required
311 SPEC_SHORT(val->etype) = 1;
317 /*------------------------------------------------------------------*/
318 /* copyStr - copies src to dest ignoring leading & trailing \"s */
319 /*------------------------------------------------------------------*/
320 void copyStr (char *dest, char *src )
327 if ( *src == '\\' ) {
352 /* embedded octal or hex constant */
353 if (*(src+1) == 'x' ||
355 x = strtol(src,&src,16);
359 x = strtol(src,&src,8);
388 /*------------------------------------------------------------------*/
389 /* strVal - converts a string constant to a value */
390 /*------------------------------------------------------------------*/
391 value *strVal ( char *s )
395 val = newValue() ; /* get a new one */
397 /* get a declarator */
398 val->type = newLink();
399 DCL_TYPE(val->type) = ARRAY ;
400 DCL_ELEM(val->type) = strlen(s) - 1;
401 val->type->next = val->etype = newLink() ;
402 val->etype->class = SPECIFIER;
403 SPEC_NOUN(val->etype) = V_CHAR ;
404 SPEC_SCLS(val->etype) = S_LITERAL;
406 SPEC_CVAL(val->etype).v_char = Safe_calloc(1,strlen(s)+1);
407 copyStr (SPEC_CVAL(val->etype).v_char,s);
412 /*------------------------------------------------------------------*/
413 /* reverseValWithType - reverses value chain with type & etype */
414 /*------------------------------------------------------------------*/
415 value *reverseValWithType ( value *val )
423 /* save the type * etype chains */
427 /* set the current one 2b null */
428 val->type = val->etype = NULL;
429 val = reverseVal (val);
431 /* restore type & etype */
438 /*------------------------------------------------------------------*/
439 /* reverseVal - reverses the values for a value chain */
440 /*------------------------------------------------------------------*/
441 value *reverseVal ( value *val)
443 value *prev , *curr, *next ;
457 val->next = (void *) NULL ;
461 /*------------------------------------------------------------------*/
462 /* copyValueChain - will copy a chain of values */
463 /*------------------------------------------------------------------*/
464 value *copyValueChain ( value *src )
471 dest = copyValue (src);
472 dest->next = copyValueChain (src->next);
477 /*------------------------------------------------------------------*/
478 /* copyValue - copies contents of a vlue to a fresh one */
479 /*------------------------------------------------------------------*/
480 value *copyValue (value *src)
485 dest->sym = copySymbol(src->sym);
486 strcpy(dest->name,src->name);
487 dest->type = (src->type ? copyLinkChain(src->type) : NULL) ;
488 dest->etype = (src->type ? getSpec(dest->type) : NULL);
493 /*------------------------------------------------------------------*/
494 /* charVal - converts a character constant to a value */
495 /*------------------------------------------------------------------*/
496 value *charVal ( char *s )
502 val->type = val->etype = newLink();
503 val->type->class = SPECIFIER ;
504 SPEC_NOUN(val->type) = V_CHAR ;
505 SPEC_SCLS(val->type) = S_LITERAL ;
507 s++ ; /* get rid of quotation */
508 /* if \ then special processing */
510 s++ ; /* go beyond the backslash */
513 SPEC_CVAL(val->type).v_int = '\n';
516 SPEC_CVAL(val->type).v_int = '\t';
519 SPEC_CVAL(val->type).v_int = '\v';
522 SPEC_CVAL(val->type).v_int = '\b';
525 SPEC_CVAL(val->type).v_int = '\r';
528 SPEC_CVAL(val->type).v_int = '\f';
531 SPEC_CVAL(val->type).v_int = '\a';
534 SPEC_CVAL(val->type).v_int = '\\';
537 SPEC_CVAL(val->type).v_int = '\?';
540 SPEC_CVAL(val->type).v_int = '\'';
543 SPEC_CVAL(val->type).v_int = '\"';
546 sscanf(s,"%o",&SPEC_CVAL(val->type).v_int);
549 s++ ; /* go behond the 'x' */
550 sscanf(s,"%x",&SPEC_CVAL(val->type).v_int);
553 SPEC_CVAL(val->type).v_int = *s;
557 else /* not a backslash */
558 SPEC_CVAL(val->type).v_int = *s;
563 /*------------------------------------------------------------------*/
564 /* valFromType - creates a value from type given */
565 /*------------------------------------------------------------------*/
566 value *valFromType ( sym_link *type)
568 value *val = newValue();
569 val->type = copyLinkChain(type);
570 val->etype = getSpec(val->type);
574 /*------------------------------------------------------------------*/
575 /* floatFromVal - value to unsinged integer conversion */
576 /*------------------------------------------------------------------*/
577 double floatFromVal ( value *val )
582 if (val->etype && SPEC_SCLS(val->etype) != S_LITERAL) {
583 werror(E_CONST_EXPECTED,val->name);
587 /* if it is not a specifier then we can assume that */
588 /* it will be an unsigned long */
589 if (!IS_SPEC(val->type))
590 return (double) SPEC_CVAL(val->etype).v_ulong;
592 if (SPEC_NOUN(val->etype) == V_FLOAT )
593 return (double) SPEC_CVAL(val->etype).v_float ;
595 if (SPEC_LONG(val->etype)) {
596 if (SPEC_USIGN(val->etype))
597 return (double) SPEC_CVAL(val->etype).v_ulong ;
599 return (double) SPEC_CVAL(val->etype).v_long ;
602 if (SPEC_USIGN(val->etype))
603 return (double) SPEC_CVAL(val->etype).v_uint ;
605 return (double) SPEC_CVAL(val->etype).v_int ;
611 /*------------------------------------------------------------------*/
612 /* valUnaryPM - dones the unary +/- operation on a constant */
613 /*------------------------------------------------------------------*/
614 value *valUnaryPM (value *val)
616 /* depending on type */
617 if (SPEC_NOUN(val->etype) == V_FLOAT )
618 SPEC_CVAL(val->etype).v_float = -1.0 * SPEC_CVAL(val->etype).v_float;
620 if ( SPEC_LONG(val->etype)) {
621 if (SPEC_USIGN(val->etype))
622 SPEC_CVAL(val->etype).v_ulong = - SPEC_CVAL(val->etype).v_ulong ;
624 SPEC_CVAL(val->etype).v_long = - SPEC_CVAL(val->etype).v_long;
627 if (SPEC_USIGN(val->etype))
628 SPEC_CVAL(val->etype).v_uint = - SPEC_CVAL(val->etype).v_uint ;
630 SPEC_CVAL(val->etype).v_int = - SPEC_CVAL(val->etype).v_int ;
637 /*------------------------------------------------------------------*/
638 /* valueComplement - complements a constant */
639 /*------------------------------------------------------------------*/
640 value *valComplement ( value *val)
642 /* depending on type */
643 if ( SPEC_LONG(val->etype)) {
644 if (SPEC_USIGN(val->etype))
645 SPEC_CVAL(val->etype).v_ulong = ~SPEC_CVAL(val->etype).v_ulong ;
647 SPEC_CVAL(val->etype).v_long = ~SPEC_CVAL(val->etype).v_long;
650 if (SPEC_USIGN(val->etype))
651 SPEC_CVAL(val->etype).v_uint = ~SPEC_CVAL(val->etype).v_uint ;
653 SPEC_CVAL(val->etype).v_int = ~SPEC_CVAL(val->etype).v_int ;
658 /*------------------------------------------------------------------*/
659 /* valueNot - complements a constant */
660 /*------------------------------------------------------------------*/
661 value *valNot ( value *val)
663 /* depending on type */
664 if ( SPEC_LONG(val->etype)) {
665 if (SPEC_USIGN(val->etype))
666 SPEC_CVAL(val->etype).v_ulong = !SPEC_CVAL(val->etype).v_ulong ;
668 SPEC_CVAL(val->etype).v_long = !SPEC_CVAL(val->etype).v_long;
671 if (SPEC_USIGN(val->etype))
672 SPEC_CVAL(val->etype).v_uint = !SPEC_CVAL(val->etype).v_uint ;
674 SPEC_CVAL(val->etype).v_int = !SPEC_CVAL(val->etype).v_int ;
679 /*------------------------------------------------------------------*/
680 /* valMult - multiply constants */
681 /*------------------------------------------------------------------*/
682 value *valMult (value *lval, value *rval)
686 /* create a new value */
688 val->type = val->etype = newLink();
689 val->type->class = SPECIFIER ;
690 SPEC_NOUN(val->type) = (IS_FLOAT(lval->etype) ||
691 IS_FLOAT(rval->etype) ? V_FLOAT : V_INT );
692 SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
693 SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
694 SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
696 if (IS_FLOAT(val->type))
697 SPEC_CVAL(val->type).v_float = floatFromVal(lval) * floatFromVal(rval);
699 if (SPEC_LONG(val->type)) {
700 if (SPEC_USIGN(val->type))
701 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) *
702 (unsigned long) floatFromVal(rval);
704 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) *
705 (long) floatFromVal(rval);
708 if (SPEC_USIGN(val->type))
709 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) *
710 (unsigned) floatFromVal(rval);
712 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) *
713 (int) floatFromVal(rval);
719 /*------------------------------------------------------------------*/
720 /* valDiv - Divide constants */
721 /*------------------------------------------------------------------*/
722 value *valDiv (value *lval, value *rval)
726 if (floatFromVal(rval) == 0) {
727 werror(E_DIVIDE_BY_ZERO);
731 /* create a new value */
733 val->type = val->etype = ((floatFromVal(lval) / floatFromVal(rval)) < 256 ?
734 newCharLink() : newIntLink());
735 if (IS_FLOAT(lval->etype) || IS_FLOAT(rval->etype))
736 SPEC_NOUN(val->etype) = V_FLOAT ;
737 SPEC_SCLS(val->etype) = S_LITERAL ;
738 SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
739 SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
741 if (IS_FLOAT(val->type))
742 SPEC_CVAL(val->type).v_float = floatFromVal(lval) / floatFromVal(rval);
744 if (SPEC_LONG(val->type)) {
745 if (SPEC_USIGN(val->type))
746 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) /
747 (unsigned long) floatFromVal(rval);
749 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) /
750 (long) floatFromVal(rval);
753 if (SPEC_USIGN(val->type))
754 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) /
755 (unsigned) floatFromVal(rval);
757 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) /
758 (int) floatFromVal(rval);
764 /*------------------------------------------------------------------*/
765 /* valMod - Modulus constants */
766 /*------------------------------------------------------------------*/
767 value *valMod (value *lval, value *rval)
771 /* create a new value */
773 val->type = val->etype = newLink();
774 val->type->class = SPECIFIER ;
775 SPEC_NOUN(val->type) = V_INT ; /* type is int */
776 SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
777 SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
778 SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
780 if (SPEC_LONG(val->type)) {
781 if (SPEC_USIGN(val->type))
782 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) %
783 (unsigned long) floatFromVal(rval);
785 SPEC_CVAL(val->type).v_long = (unsigned long) floatFromVal(lval) %
786 (unsigned long) floatFromVal(rval);
789 if (SPEC_USIGN(val->type))
790 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) %
791 (unsigned) floatFromVal(rval);
793 SPEC_CVAL(val->type).v_int = (unsigned) floatFromVal(lval) %
794 (unsigned) floatFromVal(rval);
800 /*------------------------------------------------------------------*/
801 /* valPlus - Addition constants */
802 /*------------------------------------------------------------------*/
803 value *valPlus (value *lval, value *rval)
807 /* create a new value */
809 val->type = val->etype = newLink();
810 val->type->class = SPECIFIER ;
811 SPEC_NOUN(val->type) = (IS_FLOAT(lval->etype) ||
812 IS_FLOAT(rval->etype) ? V_FLOAT : V_INT );
813 SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
814 SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
815 SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
817 if (IS_FLOAT(val->type))
818 SPEC_CVAL(val->type).v_float = floatFromVal(lval) + floatFromVal(rval);
820 if (SPEC_LONG(val->type)) {
821 if (SPEC_USIGN(val->type))
822 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) +
823 (unsigned long) floatFromVal(rval);
825 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) +
826 (long) floatFromVal(rval);
829 if (SPEC_USIGN(val->type))
830 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) +
831 (unsigned) floatFromVal(rval);
833 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) +
834 (int) floatFromVal(rval);
840 /*------------------------------------------------------------------*/
841 /* valMinus - Addition constants */
842 /*------------------------------------------------------------------*/
843 value *valMinus (value *lval, value *rval)
847 /* create a new value */
849 val->type = val->etype = newLink();
850 val->type->class = SPECIFIER ;
851 SPEC_NOUN(val->type) = (IS_FLOAT(lval->etype) ||
852 IS_FLOAT(rval->etype) ? V_FLOAT : V_INT );
853 SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
854 SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
855 SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
857 if (IS_FLOAT(val->type))
858 SPEC_CVAL(val->type).v_float = floatFromVal(lval) - floatFromVal(rval);
860 if (SPEC_LONG(val->type)) {
861 if (SPEC_USIGN(val->type))
862 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) -
863 (unsigned long) floatFromVal(rval);
865 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) -
866 (long) floatFromVal(rval);
869 if (SPEC_USIGN(val->type))
870 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) -
871 (unsigned) floatFromVal(rval);
873 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) - (int) floatFromVal(rval);
879 /*------------------------------------------------------------------*/
880 /* valShift - Shift left or right */
881 /*------------------------------------------------------------------*/
882 value *valShift (value *lval, value *rval, int lr)
886 /* create a new value */
888 val->type = val->etype = newLink();
889 val->type->class = SPECIFIER ;
890 SPEC_NOUN(val->type) = V_INT ; /* type is int */
891 SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
892 SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype));
893 SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype));
896 if (SPEC_LONG(val->type)) {
897 if (SPEC_USIGN(val->type))
898 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) <<
899 (unsigned long) floatFromVal(rval);
901 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) <<
902 (long) floatFromVal(rval);
905 if (SPEC_USIGN(val->type))
906 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) <<
907 (unsigned) floatFromVal(rval);
909 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) <<
910 (int) floatFromVal(rval);
914 if (SPEC_LONG(val->type)) {
915 if (SPEC_USIGN(val->type))
916 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) >>
917 (unsigned long) floatFromVal(rval);
919 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) >>
920 (long) floatFromVal(rval);
923 if (SPEC_USIGN(val->type))
924 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) >>
925 (unsigned) floatFromVal(rval);
927 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) >>
928 (int) floatFromVal(rval);
935 /*------------------------------------------------------------------*/
936 /* valCompare- Compares two literal */
937 /*------------------------------------------------------------------*/
938 value *valCompare (value *lval, value *rval, int ctype)
942 /* create a new value */
944 val->type = val->etype = newCharLink();
945 val->type->class = SPECIFIER ;
946 SPEC_NOUN(val->type) = V_INT ; /* type is int */
947 SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
952 SPEC_CVAL(val->type).v_int = floatFromVal(lval) < floatFromVal(rval);
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);
980 /*------------------------------------------------------------------*/
981 /* valBitwise - Bitwise operation */
982 /*------------------------------------------------------------------*/
983 value *valBitwise (value *lval, value *rval, int op)
987 /* create a new value */
989 val->type = copyLinkChain (lval->type);
990 val->etype = getSpec(val->type);
995 if (SPEC_LONG(val->type)) {
996 if (SPEC_USIGN(val->type))
997 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) &
998 (unsigned long) floatFromVal(rval);
1000 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) &
1001 (long) floatFromVal(rval);
1004 if (SPEC_USIGN(val->type))
1005 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) &
1006 (unsigned) floatFromVal(rval);
1008 SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) & (int) floatFromVal(rval);
1013 if (SPEC_LONG(val->type)) {
1014 if (SPEC_USIGN(val->type))
1015 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) |
1016 (unsigned long) floatFromVal(rval);
1018 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) |
1019 (long) floatFromVal(rval);
1022 if (SPEC_USIGN(val->type))
1023 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) |
1024 (unsigned) floatFromVal(rval);
1026 SPEC_CVAL(val->type).v_int =
1027 (int) floatFromVal(lval) | (int) floatFromVal(rval);
1033 if (SPEC_LONG(val->type)) {
1034 if (SPEC_USIGN(val->type))
1035 SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) ^
1036 (unsigned long) floatFromVal(rval);
1038 SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) ^
1039 (long) floatFromVal(rval);
1042 if (SPEC_USIGN(val->type))
1043 SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) ^
1044 (unsigned) floatFromVal(rval);
1046 SPEC_CVAL(val->type).v_int =
1047 (int) floatFromVal(lval) ^ (int) floatFromVal(rval);
1055 /*------------------------------------------------------------------*/
1056 /* valAndOr - Generates code for and / or operation */
1057 /*------------------------------------------------------------------*/
1058 value *valLogicAndOr (value *lval, value *rval, int op)
1062 /* create a new value */
1064 val->type = val->etype = newCharLink();
1065 val->type->class = SPECIFIER ;
1066 SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
1071 SPEC_CVAL(val->type).v_int = floatFromVal(lval) && floatFromVal(rval);
1075 SPEC_CVAL(val->type).v_int = floatFromVal(lval) || floatFromVal(rval);
1083 /*------------------------------------------------------------------*/
1084 /* valCastLiteral - casts a literal value to another type */
1085 /*------------------------------------------------------------------*/
1086 value *valCastLiteral (sym_link *dtype, double fval)
1094 val->etype = getSpec (val->type = copyLinkChain(dtype));
1095 SPEC_SCLS(val->etype) = S_LITERAL ;
1096 /* if it is not a specifier then we can assume that */
1097 /* it will be an unsigned long */
1098 if (!IS_SPEC(val->type)) {
1099 SPEC_CVAL(val->etype).v_ulong = (unsigned long) fval;
1103 if (SPEC_NOUN(val->etype) == V_FLOAT )
1104 SPEC_CVAL(val->etype).v_float = fval;
1106 if (SPEC_LONG(val->etype)) {
1107 if (SPEC_USIGN(val->etype))
1108 SPEC_CVAL(val->etype).v_ulong = (unsigned long) fval;
1110 SPEC_CVAL(val->etype).v_long = (long) fval;
1113 if (SPEC_USIGN(val->etype))
1114 SPEC_CVAL(val->etype).v_uint = (unsigned int) fval;
1116 SPEC_CVAL(val->etype).v_int = (int) fval;
1122 /*------------------------------------------------------------------*/
1123 /* getNelements - determines # of elements from init list */
1124 /*------------------------------------------------------------------*/
1125 int getNelements (sym_link *type,initList *ilist)
1127 sym_link *etype = getSpec(type);
1133 if (ilist->type == INIT_DEEP)
1134 ilist = ilist->init.deep;
1136 /* if type is a character array and there is only one
1137 initialiser then get the length of the string */
1138 if (IS_ARRAY(type) && IS_CHAR(etype) && !ilist->next) {
1139 ast *iast = ilist->init.node;
1140 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1142 werror(E_INIT_WRONG);
1145 if (!IS_ARRAY(v->type) || !IS_CHAR(v->etype)) {
1146 werror(E_INIT_WRONG);
1149 return DCL_ELEM(v->type);
1155 ilist = ilist->next;
1161 /*-----------------------------------------------------------------*/
1162 /* valForArray - returns a value with name of array index */
1163 /*-----------------------------------------------------------------*/
1164 value *valForArray (ast *arrExpr)
1166 value *val, *lval = NULL ;
1168 int size = getSize(arrExpr->left->ftype->next);
1169 /* if the right or left is an array
1171 if (IS_AST_OP(arrExpr->left)) {
1172 if (arrExpr->left->opval.op == '[')
1173 lval = valForArray(arrExpr->left);
1175 if (arrExpr->left->opval.op == '.')
1176 lval = valForStructElem(arrExpr->left->left,
1177 arrExpr->left->right);
1179 if (arrExpr->left->opval.op == PTR_OP &&
1180 IS_ADDRESS_OF_OP(arrExpr->left->left))
1181 lval = valForStructElem(arrExpr->left->left->left,
1182 arrExpr->left->right);
1187 if (!IS_AST_SYM_VALUE(arrExpr->left))
1190 if (!IS_AST_LIT_VALUE(arrExpr->right))
1195 sprintf(buffer,"%s",AST_SYMBOL(arrExpr->left)->rname);
1197 sprintf(buffer,"%s",lval->name);
1199 sprintf(val->name,"(%s + %d)",buffer,
1200 (int)AST_LIT_VALUE(arrExpr->right)*size);
1202 val->type = newLink();
1203 if (SPEC_SCLS(arrExpr->left->etype) == S_CODE) {
1204 DCL_TYPE(val->type) = CPOINTER ;
1205 DCL_PTR_CONST(val->type) = port->mem.code_ro;
1208 if (SPEC_SCLS(arrExpr->left->etype) == S_XDATA)
1209 DCL_TYPE(val->type) = FPOINTER;
1211 if (SPEC_SCLS(arrExpr->left->etype) == S_XSTACK )
1212 DCL_TYPE(val->type) = PPOINTER ;
1214 if (SPEC_SCLS(arrExpr->left->etype) == S_IDATA)
1215 DCL_TYPE(val->type) = IPOINTER ;
1217 if (SPEC_SCLS(arrExpr->left->etype) == S_EEPROM)
1218 DCL_TYPE(val->type) = EEPPOINTER ;
1220 DCL_TYPE(val->type) = POINTER ;
1221 val->type->next = arrExpr->left->ftype;
1222 val->etype = getSpec(val->type);
1226 /*-----------------------------------------------------------------*/
1227 /* valForStructElem - returns value with name of struct element */
1228 /*-----------------------------------------------------------------*/
1229 value *valForStructElem(ast *structT, ast *elemT)
1231 value *val, *lval = NULL;
1235 /* left could be furthur derefed */
1236 if (IS_AST_OP(structT)) {
1237 if (structT->opval.op == '[')
1238 lval = valForArray(structT);
1240 if (structT->opval.op == '.')
1241 lval = valForStructElem(structT->left,structT->right);
1243 if (structT->opval.op == PTR_OP &&
1244 IS_ADDRESS_OF_OP(structT->left))
1245 lval = valForStructElem(structT->left->left,
1251 if (!IS_AST_SYM_VALUE(elemT))
1254 if (!IS_STRUCT(structT->etype))
1257 if ((sym = getStructElement(SPEC_STRUCT(structT->etype),
1258 AST_SYMBOL(elemT))) == NULL) {
1264 sprintf(buffer,"%s",AST_SYMBOL(structT)->rname);
1266 sprintf(buffer,"%s",lval->name);
1268 sprintf(val->name,"(%s + %d)",buffer,
1271 val->type = newLink();
1272 if (SPEC_SCLS(structT->etype) == S_CODE) {
1273 DCL_TYPE(val->type) = CPOINTER ;
1274 DCL_PTR_CONST(val->type) = port->mem.code_ro;
1277 if (SPEC_SCLS(structT->etype) == S_XDATA)
1278 DCL_TYPE(val->type) = FPOINTER;
1280 if (SPEC_SCLS(structT->etype) == S_XSTACK )
1281 DCL_TYPE(val->type) = PPOINTER ;
1283 if (SPEC_SCLS(structT->etype) == S_IDATA)
1284 DCL_TYPE(val->type) = IPOINTER ;
1286 if (SPEC_SCLS(structT->etype) == S_EEPROM)
1287 DCL_TYPE(val->type) = EEPPOINTER ;
1289 DCL_TYPE(val->type) = POINTER ;
1290 val->type->next = sym->type;
1291 val->etype = getSpec(val->type);
1295 /*-----------------------------------------------------------------*/
1296 /* valForCastAggr - will return value for a cast of an aggregate */
1297 /* plus minus a constant */
1298 /*-----------------------------------------------------------------*/
1299 value *valForCastAggr (ast *aexpr, sym_link *type, ast *cnst, int op)
1303 if (!IS_AST_SYM_VALUE(aexpr)) return NULL;
1304 if (!IS_AST_LIT_VALUE(cnst)) return NULL;
1308 sprintf(val->name,"(%s %c %d)",
1309 AST_SYMBOL(aexpr)->rname, op,
1310 getSize(type->next)*(int)AST_LIT_VALUE(cnst));
1313 val->etype = getSpec(val->type);