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);
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;
336 /*! /fn char hexEscape(char **src)
338 /param src Pointer to 'x' from start of hex character value
341 char hexEscape(char **src)
345 unsigned long value ;
347 (*src)++ ; /* Skip over the 'x' */
348 s = *src ; /* Save for error detection */
350 value = strtol (*src, src, 16);
354 // no valid hex found
355 werror(E_INVALID_HEX);
362 werror(W_ESC_SEQ_OOR_FOR_CHAR);
368 /*------------------------------------------------------------------*/
369 /* octalEscape - process an octal constant of max three digits */
370 /* return the octal value, throw a warning for illegal octal */
371 /* adjust src to point at the last proccesed char */
372 /*------------------------------------------------------------------*/
374 char octalEscape (char **str) {
378 for (digits=0; digits<3; digits++) {
379 if (**str>='0' && **str<='7') {
380 value = value*8 + (**str-'0');
387 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
388 werror (W_ESC_SEQ_OOR_FOR_CHAR);
395 /fn int copyStr (char *dest, char *src)
397 Copies a source string to a dest buffer interpreting escape sequences
398 and special characters
400 /param dest Buffer to receive the resultant string
401 /param src Buffer containing the source string with escape sequecnes
402 /return Number of characters in output string
407 copyStr (char *dest, char *src)
410 char *OriginalDest = dest ;
416 else if (*src == '\\')
451 *dest++ = octalEscape(&src);
456 *dest++ = hexEscape(&src) ;
483 return dest - OriginalDest ;
486 /*------------------------------------------------------------------*/
487 /* strVal - converts a string constant to a value */
488 /*------------------------------------------------------------------*/
494 val = newValue (); /* get a new one */
496 /* get a declarator */
497 val->type = newLink ();
498 DCL_TYPE (val->type) = ARRAY;
499 val->type->next = val->etype = newLink ();
500 val->etype->class = SPECIFIER;
501 SPEC_NOUN (val->etype) = V_CHAR;
502 SPEC_SCLS (val->etype) = S_LITERAL;
504 SPEC_CVAL (val->etype).v_char = Safe_calloc (1, strlen (s) + 1);
505 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
511 /*------------------------------------------------------------------*/
512 /* reverseValWithType - reverses value chain with type & etype */
513 /*------------------------------------------------------------------*/
515 reverseValWithType (value * val)
523 /* save the type * etype chains */
527 /* set the current one 2b null */
528 val->type = val->etype = NULL;
529 val = reverseVal (val);
531 /* restore type & etype */
538 /*------------------------------------------------------------------*/
539 /* reverseVal - reverses the values for a value chain */
540 /*------------------------------------------------------------------*/
542 reverseVal (value * val)
544 value *prev, *curr, *next;
559 val->next = (void *) NULL;
563 /*------------------------------------------------------------------*/
564 /* copyValueChain - will copy a chain of values */
565 /*------------------------------------------------------------------*/
567 copyValueChain (value * src)
574 dest = copyValue (src);
575 dest->next = copyValueChain (src->next);
580 /*------------------------------------------------------------------*/
581 /* copyValue - copies contents of a vlue to a fresh one */
582 /*------------------------------------------------------------------*/
584 copyValue (value * src)
589 dest->sym = copySymbol (src->sym);
590 strcpy (dest->name, src->name);
591 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
592 dest->etype = (src->type ? getSpec (dest->type) : NULL);
597 /*------------------------------------------------------------------*/
598 /* charVal - converts a character constant to a value */
599 /*------------------------------------------------------------------*/
608 val->type = val->etype = newLink ();
609 val->type->class = SPECIFIER;
610 SPEC_NOUN (val->type) = V_CHAR;
611 SPEC_SCLS (val->type) = S_LITERAL;
613 s++; /* get rid of quotation */
614 /* if \ then special processing */
617 s++; /* go beyond the backslash */
621 SPEC_CVAL (val->type).v_int = '\n';
624 SPEC_CVAL (val->type).v_int = '\t';
627 SPEC_CVAL (val->type).v_int = '\v';
630 SPEC_CVAL (val->type).v_int = '\b';
633 SPEC_CVAL (val->type).v_int = '\r';
636 SPEC_CVAL (val->type).v_int = '\f';
639 SPEC_CVAL (val->type).v_int = '\a';
642 SPEC_CVAL (val->type).v_int = '\\';
645 SPEC_CVAL (val->type).v_int = '\?';
648 SPEC_CVAL (val->type).v_int = '\'';
651 SPEC_CVAL (val->type).v_int = '\"';
662 SPEC_CVAL (val->type).v_int = octalEscape(&s);
666 SPEC_CVAL (val->type).v_int = hexEscape(&s) ;
670 SPEC_CVAL (val->type).v_int = *s;
674 else /* not a backslash */
675 SPEC_CVAL (val->type).v_int = *s;
680 /*------------------------------------------------------------------*/
681 /* valFromType - creates a value from type given */
682 /*------------------------------------------------------------------*/
684 valFromType (sym_link * type)
686 value *val = newValue ();
687 val->type = copyLinkChain (type);
688 val->etype = getSpec (val->type);
692 /*------------------------------------------------------------------*/
693 /* floatFromVal - value to unsinged integer conversion */
694 /*------------------------------------------------------------------*/
696 floatFromVal (value * val)
701 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
703 werror (E_CONST_EXPECTED, val->name);
707 /* if it is not a specifier then we can assume that */
708 /* it will be an unsigned long */
709 if (!IS_SPEC (val->type))
710 return (double) SPEC_CVAL (val->etype).v_ulong;
712 if (SPEC_NOUN (val->etype) == V_FLOAT)
713 return (double) SPEC_CVAL (val->etype).v_float;
716 if (SPEC_LONG (val->etype))
718 if (SPEC_USIGN (val->etype))
719 return (double) SPEC_CVAL (val->etype).v_ulong;
721 return (double) SPEC_CVAL (val->etype).v_long;
725 if (SPEC_USIGN (val->etype))
726 return (double) SPEC_CVAL (val->etype).v_uint;
728 return (double) SPEC_CVAL (val->etype).v_int;
734 /*------------------------------------------------------------------*/
735 /* valUnaryPM - dones the unary +/- operation on a constant */
736 /*------------------------------------------------------------------*/
738 valUnaryPM (value * val)
740 /* depending on type */
741 if (SPEC_NOUN (val->etype) == V_FLOAT)
742 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
745 if (SPEC_LONG (val->etype))
747 if (SPEC_USIGN (val->etype))
748 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
750 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
754 if (SPEC_USIGN (val->etype))
755 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
757 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
764 /*------------------------------------------------------------------*/
765 /* valueComplement - complements a constant */
766 /*------------------------------------------------------------------*/
768 valComplement (value * val)
770 /* depending on type */
771 if (SPEC_LONG (val->etype))
773 if (SPEC_USIGN (val->etype))
774 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
776 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
780 if (SPEC_USIGN (val->etype))
781 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
783 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
788 /*------------------------------------------------------------------*/
789 /* valueNot - complements a constant */
790 /*------------------------------------------------------------------*/
794 /* depending on type */
795 if (SPEC_LONG (val->etype))
797 if (SPEC_USIGN (val->etype))
798 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
800 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
804 if (SPEC_USIGN (val->etype))
805 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
807 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
812 /*------------------------------------------------------------------*/
813 /* valMult - multiply constants */
814 /*------------------------------------------------------------------*/
816 valMult (value * lval, value * rval)
820 /* create a new value */
822 val->type = val->etype = newLink ();
823 val->type->class = SPECIFIER;
824 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
825 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
826 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
827 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
828 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
830 if (IS_FLOAT (val->type))
831 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
834 if (SPEC_LONG (val->type))
836 if (SPEC_USIGN (val->type))
837 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
838 (unsigned long) floatFromVal (rval);
840 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
841 (long) floatFromVal (rval);
845 if (SPEC_USIGN (val->type))
846 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
847 (unsigned) floatFromVal (rval);
849 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
850 (int) floatFromVal (rval);
856 /*------------------------------------------------------------------*/
857 /* valDiv - Divide constants */
858 /*------------------------------------------------------------------*/
860 valDiv (value * lval, value * rval)
864 if (floatFromVal (rval) == 0)
866 werror (E_DIVIDE_BY_ZERO);
870 /* create a new value */
872 val->type = val->etype = ((floatFromVal (lval) / floatFromVal (rval)) < 256 ?
873 newCharLink () : newIntLink ());
874 if (IS_FLOAT (lval->etype) || IS_FLOAT (rval->etype))
875 SPEC_NOUN (val->etype) = V_FLOAT;
876 SPEC_SCLS (val->etype) = S_LITERAL;
877 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
878 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
880 if (IS_FLOAT (val->type))
881 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
884 if (SPEC_LONG (val->type))
886 if (SPEC_USIGN (val->type))
887 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) /
888 (unsigned long) floatFromVal (rval);
890 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
891 (long) floatFromVal (rval);
895 if (SPEC_USIGN (val->type))
896 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
897 (unsigned) floatFromVal (rval);
899 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
900 (int) floatFromVal (rval);
906 /*------------------------------------------------------------------*/
907 /* valMod - Modulus constants */
908 /*------------------------------------------------------------------*/
910 valMod (value * lval, value * rval)
914 /* create a new value */
916 val->type = val->etype = newLink ();
917 val->type->class = SPECIFIER;
918 SPEC_NOUN (val->type) = V_INT; /* type is int */
919 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
920 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
921 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
923 if (SPEC_LONG (val->type))
925 if (SPEC_USIGN (val->type))
926 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
927 (unsigned long) floatFromVal (rval);
929 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
930 (unsigned long) floatFromVal (rval);
934 if (SPEC_USIGN (val->type))
935 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
936 (unsigned) floatFromVal (rval);
938 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
939 (unsigned) floatFromVal (rval);
945 /*------------------------------------------------------------------*/
946 /* valPlus - Addition constants */
947 /*------------------------------------------------------------------*/
949 valPlus (value * lval, value * rval)
953 /* create a new value */
955 val->type = val->etype = newLink ();
956 val->type->class = SPECIFIER;
957 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
958 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
959 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
960 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
961 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
963 if (IS_FLOAT (val->type))
964 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
967 if (SPEC_LONG (val->type))
969 if (SPEC_USIGN (val->type))
970 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
971 (unsigned long) floatFromVal (rval);
973 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
974 (long) floatFromVal (rval);
978 if (SPEC_USIGN (val->type))
979 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
980 (unsigned) floatFromVal (rval);
982 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
983 (int) floatFromVal (rval);
989 /*------------------------------------------------------------------*/
990 /* valMinus - Addition constants */
991 /*------------------------------------------------------------------*/
993 valMinus (value * lval, value * rval)
997 /* create a new value */
999 val->type = val->etype = newLink ();
1000 val->type->class = SPECIFIER;
1001 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1002 IS_FLOAT (rval->etype) ? V_FLOAT : V_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));
1007 if (IS_FLOAT (val->type))
1008 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1011 if (SPEC_LONG (val->type))
1013 if (SPEC_USIGN (val->type))
1014 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) -
1015 (unsigned long) floatFromVal (rval);
1017 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1018 (long) floatFromVal (rval);
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 = (int) floatFromVal (lval) - (int) floatFromVal (rval);
1032 /*------------------------------------------------------------------*/
1033 /* valShift - Shift left or right */
1034 /*------------------------------------------------------------------*/
1036 valShift (value * lval, value * rval, int lr)
1040 /* create a new value */
1042 val->type = val->etype = newLink ();
1043 val->type->class = SPECIFIER;
1044 SPEC_NOUN (val->type) = V_INT; /* type is int */
1045 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1046 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1047 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1051 if (SPEC_LONG (val->type))
1053 if (SPEC_USIGN (val->type))
1054 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) <<
1055 (unsigned long) floatFromVal (rval);
1057 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) <<
1058 (long) floatFromVal (rval);
1062 if (SPEC_USIGN (val->type))
1063 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) <<
1064 (unsigned) floatFromVal (rval);
1066 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) <<
1067 (int) floatFromVal (rval);
1072 if (SPEC_LONG (val->type))
1074 if (SPEC_USIGN (val->type))
1075 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) >>
1076 (unsigned long) floatFromVal (rval);
1078 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) >>
1079 (long) floatFromVal (rval);
1083 if (SPEC_USIGN (val->type))
1084 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) >>
1085 (unsigned) floatFromVal (rval);
1087 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) >>
1088 (int) floatFromVal (rval);
1095 /*------------------------------------------------------------------*/
1096 /* valCompare- Compares two literal */
1097 /*------------------------------------------------------------------*/
1099 valCompare (value * lval, value * rval, int ctype)
1103 /* create a new value */
1105 val->type = val->etype = newCharLink ();
1106 val->type->class = SPECIFIER;
1107 SPEC_NOUN (val->type) = V_INT; /* type is int */
1108 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1113 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1117 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1121 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1125 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1129 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1133 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1141 /*------------------------------------------------------------------*/
1142 /* valBitwise - Bitwise operation */
1143 /*------------------------------------------------------------------*/
1145 valBitwise (value * lval, value * rval, int op)
1149 /* create a new value */
1151 val->type = copyLinkChain (lval->type);
1152 val->etype = getSpec (val->type);
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 = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1177 if (SPEC_LONG (val->type))
1179 if (SPEC_USIGN (val->type))
1180 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1181 (unsigned long) floatFromVal (rval);
1183 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1184 (long) floatFromVal (rval);
1188 if (SPEC_USIGN (val->type))
1189 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1190 (unsigned) floatFromVal (rval);
1192 SPEC_CVAL (val->type).v_int =
1193 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1199 if (SPEC_LONG (val->type))
1201 if (SPEC_USIGN (val->type))
1202 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1203 (unsigned long) floatFromVal (rval);
1205 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1206 (long) floatFromVal (rval);
1210 if (SPEC_USIGN (val->type))
1211 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1212 (unsigned) floatFromVal (rval);
1214 SPEC_CVAL (val->type).v_int =
1215 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1223 /*------------------------------------------------------------------*/
1224 /* valAndOr - Generates code for and / or operation */
1225 /*------------------------------------------------------------------*/
1227 valLogicAndOr (value * lval, value * rval, int op)
1231 /* create a new value */
1233 val->type = val->etype = newCharLink ();
1234 val->type->class = SPECIFIER;
1235 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1240 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1244 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1252 /*------------------------------------------------------------------*/
1253 /* valCastLiteral - casts a literal value to another type */
1254 /*------------------------------------------------------------------*/
1256 valCastLiteral (sym_link * dtype, double fval)
1264 val->etype = getSpec (val->type = copyLinkChain (dtype));
1265 SPEC_SCLS (val->etype) = S_LITERAL;
1266 /* if it is not a specifier then we can assume that */
1267 /* it will be an unsigned long */
1268 if (!IS_SPEC (val->type))
1270 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1274 if (SPEC_NOUN (val->etype) == V_FLOAT)
1275 SPEC_CVAL (val->etype).v_float = fval;
1278 if (SPEC_LONG (val->etype))
1280 if (SPEC_USIGN (val->etype))
1281 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1283 SPEC_CVAL (val->etype).v_long = (long) fval;
1287 if (SPEC_USIGN (val->etype))
1288 SPEC_CVAL (val->etype).v_uint = (unsigned int) fval;
1290 SPEC_CVAL (val->etype).v_int = (int) fval;
1296 /*------------------------------------------------------------------*/
1297 /* getNelements - determines # of elements from init list */
1298 /*------------------------------------------------------------------*/
1300 getNelements (sym_link * type, initList * ilist)
1302 sym_link *etype = getSpec (type);
1308 if (ilist->type == INIT_DEEP)
1309 ilist = ilist->init.deep;
1311 /* if type is a character array and there is only one
1312 initialiser then get the length of the string */
1313 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1315 ast *iast = ilist->init.node;
1316 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1319 werror (E_INIT_WRONG);
1322 if (!IS_ARRAY (v->type) || !IS_CHAR (v->etype))
1324 werror (E_INIT_WRONG);
1327 return DCL_ELEM (v->type);
1334 ilist = ilist->next;
1340 /*-----------------------------------------------------------------*/
1341 /* valForArray - returns a value with name of array index */
1342 /*-----------------------------------------------------------------*/
1344 valForArray (ast * arrExpr)
1346 value *val, *lval = NULL;
1348 int size = getSize (arrExpr->left->ftype->next);
1349 /* if the right or left is an array
1351 if (IS_AST_OP (arrExpr->left))
1353 if (arrExpr->left->opval.op == '[')
1354 lval = valForArray (arrExpr->left);
1355 else if (arrExpr->left->opval.op == '.')
1356 lval = valForStructElem (arrExpr->left->left,
1357 arrExpr->left->right);
1358 else if (arrExpr->left->opval.op == PTR_OP &&
1359 IS_ADDRESS_OF_OP (arrExpr->left->left))
1360 lval = valForStructElem (arrExpr->left->left->left,
1361 arrExpr->left->right);
1366 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1369 if (!IS_AST_LIT_VALUE (arrExpr->right))
1374 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1376 sprintf (buffer, "%s", lval->name);
1378 sprintf (val->name, "(%s + %d)", buffer,
1379 (int) AST_LIT_VALUE (arrExpr->right) * size);
1381 val->type = newLink ();
1382 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1384 DCL_TYPE (val->type) = CPOINTER;
1385 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1387 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1388 DCL_TYPE (val->type) = FPOINTER;
1389 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1390 DCL_TYPE (val->type) = PPOINTER;
1391 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1392 DCL_TYPE (val->type) = IPOINTER;
1393 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1394 DCL_TYPE (val->type) = EEPPOINTER;
1396 DCL_TYPE (val->type) = POINTER;
1397 val->type->next = arrExpr->left->ftype;
1398 val->etype = getSpec (val->type);
1402 /*-----------------------------------------------------------------*/
1403 /* valForStructElem - returns value with name of struct element */
1404 /*-----------------------------------------------------------------*/
1406 valForStructElem (ast * structT, ast * elemT)
1408 value *val, *lval = NULL;
1412 /* left could be furthur derefed */
1413 if (IS_AST_OP (structT))
1415 if (structT->opval.op == '[')
1416 lval = valForArray (structT);
1417 else if (structT->opval.op == '.')
1418 lval = valForStructElem (structT->left, structT->right);
1419 else if (structT->opval.op == PTR_OP &&
1420 IS_ADDRESS_OF_OP (structT->left))
1421 lval = valForStructElem (structT->left->left,
1427 if (!IS_AST_SYM_VALUE (elemT))
1430 if (!IS_STRUCT (structT->etype))
1433 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1434 AST_SYMBOL (elemT))) == NULL)
1441 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1443 sprintf (buffer, "%s", lval->name);
1445 sprintf (val->name, "(%s + %d)", buffer,
1448 val->type = newLink ();
1449 if (SPEC_SCLS (structT->etype) == S_CODE)
1451 DCL_TYPE (val->type) = CPOINTER;
1452 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1454 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1455 DCL_TYPE (val->type) = FPOINTER;
1456 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1457 DCL_TYPE (val->type) = PPOINTER;
1458 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1459 DCL_TYPE (val->type) = IPOINTER;
1460 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1461 DCL_TYPE (val->type) = EEPPOINTER;
1463 DCL_TYPE (val->type) = POINTER;
1464 val->type->next = sym->type;
1465 val->etype = getSpec (val->type);
1469 /*-----------------------------------------------------------------*/
1470 /* valForCastAggr - will return value for a cast of an aggregate */
1471 /* plus minus a constant */
1472 /*-----------------------------------------------------------------*/
1474 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1478 if (!IS_AST_SYM_VALUE (aexpr))
1480 if (!IS_AST_LIT_VALUE (cnst))
1485 sprintf (val->name, "(%s %c %d)",
1486 AST_SYMBOL (aexpr)->rname, op,
1487 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1490 val->etype = getSpec (val->type);
1494 /*-----------------------------------------------------------------*/
1495 /* valForCastAggr - will return value for a cast of an aggregate */
1496 /* with no constant */
1497 /*-----------------------------------------------------------------*/
1499 valForCastArr (ast * aexpr, sym_link * type)
1503 if (!IS_AST_SYM_VALUE (aexpr))
1508 sprintf (val->name, "(%s)",
1509 AST_SYMBOL (aexpr)->rname);
1512 val->etype = getSpec (val->type);