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 (double 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);
312 // check if we have to promote to long
313 if (SPEC_LONG (val->type) ||
314 (SPEC_USIGN(val->type) && sval>0xffff) ||
315 (!SPEC_USIGN(val->type) && ((long)sval>32767 || (long)sval<-32768))) {
316 if (SPEC_USIGN (val->type))
317 SPEC_CVAL (val->type).v_ulong = sval;
319 SPEC_CVAL (val->type).v_long = sval;
320 SPEC_LONG (val->type) = 1;
324 if (SPEC_USIGN (val->type))
325 SPEC_CVAL (val->type).v_uint = sval;
327 SPEC_CVAL (val->type).v_int = sval;
330 // check if we can make it a char
331 if ((SPEC_USIGN(val->type) && sval < 256) ||
332 (!SPEC_USIGN(val->type) && ((long)sval<127 && (long)sval>-128))) {
333 SPEC_NOUN (val->etype) = V_CHAR;
338 /*! /fn char hexEscape(char **src)
340 /param src Pointer to 'x' from start of hex character value
343 char hexEscape(char **src)
347 unsigned long value ;
349 (*src)++ ; /* Skip over the 'x' */
350 s = *src ; /* Save for error detection */
352 value = strtol (*src, src, 16);
356 // no valid hex found
357 werror(E_INVALID_HEX);
364 werror(W_ESC_SEQ_OOR_FOR_CHAR);
370 /*------------------------------------------------------------------*/
371 /* octalEscape - process an octal constant of max three digits */
372 /* return the octal value, throw a warning for illegal octal */
373 /* adjust src to point at the last proccesed char */
374 /*------------------------------------------------------------------*/
376 char octalEscape (char **str) {
380 for (digits=0; digits<3; digits++) {
381 if (**str>='0' && **str<='7') {
382 value = value*8 + (**str-'0');
389 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
390 werror (W_ESC_SEQ_OOR_FOR_CHAR);
397 /fn int copyStr (char *dest, char *src)
399 Copies a source string to a dest buffer interpreting escape sequences
400 and special characters
402 /param dest Buffer to receive the resultant string
403 /param src Buffer containing the source string with escape sequecnes
404 /return Number of characters in output string
409 copyStr (char *dest, char *src)
412 char *OriginalDest = dest ;
418 else if (*src == '\\')
453 *dest++ = octalEscape(&src);
458 *dest++ = hexEscape(&src) ;
485 return dest - OriginalDest ;
488 /*------------------------------------------------------------------*/
489 /* strVal - converts a string constant to a value */
490 /*------------------------------------------------------------------*/
496 val = newValue (); /* get a new one */
498 /* get a declarator */
499 val->type = newLink ();
500 DCL_TYPE (val->type) = ARRAY;
501 val->type->next = val->etype = newLink ();
502 val->etype->class = SPECIFIER;
503 SPEC_NOUN (val->etype) = V_CHAR;
504 SPEC_SCLS (val->etype) = S_LITERAL;
506 SPEC_CVAL (val->etype).v_char = Safe_calloc (1, strlen (s) + 1);
507 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
513 /*------------------------------------------------------------------*/
514 /* reverseValWithType - reverses value chain with type & etype */
515 /*------------------------------------------------------------------*/
517 reverseValWithType (value * val)
525 /* save the type * etype chains */
529 /* set the current one 2b null */
530 val->type = val->etype = NULL;
531 val = reverseVal (val);
533 /* restore type & etype */
540 /*------------------------------------------------------------------*/
541 /* reverseVal - reverses the values for a value chain */
542 /*------------------------------------------------------------------*/
544 reverseVal (value * val)
546 value *prev, *curr, *next;
561 val->next = (void *) NULL;
565 /*------------------------------------------------------------------*/
566 /* copyValueChain - will copy a chain of values */
567 /*------------------------------------------------------------------*/
569 copyValueChain (value * src)
576 dest = copyValue (src);
577 dest->next = copyValueChain (src->next);
582 /*------------------------------------------------------------------*/
583 /* copyValue - copies contents of a vlue to a fresh one */
584 /*------------------------------------------------------------------*/
586 copyValue (value * src)
591 dest->sym = copySymbol (src->sym);
592 strcpy (dest->name, src->name);
593 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
594 dest->etype = (src->type ? getSpec (dest->type) : NULL);
599 /*------------------------------------------------------------------*/
600 /* charVal - converts a character constant to a value */
601 /*------------------------------------------------------------------*/
610 val->type = val->etype = newLink ();
611 val->type->class = SPECIFIER;
612 SPEC_NOUN (val->type) = V_CHAR;
613 SPEC_SCLS (val->type) = S_LITERAL;
615 s++; /* get rid of quotation */
616 /* if \ then special processing */
619 s++; /* go beyond the backslash */
623 SPEC_CVAL (val->type).v_int = '\n';
626 SPEC_CVAL (val->type).v_int = '\t';
629 SPEC_CVAL (val->type).v_int = '\v';
632 SPEC_CVAL (val->type).v_int = '\b';
635 SPEC_CVAL (val->type).v_int = '\r';
638 SPEC_CVAL (val->type).v_int = '\f';
641 SPEC_CVAL (val->type).v_int = '\a';
644 SPEC_CVAL (val->type).v_int = '\\';
647 SPEC_CVAL (val->type).v_int = '\?';
650 SPEC_CVAL (val->type).v_int = '\'';
653 SPEC_CVAL (val->type).v_int = '\"';
664 SPEC_CVAL (val->type).v_int = octalEscape(&s);
668 SPEC_CVAL (val->type).v_int = hexEscape(&s) ;
672 SPEC_CVAL (val->type).v_int = *s;
676 else /* not a backslash */
677 SPEC_CVAL (val->type).v_int = *s;
682 /*------------------------------------------------------------------*/
683 /* valFromType - creates a value from type given */
684 /*------------------------------------------------------------------*/
686 valFromType (sym_link * type)
688 value *val = newValue ();
689 val->type = copyLinkChain (type);
690 val->etype = getSpec (val->type);
694 /*------------------------------------------------------------------*/
695 /* floatFromVal - value to unsinged integer conversion */
696 /*------------------------------------------------------------------*/
698 floatFromVal (value * val)
703 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
705 werror (E_CONST_EXPECTED, val->name);
709 /* if it is not a specifier then we can assume that */
710 /* it will be an unsigned long */
711 if (!IS_SPEC (val->type))
712 return (double) SPEC_CVAL (val->etype).v_ulong;
714 if (SPEC_NOUN (val->etype) == V_FLOAT)
715 return (double) SPEC_CVAL (val->etype).v_float;
718 if (SPEC_LONG (val->etype))
720 if (SPEC_USIGN (val->etype))
721 return (double) SPEC_CVAL (val->etype).v_ulong;
723 return (double) SPEC_CVAL (val->etype).v_long;
727 if (SPEC_USIGN (val->etype))
728 return (double) SPEC_CVAL (val->etype).v_uint;
730 return (double) SPEC_CVAL (val->etype).v_int;
736 /*------------------------------------------------------------------*/
737 /* valUnaryPM - dones the unary +/- operation on a constant */
738 /*------------------------------------------------------------------*/
740 valUnaryPM (value * val)
742 /* depending on type */
743 if (SPEC_NOUN (val->etype) == V_FLOAT)
744 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
747 if (SPEC_LONG (val->etype))
749 if (SPEC_USIGN (val->etype))
750 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
752 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
756 if (SPEC_USIGN (val->etype))
757 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
759 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
766 /*------------------------------------------------------------------*/
767 /* valueComplement - complements a constant */
768 /*------------------------------------------------------------------*/
770 valComplement (value * val)
772 /* depending on type */
773 if (SPEC_LONG (val->etype))
775 if (SPEC_USIGN (val->etype))
776 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
778 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
782 if (SPEC_USIGN (val->etype))
783 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
785 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
790 /*------------------------------------------------------------------*/
791 /* valueNot - complements a constant */
792 /*------------------------------------------------------------------*/
796 /* depending on type */
797 if (SPEC_LONG (val->etype))
799 if (SPEC_USIGN (val->etype))
800 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
802 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
806 if (SPEC_USIGN (val->etype))
807 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
809 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
814 /*------------------------------------------------------------------*/
815 /* valMult - multiply constants */
816 /*------------------------------------------------------------------*/
818 valMult (value * lval, value * rval)
822 /* create a new value */
824 val->type = val->etype = newLink ();
825 val->type->class = SPECIFIER;
826 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
827 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
828 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
829 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
830 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
832 if (IS_FLOAT (val->type))
833 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
836 if (SPEC_LONG (val->type))
838 if (SPEC_USIGN (val->type))
839 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
840 (unsigned long) floatFromVal (rval);
842 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
843 (long) floatFromVal (rval);
847 if (SPEC_USIGN (val->type))
848 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
849 (unsigned) floatFromVal (rval);
851 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
852 (int) floatFromVal (rval);
858 /*------------------------------------------------------------------*/
859 /* valDiv - Divide constants */
860 /*------------------------------------------------------------------*/
862 valDiv (value * lval, value * rval)
866 if (floatFromVal (rval) == 0)
868 werror (E_DIVIDE_BY_ZERO);
872 /* create a new value */
874 val->type = val->etype = ((floatFromVal (lval) / floatFromVal (rval)) < 256 ?
875 newCharLink () : newIntLink ());
876 if (IS_FLOAT (lval->etype) || IS_FLOAT (rval->etype))
877 SPEC_NOUN (val->etype) = V_FLOAT;
878 SPEC_SCLS (val->etype) = S_LITERAL;
879 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
880 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
882 if (IS_FLOAT (val->type))
883 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
886 if (SPEC_LONG (val->type))
888 if (SPEC_USIGN (val->type))
889 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) /
890 (unsigned long) floatFromVal (rval);
892 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
893 (long) floatFromVal (rval);
897 if (SPEC_USIGN (val->type))
898 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
899 (unsigned) floatFromVal (rval);
901 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
902 (int) floatFromVal (rval);
908 /*------------------------------------------------------------------*/
909 /* valMod - Modulus constants */
910 /*------------------------------------------------------------------*/
912 valMod (value * lval, value * rval)
916 /* create a new value */
918 val->type = val->etype = newLink ();
919 val->type->class = SPECIFIER;
920 SPEC_NOUN (val->type) = V_INT; /* type is int */
921 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
922 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
923 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
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 = (unsigned long) floatFromVal (lval) %
932 (unsigned 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 = (unsigned) floatFromVal (lval) %
941 (unsigned) floatFromVal (rval);
947 /*------------------------------------------------------------------*/
948 /* valPlus - Addition constants */
949 /*------------------------------------------------------------------*/
951 valPlus (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) +
985 (int) floatFromVal (rval);
991 /*------------------------------------------------------------------*/
992 /* valMinus - Addition constants */
993 /*------------------------------------------------------------------*/
995 valMinus (value * lval, value * rval)
999 /* create a new value */
1001 val->type = val->etype = newLink ();
1002 val->type->class = SPECIFIER;
1003 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1004 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1005 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1006 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1007 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1009 if (IS_FLOAT (val->type))
1010 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1013 if (SPEC_LONG (val->type))
1015 if (SPEC_USIGN (val->type))
1016 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) -
1017 (unsigned long) floatFromVal (rval);
1019 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1020 (long) floatFromVal (rval);
1024 if (SPEC_USIGN (val->type))
1025 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1026 (unsigned) floatFromVal (rval);
1028 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - (int) floatFromVal (rval);
1034 /*------------------------------------------------------------------*/
1035 /* valShift - Shift left or right */
1036 /*------------------------------------------------------------------*/
1038 valShift (value * lval, value * rval, int lr)
1042 /* create a new value */
1044 val->type = val->etype = newLink ();
1045 val->type->class = SPECIFIER;
1046 SPEC_NOUN (val->type) = V_INT; /* type is int */
1047 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1048 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1049 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1053 if (SPEC_LONG (val->type))
1055 if (SPEC_USIGN (val->type))
1056 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) <<
1057 (unsigned long) floatFromVal (rval);
1059 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) <<
1060 (long) floatFromVal (rval);
1064 if (SPEC_USIGN (val->type))
1065 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) <<
1066 (unsigned) floatFromVal (rval);
1068 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) <<
1069 (int) floatFromVal (rval);
1074 if (SPEC_LONG (val->type))
1076 if (SPEC_USIGN (val->type))
1077 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) >>
1078 (unsigned long) floatFromVal (rval);
1080 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) >>
1081 (long) floatFromVal (rval);
1085 if (SPEC_USIGN (val->type))
1086 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) >>
1087 (unsigned) floatFromVal (rval);
1089 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) >>
1090 (int) floatFromVal (rval);
1097 /*------------------------------------------------------------------*/
1098 /* valCompare- Compares two literal */
1099 /*------------------------------------------------------------------*/
1101 valCompare (value * lval, value * rval, int ctype)
1105 /* create a new value */
1107 val->type = val->etype = newCharLink ();
1108 val->type->class = SPECIFIER;
1109 SPEC_NOUN (val->type) = V_INT; /* type is int */
1110 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1115 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1119 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1123 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1127 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1131 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1135 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1143 /*------------------------------------------------------------------*/
1144 /* valBitwise - Bitwise operation */
1145 /*------------------------------------------------------------------*/
1147 valBitwise (value * lval, value * rval, int op)
1151 /* create a new value */
1153 val->type = copyLinkChain (lval->type);
1154 val->etype = getSpec (val->type);
1159 if (SPEC_LONG (val->type))
1161 if (SPEC_USIGN (val->type))
1162 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1163 (unsigned long) floatFromVal (rval);
1165 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1166 (long) floatFromVal (rval);
1170 if (SPEC_USIGN (val->type))
1171 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1172 (unsigned) floatFromVal (rval);
1174 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1179 if (SPEC_LONG (val->type))
1181 if (SPEC_USIGN (val->type))
1182 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1183 (unsigned long) floatFromVal (rval);
1185 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1186 (long) floatFromVal (rval);
1190 if (SPEC_USIGN (val->type))
1191 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1192 (unsigned) floatFromVal (rval);
1194 SPEC_CVAL (val->type).v_int =
1195 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1201 if (SPEC_LONG (val->type))
1203 if (SPEC_USIGN (val->type))
1204 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1205 (unsigned long) floatFromVal (rval);
1207 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1208 (long) floatFromVal (rval);
1212 if (SPEC_USIGN (val->type))
1213 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1214 (unsigned) floatFromVal (rval);
1216 SPEC_CVAL (val->type).v_int =
1217 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1225 /*------------------------------------------------------------------*/
1226 /* valAndOr - Generates code for and / or operation */
1227 /*------------------------------------------------------------------*/
1229 valLogicAndOr (value * lval, value * rval, int op)
1233 /* create a new value */
1235 val->type = val->etype = newCharLink ();
1236 val->type->class = SPECIFIER;
1237 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1242 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1246 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1254 /*------------------------------------------------------------------*/
1255 /* valCastLiteral - casts a literal value to another type */
1256 /*------------------------------------------------------------------*/
1258 valCastLiteral (sym_link * dtype, double fval)
1266 val->etype = getSpec (val->type = copyLinkChain (dtype));
1267 SPEC_SCLS (val->etype) = S_LITERAL;
1268 /* if it is not a specifier then we can assume that */
1269 /* it will be an unsigned long */
1270 if (!IS_SPEC (val->type))
1272 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1276 if (SPEC_NOUN (val->etype) == V_FLOAT)
1277 SPEC_CVAL (val->etype).v_float = fval;
1280 if (SPEC_LONG (val->etype))
1282 if (SPEC_USIGN (val->etype))
1283 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1285 SPEC_CVAL (val->etype).v_long = (long) fval;
1289 if (SPEC_USIGN (val->etype))
1290 SPEC_CVAL (val->etype).v_uint = (unsigned int) fval;
1292 SPEC_CVAL (val->etype).v_int = (int) fval;
1298 /*------------------------------------------------------------------*/
1299 /* getNelements - determines # of elements from init list */
1300 /*------------------------------------------------------------------*/
1302 getNelements (sym_link * type, initList * ilist)
1304 sym_link *etype = getSpec (type);
1310 if (ilist->type == INIT_DEEP)
1311 ilist = ilist->init.deep;
1313 /* if type is a character array and there is only one
1314 initialiser then get the length of the string */
1315 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1317 ast *iast = ilist->init.node;
1318 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1321 werror (E_INIT_WRONG);
1324 if (!IS_ARRAY (v->type) || !IS_CHAR (v->etype))
1326 werror (E_INIT_WRONG);
1329 return DCL_ELEM (v->type);
1336 ilist = ilist->next;
1342 /*-----------------------------------------------------------------*/
1343 /* valForArray - returns a value with name of array index */
1344 /*-----------------------------------------------------------------*/
1346 valForArray (ast * arrExpr)
1348 value *val, *lval = NULL;
1350 int size = getSize (arrExpr->left->ftype->next);
1351 /* if the right or left is an array
1353 if (IS_AST_OP (arrExpr->left))
1355 if (arrExpr->left->opval.op == '[')
1356 lval = valForArray (arrExpr->left);
1357 else if (arrExpr->left->opval.op == '.')
1358 lval = valForStructElem (arrExpr->left->left,
1359 arrExpr->left->right);
1360 else if (arrExpr->left->opval.op == PTR_OP &&
1361 IS_ADDRESS_OF_OP (arrExpr->left->left))
1362 lval = valForStructElem (arrExpr->left->left->left,
1363 arrExpr->left->right);
1368 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1371 if (!IS_AST_LIT_VALUE (arrExpr->right))
1376 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1378 sprintf (buffer, "%s", lval->name);
1380 sprintf (val->name, "(%s + %d)", buffer,
1381 (int) AST_LIT_VALUE (arrExpr->right) * size);
1383 val->type = newLink ();
1384 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1386 DCL_TYPE (val->type) = CPOINTER;
1387 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1389 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1390 DCL_TYPE (val->type) = FPOINTER;
1391 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1392 DCL_TYPE (val->type) = PPOINTER;
1393 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1394 DCL_TYPE (val->type) = IPOINTER;
1395 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1396 DCL_TYPE (val->type) = EEPPOINTER;
1398 DCL_TYPE (val->type) = POINTER;
1399 val->type->next = arrExpr->left->ftype;
1400 val->etype = getSpec (val->type);
1404 /*-----------------------------------------------------------------*/
1405 /* valForStructElem - returns value with name of struct element */
1406 /*-----------------------------------------------------------------*/
1408 valForStructElem (ast * structT, ast * elemT)
1410 value *val, *lval = NULL;
1414 /* left could be furthur derefed */
1415 if (IS_AST_OP (structT))
1417 if (structT->opval.op == '[')
1418 lval = valForArray (structT);
1419 else if (structT->opval.op == '.')
1420 lval = valForStructElem (structT->left, structT->right);
1421 else if (structT->opval.op == PTR_OP &&
1422 IS_ADDRESS_OF_OP (structT->left))
1423 lval = valForStructElem (structT->left->left,
1429 if (!IS_AST_SYM_VALUE (elemT))
1432 if (!IS_STRUCT (structT->etype))
1435 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1436 AST_SYMBOL (elemT))) == NULL)
1443 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1445 sprintf (buffer, "%s", lval->name);
1447 sprintf (val->name, "(%s + %d)", buffer,
1450 val->type = newLink ();
1451 if (SPEC_SCLS (structT->etype) == S_CODE)
1453 DCL_TYPE (val->type) = CPOINTER;
1454 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1456 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1457 DCL_TYPE (val->type) = FPOINTER;
1458 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1459 DCL_TYPE (val->type) = PPOINTER;
1460 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1461 DCL_TYPE (val->type) = IPOINTER;
1462 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1463 DCL_TYPE (val->type) = EEPPOINTER;
1465 DCL_TYPE (val->type) = POINTER;
1466 val->type->next = sym->type;
1467 val->etype = getSpec (val->type);
1471 /*-----------------------------------------------------------------*/
1472 /* valForCastAggr - will return value for a cast of an aggregate */
1473 /* plus minus a constant */
1474 /*-----------------------------------------------------------------*/
1476 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1480 if (!IS_AST_SYM_VALUE (aexpr))
1482 if (!IS_AST_LIT_VALUE (cnst))
1487 sprintf (val->name, "(%s %c %d)",
1488 AST_SYMBOL (aexpr)->rname, op,
1489 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1492 val->etype = getSpec (val->type);
1496 /*-----------------------------------------------------------------*/
1497 /* valForCastAggr - will return value for a cast of an aggregate */
1498 /* with no constant */
1499 /*-----------------------------------------------------------------*/
1501 valForCastArr (ast * aexpr, sym_link * type)
1505 if (!IS_AST_SYM_VALUE (aexpr))
1510 sprintf (val->name, "(%s)",
1511 AST_SYMBOL (aexpr)->rname);
1514 val->etype = getSpec (val->type);