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;
101 convertIListToConstList(initList *src, literalList **lList)
104 literalList *head, *last, *newL;
108 if (!src || src->type != INIT_DEEP)
113 iLoop = src->init.deep;
117 if (iLoop->type != INIT_NODE)
122 if (!IS_AST_LIT_VALUE(iLoop->init.node))
129 // We've now established that the initializer list contains only literal values.
131 iLoop = src->init.deep;
134 double val = AST_LIT_VALUE(iLoop->init.node);
136 if (last && last->literalValue == val)
142 newL = Safe_malloc(sizeof(literalList));
143 newL->literalValue = val;
170 copyLiteralList(literalList *src)
172 literalList *head, *prev, *newL;
178 newL = Safe_malloc(sizeof(literalList));
180 newL->literalValue = src->literalValue;
181 newL->count = src->count;
201 /*------------------------------------------------------------------*/
202 /* copyIlist - copy initializer list */
203 /*------------------------------------------------------------------*/
205 copyIlist (initList * src)
207 initList *dest = NULL;
215 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
218 dest = newiList (INIT_NODE, copyAst (src->init.node));
223 dest->next = copyIlist (src->next);
228 /*------------------------------------------------------------------*/
229 /* list2int - converts the first element of the list to value */
230 /*------------------------------------------------------------------*/
232 list2int (initList * val)
236 if (i->type == INIT_DEEP)
237 return list2int (val->init.deep);
239 return floatFromVal (constExprValue (val->init.node, TRUE));
242 /*------------------------------------------------------------------*/
243 /* list2val - converts the first element of the list to value */
244 /*------------------------------------------------------------------*/
246 list2val (initList * val)
251 if (val->type == INIT_DEEP)
252 return list2val (val->init.deep);
254 return constExprValue (val->init.node, TRUE);
257 /*------------------------------------------------------------------*/
258 /* list2expr - returns the first expression in the initializer list */
259 /*------------------------------------------------------------------*/
261 list2expr (initList * ilist)
263 if (ilist->type == INIT_DEEP)
264 return list2expr (ilist->init.deep);
265 return ilist->init.node;
268 /*------------------------------------------------------------------*/
269 /* resolveIvalSym - resolve symbols in initial values */
270 /*------------------------------------------------------------------*/
272 resolveIvalSym (initList * ilist)
277 if (ilist->type == INIT_NODE)
278 ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
280 if (ilist->type == INIT_DEEP)
281 resolveIvalSym (ilist->init.deep);
283 resolveIvalSym (ilist->next);
286 /*-----------------------------------------------------------------*/
287 /* symbolVal - creates a value for a symbol */
288 /*-----------------------------------------------------------------*/
290 symbolVal (symbol * sym)
302 val->type = sym->type;
303 val->etype = getSpec (val->type);
307 sprintf (val->name, "%s", sym->rname);
309 sprintf (val->name, "_%s", sym->name);
315 /*-----------------------------------------------------------------*/
316 /* valueFromLit - creates a value from a literal */
317 /*-----------------------------------------------------------------*/
319 valueFromLit (double lit)
323 if ((((long) lit) - lit) == 0)
325 sprintf (buffer, "%ld", (long) lit);
326 return constVal (buffer);
329 sprintf (buffer, "%f", lit);
330 return constFloatVal (buffer);
333 /*-----------------------------------------------------------------*/
334 /* constFloatVal - converts a FLOAT constant to value */
335 /*-----------------------------------------------------------------*/
337 constFloatVal (char *s)
339 value *val = newValue ();
342 if (sscanf (s, "%f", &sval) != 1)
344 werror (E_INVALID_FLOAT_CONST, s);
345 return constVal ("0");
348 val->type = val->etype = newLink ();
349 val->type->class = SPECIFIER;
350 SPEC_NOUN (val->type) = V_FLOAT;
351 SPEC_SCLS (val->type) = S_LITERAL;
352 SPEC_CVAL (val->type).v_float = sval;
357 /*-----------------------------------------------------------------*/
358 /* constVal - converts a INTEGER constant into a value */
359 /*-----------------------------------------------------------------*/
364 short hex = 0, octal = 0;
369 val = newValue (); /* alloc space for value */
371 val->type = val->etype = newLink (); /* create the spcifier */
372 val->type->class = SPECIFIER;
373 SPEC_NOUN (val->type) = V_INT;
374 SPEC_SCLS (val->type) = S_LITERAL;
376 /* set the _unsigned flag if 'uU' found */
377 if (strchr (s, 'u') || strchr (s, 'U'))
378 SPEC_USIGN (val->type) = 1;
380 /* set the _long flag if 'lL' is found */
381 if (strchr (s, 'l') || strchr (s, 'L'))
382 SPEC_LONG (val->type) = 1;
384 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
386 /* set the octal flag */
387 if (!hex && *s == '0' && *(s + 1))
390 /* create the scan string */
391 scanFmt[scI++] = '%';
394 scanFmt[scI++] = 'o';
396 scanFmt[scI++] = 'x';
397 else if (SPEC_USIGN (val->type))
398 scanFmt[scI++] = 'u';
400 scanFmt[scI++] = 'd';
402 scanFmt[scI++] = '\0';
404 /* if hex or octal then set the unsigned flag */
407 SPEC_USIGN (val->type) = 1;
408 sscanf (s, scanFmt, &sval);
413 // check if we have to promote to long
414 if (SPEC_LONG (val->type) ||
415 (SPEC_USIGN(val->type) && sval>0xffff) ||
416 (!SPEC_USIGN(val->type) && ((long)sval>32767 || (long)sval<-32768))) {
417 if (SPEC_USIGN (val->type))
418 SPEC_CVAL (val->type).v_ulong = sval;
420 SPEC_CVAL (val->type).v_long = sval;
421 SPEC_LONG (val->type) = 1;
425 if (SPEC_USIGN (val->type))
426 SPEC_CVAL (val->type).v_uint = sval;
428 SPEC_CVAL (val->type).v_int = sval;
431 // check if we can make it a char
432 if ((SPEC_USIGN(val->type) && sval < 256) ||
433 (!SPEC_USIGN(val->type) && ((long)sval<127 && (long)sval>-128))) {
434 SPEC_NOUN (val->etype) = V_CHAR;
439 /*! /fn char hexEscape(char **src)
441 /param src Pointer to 'x' from start of hex character value
444 char hexEscape(char **src)
448 unsigned long value ;
450 (*src)++ ; /* Skip over the 'x' */
451 s = *src ; /* Save for error detection */
453 value = strtol (*src, src, 16);
457 // no valid hex found
458 werror(E_INVALID_HEX);
465 werror(W_ESC_SEQ_OOR_FOR_CHAR);
471 /*------------------------------------------------------------------*/
472 /* octalEscape - process an octal constant of max three digits */
473 /* return the octal value, throw a warning for illegal octal */
474 /* adjust src to point at the last proccesed char */
475 /*------------------------------------------------------------------*/
477 char octalEscape (char **str) {
481 for (digits=0; digits<3; digits++) {
482 if (**str>='0' && **str<='7') {
483 value = value*8 + (**str-'0');
490 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
491 werror (W_ESC_SEQ_OOR_FOR_CHAR);
498 /fn int copyStr (char *dest, char *src)
500 Copies a source string to a dest buffer interpreting escape sequences
501 and special characters
503 /param dest Buffer to receive the resultant string
504 /param src Buffer containing the source string with escape sequecnes
505 /return Number of characters in output string
510 copyStr (char *dest, char *src)
513 char *OriginalDest = dest ;
519 else if (*src == '\\')
554 *dest++ = octalEscape(&src);
559 *dest++ = hexEscape(&src) ;
586 return dest - OriginalDest ;
589 /*------------------------------------------------------------------*/
590 /* strVal - converts a string constant to a value */
591 /*------------------------------------------------------------------*/
597 val = newValue (); /* get a new one */
599 /* get a declarator */
600 val->type = newLink ();
601 DCL_TYPE (val->type) = ARRAY;
602 val->type->next = val->etype = newLink ();
603 val->etype->class = SPECIFIER;
604 SPEC_NOUN (val->etype) = V_CHAR;
605 SPEC_SCLS (val->etype) = S_LITERAL;
607 SPEC_CVAL (val->etype).v_char = Safe_calloc (1, strlen (s) + 1);
608 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
614 /*------------------------------------------------------------------*/
615 /* reverseValWithType - reverses value chain with type & etype */
616 /*------------------------------------------------------------------*/
618 reverseValWithType (value * val)
626 /* save the type * etype chains */
630 /* set the current one 2b null */
631 val->type = val->etype = NULL;
632 val = reverseVal (val);
634 /* restore type & etype */
641 /*------------------------------------------------------------------*/
642 /* reverseVal - reverses the values for a value chain */
643 /*------------------------------------------------------------------*/
645 reverseVal (value * val)
647 value *prev, *curr, *next;
662 val->next = (void *) NULL;
666 /*------------------------------------------------------------------*/
667 /* copyValueChain - will copy a chain of values */
668 /*------------------------------------------------------------------*/
670 copyValueChain (value * src)
677 dest = copyValue (src);
678 dest->next = copyValueChain (src->next);
683 /*------------------------------------------------------------------*/
684 /* copyValue - copies contents of a vlue to a fresh one */
685 /*------------------------------------------------------------------*/
687 copyValue (value * src)
692 dest->sym = copySymbol (src->sym);
693 strcpy (dest->name, src->name);
694 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
695 dest->etype = (src->type ? getSpec (dest->type) : NULL);
700 /*------------------------------------------------------------------*/
701 /* charVal - converts a character constant to a value */
702 /*------------------------------------------------------------------*/
711 val->type = val->etype = newLink ();
712 val->type->class = SPECIFIER;
713 SPEC_NOUN (val->type) = V_CHAR;
714 SPEC_SCLS (val->type) = S_LITERAL;
716 s++; /* get rid of quotation */
717 /* if \ then special processing */
720 s++; /* go beyond the backslash */
724 SPEC_CVAL (val->type).v_int = '\n';
727 SPEC_CVAL (val->type).v_int = '\t';
730 SPEC_CVAL (val->type).v_int = '\v';
733 SPEC_CVAL (val->type).v_int = '\b';
736 SPEC_CVAL (val->type).v_int = '\r';
739 SPEC_CVAL (val->type).v_int = '\f';
742 SPEC_CVAL (val->type).v_int = '\a';
745 SPEC_CVAL (val->type).v_int = '\\';
748 SPEC_CVAL (val->type).v_int = '\?';
751 SPEC_CVAL (val->type).v_int = '\'';
754 SPEC_CVAL (val->type).v_int = '\"';
765 SPEC_CVAL (val->type).v_int = octalEscape(&s);
769 SPEC_CVAL (val->type).v_int = hexEscape(&s) ;
773 SPEC_CVAL (val->type).v_int = *s;
777 else /* not a backslash */
778 SPEC_CVAL (val->type).v_int = *s;
783 /*------------------------------------------------------------------*/
784 /* valFromType - creates a value from type given */
785 /*------------------------------------------------------------------*/
787 valFromType (sym_link * type)
789 value *val = newValue ();
790 val->type = copyLinkChain (type);
791 val->etype = getSpec (val->type);
795 /*------------------------------------------------------------------*/
796 /* floatFromVal - value to unsinged integer conversion */
797 /*------------------------------------------------------------------*/
799 floatFromVal (value * val)
804 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
806 werror (E_CONST_EXPECTED, val->name);
810 /* if it is not a specifier then we can assume that */
811 /* it will be an unsigned long */
812 if (!IS_SPEC (val->type))
813 return (double) SPEC_CVAL (val->etype).v_ulong;
815 if (SPEC_NOUN (val->etype) == V_FLOAT)
816 return (double) SPEC_CVAL (val->etype).v_float;
819 if (SPEC_LONG (val->etype))
821 if (SPEC_USIGN (val->etype))
822 return (double) SPEC_CVAL (val->etype).v_ulong;
824 return (double) SPEC_CVAL (val->etype).v_long;
828 if (SPEC_USIGN (val->etype))
829 return (double) SPEC_CVAL (val->etype).v_uint;
831 return (double) SPEC_CVAL (val->etype).v_int;
837 /*------------------------------------------------------------------*/
838 /* valUnaryPM - dones the unary +/- operation on a constant */
839 /*------------------------------------------------------------------*/
841 valUnaryPM (value * val)
843 /* depending on type */
844 if (SPEC_NOUN (val->etype) == V_FLOAT)
845 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
848 if (SPEC_LONG (val->etype))
850 if (SPEC_USIGN (val->etype))
851 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
853 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
857 if (SPEC_USIGN (val->etype))
858 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
860 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
867 /*------------------------------------------------------------------*/
868 /* valueComplement - complements a constant */
869 /*------------------------------------------------------------------*/
871 valComplement (value * val)
873 /* depending on type */
874 if (SPEC_LONG (val->etype))
876 if (SPEC_USIGN (val->etype))
877 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
879 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
883 if (SPEC_USIGN (val->etype))
884 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
886 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
891 /*------------------------------------------------------------------*/
892 /* valueNot - complements a constant */
893 /*------------------------------------------------------------------*/
897 /* depending on type */
898 if (SPEC_LONG (val->etype))
900 if (SPEC_USIGN (val->etype))
901 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
903 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
907 if (SPEC_USIGN (val->etype))
908 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
910 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
915 /*------------------------------------------------------------------*/
916 /* valMult - multiply constants */
917 /*------------------------------------------------------------------*/
919 valMult (value * lval, value * rval)
923 /* create a new value */
925 val->type = val->etype = newLink ();
926 val->type->class = SPECIFIER;
927 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
928 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
929 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
930 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
931 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
933 if (IS_FLOAT (val->type))
934 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
937 if (SPEC_LONG (val->type))
939 if (SPEC_USIGN (val->type))
940 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
941 (unsigned long) floatFromVal (rval);
943 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
944 (long) floatFromVal (rval);
948 if (SPEC_USIGN (val->type))
949 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
950 (unsigned) floatFromVal (rval);
952 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
953 (int) floatFromVal (rval);
959 /*------------------------------------------------------------------*/
960 /* valDiv - Divide constants */
961 /*------------------------------------------------------------------*/
963 valDiv (value * lval, value * rval)
967 if (floatFromVal (rval) == 0)
969 werror (E_DIVIDE_BY_ZERO);
973 /* create a new value */
975 val->type = val->etype = ((floatFromVal (lval) / floatFromVal (rval)) < 256 ?
976 newCharLink () : newIntLink ());
977 if (IS_FLOAT (lval->etype) || IS_FLOAT (rval->etype))
978 SPEC_NOUN (val->etype) = V_FLOAT;
979 SPEC_SCLS (val->etype) = S_LITERAL;
980 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
981 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
983 if (IS_FLOAT (val->type))
984 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
987 if (SPEC_LONG (val->type))
989 if (SPEC_USIGN (val->type))
990 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) /
991 (unsigned long) floatFromVal (rval);
993 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
994 (long) floatFromVal (rval);
998 if (SPEC_USIGN (val->type))
999 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1000 (unsigned) floatFromVal (rval);
1002 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1003 (int) floatFromVal (rval);
1009 /*------------------------------------------------------------------*/
1010 /* valMod - Modulus constants */
1011 /*------------------------------------------------------------------*/
1013 valMod (value * lval, value * rval)
1017 /* create a new value */
1019 val->type = val->etype = newLink ();
1020 val->type->class = SPECIFIER;
1021 SPEC_NOUN (val->type) = V_INT; /* type is int */
1022 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1023 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1024 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1026 if (SPEC_LONG (val->type))
1028 if (SPEC_USIGN (val->type))
1029 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1030 (unsigned long) floatFromVal (rval);
1032 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1033 (unsigned long) floatFromVal (rval);
1037 if (SPEC_USIGN (val->type))
1038 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1039 (unsigned) floatFromVal (rval);
1041 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1042 (unsigned) floatFromVal (rval);
1048 /*------------------------------------------------------------------*/
1049 /* valPlus - Addition constants */
1050 /*------------------------------------------------------------------*/
1052 valPlus (value * lval, value * rval)
1056 /* create a new value */
1058 val->type = val->etype = newLink ();
1059 val->type->class = SPECIFIER;
1060 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1061 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1062 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1063 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1064 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1066 if (IS_FLOAT (val->type))
1067 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1070 if (SPEC_LONG (val->type))
1072 if (SPEC_USIGN (val->type))
1073 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1074 (unsigned long) floatFromVal (rval);
1076 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1077 (long) floatFromVal (rval);
1081 if (SPEC_USIGN (val->type))
1082 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
1083 (unsigned) floatFromVal (rval);
1085 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
1086 (int) floatFromVal (rval);
1092 /*------------------------------------------------------------------*/
1093 /* valMinus - Addition constants */
1094 /*------------------------------------------------------------------*/
1096 valMinus (value * lval, value * rval)
1100 /* create a new value */
1102 val->type = val->etype = newLink ();
1103 val->type->class = SPECIFIER;
1104 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1105 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1106 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1107 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1108 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1110 if (IS_FLOAT (val->type))
1111 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1114 if (SPEC_LONG (val->type))
1116 if (SPEC_USIGN (val->type))
1117 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) -
1118 (unsigned long) floatFromVal (rval);
1120 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1121 (long) floatFromVal (rval);
1125 if (SPEC_USIGN (val->type))
1126 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1127 (unsigned) floatFromVal (rval);
1129 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - (int) floatFromVal (rval);
1135 /*------------------------------------------------------------------*/
1136 /* valShift - Shift left or right */
1137 /*------------------------------------------------------------------*/
1139 valShift (value * lval, value * rval, int lr)
1143 /* create a new value */
1145 val->type = val->etype = newLink ();
1146 val->type->class = SPECIFIER;
1147 SPEC_NOUN (val->type) = V_INT; /* type is int */
1148 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1149 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1150 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1154 if (SPEC_LONG (val->type))
1156 if (SPEC_USIGN (val->type))
1157 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) <<
1158 (unsigned long) floatFromVal (rval);
1160 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) <<
1161 (long) floatFromVal (rval);
1165 if (SPEC_USIGN (val->type))
1166 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) <<
1167 (unsigned) floatFromVal (rval);
1169 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) <<
1170 (int) floatFromVal (rval);
1175 if (SPEC_LONG (val->type))
1177 if (SPEC_USIGN (val->type))
1178 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) >>
1179 (unsigned long) floatFromVal (rval);
1181 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) >>
1182 (long) floatFromVal (rval);
1186 if (SPEC_USIGN (val->type))
1187 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) >>
1188 (unsigned) floatFromVal (rval);
1190 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) >>
1191 (int) floatFromVal (rval);
1198 /*------------------------------------------------------------------*/
1199 /* valCompare- Compares two literal */
1200 /*------------------------------------------------------------------*/
1202 valCompare (value * lval, value * rval, int ctype)
1206 /* create a new value */
1208 val->type = val->etype = newCharLink ();
1209 val->type->class = SPECIFIER;
1210 SPEC_NOUN (val->type) = V_INT; /* type is int */
1211 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1216 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1220 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1224 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1228 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1232 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1236 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1244 /*------------------------------------------------------------------*/
1245 /* valBitwise - Bitwise operation */
1246 /*------------------------------------------------------------------*/
1248 valBitwise (value * lval, value * rval, int op)
1252 /* create a new value */
1254 val->type = copyLinkChain (lval->type);
1255 val->etype = getSpec (val->type);
1260 if (SPEC_LONG (val->type))
1262 if (SPEC_USIGN (val->type))
1263 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1264 (unsigned long) floatFromVal (rval);
1266 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1267 (long) floatFromVal (rval);
1271 if (SPEC_USIGN (val->type))
1272 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1273 (unsigned) floatFromVal (rval);
1275 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1280 if (SPEC_LONG (val->type))
1282 if (SPEC_USIGN (val->type))
1283 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1284 (unsigned long) floatFromVal (rval);
1286 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1287 (long) floatFromVal (rval);
1291 if (SPEC_USIGN (val->type))
1292 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1293 (unsigned) floatFromVal (rval);
1295 SPEC_CVAL (val->type).v_int =
1296 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1302 if (SPEC_LONG (val->type))
1304 if (SPEC_USIGN (val->type))
1305 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1306 (unsigned long) floatFromVal (rval);
1308 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1309 (long) floatFromVal (rval);
1313 if (SPEC_USIGN (val->type))
1314 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1315 (unsigned) floatFromVal (rval);
1317 SPEC_CVAL (val->type).v_int =
1318 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1326 /*------------------------------------------------------------------*/
1327 /* valAndOr - Generates code for and / or operation */
1328 /*------------------------------------------------------------------*/
1330 valLogicAndOr (value * lval, value * rval, int op)
1334 /* create a new value */
1336 val->type = val->etype = newCharLink ();
1337 val->type->class = SPECIFIER;
1338 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1343 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1347 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1355 /*------------------------------------------------------------------*/
1356 /* valCastLiteral - casts a literal value to another type */
1357 /*------------------------------------------------------------------*/
1359 valCastLiteral (sym_link * dtype, double fval)
1367 val->etype = getSpec (val->type = copyLinkChain (dtype));
1368 SPEC_SCLS (val->etype) = S_LITERAL;
1369 /* if it is not a specifier then we can assume that */
1370 /* it will be an unsigned long */
1371 if (!IS_SPEC (val->type))
1373 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1377 if (SPEC_NOUN (val->etype) == V_FLOAT)
1378 SPEC_CVAL (val->etype).v_float = fval;
1381 if (SPEC_LONG (val->etype))
1383 if (SPEC_USIGN (val->etype))
1384 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1386 SPEC_CVAL (val->etype).v_long = (long) fval;
1390 if (SPEC_USIGN (val->etype))
1391 SPEC_CVAL (val->etype).v_uint = (unsigned int) fval;
1393 SPEC_CVAL (val->etype).v_int = (int) fval;
1399 /*------------------------------------------------------------------*/
1400 /* getNelements - determines # of elements from init list */
1401 /*------------------------------------------------------------------*/
1403 getNelements (sym_link * type, initList * ilist)
1405 sym_link *etype = getSpec (type);
1411 if (ilist->type == INIT_DEEP)
1412 ilist = ilist->init.deep;
1414 /* if type is a character array and there is only one
1415 (string) initialiser then get the length of the string */
1416 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1418 ast *iast = ilist->init.node;
1419 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1422 werror (E_INIT_WRONG);
1426 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1427 // yep, it's a string
1429 return DCL_ELEM (v->type);
1437 ilist = ilist->next;
1443 /*-----------------------------------------------------------------*/
1444 /* valForArray - returns a value with name of array index */
1445 /*-----------------------------------------------------------------*/
1447 valForArray (ast * arrExpr)
1449 value *val, *lval = NULL;
1451 int size = getSize (arrExpr->left->ftype->next);
1452 /* if the right or left is an array
1454 if (IS_AST_OP (arrExpr->left))
1456 if (arrExpr->left->opval.op == '[')
1457 lval = valForArray (arrExpr->left);
1458 else if (arrExpr->left->opval.op == '.')
1459 lval = valForStructElem (arrExpr->left->left,
1460 arrExpr->left->right);
1461 else if (arrExpr->left->opval.op == PTR_OP &&
1462 IS_ADDRESS_OF_OP (arrExpr->left->left))
1463 lval = valForStructElem (arrExpr->left->left->left,
1464 arrExpr->left->right);
1469 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1472 if (!IS_AST_LIT_VALUE (arrExpr->right))
1477 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1479 sprintf (buffer, "%s", lval->name);
1481 sprintf (val->name, "(%s + %d)", buffer,
1482 (int) AST_LIT_VALUE (arrExpr->right) * size);
1484 val->type = newLink ();
1485 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1487 DCL_TYPE (val->type) = CPOINTER;
1488 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1490 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1491 DCL_TYPE (val->type) = FPOINTER;
1492 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1493 DCL_TYPE (val->type) = PPOINTER;
1494 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1495 DCL_TYPE (val->type) = IPOINTER;
1496 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1497 DCL_TYPE (val->type) = EEPPOINTER;
1499 DCL_TYPE (val->type) = POINTER;
1500 val->type->next = arrExpr->left->ftype;
1501 val->etype = getSpec (val->type);
1505 /*-----------------------------------------------------------------*/
1506 /* valForStructElem - returns value with name of struct element */
1507 /*-----------------------------------------------------------------*/
1509 valForStructElem (ast * structT, ast * elemT)
1511 value *val, *lval = NULL;
1515 /* left could be furthur derefed */
1516 if (IS_AST_OP (structT))
1518 if (structT->opval.op == '[')
1519 lval = valForArray (structT);
1520 else if (structT->opval.op == '.')
1521 lval = valForStructElem (structT->left, structT->right);
1522 else if (structT->opval.op == PTR_OP &&
1523 IS_ADDRESS_OF_OP (structT->left))
1524 lval = valForStructElem (structT->left->left,
1530 if (!IS_AST_SYM_VALUE (elemT))
1533 if (!IS_STRUCT (structT->etype))
1536 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1537 AST_SYMBOL (elemT))) == NULL)
1544 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1546 sprintf (buffer, "%s", lval->name);
1548 sprintf (val->name, "(%s + %d)", buffer,
1551 val->type = newLink ();
1552 if (SPEC_SCLS (structT->etype) == S_CODE)
1554 DCL_TYPE (val->type) = CPOINTER;
1555 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1557 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1558 DCL_TYPE (val->type) = FPOINTER;
1559 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1560 DCL_TYPE (val->type) = PPOINTER;
1561 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1562 DCL_TYPE (val->type) = IPOINTER;
1563 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1564 DCL_TYPE (val->type) = EEPPOINTER;
1566 DCL_TYPE (val->type) = POINTER;
1567 val->type->next = sym->type;
1568 val->etype = getSpec (val->type);
1572 /*-----------------------------------------------------------------*/
1573 /* valForCastAggr - will return value for a cast of an aggregate */
1574 /* plus minus a constant */
1575 /*-----------------------------------------------------------------*/
1577 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1581 if (!IS_AST_SYM_VALUE (aexpr))
1583 if (!IS_AST_LIT_VALUE (cnst))
1588 sprintf (val->name, "(%s %c %d)",
1589 AST_SYMBOL (aexpr)->rname, op,
1590 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1593 val->etype = getSpec (val->type);
1597 /*-----------------------------------------------------------------*/
1598 /* valForCastAggr - will return value for a cast of an aggregate */
1599 /* with no constant */
1600 /*-----------------------------------------------------------------*/
1602 valForCastArr (ast * aexpr, sym_link * type)
1606 if (!IS_AST_SYM_VALUE (aexpr))
1611 sprintf (val->name, "(%s)",
1612 AST_SYMBOL (aexpr)->rname);
1615 val->etype = getSpec (val->type);