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(decorateType(resolveSymbols(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 an INTEGER constant into a cheapest value */
359 /*-----------------------------------------------------------------*/
360 value *constVal (char *s)
363 short hex = 0, octal = 0;
368 val = newValue (); /* alloc space for value */
370 val->type = val->etype = newLink (); /* create the spcifier */
371 val->type->class = SPECIFIER;
372 SPEC_SCLS (val->type) = S_LITERAL;
373 // let's start with an unsigned char
374 SPEC_NOUN (val->type) = V_CHAR;
375 SPEC_USIGN (val->type) = 1;
377 /* set the _long flag if 'lL' is found */
378 if (strchr (s, 'l') || strchr (s, 'L'))
379 SPEC_LONG (val->type) = 1;
381 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
383 /* set the octal flag */
384 if (!hex && *s == '0' && *(s + 1))
387 /* create the scan string */
388 scanFmt[scI++] = '%';
391 scanFmt[scI++] = 'o';
393 scanFmt[scI++] = 'x';
395 scanFmt[scI++] = 'd';
397 scanFmt[scI++] = 'L';
398 scanFmt[scI++] = '\0';
400 sscanf (s, scanFmt, &sval);
402 if (sval<0) { // "-28u" will still be signed and negative
403 SPEC_USIGN (val->type) = 0;
404 if (sval<-32768) { // check if have to promote to long
405 SPEC_NOUN (val->type) = V_INT;
406 SPEC_LONG (val->type) = 1;
407 SPEC_CVAL (val->type).v_long=sval;
409 SPEC_CVAL (val->type).v_int=sval;
410 if (sval<-128) { // check if we have to promote to int
411 SPEC_NOUN (val->type) = V_INT;
415 if (sval>0xffff) { // check if we have to promote to long
416 SPEC_NOUN (val->type) = V_INT;
417 SPEC_LONG (val->type) = 1;
418 SPEC_CVAL (val->type).v_ulong=sval;
420 SPEC_CVAL (val->type).v_uint=sval;
421 if (sval>0xff) { // check if we have to promote to int
422 SPEC_NOUN (val->type) = V_INT;
430 /*! /fn char hexEscape(char **src)
432 /param src Pointer to 'x' from start of hex character value
435 char hexEscape(char **src)
439 unsigned long value ;
441 (*src)++ ; /* Skip over the 'x' */
442 s = *src ; /* Save for error detection */
444 value = strtol (*src, src, 16);
448 // no valid hex found
449 werror(E_INVALID_HEX);
456 werror(W_ESC_SEQ_OOR_FOR_CHAR);
462 /*------------------------------------------------------------------*/
463 /* octalEscape - process an octal constant of max three digits */
464 /* return the octal value, throw a warning for illegal octal */
465 /* adjust src to point at the last proccesed char */
466 /*------------------------------------------------------------------*/
468 char octalEscape (char **str) {
472 for (digits=0; digits<3; digits++) {
473 if (**str>='0' && **str<='7') {
474 value = value*8 + (**str-'0');
481 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
482 werror (W_ESC_SEQ_OOR_FOR_CHAR);
489 /fn int copyStr (char *dest, char *src)
491 Copies a source string to a dest buffer interpreting escape sequences
492 and special characters
494 /param dest Buffer to receive the resultant string
495 /param src Buffer containing the source string with escape sequecnes
496 /return Number of characters in output string
501 copyStr (char *dest, char *src)
504 char *OriginalDest = dest ;
510 else if (*src == '\\')
545 *dest++ = octalEscape(&src);
550 *dest++ = hexEscape(&src) ;
577 return dest - OriginalDest ;
580 /*------------------------------------------------------------------*/
581 /* strVal - converts a string constant to a value */
582 /*------------------------------------------------------------------*/
588 val = newValue (); /* get a new one */
590 /* get a declarator */
591 val->type = newLink ();
592 DCL_TYPE (val->type) = ARRAY;
593 val->type->next = val->etype = newLink ();
594 val->etype->class = SPECIFIER;
595 SPEC_NOUN (val->etype) = V_CHAR;
596 SPEC_SCLS (val->etype) = S_LITERAL;
598 SPEC_CVAL (val->etype).v_char = Safe_calloc (1, strlen (s) + 1);
599 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
605 /*------------------------------------------------------------------*/
606 /* reverseValWithType - reverses value chain with type & etype */
607 /*------------------------------------------------------------------*/
609 reverseValWithType (value * val)
617 /* save the type * etype chains */
621 /* set the current one 2b null */
622 val->type = val->etype = NULL;
623 val = reverseVal (val);
625 /* restore type & etype */
632 /*------------------------------------------------------------------*/
633 /* reverseVal - reverses the values for a value chain */
634 /*------------------------------------------------------------------*/
636 reverseVal (value * val)
638 value *prev, *curr, *next;
653 val->next = (void *) NULL;
657 /*------------------------------------------------------------------*/
658 /* copyValueChain - will copy a chain of values */
659 /*------------------------------------------------------------------*/
661 copyValueChain (value * src)
668 dest = copyValue (src);
669 dest->next = copyValueChain (src->next);
674 /*------------------------------------------------------------------*/
675 /* copyValue - copies contents of a vlue to a fresh one */
676 /*------------------------------------------------------------------*/
678 copyValue (value * src)
683 dest->sym = copySymbol (src->sym);
684 strcpy (dest->name, src->name);
685 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
686 dest->etype = (src->type ? getSpec (dest->type) : NULL);
691 /*------------------------------------------------------------------*/
692 /* charVal - converts a character constant to a value */
693 /*------------------------------------------------------------------*/
702 val->type = val->etype = newLink ();
703 val->type->class = SPECIFIER;
704 SPEC_NOUN (val->type) = V_CHAR;
705 SPEC_USIGN(val->type) = 1;
706 SPEC_SCLS (val->type) = S_LITERAL;
708 s++; /* get rid of quotation */
709 /* if \ then special processing */
712 s++; /* go beyond the backslash */
716 SPEC_CVAL (val->type).v_int = '\n';
719 SPEC_CVAL (val->type).v_int = '\t';
722 SPEC_CVAL (val->type).v_int = '\v';
725 SPEC_CVAL (val->type).v_int = '\b';
728 SPEC_CVAL (val->type).v_int = '\r';
731 SPEC_CVAL (val->type).v_int = '\f';
734 SPEC_CVAL (val->type).v_int = '\a';
737 SPEC_CVAL (val->type).v_int = '\\';
740 SPEC_CVAL (val->type).v_int = '\?';
743 SPEC_CVAL (val->type).v_int = '\'';
746 SPEC_CVAL (val->type).v_int = '\"';
757 SPEC_CVAL (val->type).v_int = octalEscape(&s);
761 SPEC_CVAL (val->type).v_int = hexEscape(&s) ;
765 SPEC_CVAL (val->type).v_int = *s;
769 else /* not a backslash */
770 SPEC_CVAL (val->type).v_int = *s;
775 /*------------------------------------------------------------------*/
776 /* valFromType - creates a value from type given */
777 /*------------------------------------------------------------------*/
779 valFromType (sym_link * type)
781 value *val = newValue ();
782 val->type = copyLinkChain (type);
783 val->etype = getSpec (val->type);
787 /*------------------------------------------------------------------*/
788 /* floatFromVal - value to unsinged integer conversion */
789 /*------------------------------------------------------------------*/
791 floatFromVal (value * val)
796 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
798 werror (E_CONST_EXPECTED, val->name);
802 /* if it is not a specifier then we can assume that */
803 /* it will be an unsigned long */
804 if (!IS_SPEC (val->type))
805 return (double) SPEC_CVAL (val->etype).v_ulong;
807 if (SPEC_NOUN (val->etype) == V_FLOAT)
808 return (double) SPEC_CVAL (val->etype).v_float;
811 if (SPEC_LONG (val->etype))
813 if (SPEC_USIGN (val->etype))
814 return (double) SPEC_CVAL (val->etype).v_ulong;
816 return (double) SPEC_CVAL (val->etype).v_long;
820 if (SPEC_USIGN (val->etype))
821 return (double) SPEC_CVAL (val->etype).v_uint;
823 return (double) SPEC_CVAL (val->etype).v_int;
829 /*------------------------------------------------------------------*/
830 /* valUnaryPM - dones the unary +/- operation on a constant */
831 /*------------------------------------------------------------------*/
833 valUnaryPM (value * val)
835 /* depending on type */
836 if (SPEC_NOUN (val->etype) == V_FLOAT)
837 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
840 if (SPEC_LONG (val->etype))
842 if (SPEC_USIGN (val->etype))
843 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
845 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
849 if (SPEC_USIGN (val->etype))
850 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
852 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
859 /*------------------------------------------------------------------*/
860 /* valueComplement - complements a constant */
861 /*------------------------------------------------------------------*/
863 valComplement (value * val)
865 /* depending on type */
866 if (SPEC_LONG (val->etype))
868 if (SPEC_USIGN (val->etype))
869 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
871 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
875 if (SPEC_USIGN (val->etype))
876 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
878 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
883 /*------------------------------------------------------------------*/
884 /* valueNot - complements a constant */
885 /*------------------------------------------------------------------*/
889 /* depending on type */
890 if (SPEC_LONG (val->etype))
892 if (SPEC_USIGN (val->etype))
893 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
895 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
899 if (SPEC_USIGN (val->etype))
900 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
902 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
907 /*------------------------------------------------------------------*/
908 /* valMult - multiply constants */
909 /*------------------------------------------------------------------*/
911 valMult (value * lval, value * rval)
915 /* create a new value */
917 val->type = val->etype = newLink ();
918 val->type->class = SPECIFIER;
919 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
920 IS_FLOAT (rval->etype) ? V_FLOAT : V_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 (IS_FLOAT (val->type))
926 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
929 if (SPEC_LONG (val->type))
931 if (SPEC_USIGN (val->type))
932 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
933 (unsigned long) floatFromVal (rval);
935 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
936 (long) floatFromVal (rval);
940 if (SPEC_USIGN (val->type))
941 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
942 (unsigned) floatFromVal (rval);
944 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
945 (int) floatFromVal (rval);
951 /*------------------------------------------------------------------*/
952 /* valDiv - Divide constants */
953 /*------------------------------------------------------------------*/
955 valDiv (value * lval, value * rval)
959 if (floatFromVal (rval) == 0)
961 werror (E_DIVIDE_BY_ZERO);
965 /* create a new value */
967 val->type = val->etype = newLink();
968 val->type->class = SPECIFIER;
969 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
970 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
971 SPEC_SCLS (val->etype) = S_LITERAL;
972 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
973 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
975 if (IS_FLOAT (val->type))
976 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
979 if (SPEC_LONG (val->type))
981 if (SPEC_USIGN (val->type))
982 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) /
983 (unsigned long) floatFromVal (rval);
985 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
986 (long) floatFromVal (rval);
990 if (SPEC_USIGN (val->type)) {
991 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
992 (unsigned) floatFromVal (rval);
993 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
994 (SPEC_CVAL (val->type).v_uint <=255)) {
995 SPEC_NOUN (val->type) = V_CHAR;
998 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
999 (int) floatFromVal (rval);
1000 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1001 (SPEC_CVAL (val->type).v_int >=-128) &&
1002 (SPEC_CVAL (val->type).v_int <=127)) {
1003 SPEC_NOUN (val->type) = V_CHAR;
1011 /*------------------------------------------------------------------*/
1012 /* valMod - Modulus constants */
1013 /*------------------------------------------------------------------*/
1015 valMod (value * lval, value * rval)
1019 /* create a new value */
1021 val->type = val->etype = newLink ();
1022 val->type->class = SPECIFIER;
1023 SPEC_NOUN (val->type) = V_INT; /* type is int */
1024 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1025 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1026 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1028 if (SPEC_LONG (val->type))
1030 if (SPEC_USIGN (val->type))
1031 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1032 (unsigned long) floatFromVal (rval);
1034 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1035 (unsigned long) floatFromVal (rval);
1039 if (SPEC_USIGN (val->type)) {
1040 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1041 (unsigned) floatFromVal (rval);
1042 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1043 (SPEC_CVAL (val->type).v_uint <=255)) {
1044 SPEC_NOUN (val->type) = V_CHAR;
1047 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1048 (unsigned) floatFromVal (rval);
1049 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1050 (SPEC_CVAL (val->type).v_int >=-128) &&
1051 (SPEC_CVAL (val->type).v_int <=127)) {
1052 SPEC_NOUN (val->type) = V_CHAR;
1060 /*------------------------------------------------------------------*/
1061 /* valPlus - Addition constants */
1062 /*------------------------------------------------------------------*/
1064 valPlus (value * lval, value * rval)
1068 /* create a new value */
1070 val->type = val->etype = newLink ();
1071 val->type->class = SPECIFIER;
1072 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1073 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1074 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1075 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1076 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1078 if (IS_FLOAT (val->type))
1079 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1082 if (SPEC_LONG (val->type))
1084 if (SPEC_USIGN (val->type))
1085 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1086 (unsigned long) floatFromVal (rval);
1088 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1089 (long) floatFromVal (rval);
1093 if (SPEC_USIGN (val->type)) {
1094 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
1095 (unsigned) floatFromVal (rval);
1096 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1097 (SPEC_CVAL (val->type).v_uint <=255)) {
1098 SPEC_NOUN (val->type) = V_CHAR;
1101 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
1102 (int) floatFromVal (rval);
1103 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1104 (SPEC_CVAL (val->type).v_int >=-128) &&
1105 (SPEC_CVAL (val->type).v_int <=127)) {
1106 SPEC_NOUN (val->type) = V_CHAR;
1114 /*------------------------------------------------------------------*/
1115 /* valMinus - Addition constants */
1116 /*------------------------------------------------------------------*/
1118 valMinus (value * lval, value * rval)
1122 /* create a new value */
1124 val->type = val->etype = newLink ();
1125 val->type->class = SPECIFIER;
1126 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1127 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1128 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1129 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1130 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1132 if (IS_FLOAT (val->type))
1133 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1136 if (SPEC_LONG (val->type))
1138 if (SPEC_USIGN (val->type)) {
1139 SPEC_CVAL (val->type).v_ulong =
1140 (unsigned long) floatFromVal (lval) -
1141 (unsigned long) floatFromVal (rval);
1143 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1144 (long) floatFromVal (rval);
1149 if (SPEC_USIGN (val->type)) {
1150 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1151 (unsigned) floatFromVal (rval);
1152 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1153 (SPEC_CVAL (val->type).v_uint <=255)) {
1154 SPEC_NOUN (val->type) = V_CHAR;
1157 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - (int) floatFromVal (rval);
1158 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1159 (SPEC_CVAL (val->type).v_int >=-128) &&
1160 (SPEC_CVAL (val->type).v_int <=127)) {
1161 SPEC_NOUN (val->type) = V_CHAR;
1169 /*------------------------------------------------------------------*/
1170 /* valShift - Shift left or right */
1171 /*------------------------------------------------------------------*/
1173 valShift (value * lval, value * rval, int lr)
1177 /* create a new value */
1179 val->type = val->etype = newIntLink ();
1180 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1181 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1182 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1184 if (SPEC_LONG (val->type))
1186 if (SPEC_USIGN (val->type))
1187 SPEC_CVAL (val->type).v_ulong = lr ?
1188 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1189 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1191 SPEC_CVAL (val->type).v_long = lr ?
1192 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1193 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1197 if (SPEC_USIGN (val->type)) {
1198 SPEC_CVAL (val->type).v_uint = lr ?
1199 (unsigned) floatFromVal (lval) << (unsigned) floatFromVal (rval) :\
1200 (unsigned) floatFromVal (lval) >> (unsigned) floatFromVal (rval);
1201 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1202 (SPEC_CVAL (val->type).v_uint <=255)) {
1203 SPEC_NOUN (val->type) = V_CHAR;
1206 SPEC_CVAL (val->type).v_int = lr ?
1207 (int) floatFromVal (lval) << (int) floatFromVal (rval) : \
1208 (int) floatFromVal (lval) >> (int) floatFromVal (rval);
1209 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1210 (SPEC_CVAL (val->type).v_int >=-128) &&
1211 (SPEC_CVAL (val->type).v_int <=127)) {
1212 SPEC_NOUN (val->type) = V_CHAR;
1220 /*------------------------------------------------------------------*/
1221 /* valCompare- Compares two literal */
1222 /*------------------------------------------------------------------*/
1224 valCompare (value * lval, value * rval, int ctype)
1228 /* create a new value */
1230 val->type = val->etype = newCharLink ();
1231 val->type->class = SPECIFIER;
1232 SPEC_NOUN (val->type) = V_INT; /* type is int */
1233 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1238 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1242 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1246 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1250 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1254 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1258 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1266 /*------------------------------------------------------------------*/
1267 /* valBitwise - Bitwise operation */
1268 /*------------------------------------------------------------------*/
1270 valBitwise (value * lval, value * rval, int op)
1274 /* create a new value */
1276 val->type = copyLinkChain (lval->type);
1277 val->etype = getSpec (val->type);
1282 if (SPEC_LONG (val->type))
1284 if (SPEC_USIGN (val->type))
1285 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1286 (unsigned long) floatFromVal (rval);
1288 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1289 (long) floatFromVal (rval);
1293 if (SPEC_USIGN (val->type))
1294 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1295 (unsigned) floatFromVal (rval);
1297 SPEC_CVAL (val->type).v_int = (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);
1324 if (SPEC_LONG (val->type))
1326 if (SPEC_USIGN (val->type))
1327 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1328 (unsigned long) floatFromVal (rval);
1330 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1331 (long) floatFromVal (rval);
1335 if (SPEC_USIGN (val->type))
1336 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1337 (unsigned) floatFromVal (rval);
1339 SPEC_CVAL (val->type).v_int =
1340 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1348 /*------------------------------------------------------------------*/
1349 /* valAndOr - Generates code for and / or operation */
1350 /*------------------------------------------------------------------*/
1352 valLogicAndOr (value * lval, value * rval, int op)
1356 /* create a new value */
1358 val->type = val->etype = newCharLink ();
1359 val->type->class = SPECIFIER;
1360 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1365 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1369 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1377 /*------------------------------------------------------------------*/
1378 /* valCastLiteral - casts a literal value to another type */
1379 /*------------------------------------------------------------------*/
1381 valCastLiteral (sym_link * dtype, double fval)
1389 val->etype = getSpec (val->type = copyLinkChain (dtype));
1390 SPEC_SCLS (val->etype) = S_LITERAL;
1391 /* if it is not a specifier then we can assume that */
1392 /* it will be an unsigned long */
1393 if (!IS_SPEC (val->type))
1395 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1399 if (SPEC_NOUN (val->etype) == V_FLOAT)
1400 SPEC_CVAL (val->etype).v_float = fval;
1403 if (SPEC_LONG (val->etype))
1405 if (SPEC_USIGN (val->etype))
1406 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1408 SPEC_CVAL (val->etype).v_long = (long) fval;
1412 if (SPEC_USIGN (val->etype))
1413 SPEC_CVAL (val->etype).v_uint = (unsigned int) fval;
1415 SPEC_CVAL (val->etype).v_int = (int) fval;
1421 /*------------------------------------------------------------------*/
1422 /* getNelements - determines # of elements from init list */
1423 /*------------------------------------------------------------------*/
1425 getNelements (sym_link * type, initList * ilist)
1427 sym_link *etype = getSpec (type);
1433 if (ilist->type == INIT_DEEP)
1434 ilist = ilist->init.deep;
1436 /* if type is a character array and there is only one
1437 (string) initialiser then get the length of the string */
1438 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1440 ast *iast = ilist->init.node;
1441 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1444 werror (W_INIT_WRONG);
1448 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1449 // yep, it's a string
1451 return DCL_ELEM (v->type);
1459 ilist = ilist->next;
1465 /*-----------------------------------------------------------------*/
1466 /* valForArray - returns a value with name of array index */
1467 /*-----------------------------------------------------------------*/
1469 valForArray (ast * arrExpr)
1471 value *val, *lval = NULL;
1473 int size = getSize (arrExpr->left->ftype->next);
1474 /* if the right or left is an array
1476 if (IS_AST_OP (arrExpr->left))
1478 if (arrExpr->left->opval.op == '[')
1479 lval = valForArray (arrExpr->left);
1480 else if (arrExpr->left->opval.op == '.')
1481 lval = valForStructElem (arrExpr->left->left,
1482 arrExpr->left->right);
1483 else if (arrExpr->left->opval.op == PTR_OP &&
1484 IS_ADDRESS_OF_OP (arrExpr->left->left))
1485 lval = valForStructElem (arrExpr->left->left->left,
1486 arrExpr->left->right);
1491 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1494 if (!IS_AST_LIT_VALUE (arrExpr->right))
1499 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1501 sprintf (buffer, "%s", lval->name);
1503 sprintf (val->name, "(%s + %d)", buffer,
1504 (int) AST_LIT_VALUE (arrExpr->right) * size);
1506 val->type = newLink ();
1507 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1509 DCL_TYPE (val->type) = CPOINTER;
1510 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1512 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1513 DCL_TYPE (val->type) = FPOINTER;
1514 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1515 DCL_TYPE (val->type) = PPOINTER;
1516 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1517 DCL_TYPE (val->type) = IPOINTER;
1518 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1519 DCL_TYPE (val->type) = EEPPOINTER;
1521 DCL_TYPE (val->type) = POINTER;
1522 val->type->next = arrExpr->left->ftype;
1523 val->etype = getSpec (val->type);
1527 /*-----------------------------------------------------------------*/
1528 /* valForStructElem - returns value with name of struct element */
1529 /*-----------------------------------------------------------------*/
1531 valForStructElem (ast * structT, ast * elemT)
1533 value *val, *lval = NULL;
1537 /* left could be furthur derefed */
1538 if (IS_AST_OP (structT))
1540 if (structT->opval.op == '[')
1541 lval = valForArray (structT);
1542 else if (structT->opval.op == '.')
1543 lval = valForStructElem (structT->left, structT->right);
1544 else if (structT->opval.op == PTR_OP &&
1545 IS_ADDRESS_OF_OP (structT->left))
1546 lval = valForStructElem (structT->left->left,
1552 if (!IS_AST_SYM_VALUE (elemT))
1555 if (!IS_STRUCT (structT->etype))
1558 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1559 AST_SYMBOL (elemT))) == NULL)
1566 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1568 sprintf (buffer, "%s", lval->name);
1570 sprintf (val->name, "(%s + %d)", buffer,
1573 val->type = newLink ();
1574 if (SPEC_SCLS (structT->etype) == S_CODE)
1576 DCL_TYPE (val->type) = CPOINTER;
1577 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1579 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1580 DCL_TYPE (val->type) = FPOINTER;
1581 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1582 DCL_TYPE (val->type) = PPOINTER;
1583 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1584 DCL_TYPE (val->type) = IPOINTER;
1585 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1586 DCL_TYPE (val->type) = EEPPOINTER;
1588 DCL_TYPE (val->type) = POINTER;
1589 val->type->next = sym->type;
1590 val->etype = getSpec (val->type);
1594 /*-----------------------------------------------------------------*/
1595 /* valForCastAggr - will return value for a cast of an aggregate */
1596 /* plus minus a constant */
1597 /*-----------------------------------------------------------------*/
1599 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1603 if (!IS_AST_SYM_VALUE (aexpr))
1605 if (!IS_AST_LIT_VALUE (cnst))
1610 sprintf (val->name, "(%s %c %d)",
1611 AST_SYMBOL (aexpr)->rname, op,
1612 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1615 val->etype = getSpec (val->type);
1619 /*-----------------------------------------------------------------*/
1620 /* valForCastAggr - will return value for a cast of an aggregate */
1621 /* with no constant */
1622 /*-----------------------------------------------------------------*/
1624 valForCastArr (ast * aexpr, sym_link * type)
1628 if (!IS_AST_SYM_VALUE (aexpr))
1633 sprintf (val->name, "(%s)",
1634 AST_SYMBOL (aexpr)->rname);
1637 val->etype = getSpec (val->type);