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 /*-----------------------------------------------------------------*/
42 val = Safe_calloc (1, sizeof (value));
47 /*-----------------------------------------------------------------*/
48 /* newiList - new initializer list */
49 /*-----------------------------------------------------------------*/
51 newiList (int type, void *ilist)
56 nilist = Safe_calloc (1, sizeof (initList));
59 nilist->lineno = yylineno;
64 nilist->init.node = (struct ast *) ilist;
68 nilist->init.deep = (struct initList *) ilist;
75 /*------------------------------------------------------------------*/
76 /* revinit - reverses the initial values for a value chain */
77 /*------------------------------------------------------------------*/
79 revinit (initList * val)
81 initList *prev, *curr, *next;
96 val->next = (void *) NULL;
100 /*------------------------------------------------------------------*/
101 /* copyIlist - copy initializer list */
102 /*------------------------------------------------------------------*/
104 copyIlist (initList * src)
106 initList *dest = NULL;
114 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
117 dest = newiList (INIT_NODE, copyAst (src->init.node));
122 dest->next = copyIlist (src->next);
127 /*------------------------------------------------------------------*/
128 /* list2int - converts the first element of the list to value */
129 /*------------------------------------------------------------------*/
131 list2int (initList * val)
135 if (i->type == INIT_DEEP)
136 return list2int (val->init.deep);
138 return floatFromVal (constExprValue (val->init.node, TRUE));
141 /*------------------------------------------------------------------*/
142 /* list2val - converts the first element of the list to value */
143 /*------------------------------------------------------------------*/
145 list2val (initList * val)
150 if (val->type == INIT_DEEP)
151 return list2val (val->init.deep);
153 return constExprValue (val->init.node, TRUE);
156 /*------------------------------------------------------------------*/
157 /* list2expr - returns the first expression in the initializer list */
158 /*------------------------------------------------------------------*/
160 list2expr (initList * ilist)
162 if (ilist->type == INIT_DEEP)
163 return list2expr (ilist->init.deep);
164 return ilist->init.node;
167 /*------------------------------------------------------------------*/
168 /* resolveIvalSym - resolve symbols in initial values */
169 /*------------------------------------------------------------------*/
171 resolveIvalSym (initList * ilist)
176 if (ilist->type == INIT_NODE)
177 ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
179 if (ilist->type == INIT_DEEP)
180 resolveIvalSym (ilist->init.deep);
182 resolveIvalSym (ilist->next);
185 /*-----------------------------------------------------------------*/
186 /* symbolVal - creates a value for a symbol */
187 /*-----------------------------------------------------------------*/
189 symbolVal (symbol * sym)
201 val->type = sym->type;
202 val->etype = getSpec (val->type);
206 sprintf (val->name, "%s", sym->rname);
208 sprintf (val->name, "_%s", sym->name);
214 /*-----------------------------------------------------------------*/
215 /* valueFromLit - creates a value from a literal */
216 /*-----------------------------------------------------------------*/
218 valueFromLit (float lit)
222 if ((((long) lit) - lit) == 0)
224 sprintf (buffer, "%ld", (long) lit);
225 return constVal (buffer);
228 sprintf (buffer, "%f", lit);
229 return constFloatVal (buffer);
232 /*-----------------------------------------------------------------*/
233 /* constFloatVal - converts a FLOAT constant to value */
234 /*-----------------------------------------------------------------*/
236 constFloatVal (char *s)
238 value *val = newValue ();
241 if (sscanf (s, "%f", &sval) != 1)
243 werror (E_INVALID_FLOAT_CONST, s);
244 return constVal ("0");
247 val->type = val->etype = newLink ();
248 val->type->class = SPECIFIER;
249 SPEC_NOUN (val->type) = V_FLOAT;
250 SPEC_SCLS (val->type) = S_LITERAL;
251 SPEC_CVAL (val->type).v_float = sval;
256 /*-----------------------------------------------------------------*/
257 /* constVal - converts a INTEGER constant into a value */
258 /*-----------------------------------------------------------------*/
263 short hex = 0, octal = 0;
268 val = newValue (); /* alloc space for value */
270 val->type = val->etype = newLink (); /* create the spcifier */
271 val->type->class = SPECIFIER;
272 SPEC_NOUN (val->type) = V_INT;
273 SPEC_SCLS (val->type) = S_LITERAL;
275 /* set the _unsigned flag if 'uU' found */
276 if (strchr (s, 'u') || strchr (s, 'U'))
277 SPEC_USIGN (val->type) = 1;
279 /* set the _long flag if 'lL' is found */
280 if (strchr (s, 'l') || strchr (s, 'L'))
281 SPEC_LONG (val->type) = 1;
283 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
285 /* set the octal flag */
286 if (!hex && *s == '0' && *(s + 1))
289 /* create the scan string */
290 scanFmt[scI++] = '%';
293 scanFmt[scI++] = 'o';
295 scanFmt[scI++] = 'x';
296 else if (SPEC_USIGN (val->type))
297 scanFmt[scI++] = 'u';
299 scanFmt[scI++] = 'd';
301 scanFmt[scI++] = '\0';
303 /* if hex or octal then set the unsigned flag */
306 SPEC_USIGN (val->type) = 1;
307 sscanf (s, scanFmt, &sval);
313 if (SPEC_LONG (val->type) || sval > 32768)
315 if (SPEC_USIGN (val->type))
316 SPEC_CVAL (val->type).v_ulong = sval;
318 SPEC_CVAL (val->type).v_long = sval;
319 SPEC_LONG (val->type) = 1;
323 if (SPEC_USIGN (val->type))
324 SPEC_CVAL (val->type).v_uint = sval;
326 SPEC_CVAL (val->type).v_int = sval;
329 // check the size and make it a short if required
331 SPEC_SHORT (val->etype) = 1;
337 /*------------------------------------------------------------------*/
338 /* octalEscape - process an octal constant of max three digits */
339 /* return the octal value, throw a warning for illegal octal */
340 /* adjust src to point at the last proccesed char */
341 /*------------------------------------------------------------------*/
343 char octalEscape (char **str) {
347 for (digits=0; digits<3; digits++) {
348 if (**str>='0' && **str<='7') {
349 value = value*8 + (**str-'0');
356 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
357 werror (W_ESC_SEQ_OOR_FOR_CHAR);
364 /*------------------------------------------------------------------*/
365 /* copyStr - copies src to dest ignoring leading & trailing \"s */
366 /*------------------------------------------------------------------*/
368 copyStr (char *dest, char *src)
374 else if (*src == '\\')
409 *dest++ = octalEscape(&src);
414 unsigned long value=strtol (src, &src, 16);
417 // no valid hex found
418 werror(E_INVALID_HEX);
421 werror(W_ESC_SEQ_OOR_FOR_CHAR);
454 /*------------------------------------------------------------------*/
455 /* strVal - converts a string constant to a value */
456 /*------------------------------------------------------------------*/
462 val = newValue (); /* get a new one */
464 /* get a declarator */
465 val->type = newLink ();
466 DCL_TYPE (val->type) = ARRAY;
467 DCL_ELEM (val->type) = strlen (s) - 1;
468 val->type->next = val->etype = newLink ();
469 val->etype->class = SPECIFIER;
470 SPEC_NOUN (val->etype) = V_CHAR;
471 SPEC_SCLS (val->etype) = S_LITERAL;
473 SPEC_CVAL (val->etype).v_char = Safe_calloc (1, strlen (s) + 1);
474 copyStr (SPEC_CVAL (val->etype).v_char, s);
479 /*------------------------------------------------------------------*/
480 /* reverseValWithType - reverses value chain with type & etype */
481 /*------------------------------------------------------------------*/
483 reverseValWithType (value * val)
491 /* save the type * etype chains */
495 /* set the current one 2b null */
496 val->type = val->etype = NULL;
497 val = reverseVal (val);
499 /* restore type & etype */
506 /*------------------------------------------------------------------*/
507 /* reverseVal - reverses the values for a value chain */
508 /*------------------------------------------------------------------*/
510 reverseVal (value * val)
512 value *prev, *curr, *next;
527 val->next = (void *) NULL;
531 /*------------------------------------------------------------------*/
532 /* copyValueChain - will copy a chain of values */
533 /*------------------------------------------------------------------*/
535 copyValueChain (value * src)
542 dest = copyValue (src);
543 dest->next = copyValueChain (src->next);
548 /*------------------------------------------------------------------*/
549 /* copyValue - copies contents of a vlue to a fresh one */
550 /*------------------------------------------------------------------*/
552 copyValue (value * src)
557 dest->sym = copySymbol (src->sym);
558 strcpy (dest->name, src->name);
559 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
560 dest->etype = (src->type ? getSpec (dest->type) : NULL);
565 /*------------------------------------------------------------------*/
566 /* charVal - converts a character constant to a value */
567 /*------------------------------------------------------------------*/
575 val->type = val->etype = newLink ();
576 val->type->class = SPECIFIER;
577 SPEC_NOUN (val->type) = V_CHAR;
578 SPEC_SCLS (val->type) = S_LITERAL;
580 s++; /* get rid of quotation */
581 /* if \ then special processing */
584 s++; /* go beyond the backslash */
588 SPEC_CVAL (val->type).v_int = '\n';
591 SPEC_CVAL (val->type).v_int = '\t';
594 SPEC_CVAL (val->type).v_int = '\v';
597 SPEC_CVAL (val->type).v_int = '\b';
600 SPEC_CVAL (val->type).v_int = '\r';
603 SPEC_CVAL (val->type).v_int = '\f';
606 SPEC_CVAL (val->type).v_int = '\a';
609 SPEC_CVAL (val->type).v_int = '\\';
612 SPEC_CVAL (val->type).v_int = '\?';
615 SPEC_CVAL (val->type).v_int = '\'';
618 SPEC_CVAL (val->type).v_int = '\"';
621 sscanf (s, "%o", &SPEC_CVAL (val->type).v_int);
624 s++; /* go behond the 'x' */
625 sscanf (s, "%x", &SPEC_CVAL (val->type).v_int);
628 SPEC_CVAL (val->type).v_int = *s;
632 else /* not a backslash */
633 SPEC_CVAL (val->type).v_int = *s;
638 /*------------------------------------------------------------------*/
639 /* valFromType - creates a value from type given */
640 /*------------------------------------------------------------------*/
642 valFromType (sym_link * type)
644 value *val = newValue ();
645 val->type = copyLinkChain (type);
646 val->etype = getSpec (val->type);
650 /*------------------------------------------------------------------*/
651 /* floatFromVal - value to unsinged integer conversion */
652 /*------------------------------------------------------------------*/
654 floatFromVal (value * val)
659 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
661 werror (E_CONST_EXPECTED, val->name);
665 /* if it is not a specifier then we can assume that */
666 /* it will be an unsigned long */
667 if (!IS_SPEC (val->type))
668 return (double) SPEC_CVAL (val->etype).v_ulong;
670 if (SPEC_NOUN (val->etype) == V_FLOAT)
671 return (double) SPEC_CVAL (val->etype).v_float;
674 if (SPEC_LONG (val->etype))
676 if (SPEC_USIGN (val->etype))
677 return (double) SPEC_CVAL (val->etype).v_ulong;
679 return (double) SPEC_CVAL (val->etype).v_long;
683 if (SPEC_USIGN (val->etype))
684 return (double) SPEC_CVAL (val->etype).v_uint;
686 return (double) SPEC_CVAL (val->etype).v_int;
692 /*------------------------------------------------------------------*/
693 /* valUnaryPM - dones the unary +/- operation on a constant */
694 /*------------------------------------------------------------------*/
696 valUnaryPM (value * val)
698 /* depending on type */
699 if (SPEC_NOUN (val->etype) == V_FLOAT)
700 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
703 if (SPEC_LONG (val->etype))
705 if (SPEC_USIGN (val->etype))
706 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
708 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
712 if (SPEC_USIGN (val->etype))
713 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
715 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
722 /*------------------------------------------------------------------*/
723 /* valueComplement - complements a constant */
724 /*------------------------------------------------------------------*/
726 valComplement (value * val)
728 /* depending on type */
729 if (SPEC_LONG (val->etype))
731 if (SPEC_USIGN (val->etype))
732 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
734 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
738 if (SPEC_USIGN (val->etype))
739 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
741 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
746 /*------------------------------------------------------------------*/
747 /* valueNot - complements a constant */
748 /*------------------------------------------------------------------*/
752 /* depending on type */
753 if (SPEC_LONG (val->etype))
755 if (SPEC_USIGN (val->etype))
756 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
758 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
762 if (SPEC_USIGN (val->etype))
763 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
765 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
770 /*------------------------------------------------------------------*/
771 /* valMult - multiply constants */
772 /*------------------------------------------------------------------*/
774 valMult (value * lval, value * rval)
778 /* create a new value */
780 val->type = val->etype = newLink ();
781 val->type->class = SPECIFIER;
782 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
783 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
784 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
785 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
786 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
788 if (IS_FLOAT (val->type))
789 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
792 if (SPEC_LONG (val->type))
794 if (SPEC_USIGN (val->type))
795 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
796 (unsigned long) floatFromVal (rval);
798 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
799 (long) floatFromVal (rval);
803 if (SPEC_USIGN (val->type))
804 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
805 (unsigned) floatFromVal (rval);
807 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
808 (int) floatFromVal (rval);
814 /*------------------------------------------------------------------*/
815 /* valDiv - Divide constants */
816 /*------------------------------------------------------------------*/
818 valDiv (value * lval, value * rval)
822 if (floatFromVal (rval) == 0)
824 werror (E_DIVIDE_BY_ZERO);
828 /* create a new value */
830 val->type = val->etype = ((floatFromVal (lval) / floatFromVal (rval)) < 256 ?
831 newCharLink () : newIntLink ());
832 if (IS_FLOAT (lval->etype) || IS_FLOAT (rval->etype))
833 SPEC_NOUN (val->etype) = V_FLOAT;
834 SPEC_SCLS (val->etype) = S_LITERAL;
835 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
836 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
838 if (IS_FLOAT (val->type))
839 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
842 if (SPEC_LONG (val->type))
844 if (SPEC_USIGN (val->type))
845 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) /
846 (unsigned long) floatFromVal (rval);
848 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
849 (long) floatFromVal (rval);
853 if (SPEC_USIGN (val->type))
854 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
855 (unsigned) floatFromVal (rval);
857 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
858 (int) floatFromVal (rval);
864 /*------------------------------------------------------------------*/
865 /* valMod - Modulus constants */
866 /*------------------------------------------------------------------*/
868 valMod (value * lval, value * rval)
872 /* create a new value */
874 val->type = val->etype = newLink ();
875 val->type->class = SPECIFIER;
876 SPEC_NOUN (val->type) = V_INT; /* type is int */
877 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
878 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
879 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
881 if (SPEC_LONG (val->type))
883 if (SPEC_USIGN (val->type))
884 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
885 (unsigned long) floatFromVal (rval);
887 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
888 (unsigned long) floatFromVal (rval);
892 if (SPEC_USIGN (val->type))
893 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
894 (unsigned) floatFromVal (rval);
896 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
897 (unsigned) floatFromVal (rval);
903 /*------------------------------------------------------------------*/
904 /* valPlus - Addition constants */
905 /*------------------------------------------------------------------*/
907 valPlus (value * lval, value * rval)
911 /* create a new value */
913 val->type = val->etype = newLink ();
914 val->type->class = SPECIFIER;
915 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
916 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
917 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
918 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
919 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
921 if (IS_FLOAT (val->type))
922 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
925 if (SPEC_LONG (val->type))
927 if (SPEC_USIGN (val->type))
928 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
929 (unsigned long) floatFromVal (rval);
931 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
932 (long) floatFromVal (rval);
936 if (SPEC_USIGN (val->type))
937 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
938 (unsigned) floatFromVal (rval);
940 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
941 (int) floatFromVal (rval);
947 /*------------------------------------------------------------------*/
948 /* valMinus - Addition constants */
949 /*------------------------------------------------------------------*/
951 valMinus (value * lval, value * rval)
955 /* create a new value */
957 val->type = val->etype = newLink ();
958 val->type->class = SPECIFIER;
959 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
960 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
961 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
962 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
963 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
965 if (IS_FLOAT (val->type))
966 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
969 if (SPEC_LONG (val->type))
971 if (SPEC_USIGN (val->type))
972 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) -
973 (unsigned long) floatFromVal (rval);
975 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
976 (long) floatFromVal (rval);
980 if (SPEC_USIGN (val->type))
981 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
982 (unsigned) floatFromVal (rval);
984 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - (int) floatFromVal (rval);
990 /*------------------------------------------------------------------*/
991 /* valShift - Shift left or right */
992 /*------------------------------------------------------------------*/
994 valShift (value * lval, value * rval, int lr)
998 /* create a new value */
1000 val->type = val->etype = newLink ();
1001 val->type->class = SPECIFIER;
1002 SPEC_NOUN (val->type) = V_INT; /* type is int */
1003 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1004 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1005 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1009 if (SPEC_LONG (val->type))
1011 if (SPEC_USIGN (val->type))
1012 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) <<
1013 (unsigned long) floatFromVal (rval);
1015 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) <<
1016 (long) floatFromVal (rval);
1020 if (SPEC_USIGN (val->type))
1021 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) <<
1022 (unsigned) floatFromVal (rval);
1024 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) <<
1025 (int) floatFromVal (rval);
1030 if (SPEC_LONG (val->type))
1032 if (SPEC_USIGN (val->type))
1033 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) >>
1034 (unsigned long) floatFromVal (rval);
1036 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) >>
1037 (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 = (int) floatFromVal (lval) >>
1046 (int) floatFromVal (rval);
1053 /*------------------------------------------------------------------*/
1054 /* valCompare- Compares two literal */
1055 /*------------------------------------------------------------------*/
1057 valCompare (value * lval, value * rval, int ctype)
1061 /* create a new value */
1063 val->type = val->etype = newCharLink ();
1064 val->type->class = SPECIFIER;
1065 SPEC_NOUN (val->type) = V_INT; /* type is int */
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);
1079 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1083 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1087 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1091 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1099 /*------------------------------------------------------------------*/
1100 /* valBitwise - Bitwise operation */
1101 /*------------------------------------------------------------------*/
1103 valBitwise (value * lval, value * rval, int op)
1107 /* create a new value */
1109 val->type = copyLinkChain (lval->type);
1110 val->etype = getSpec (val->type);
1115 if (SPEC_LONG (val->type))
1117 if (SPEC_USIGN (val->type))
1118 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1119 (unsigned long) floatFromVal (rval);
1121 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1122 (long) floatFromVal (rval);
1126 if (SPEC_USIGN (val->type))
1127 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1128 (unsigned) floatFromVal (rval);
1130 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1135 if (SPEC_LONG (val->type))
1137 if (SPEC_USIGN (val->type))
1138 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1139 (unsigned long) floatFromVal (rval);
1141 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1142 (long) floatFromVal (rval);
1146 if (SPEC_USIGN (val->type))
1147 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1148 (unsigned) floatFromVal (rval);
1150 SPEC_CVAL (val->type).v_int =
1151 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1157 if (SPEC_LONG (val->type))
1159 if (SPEC_USIGN (val->type))
1160 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1161 (unsigned long) floatFromVal (rval);
1163 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1164 (long) floatFromVal (rval);
1168 if (SPEC_USIGN (val->type))
1169 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1170 (unsigned) floatFromVal (rval);
1172 SPEC_CVAL (val->type).v_int =
1173 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1181 /*------------------------------------------------------------------*/
1182 /* valAndOr - Generates code for and / or operation */
1183 /*------------------------------------------------------------------*/
1185 valLogicAndOr (value * lval, value * rval, int op)
1189 /* create a new value */
1191 val->type = val->etype = newCharLink ();
1192 val->type->class = SPECIFIER;
1193 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1198 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1202 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1210 /*------------------------------------------------------------------*/
1211 /* valCastLiteral - casts a literal value to another type */
1212 /*------------------------------------------------------------------*/
1214 valCastLiteral (sym_link * dtype, double fval)
1222 val->etype = getSpec (val->type = copyLinkChain (dtype));
1223 SPEC_SCLS (val->etype) = S_LITERAL;
1224 /* if it is not a specifier then we can assume that */
1225 /* it will be an unsigned long */
1226 if (!IS_SPEC (val->type))
1228 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1232 if (SPEC_NOUN (val->etype) == V_FLOAT)
1233 SPEC_CVAL (val->etype).v_float = fval;
1236 if (SPEC_LONG (val->etype))
1238 if (SPEC_USIGN (val->etype))
1239 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1241 SPEC_CVAL (val->etype).v_long = (long) fval;
1245 if (SPEC_USIGN (val->etype))
1246 SPEC_CVAL (val->etype).v_uint = (unsigned int) fval;
1248 SPEC_CVAL (val->etype).v_int = (int) fval;
1254 /*------------------------------------------------------------------*/
1255 /* getNelements - determines # of elements from init list */
1256 /*------------------------------------------------------------------*/
1258 getNelements (sym_link * type, initList * ilist)
1260 sym_link *etype = getSpec (type);
1266 if (ilist->type == INIT_DEEP)
1267 ilist = ilist->init.deep;
1269 /* if type is a character array and there is only one
1270 initialiser then get the length of the string */
1271 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1273 ast *iast = ilist->init.node;
1274 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1277 werror (E_INIT_WRONG);
1280 if (!IS_ARRAY (v->type) || !IS_CHAR (v->etype))
1282 werror (E_INIT_WRONG);
1285 return DCL_ELEM (v->type);
1292 ilist = ilist->next;
1298 /*-----------------------------------------------------------------*/
1299 /* valForArray - returns a value with name of array index */
1300 /*-----------------------------------------------------------------*/
1302 valForArray (ast * arrExpr)
1304 value *val, *lval = NULL;
1306 int size = getSize (arrExpr->left->ftype->next);
1307 /* if the right or left is an array
1309 if (IS_AST_OP (arrExpr->left))
1311 if (arrExpr->left->opval.op == '[')
1312 lval = valForArray (arrExpr->left);
1313 else if (arrExpr->left->opval.op == '.')
1314 lval = valForStructElem (arrExpr->left->left,
1315 arrExpr->left->right);
1316 else if (arrExpr->left->opval.op == PTR_OP &&
1317 IS_ADDRESS_OF_OP (arrExpr->left->left))
1318 lval = valForStructElem (arrExpr->left->left->left,
1319 arrExpr->left->right);
1324 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1327 if (!IS_AST_LIT_VALUE (arrExpr->right))
1332 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1334 sprintf (buffer, "%s", lval->name);
1336 sprintf (val->name, "(%s + %d)", buffer,
1337 (int) AST_LIT_VALUE (arrExpr->right) * size);
1339 val->type = newLink ();
1340 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1342 DCL_TYPE (val->type) = CPOINTER;
1343 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1345 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1346 DCL_TYPE (val->type) = FPOINTER;
1347 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1348 DCL_TYPE (val->type) = PPOINTER;
1349 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1350 DCL_TYPE (val->type) = IPOINTER;
1351 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1352 DCL_TYPE (val->type) = EEPPOINTER;
1354 DCL_TYPE (val->type) = POINTER;
1355 val->type->next = arrExpr->left->ftype;
1356 val->etype = getSpec (val->type);
1360 /*-----------------------------------------------------------------*/
1361 /* valForStructElem - returns value with name of struct element */
1362 /*-----------------------------------------------------------------*/
1364 valForStructElem (ast * structT, ast * elemT)
1366 value *val, *lval = NULL;
1370 /* left could be furthur derefed */
1371 if (IS_AST_OP (structT))
1373 if (structT->opval.op == '[')
1374 lval = valForArray (structT);
1375 else if (structT->opval.op == '.')
1376 lval = valForStructElem (structT->left, structT->right);
1377 else if (structT->opval.op == PTR_OP &&
1378 IS_ADDRESS_OF_OP (structT->left))
1379 lval = valForStructElem (structT->left->left,
1385 if (!IS_AST_SYM_VALUE (elemT))
1388 if (!IS_STRUCT (structT->etype))
1391 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1392 AST_SYMBOL (elemT))) == NULL)
1399 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1401 sprintf (buffer, "%s", lval->name);
1403 sprintf (val->name, "(%s + %d)", buffer,
1406 val->type = newLink ();
1407 if (SPEC_SCLS (structT->etype) == S_CODE)
1409 DCL_TYPE (val->type) = CPOINTER;
1410 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1412 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1413 DCL_TYPE (val->type) = FPOINTER;
1414 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1415 DCL_TYPE (val->type) = PPOINTER;
1416 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1417 DCL_TYPE (val->type) = IPOINTER;
1418 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1419 DCL_TYPE (val->type) = EEPPOINTER;
1421 DCL_TYPE (val->type) = POINTER;
1422 val->type->next = sym->type;
1423 val->etype = getSpec (val->type);
1427 /*-----------------------------------------------------------------*/
1428 /* valForCastAggr - will return value for a cast of an aggregate */
1429 /* plus minus a constant */
1430 /*-----------------------------------------------------------------*/
1432 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1436 if (!IS_AST_SYM_VALUE (aexpr))
1438 if (!IS_AST_LIT_VALUE (cnst))
1443 sprintf (val->name, "(%s %c %d)",
1444 AST_SYMBOL (aexpr)->rname, op,
1445 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1448 val->etype = getSpec (val->type);
1452 /*-----------------------------------------------------------------*/
1453 /* valForCastAggr - will return value for a cast of an aggregate */
1454 /* with no constant */
1455 /*-----------------------------------------------------------------*/
1457 valForCastArr (ast * aexpr, sym_link * type)
1461 if (!IS_AST_SYM_VALUE (aexpr))
1466 sprintf (val->name, "(%s)",
1467 AST_SYMBOL (aexpr)->rname);
1470 val->etype = getSpec (val->type);