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 'uUoOxX' found */
377 if (strchr (s, 'u') || strchr (s, 'U') ||
378 strchr (s, 'o') || strchr (s, 'O') ||
379 strchr (s, 'x') || strchr (s, 'x'))
380 SPEC_USIGN (val->type) = 1;
382 /* set the _long flag if 'lL' is found */
383 if (strchr (s, 'l') || strchr (s, 'L'))
384 SPEC_LONG (val->type) = 1;
386 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
388 /* set the octal flag */
389 if (!hex && *s == '0' && *(s + 1))
392 /* create the scan string */
393 scanFmt[scI++] = '%';
396 scanFmt[scI++] = 'o';
398 scanFmt[scI++] = 'x';
399 else if (SPEC_USIGN (val->type))
400 scanFmt[scI++] = 'u';
402 scanFmt[scI++] = 'd';
404 scanFmt[scI++] = '\0';
406 /* if hex or octal then set the unsigned flag */
409 SPEC_USIGN (val->type) = 1;
410 sscanf (s, scanFmt, &sval);
415 // check if we have to promote to long
416 if (SPEC_LONG (val->type) ||
417 (SPEC_USIGN(val->type) && sval>0xffff) ||
418 (!SPEC_USIGN(val->type) && ((long)sval>32767 || (long)sval<-32768))) {
419 if (SPEC_USIGN (val->type))
420 SPEC_CVAL (val->type).v_ulong = sval;
422 SPEC_CVAL (val->type).v_long = sval;
423 SPEC_LONG (val->type) = 1;
427 if (SPEC_USIGN (val->type))
428 SPEC_CVAL (val->type).v_uint = sval;
430 SPEC_CVAL (val->type).v_int = sval;
433 // check if we can make it a char
434 if ((SPEC_USIGN(val->type) && sval < 256) ||
435 (!SPEC_USIGN(val->type) && ((long)sval<127 && (long)sval>-128))) {
436 SPEC_NOUN (val->etype) = V_CHAR;
441 /*! /fn char hexEscape(char **src)
443 /param src Pointer to 'x' from start of hex character value
446 char hexEscape(char **src)
450 unsigned long value ;
452 (*src)++ ; /* Skip over the 'x' */
453 s = *src ; /* Save for error detection */
455 value = strtol (*src, src, 16);
459 // no valid hex found
460 werror(E_INVALID_HEX);
467 werror(W_ESC_SEQ_OOR_FOR_CHAR);
473 /*------------------------------------------------------------------*/
474 /* octalEscape - process an octal constant of max three digits */
475 /* return the octal value, throw a warning for illegal octal */
476 /* adjust src to point at the last proccesed char */
477 /*------------------------------------------------------------------*/
479 char octalEscape (char **str) {
483 for (digits=0; digits<3; digits++) {
484 if (**str>='0' && **str<='7') {
485 value = value*8 + (**str-'0');
492 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
493 werror (W_ESC_SEQ_OOR_FOR_CHAR);
500 /fn int copyStr (char *dest, char *src)
502 Copies a source string to a dest buffer interpreting escape sequences
503 and special characters
505 /param dest Buffer to receive the resultant string
506 /param src Buffer containing the source string with escape sequecnes
507 /return Number of characters in output string
512 copyStr (char *dest, char *src)
515 char *OriginalDest = dest ;
521 else if (*src == '\\')
556 *dest++ = octalEscape(&src);
561 *dest++ = hexEscape(&src) ;
588 return dest - OriginalDest ;
591 /*------------------------------------------------------------------*/
592 /* strVal - converts a string constant to a value */
593 /*------------------------------------------------------------------*/
599 val = newValue (); /* get a new one */
601 /* get a declarator */
602 val->type = newLink ();
603 DCL_TYPE (val->type) = ARRAY;
604 val->type->next = val->etype = newLink ();
605 val->etype->class = SPECIFIER;
606 SPEC_NOUN (val->etype) = V_CHAR;
607 SPEC_SCLS (val->etype) = S_LITERAL;
609 SPEC_CVAL (val->etype).v_char = Safe_calloc (1, strlen (s) + 1);
610 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
616 /*------------------------------------------------------------------*/
617 /* reverseValWithType - reverses value chain with type & etype */
618 /*------------------------------------------------------------------*/
620 reverseValWithType (value * val)
628 /* save the type * etype chains */
632 /* set the current one 2b null */
633 val->type = val->etype = NULL;
634 val = reverseVal (val);
636 /* restore type & etype */
643 /*------------------------------------------------------------------*/
644 /* reverseVal - reverses the values for a value chain */
645 /*------------------------------------------------------------------*/
647 reverseVal (value * val)
649 value *prev, *curr, *next;
664 val->next = (void *) NULL;
668 /*------------------------------------------------------------------*/
669 /* copyValueChain - will copy a chain of values */
670 /*------------------------------------------------------------------*/
672 copyValueChain (value * src)
679 dest = copyValue (src);
680 dest->next = copyValueChain (src->next);
685 /*------------------------------------------------------------------*/
686 /* copyValue - copies contents of a vlue to a fresh one */
687 /*------------------------------------------------------------------*/
689 copyValue (value * src)
694 dest->sym = copySymbol (src->sym);
695 strcpy (dest->name, src->name);
696 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
697 dest->etype = (src->type ? getSpec (dest->type) : NULL);
702 /*------------------------------------------------------------------*/
703 /* charVal - converts a character constant to a value */
704 /*------------------------------------------------------------------*/
713 val->type = val->etype = newLink ();
714 val->type->class = SPECIFIER;
715 SPEC_NOUN (val->type) = V_CHAR;
716 SPEC_USIGN(val->type) = 1;
717 SPEC_SCLS (val->type) = S_LITERAL;
719 s++; /* get rid of quotation */
720 /* if \ then special processing */
723 s++; /* go beyond the backslash */
727 SPEC_CVAL (val->type).v_int = '\n';
730 SPEC_CVAL (val->type).v_int = '\t';
733 SPEC_CVAL (val->type).v_int = '\v';
736 SPEC_CVAL (val->type).v_int = '\b';
739 SPEC_CVAL (val->type).v_int = '\r';
742 SPEC_CVAL (val->type).v_int = '\f';
745 SPEC_CVAL (val->type).v_int = '\a';
748 SPEC_CVAL (val->type).v_int = '\\';
751 SPEC_CVAL (val->type).v_int = '\?';
754 SPEC_CVAL (val->type).v_int = '\'';
757 SPEC_CVAL (val->type).v_int = '\"';
768 SPEC_CVAL (val->type).v_int = octalEscape(&s);
772 SPEC_CVAL (val->type).v_int = hexEscape(&s) ;
776 SPEC_CVAL (val->type).v_int = *s;
780 else /* not a backslash */
781 SPEC_CVAL (val->type).v_int = *s;
786 /*------------------------------------------------------------------*/
787 /* valFromType - creates a value from type given */
788 /*------------------------------------------------------------------*/
790 valFromType (sym_link * type)
792 value *val = newValue ();
793 val->type = copyLinkChain (type);
794 val->etype = getSpec (val->type);
798 /*------------------------------------------------------------------*/
799 /* floatFromVal - value to unsinged integer conversion */
800 /*------------------------------------------------------------------*/
802 floatFromVal (value * val)
807 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
809 werror (E_CONST_EXPECTED, val->name);
813 /* if it is not a specifier then we can assume that */
814 /* it will be an unsigned long */
815 if (!IS_SPEC (val->type))
816 return (double) SPEC_CVAL (val->etype).v_ulong;
818 if (SPEC_NOUN (val->etype) == V_FLOAT)
819 return (double) SPEC_CVAL (val->etype).v_float;
822 if (SPEC_LONG (val->etype))
824 if (SPEC_USIGN (val->etype))
825 return (double) SPEC_CVAL (val->etype).v_ulong;
827 return (double) SPEC_CVAL (val->etype).v_long;
831 if (SPEC_USIGN (val->etype))
832 return (double) SPEC_CVAL (val->etype).v_uint;
834 return (double) SPEC_CVAL (val->etype).v_int;
840 /*------------------------------------------------------------------*/
841 /* valUnaryPM - dones the unary +/- operation on a constant */
842 /*------------------------------------------------------------------*/
844 valUnaryPM (value * val)
846 /* depending on type */
847 if (SPEC_NOUN (val->etype) == V_FLOAT)
848 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
851 if (SPEC_LONG (val->etype))
853 if (SPEC_USIGN (val->etype))
854 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
856 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
860 if (SPEC_USIGN (val->etype))
861 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
863 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
870 /*------------------------------------------------------------------*/
871 /* valueComplement - complements a constant */
872 /*------------------------------------------------------------------*/
874 valComplement (value * val)
876 /* depending on type */
877 if (SPEC_LONG (val->etype))
879 if (SPEC_USIGN (val->etype))
880 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
882 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
886 if (SPEC_USIGN (val->etype))
887 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
889 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
894 /*------------------------------------------------------------------*/
895 /* valueNot - complements a constant */
896 /*------------------------------------------------------------------*/
900 /* depending on type */
901 if (SPEC_LONG (val->etype))
903 if (SPEC_USIGN (val->etype))
904 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
906 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
910 if (SPEC_USIGN (val->etype))
911 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
913 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
918 /*------------------------------------------------------------------*/
919 /* valMult - multiply constants */
920 /*------------------------------------------------------------------*/
922 valMult (value * lval, value * rval)
926 /* create a new value */
928 val->type = val->etype = newLink ();
929 val->type->class = SPECIFIER;
930 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
931 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
932 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
933 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
934 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
936 if (IS_FLOAT (val->type))
937 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
940 if (SPEC_LONG (val->type))
942 if (SPEC_USIGN (val->type))
943 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
944 (unsigned long) floatFromVal (rval);
946 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
947 (long) floatFromVal (rval);
951 if (SPEC_USIGN (val->type))
952 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
953 (unsigned) floatFromVal (rval);
955 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
956 (int) floatFromVal (rval);
962 /*------------------------------------------------------------------*/
963 /* valDiv - Divide constants */
964 /*------------------------------------------------------------------*/
966 valDiv (value * lval, value * rval)
970 if (floatFromVal (rval) == 0)
972 werror (E_DIVIDE_BY_ZERO);
976 /* create a new value */
978 val->type = val->etype = newLink();
979 val->type->class = SPECIFIER;
980 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
981 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
982 SPEC_SCLS (val->etype) = S_LITERAL;
983 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
984 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
986 if (IS_FLOAT (val->type))
987 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
990 if (SPEC_LONG (val->type))
992 if (SPEC_USIGN (val->type))
993 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) /
994 (unsigned long) floatFromVal (rval);
996 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
997 (long) floatFromVal (rval);
1001 if (SPEC_USIGN (val->type)) {
1002 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1003 (unsigned) floatFromVal (rval);
1004 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1005 (SPEC_CVAL (val->type).v_uint <=255)) {
1006 SPEC_NOUN (val->type) = V_CHAR;
1009 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1010 (int) floatFromVal (rval);
1011 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1012 (SPEC_CVAL (val->type).v_int >=-128) &&
1013 (SPEC_CVAL (val->type).v_int <=127)) {
1014 SPEC_NOUN (val->type) = V_CHAR;
1022 /*------------------------------------------------------------------*/
1023 /* valMod - Modulus constants */
1024 /*------------------------------------------------------------------*/
1026 valMod (value * lval, value * rval)
1030 /* create a new value */
1032 val->type = val->etype = newLink ();
1033 val->type->class = SPECIFIER;
1034 SPEC_NOUN (val->type) = V_INT; /* type is int */
1035 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1036 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1037 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1039 if (SPEC_LONG (val->type))
1041 if (SPEC_USIGN (val->type))
1042 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1043 (unsigned long) floatFromVal (rval);
1045 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1046 (unsigned long) floatFromVal (rval);
1050 if (SPEC_USIGN (val->type)) {
1051 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1052 (unsigned) floatFromVal (rval);
1053 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1054 (SPEC_CVAL (val->type).v_uint <=255)) {
1055 SPEC_NOUN (val->type) = V_CHAR;
1058 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1059 (unsigned) floatFromVal (rval);
1060 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1061 (SPEC_CVAL (val->type).v_int >=-128) &&
1062 (SPEC_CVAL (val->type).v_int <=127)) {
1063 SPEC_NOUN (val->type) = V_CHAR;
1071 /*------------------------------------------------------------------*/
1072 /* valPlus - Addition constants */
1073 /*------------------------------------------------------------------*/
1075 valPlus (value * lval, value * rval)
1079 /* create a new value */
1081 val->type = val->etype = newLink ();
1082 val->type->class = SPECIFIER;
1083 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1084 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1085 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1086 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1087 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1089 if (IS_FLOAT (val->type))
1090 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1093 if (SPEC_LONG (val->type))
1095 if (SPEC_USIGN (val->type))
1096 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1097 (unsigned long) floatFromVal (rval);
1099 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1100 (long) floatFromVal (rval);
1104 if (SPEC_USIGN (val->type)) {
1105 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
1106 (unsigned) floatFromVal (rval);
1107 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1108 (SPEC_CVAL (val->type).v_uint <=255)) {
1109 SPEC_NOUN (val->type) = V_CHAR;
1112 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
1113 (int) floatFromVal (rval);
1114 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1115 (SPEC_CVAL (val->type).v_int >=-128) &&
1116 (SPEC_CVAL (val->type).v_int <=127)) {
1117 SPEC_NOUN (val->type) = V_CHAR;
1125 /*------------------------------------------------------------------*/
1126 /* valMinus - Addition constants */
1127 /*------------------------------------------------------------------*/
1129 valMinus (value * lval, value * rval)
1133 /* create a new value */
1135 val->type = val->etype = newLink ();
1136 val->type->class = SPECIFIER;
1137 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1138 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1139 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1140 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1141 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1143 if (IS_FLOAT (val->type))
1144 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1147 if (SPEC_LONG (val->type))
1149 if (SPEC_USIGN (val->type)) {
1150 SPEC_CVAL (val->type).v_ulong =
1151 (unsigned long) floatFromVal (lval) -
1152 (unsigned long) floatFromVal (rval);
1154 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1155 (long) floatFromVal (rval);
1160 if (SPEC_USIGN (val->type)) {
1161 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1162 (unsigned) floatFromVal (rval);
1163 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1164 (SPEC_CVAL (val->type).v_uint <=255)) {
1165 SPEC_NOUN (val->type) = V_CHAR;
1168 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - (int) floatFromVal (rval);
1169 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1170 (SPEC_CVAL (val->type).v_int >=-128) &&
1171 (SPEC_CVAL (val->type).v_int <=127)) {
1172 SPEC_NOUN (val->type) = V_CHAR;
1180 /*------------------------------------------------------------------*/
1181 /* valShift - Shift left or right */
1182 /*------------------------------------------------------------------*/
1184 valShift (value * lval, value * rval, int lr)
1188 /* create a new value */
1190 val->type = val->etype = newIntLink ();
1191 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1192 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1193 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1195 if (SPEC_LONG (val->type))
1197 if (SPEC_USIGN (val->type))
1198 SPEC_CVAL (val->type).v_ulong = lr ?
1199 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1200 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1202 SPEC_CVAL (val->type).v_long = lr ?
1203 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1204 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1208 if (SPEC_USIGN (val->type)) {
1209 SPEC_CVAL (val->type).v_uint = lr ?
1210 (unsigned) floatFromVal (lval) << (unsigned) floatFromVal (rval) :\
1211 (unsigned) floatFromVal (lval) >> (unsigned) floatFromVal (rval);
1212 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1213 (SPEC_CVAL (val->type).v_uint <=255)) {
1214 SPEC_NOUN (val->type) = V_CHAR;
1217 SPEC_CVAL (val->type).v_int = lr ?
1218 (int) floatFromVal (lval) << (int) floatFromVal (rval) : \
1219 (int) floatFromVal (lval) >> (int) floatFromVal (rval);
1220 if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1221 (SPEC_CVAL (val->type).v_int >=-128) &&
1222 (SPEC_CVAL (val->type).v_int <=127)) {
1223 SPEC_NOUN (val->type) = V_CHAR;
1231 /*------------------------------------------------------------------*/
1232 /* valCompare- Compares two literal */
1233 /*------------------------------------------------------------------*/
1235 valCompare (value * lval, value * rval, int ctype)
1239 /* create a new value */
1241 val->type = val->etype = newCharLink ();
1242 val->type->class = SPECIFIER;
1243 SPEC_NOUN (val->type) = V_INT; /* type is int */
1244 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1249 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1253 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1257 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1261 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1265 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1269 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1277 /*------------------------------------------------------------------*/
1278 /* valBitwise - Bitwise operation */
1279 /*------------------------------------------------------------------*/
1281 valBitwise (value * lval, value * rval, int op)
1285 /* create a new value */
1287 val->type = copyLinkChain (lval->type);
1288 val->etype = getSpec (val->type);
1293 if (SPEC_LONG (val->type))
1295 if (SPEC_USIGN (val->type))
1296 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1297 (unsigned long) floatFromVal (rval);
1299 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1300 (long) floatFromVal (rval);
1304 if (SPEC_USIGN (val->type))
1305 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1306 (unsigned) floatFromVal (rval);
1308 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1313 if (SPEC_LONG (val->type))
1315 if (SPEC_USIGN (val->type))
1316 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1317 (unsigned long) floatFromVal (rval);
1319 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1320 (long) floatFromVal (rval);
1324 if (SPEC_USIGN (val->type))
1325 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1326 (unsigned) floatFromVal (rval);
1328 SPEC_CVAL (val->type).v_int =
1329 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1335 if (SPEC_LONG (val->type))
1337 if (SPEC_USIGN (val->type))
1338 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1339 (unsigned long) floatFromVal (rval);
1341 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1342 (long) floatFromVal (rval);
1346 if (SPEC_USIGN (val->type))
1347 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1348 (unsigned) floatFromVal (rval);
1350 SPEC_CVAL (val->type).v_int =
1351 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1359 /*------------------------------------------------------------------*/
1360 /* valAndOr - Generates code for and / or operation */
1361 /*------------------------------------------------------------------*/
1363 valLogicAndOr (value * lval, value * rval, int op)
1367 /* create a new value */
1369 val->type = val->etype = newCharLink ();
1370 val->type->class = SPECIFIER;
1371 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1376 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1380 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1388 /*------------------------------------------------------------------*/
1389 /* valCastLiteral - casts a literal value to another type */
1390 /*------------------------------------------------------------------*/
1392 valCastLiteral (sym_link * dtype, double fval)
1400 val->etype = getSpec (val->type = copyLinkChain (dtype));
1401 SPEC_SCLS (val->etype) = S_LITERAL;
1402 /* if it is not a specifier then we can assume that */
1403 /* it will be an unsigned long */
1404 if (!IS_SPEC (val->type))
1406 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1410 if (SPEC_NOUN (val->etype) == V_FLOAT)
1411 SPEC_CVAL (val->etype).v_float = fval;
1414 if (SPEC_LONG (val->etype))
1416 if (SPEC_USIGN (val->etype))
1417 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1419 SPEC_CVAL (val->etype).v_long = (long) fval;
1423 if (SPEC_USIGN (val->etype))
1424 SPEC_CVAL (val->etype).v_uint = (unsigned int) fval;
1426 SPEC_CVAL (val->etype).v_int = (int) fval;
1432 /*------------------------------------------------------------------*/
1433 /* getNelements - determines # of elements from init list */
1434 /*------------------------------------------------------------------*/
1436 getNelements (sym_link * type, initList * ilist)
1438 sym_link *etype = getSpec (type);
1444 if (ilist->type == INIT_DEEP)
1445 ilist = ilist->init.deep;
1447 /* if type is a character array and there is only one
1448 (string) initialiser then get the length of the string */
1449 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1451 ast *iast = ilist->init.node;
1452 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1455 werror (W_INIT_WRONG);
1459 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1460 // yep, it's a string
1462 return DCL_ELEM (v->type);
1470 ilist = ilist->next;
1476 /*-----------------------------------------------------------------*/
1477 /* valForArray - returns a value with name of array index */
1478 /*-----------------------------------------------------------------*/
1480 valForArray (ast * arrExpr)
1482 value *val, *lval = NULL;
1484 int size = getSize (arrExpr->left->ftype->next);
1485 /* if the right or left is an array
1487 if (IS_AST_OP (arrExpr->left))
1489 if (arrExpr->left->opval.op == '[')
1490 lval = valForArray (arrExpr->left);
1491 else if (arrExpr->left->opval.op == '.')
1492 lval = valForStructElem (arrExpr->left->left,
1493 arrExpr->left->right);
1494 else if (arrExpr->left->opval.op == PTR_OP &&
1495 IS_ADDRESS_OF_OP (arrExpr->left->left))
1496 lval = valForStructElem (arrExpr->left->left->left,
1497 arrExpr->left->right);
1502 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1505 if (!IS_AST_LIT_VALUE (arrExpr->right))
1510 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1512 sprintf (buffer, "%s", lval->name);
1514 sprintf (val->name, "(%s + %d)", buffer,
1515 (int) AST_LIT_VALUE (arrExpr->right) * size);
1517 val->type = newLink ();
1518 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1520 DCL_TYPE (val->type) = CPOINTER;
1521 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1523 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1524 DCL_TYPE (val->type) = FPOINTER;
1525 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1526 DCL_TYPE (val->type) = PPOINTER;
1527 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1528 DCL_TYPE (val->type) = IPOINTER;
1529 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1530 DCL_TYPE (val->type) = EEPPOINTER;
1532 DCL_TYPE (val->type) = POINTER;
1533 val->type->next = arrExpr->left->ftype;
1534 val->etype = getSpec (val->type);
1538 /*-----------------------------------------------------------------*/
1539 /* valForStructElem - returns value with name of struct element */
1540 /*-----------------------------------------------------------------*/
1542 valForStructElem (ast * structT, ast * elemT)
1544 value *val, *lval = NULL;
1548 /* left could be furthur derefed */
1549 if (IS_AST_OP (structT))
1551 if (structT->opval.op == '[')
1552 lval = valForArray (structT);
1553 else if (structT->opval.op == '.')
1554 lval = valForStructElem (structT->left, structT->right);
1555 else if (structT->opval.op == PTR_OP &&
1556 IS_ADDRESS_OF_OP (structT->left))
1557 lval = valForStructElem (structT->left->left,
1563 if (!IS_AST_SYM_VALUE (elemT))
1566 if (!IS_STRUCT (structT->etype))
1569 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1570 AST_SYMBOL (elemT))) == NULL)
1577 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1579 sprintf (buffer, "%s", lval->name);
1581 sprintf (val->name, "(%s + %d)", buffer,
1584 val->type = newLink ();
1585 if (SPEC_SCLS (structT->etype) == S_CODE)
1587 DCL_TYPE (val->type) = CPOINTER;
1588 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1590 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1591 DCL_TYPE (val->type) = FPOINTER;
1592 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1593 DCL_TYPE (val->type) = PPOINTER;
1594 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1595 DCL_TYPE (val->type) = IPOINTER;
1596 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1597 DCL_TYPE (val->type) = EEPPOINTER;
1599 DCL_TYPE (val->type) = POINTER;
1600 val->type->next = sym->type;
1601 val->etype = getSpec (val->type);
1605 /*-----------------------------------------------------------------*/
1606 /* valForCastAggr - will return value for a cast of an aggregate */
1607 /* plus minus a constant */
1608 /*-----------------------------------------------------------------*/
1610 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1614 if (!IS_AST_SYM_VALUE (aexpr))
1616 if (!IS_AST_LIT_VALUE (cnst))
1621 sprintf (val->name, "(%s %c %d)",
1622 AST_SYMBOL (aexpr)->rname, op,
1623 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1626 val->etype = getSpec (val->type);
1630 /*-----------------------------------------------------------------*/
1631 /* valForCastAggr - will return value for a cast of an aggregate */
1632 /* with no constant */
1633 /*-----------------------------------------------------------------*/
1635 valForCastArr (ast * aexpr, sym_link * type)
1639 if (!IS_AST_SYM_VALUE (aexpr))
1644 sprintf (val->name, "(%s)",
1645 AST_SYMBOL (aexpr)->rname);
1648 val->etype = getSpec (val->type);