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 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 = newLink();
976 val->type->class = SPECIFIER;
977 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
978 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
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);
1001 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1002 (SPEC_CVAL (val->type).v_uint <=255)) {
1003 SPEC_NOUN (val->type) = V_CHAR;
1006 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1007 (int) floatFromVal (rval);
1008 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1009 (SPEC_CVAL (val->type).v_int >=-128) &&
1010 (SPEC_CVAL (val->type).v_int <=127)) {
1011 SPEC_NOUN (val->type) = V_CHAR;
1019 /*------------------------------------------------------------------*/
1020 /* valMod - Modulus constants */
1021 /*------------------------------------------------------------------*/
1023 valMod (value * lval, value * rval)
1027 /* create a new value */
1029 val->type = val->etype = newLink ();
1030 val->type->class = SPECIFIER;
1031 SPEC_NOUN (val->type) = V_INT; /* type is int */
1032 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1033 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1034 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1036 if (SPEC_LONG (val->type))
1038 if (SPEC_USIGN (val->type))
1039 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1040 (unsigned long) floatFromVal (rval);
1042 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1043 (unsigned long) floatFromVal (rval);
1047 if (SPEC_USIGN (val->type)) {
1048 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1049 (unsigned) floatFromVal (rval);
1050 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1051 (SPEC_CVAL (val->type).v_uint <=255)) {
1052 SPEC_NOUN (val->type) = V_CHAR;
1055 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1056 (unsigned) floatFromVal (rval);
1057 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1058 (SPEC_CVAL (val->type).v_int >=-128) &&
1059 (SPEC_CVAL (val->type).v_int <=127)) {
1060 SPEC_NOUN (val->type) = V_CHAR;
1068 /*------------------------------------------------------------------*/
1069 /* valPlus - Addition constants */
1070 /*------------------------------------------------------------------*/
1072 valPlus (value * lval, value * rval)
1076 /* create a new value */
1078 val->type = val->etype = newLink ();
1079 val->type->class = SPECIFIER;
1080 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1081 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1082 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1083 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1084 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1086 if (IS_FLOAT (val->type))
1087 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1090 if (SPEC_LONG (val->type))
1092 if (SPEC_USIGN (val->type))
1093 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1094 (unsigned long) floatFromVal (rval);
1096 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1097 (long) floatFromVal (rval);
1101 if (SPEC_USIGN (val->type)) {
1102 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
1103 (unsigned) floatFromVal (rval);
1104 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1105 (SPEC_CVAL (val->type).v_uint <=255)) {
1106 SPEC_NOUN (val->type) = V_CHAR;
1109 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
1110 (int) floatFromVal (rval);
1111 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1112 (SPEC_CVAL (val->type).v_int >=-128) &&
1113 (SPEC_CVAL (val->type).v_int <=127)) {
1114 SPEC_NOUN (val->type) = V_CHAR;
1122 /*------------------------------------------------------------------*/
1123 /* valMinus - Addition constants */
1124 /*------------------------------------------------------------------*/
1126 valMinus (value * lval, value * rval)
1130 /* create a new value */
1132 val->type = val->etype = newLink ();
1133 val->type->class = SPECIFIER;
1134 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1135 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1136 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1137 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1138 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1140 if (IS_FLOAT (val->type))
1141 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1144 if (SPEC_LONG (val->type))
1146 if (SPEC_USIGN (val->type)) {
1147 SPEC_CVAL (val->type).v_ulong =
1148 (unsigned long) floatFromVal (lval) -
1149 (unsigned long) floatFromVal (rval);
1151 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1152 (long) floatFromVal (rval);
1157 if (SPEC_USIGN (val->type)) {
1158 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1159 (unsigned) floatFromVal (rval);
1160 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1161 (SPEC_CVAL (val->type).v_uint <=255)) {
1162 SPEC_NOUN (val->type) = V_CHAR;
1165 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - (int) floatFromVal (rval);
1166 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1167 (SPEC_CVAL (val->type).v_int >=-128) &&
1168 (SPEC_CVAL (val->type).v_int <=127)) {
1169 SPEC_NOUN (val->type) = V_CHAR;
1177 /*------------------------------------------------------------------*/
1178 /* valShift - Shift left or right */
1179 /*------------------------------------------------------------------*/
1181 valShift (value * lval, value * rval, int lr)
1185 /* create a new value */
1187 val->type = val->etype = newIntLink ();
1188 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1189 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1190 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1192 if (SPEC_LONG (val->type))
1194 if (SPEC_USIGN (val->type))
1195 SPEC_CVAL (val->type).v_ulong = lr ?
1196 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1197 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1199 SPEC_CVAL (val->type).v_long = lr ?
1200 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1201 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1205 if (SPEC_USIGN (val->type)) {
1206 SPEC_CVAL (val->type).v_uint = lr ?
1207 (unsigned) floatFromVal (lval) << (unsigned) floatFromVal (rval) :\
1208 (unsigned) floatFromVal (lval) >> (unsigned) floatFromVal (rval);
1209 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1210 (SPEC_CVAL (val->type).v_uint <=255)) {
1211 SPEC_NOUN (val->type) = V_CHAR;
1214 SPEC_CVAL (val->type).v_int = lr ?
1215 (int) floatFromVal (lval) << (int) floatFromVal (rval) : \
1216 (int) floatFromVal (lval) >> (int) floatFromVal (rval);
1217 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1218 (SPEC_CVAL (val->type).v_int >=-128) &&
1219 (SPEC_CVAL (val->type).v_int <=127)) {
1220 SPEC_NOUN (val->type) = V_CHAR;
1228 /*------------------------------------------------------------------*/
1229 /* valCompare- Compares two literal */
1230 /*------------------------------------------------------------------*/
1232 valCompare (value * lval, value * rval, int ctype)
1236 /* create a new value */
1238 val->type = val->etype = newCharLink ();
1239 val->type->class = SPECIFIER;
1240 SPEC_NOUN (val->type) = V_INT; /* type is int */
1241 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
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);
1262 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1266 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1274 /*------------------------------------------------------------------*/
1275 /* valBitwise - Bitwise operation */
1276 /*------------------------------------------------------------------*/
1278 valBitwise (value * lval, value * rval, int op)
1282 /* create a new value */
1284 val->type = copyLinkChain (lval->type);
1285 val->etype = getSpec (val->type);
1290 if (SPEC_LONG (val->type))
1292 if (SPEC_USIGN (val->type))
1293 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1294 (unsigned long) floatFromVal (rval);
1296 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1297 (long) floatFromVal (rval);
1301 if (SPEC_USIGN (val->type))
1302 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1303 (unsigned) floatFromVal (rval);
1305 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1310 if (SPEC_LONG (val->type))
1312 if (SPEC_USIGN (val->type))
1313 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1314 (unsigned long) floatFromVal (rval);
1316 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1317 (long) floatFromVal (rval);
1321 if (SPEC_USIGN (val->type))
1322 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1323 (unsigned) floatFromVal (rval);
1325 SPEC_CVAL (val->type).v_int =
1326 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1332 if (SPEC_LONG (val->type))
1334 if (SPEC_USIGN (val->type))
1335 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1336 (unsigned long) floatFromVal (rval);
1338 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1339 (long) floatFromVal (rval);
1343 if (SPEC_USIGN (val->type))
1344 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1345 (unsigned) floatFromVal (rval);
1347 SPEC_CVAL (val->type).v_int =
1348 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1356 /*------------------------------------------------------------------*/
1357 /* valAndOr - Generates code for and / or operation */
1358 /*------------------------------------------------------------------*/
1360 valLogicAndOr (value * lval, value * rval, int op)
1364 /* create a new value */
1366 val->type = val->etype = newCharLink ();
1367 val->type->class = SPECIFIER;
1368 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1373 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1377 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1385 /*------------------------------------------------------------------*/
1386 /* valCastLiteral - casts a literal value to another type */
1387 /*------------------------------------------------------------------*/
1389 valCastLiteral (sym_link * dtype, double fval)
1397 val->etype = getSpec (val->type = copyLinkChain (dtype));
1398 SPEC_SCLS (val->etype) = S_LITERAL;
1399 /* if it is not a specifier then we can assume that */
1400 /* it will be an unsigned long */
1401 if (!IS_SPEC (val->type))
1403 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1407 if (SPEC_NOUN (val->etype) == V_FLOAT)
1408 SPEC_CVAL (val->etype).v_float = fval;
1411 if (SPEC_LONG (val->etype))
1413 if (SPEC_USIGN (val->etype))
1414 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1416 SPEC_CVAL (val->etype).v_long = (long) fval;
1420 if (SPEC_USIGN (val->etype))
1421 SPEC_CVAL (val->etype).v_uint = (unsigned int) fval;
1423 SPEC_CVAL (val->etype).v_int = (int) fval;
1429 /*------------------------------------------------------------------*/
1430 /* getNelements - determines # of elements from init list */
1431 /*------------------------------------------------------------------*/
1433 getNelements (sym_link * type, initList * ilist)
1435 sym_link *etype = getSpec (type);
1441 if (ilist->type == INIT_DEEP)
1442 ilist = ilist->init.deep;
1444 /* if type is a character array and there is only one
1445 (string) initialiser then get the length of the string */
1446 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1448 ast *iast = ilist->init.node;
1449 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1452 werror (E_INIT_WRONG);
1456 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1457 // yep, it's a string
1459 return DCL_ELEM (v->type);
1467 ilist = ilist->next;
1473 /*-----------------------------------------------------------------*/
1474 /* valForArray - returns a value with name of array index */
1475 /*-----------------------------------------------------------------*/
1477 valForArray (ast * arrExpr)
1479 value *val, *lval = NULL;
1481 int size = getSize (arrExpr->left->ftype->next);
1482 /* if the right or left is an array
1484 if (IS_AST_OP (arrExpr->left))
1486 if (arrExpr->left->opval.op == '[')
1487 lval = valForArray (arrExpr->left);
1488 else if (arrExpr->left->opval.op == '.')
1489 lval = valForStructElem (arrExpr->left->left,
1490 arrExpr->left->right);
1491 else if (arrExpr->left->opval.op == PTR_OP &&
1492 IS_ADDRESS_OF_OP (arrExpr->left->left))
1493 lval = valForStructElem (arrExpr->left->left->left,
1494 arrExpr->left->right);
1499 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1502 if (!IS_AST_LIT_VALUE (arrExpr->right))
1507 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1509 sprintf (buffer, "%s", lval->name);
1511 sprintf (val->name, "(%s + %d)", buffer,
1512 (int) AST_LIT_VALUE (arrExpr->right) * size);
1514 val->type = newLink ();
1515 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1517 DCL_TYPE (val->type) = CPOINTER;
1518 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1520 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1521 DCL_TYPE (val->type) = FPOINTER;
1522 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1523 DCL_TYPE (val->type) = PPOINTER;
1524 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1525 DCL_TYPE (val->type) = IPOINTER;
1526 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1527 DCL_TYPE (val->type) = EEPPOINTER;
1529 DCL_TYPE (val->type) = POINTER;
1530 val->type->next = arrExpr->left->ftype;
1531 val->etype = getSpec (val->type);
1535 /*-----------------------------------------------------------------*/
1536 /* valForStructElem - returns value with name of struct element */
1537 /*-----------------------------------------------------------------*/
1539 valForStructElem (ast * structT, ast * elemT)
1541 value *val, *lval = NULL;
1545 /* left could be furthur derefed */
1546 if (IS_AST_OP (structT))
1548 if (structT->opval.op == '[')
1549 lval = valForArray (structT);
1550 else if (structT->opval.op == '.')
1551 lval = valForStructElem (structT->left, structT->right);
1552 else if (structT->opval.op == PTR_OP &&
1553 IS_ADDRESS_OF_OP (structT->left))
1554 lval = valForStructElem (structT->left->left,
1560 if (!IS_AST_SYM_VALUE (elemT))
1563 if (!IS_STRUCT (structT->etype))
1566 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1567 AST_SYMBOL (elemT))) == NULL)
1574 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1576 sprintf (buffer, "%s", lval->name);
1578 sprintf (val->name, "(%s + %d)", buffer,
1581 val->type = newLink ();
1582 if (SPEC_SCLS (structT->etype) == S_CODE)
1584 DCL_TYPE (val->type) = CPOINTER;
1585 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1587 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1588 DCL_TYPE (val->type) = FPOINTER;
1589 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1590 DCL_TYPE (val->type) = PPOINTER;
1591 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1592 DCL_TYPE (val->type) = IPOINTER;
1593 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1594 DCL_TYPE (val->type) = EEPPOINTER;
1596 DCL_TYPE (val->type) = POINTER;
1597 val->type->next = sym->type;
1598 val->etype = getSpec (val->type);
1602 /*-----------------------------------------------------------------*/
1603 /* valForCastAggr - will return value for a cast of an aggregate */
1604 /* plus minus a constant */
1605 /*-----------------------------------------------------------------*/
1607 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1611 if (!IS_AST_SYM_VALUE (aexpr))
1613 if (!IS_AST_LIT_VALUE (cnst))
1618 sprintf (val->name, "(%s %c %d)",
1619 AST_SYMBOL (aexpr)->rname, op,
1620 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1623 val->etype = getSpec (val->type);
1627 /*-----------------------------------------------------------------*/
1628 /* valForCastAggr - will return value for a cast of an aggregate */
1629 /* with no constant */
1630 /*-----------------------------------------------------------------*/
1632 valForCastArr (ast * aexpr, sym_link * type)
1636 if (!IS_AST_SYM_VALUE (aexpr))
1641 sprintf (val->name, "(%s)",
1642 AST_SYMBOL (aexpr)->rname);
1645 val->etype = getSpec (val->type);