1 /*----------------------------------------------------------------------
2 SDCCval.c :- has routine to do all kinds of fun stuff with the
3 value wrapper & with initialiser lists.
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 In other words, you are welcome to use, share and improve this program.
22 You are forbidden to forbid anyone else to use, share and improve
23 what you give them. Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
34 /*-----------------------------------------------------------------*/
35 /* newValue - allocates and returns a new value */
36 /*-----------------------------------------------------------------*/
42 val = Safe_calloc (1, sizeof (value));
47 /*-----------------------------------------------------------------*/
48 /* newiList - new initializer list */
49 /*-----------------------------------------------------------------*/
51 newiList (int type, void *ilist)
56 nilist = Safe_calloc (1, sizeof (initList));
59 nilist->lineno = yylineno;
64 nilist->init.node = (struct ast *) ilist;
68 nilist->init.deep = (struct initList *) ilist;
75 /*------------------------------------------------------------------*/
76 /* revinit - reverses the initial values for a value chain */
77 /*------------------------------------------------------------------*/
79 revinit (initList * val)
81 initList *prev, *curr, *next;
96 val->next = (void *) NULL;
100 /*------------------------------------------------------------------*/
101 /* copyIlist - copy initializer list */
102 /*------------------------------------------------------------------*/
104 copyIlist (initList * src)
106 initList *dest = NULL;
114 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
117 dest = newiList (INIT_NODE, copyAst (src->init.node));
122 dest->next = copyIlist (src->next);
127 /*------------------------------------------------------------------*/
128 /* list2int - converts the first element of the list to value */
129 /*------------------------------------------------------------------*/
131 list2int (initList * val)
135 if (i->type == INIT_DEEP)
136 return list2int (val->init.deep);
138 return floatFromVal (constExprValue (val->init.node, TRUE));
141 /*------------------------------------------------------------------*/
142 /* list2val - converts the first element of the list to value */
143 /*------------------------------------------------------------------*/
145 list2val (initList * val)
150 if (val->type == INIT_DEEP)
151 return list2val (val->init.deep);
153 return constExprValue (val->init.node, TRUE);
156 /*------------------------------------------------------------------*/
157 /* list2expr - returns the first expression in the initializer list */
158 /*------------------------------------------------------------------*/
160 list2expr (initList * ilist)
162 if (ilist->type == INIT_DEEP)
163 return list2expr (ilist->init.deep);
164 return ilist->init.node;
167 /*------------------------------------------------------------------*/
168 /* resolveIvalSym - resolve symbols in initial values */
169 /*------------------------------------------------------------------*/
171 resolveIvalSym (initList * ilist)
176 if (ilist->type == INIT_NODE)
177 ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
179 if (ilist->type == INIT_DEEP)
180 resolveIvalSym (ilist->init.deep);
182 resolveIvalSym (ilist->next);
185 /*-----------------------------------------------------------------*/
186 /* symbolVal - creates a value for a symbol */
187 /*-----------------------------------------------------------------*/
189 symbolVal (symbol * sym)
201 val->type = sym->type;
202 val->etype = getSpec (val->type);
206 sprintf (val->name, "%s", sym->rname);
208 sprintf (val->name, "_%s", sym->name);
214 /*-----------------------------------------------------------------*/
215 /* valueFromLit - creates a value from a literal */
216 /*-----------------------------------------------------------------*/
218 valueFromLit (float lit)
222 if ((((long) lit) - lit) == 0)
224 sprintf (buffer, "%ld", (long) lit);
225 return constVal (buffer);
228 sprintf (buffer, "%f", lit);
229 return constFloatVal (buffer);
232 /*-----------------------------------------------------------------*/
233 /* constFloatVal - converts a FLOAT constant to value */
234 /*-----------------------------------------------------------------*/
236 constFloatVal (char *s)
238 value *val = newValue ();
241 if (sscanf (s, "%f", &sval) != 1)
243 werror (E_INVALID_FLOAT_CONST, s);
244 return constVal ("0");
247 val->type = val->etype = newLink ();
248 val->type->class = SPECIFIER;
249 SPEC_NOUN (val->type) = V_FLOAT;
250 SPEC_SCLS (val->type) = S_LITERAL;
251 SPEC_CVAL (val->type).v_float = sval;
256 /*-----------------------------------------------------------------*/
257 /* constVal - converts a INTEGER constant into a value */
258 /*-----------------------------------------------------------------*/
263 short hex = 0, octal = 0;
268 val = newValue (); /* alloc space for value */
270 val->type = val->etype = newLink (); /* create the spcifier */
271 val->type->class = SPECIFIER;
272 SPEC_NOUN (val->type) = V_INT;
273 SPEC_SCLS (val->type) = S_LITERAL;
275 /* set the _unsigned flag if 'uU' found */
276 if (strchr (s, 'u') || strchr (s, 'U'))
277 SPEC_USIGN (val->type) = 1;
279 /* set the _long flag if 'lL' is found */
280 if (strchr (s, 'l') || strchr (s, 'L'))
281 SPEC_LONG (val->type) = 1;
283 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
285 /* set the octal flag */
286 if (!hex && *s == '0' && *(s + 1))
289 /* create the scan string */
290 scanFmt[scI++] = '%';
293 scanFmt[scI++] = 'o';
295 scanFmt[scI++] = 'x';
296 else if (SPEC_USIGN (val->type))
297 scanFmt[scI++] = 'u';
299 scanFmt[scI++] = 'd';
301 scanFmt[scI++] = '\0';
303 /* if hex or octal then set the unsigned flag */
306 SPEC_USIGN (val->type) = 1;
307 sscanf (s, scanFmt, &sval);
313 if (SPEC_LONG (val->type) || sval > 32768)
315 if (SPEC_USIGN (val->type))
316 SPEC_CVAL (val->type).v_ulong = sval;
318 SPEC_CVAL (val->type).v_long = sval;
319 SPEC_LONG (val->type) = 1;
323 if (SPEC_USIGN (val->type))
324 SPEC_CVAL (val->type).v_uint = sval;
326 SPEC_CVAL (val->type).v_int = sval;
329 // check the size and make it a short if required
331 SPEC_SHORT (val->etype) = 1;
337 /*------------------------------------------------------------------*/
338 /* copyStr - copies src to dest ignoring leading & trailing \"s */
339 /*------------------------------------------------------------------*/
341 copyStr (char *dest, char *src)
348 else if (*src == '\\')
375 /* embedded octal or hex constant */
376 if (*(src + 1) == 'x' ||
379 x = strtol (src, &src, 16);
385 x = strtol (src, &src, 8);
414 /*------------------------------------------------------------------*/
415 /* strVal - converts a string constant to a value */
416 /*------------------------------------------------------------------*/
422 val = newValue (); /* get a new one */
424 /* get a declarator */
425 val->type = newLink ();
426 DCL_TYPE (val->type) = ARRAY;
427 DCL_ELEM (val->type) = strlen (s) - 1;
428 val->type->next = val->etype = newLink ();
429 val->etype->class = SPECIFIER;
430 SPEC_NOUN (val->etype) = V_CHAR;
431 SPEC_SCLS (val->etype) = S_LITERAL;
433 SPEC_CVAL (val->etype).v_char = Safe_calloc (1, strlen (s) + 1);
434 copyStr (SPEC_CVAL (val->etype).v_char, s);
439 /*------------------------------------------------------------------*/
440 /* reverseValWithType - reverses value chain with type & etype */
441 /*------------------------------------------------------------------*/
443 reverseValWithType (value * val)
451 /* save the type * etype chains */
455 /* set the current one 2b null */
456 val->type = val->etype = NULL;
457 val = reverseVal (val);
459 /* restore type & etype */
466 /*------------------------------------------------------------------*/
467 /* reverseVal - reverses the values for a value chain */
468 /*------------------------------------------------------------------*/
470 reverseVal (value * val)
472 value *prev, *curr, *next;
487 val->next = (void *) NULL;
491 /*------------------------------------------------------------------*/
492 /* copyValueChain - will copy a chain of values */
493 /*------------------------------------------------------------------*/
495 copyValueChain (value * src)
502 dest = copyValue (src);
503 dest->next = copyValueChain (src->next);
508 /*------------------------------------------------------------------*/
509 /* copyValue - copies contents of a vlue to a fresh one */
510 /*------------------------------------------------------------------*/
512 copyValue (value * src)
517 dest->sym = copySymbol (src->sym);
518 strcpy (dest->name, src->name);
519 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
520 dest->etype = (src->type ? getSpec (dest->type) : NULL);
525 /*------------------------------------------------------------------*/
526 /* charVal - converts a character constant to a value */
527 /*------------------------------------------------------------------*/
535 val->type = val->etype = newLink ();
536 val->type->class = SPECIFIER;
537 SPEC_NOUN (val->type) = V_CHAR;
538 SPEC_SCLS (val->type) = S_LITERAL;
540 s++; /* get rid of quotation */
541 /* if \ then special processing */
544 s++; /* go beyond the backslash */
548 SPEC_CVAL (val->type).v_int = '\n';
551 SPEC_CVAL (val->type).v_int = '\t';
554 SPEC_CVAL (val->type).v_int = '\v';
557 SPEC_CVAL (val->type).v_int = '\b';
560 SPEC_CVAL (val->type).v_int = '\r';
563 SPEC_CVAL (val->type).v_int = '\f';
566 SPEC_CVAL (val->type).v_int = '\a';
569 SPEC_CVAL (val->type).v_int = '\\';
572 SPEC_CVAL (val->type).v_int = '\?';
575 SPEC_CVAL (val->type).v_int = '\'';
578 SPEC_CVAL (val->type).v_int = '\"';
581 sscanf (s, "%o", &SPEC_CVAL (val->type).v_int);
584 s++; /* go behond the 'x' */
585 sscanf (s, "%x", &SPEC_CVAL (val->type).v_int);
588 SPEC_CVAL (val->type).v_int = *s;
592 else /* not a backslash */
593 SPEC_CVAL (val->type).v_int = *s;
598 /*------------------------------------------------------------------*/
599 /* valFromType - creates a value from type given */
600 /*------------------------------------------------------------------*/
602 valFromType (sym_link * type)
604 value *val = newValue ();
605 val->type = copyLinkChain (type);
606 val->etype = getSpec (val->type);
610 /*------------------------------------------------------------------*/
611 /* floatFromVal - value to unsinged integer conversion */
612 /*------------------------------------------------------------------*/
614 floatFromVal (value * val)
619 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
621 werror (E_CONST_EXPECTED, val->name);
625 /* if it is not a specifier then we can assume that */
626 /* it will be an unsigned long */
627 if (!IS_SPEC (val->type))
628 return (double) SPEC_CVAL (val->etype).v_ulong;
630 if (SPEC_NOUN (val->etype) == V_FLOAT)
631 return (double) SPEC_CVAL (val->etype).v_float;
634 if (SPEC_LONG (val->etype))
636 if (SPEC_USIGN (val->etype))
637 return (double) SPEC_CVAL (val->etype).v_ulong;
639 return (double) SPEC_CVAL (val->etype).v_long;
643 if (SPEC_USIGN (val->etype))
644 return (double) SPEC_CVAL (val->etype).v_uint;
646 return (double) SPEC_CVAL (val->etype).v_int;
652 /*------------------------------------------------------------------*/
653 /* valUnaryPM - dones the unary +/- operation on a constant */
654 /*------------------------------------------------------------------*/
656 valUnaryPM (value * val)
658 /* depending on type */
659 if (SPEC_NOUN (val->etype) == V_FLOAT)
660 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
663 if (SPEC_LONG (val->etype))
665 if (SPEC_USIGN (val->etype))
666 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
668 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
672 if (SPEC_USIGN (val->etype))
673 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
675 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
682 /*------------------------------------------------------------------*/
683 /* valueComplement - complements a constant */
684 /*------------------------------------------------------------------*/
686 valComplement (value * val)
688 /* depending on type */
689 if (SPEC_LONG (val->etype))
691 if (SPEC_USIGN (val->etype))
692 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
694 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
698 if (SPEC_USIGN (val->etype))
699 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
701 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
706 /*------------------------------------------------------------------*/
707 /* valueNot - complements a constant */
708 /*------------------------------------------------------------------*/
712 /* depending on type */
713 if (SPEC_LONG (val->etype))
715 if (SPEC_USIGN (val->etype))
716 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
718 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
722 if (SPEC_USIGN (val->etype))
723 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
725 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
730 /*------------------------------------------------------------------*/
731 /* valMult - multiply constants */
732 /*------------------------------------------------------------------*/
734 valMult (value * lval, value * rval)
738 /* create a new value */
740 val->type = val->etype = newLink ();
741 val->type->class = SPECIFIER;
742 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
743 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
744 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
745 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
746 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
748 if (IS_FLOAT (val->type))
749 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
752 if (SPEC_LONG (val->type))
754 if (SPEC_USIGN (val->type))
755 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
756 (unsigned long) floatFromVal (rval);
758 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
759 (long) floatFromVal (rval);
763 if (SPEC_USIGN (val->type))
764 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
765 (unsigned) floatFromVal (rval);
767 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
768 (int) floatFromVal (rval);
774 /*------------------------------------------------------------------*/
775 /* valDiv - Divide constants */
776 /*------------------------------------------------------------------*/
778 valDiv (value * lval, value * rval)
782 if (floatFromVal (rval) == 0)
784 werror (E_DIVIDE_BY_ZERO);
788 /* create a new value */
790 val->type = val->etype = ((floatFromVal (lval) / floatFromVal (rval)) < 256 ?
791 newCharLink () : newIntLink ());
792 if (IS_FLOAT (lval->etype) || IS_FLOAT (rval->etype))
793 SPEC_NOUN (val->etype) = V_FLOAT;
794 SPEC_SCLS (val->etype) = S_LITERAL;
795 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
796 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
798 if (IS_FLOAT (val->type))
799 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
802 if (SPEC_LONG (val->type))
804 if (SPEC_USIGN (val->type))
805 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) /
806 (unsigned long) floatFromVal (rval);
808 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
809 (long) floatFromVal (rval);
813 if (SPEC_USIGN (val->type))
814 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
815 (unsigned) floatFromVal (rval);
817 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
818 (int) floatFromVal (rval);
824 /*------------------------------------------------------------------*/
825 /* valMod - Modulus constants */
826 /*------------------------------------------------------------------*/
828 valMod (value * lval, value * rval)
832 /* create a new value */
834 val->type = val->etype = newLink ();
835 val->type->class = SPECIFIER;
836 SPEC_NOUN (val->type) = V_INT; /* type is int */
837 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
838 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
839 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
841 if (SPEC_LONG (val->type))
843 if (SPEC_USIGN (val->type))
844 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
845 (unsigned long) floatFromVal (rval);
847 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
848 (unsigned long) floatFromVal (rval);
852 if (SPEC_USIGN (val->type))
853 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
854 (unsigned) floatFromVal (rval);
856 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
857 (unsigned) floatFromVal (rval);
863 /*------------------------------------------------------------------*/
864 /* valPlus - Addition constants */
865 /*------------------------------------------------------------------*/
867 valPlus (value * lval, value * rval)
871 /* create a new value */
873 val->type = val->etype = newLink ();
874 val->type->class = SPECIFIER;
875 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
876 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
877 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
878 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
879 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
881 if (IS_FLOAT (val->type))
882 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
885 if (SPEC_LONG (val->type))
887 if (SPEC_USIGN (val->type))
888 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
889 (unsigned long) floatFromVal (rval);
891 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
892 (long) floatFromVal (rval);
896 if (SPEC_USIGN (val->type))
897 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
898 (unsigned) floatFromVal (rval);
900 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
901 (int) floatFromVal (rval);
907 /*------------------------------------------------------------------*/
908 /* valMinus - Addition constants */
909 /*------------------------------------------------------------------*/
911 valMinus (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) - (int) floatFromVal (rval);
950 /*------------------------------------------------------------------*/
951 /* valShift - Shift left or right */
952 /*------------------------------------------------------------------*/
954 valShift (value * lval, value * rval, int lr)
958 /* create a new value */
960 val->type = val->etype = newLink ();
961 val->type->class = SPECIFIER;
962 SPEC_NOUN (val->type) = V_INT; /* type is int */
963 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
964 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
965 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
969 if (SPEC_LONG (val->type))
971 if (SPEC_USIGN (val->type))
972 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) <<
973 (unsigned long) floatFromVal (rval);
975 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) <<
976 (long) floatFromVal (rval);
980 if (SPEC_USIGN (val->type))
981 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) <<
982 (unsigned) floatFromVal (rval);
984 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) <<
985 (int) 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);
1005 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) >>
1006 (int) floatFromVal (rval);
1013 /*------------------------------------------------------------------*/
1014 /* valCompare- Compares two literal */
1015 /*------------------------------------------------------------------*/
1017 valCompare (value * lval, value * rval, int ctype)
1021 /* create a new value */
1023 val->type = val->etype = newCharLink ();
1024 val->type->class = SPECIFIER;
1025 SPEC_NOUN (val->type) = V_INT; /* type is int */
1026 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1031 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1035 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1039 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1043 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1047 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1051 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1059 /*------------------------------------------------------------------*/
1060 /* valBitwise - Bitwise operation */
1061 /*------------------------------------------------------------------*/
1063 valBitwise (value * lval, value * rval, int op)
1067 /* create a new value */
1069 val->type = copyLinkChain (lval->type);
1070 val->etype = getSpec (val->type);
1075 if (SPEC_LONG (val->type))
1077 if (SPEC_USIGN (val->type))
1078 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1079 (unsigned long) floatFromVal (rval);
1081 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1082 (long) floatFromVal (rval);
1086 if (SPEC_USIGN (val->type))
1087 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1088 (unsigned) floatFromVal (rval);
1090 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1095 if (SPEC_LONG (val->type))
1097 if (SPEC_USIGN (val->type))
1098 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1099 (unsigned long) floatFromVal (rval);
1101 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1102 (long) floatFromVal (rval);
1106 if (SPEC_USIGN (val->type))
1107 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1108 (unsigned) floatFromVal (rval);
1110 SPEC_CVAL (val->type).v_int =
1111 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1117 if (SPEC_LONG (val->type))
1119 if (SPEC_USIGN (val->type))
1120 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1121 (unsigned long) floatFromVal (rval);
1123 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1124 (long) floatFromVal (rval);
1128 if (SPEC_USIGN (val->type))
1129 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1130 (unsigned) floatFromVal (rval);
1132 SPEC_CVAL (val->type).v_int =
1133 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1141 /*------------------------------------------------------------------*/
1142 /* valAndOr - Generates code for and / or operation */
1143 /*------------------------------------------------------------------*/
1145 valLogicAndOr (value * lval, value * rval, int op)
1149 /* create a new value */
1151 val->type = val->etype = newCharLink ();
1152 val->type->class = SPECIFIER;
1153 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1158 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1162 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1170 /*------------------------------------------------------------------*/
1171 /* valCastLiteral - casts a literal value to another type */
1172 /*------------------------------------------------------------------*/
1174 valCastLiteral (sym_link * dtype, double fval)
1182 val->etype = getSpec (val->type = copyLinkChain (dtype));
1183 SPEC_SCLS (val->etype) = S_LITERAL;
1184 /* if it is not a specifier then we can assume that */
1185 /* it will be an unsigned long */
1186 if (!IS_SPEC (val->type))
1188 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1192 if (SPEC_NOUN (val->etype) == V_FLOAT)
1193 SPEC_CVAL (val->etype).v_float = fval;
1196 if (SPEC_LONG (val->etype))
1198 if (SPEC_USIGN (val->etype))
1199 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1201 SPEC_CVAL (val->etype).v_long = (long) fval;
1205 if (SPEC_USIGN (val->etype))
1206 SPEC_CVAL (val->etype).v_uint = (unsigned int) fval;
1208 SPEC_CVAL (val->etype).v_int = (int) fval;
1214 /*------------------------------------------------------------------*/
1215 /* getNelements - determines # of elements from init list */
1216 /*------------------------------------------------------------------*/
1218 getNelements (sym_link * type, initList * ilist)
1220 sym_link *etype = getSpec (type);
1226 if (ilist->type == INIT_DEEP)
1227 ilist = ilist->init.deep;
1229 /* if type is a character array and there is only one
1230 initialiser then get the length of the string */
1231 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1233 ast *iast = ilist->init.node;
1234 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1237 werror (E_INIT_WRONG);
1240 if (!IS_ARRAY (v->type) || !IS_CHAR (v->etype))
1242 werror (E_INIT_WRONG);
1245 return DCL_ELEM (v->type);
1252 ilist = ilist->next;
1258 /*-----------------------------------------------------------------*/
1259 /* valForArray - returns a value with name of array index */
1260 /*-----------------------------------------------------------------*/
1262 valForArray (ast * arrExpr)
1264 value *val, *lval = NULL;
1266 int size = getSize (arrExpr->left->ftype->next);
1267 /* if the right or left is an array
1269 if (IS_AST_OP (arrExpr->left))
1271 if (arrExpr->left->opval.op == '[')
1272 lval = valForArray (arrExpr->left);
1273 else if (arrExpr->left->opval.op == '.')
1274 lval = valForStructElem (arrExpr->left->left,
1275 arrExpr->left->right);
1276 else if (arrExpr->left->opval.op == PTR_OP &&
1277 IS_ADDRESS_OF_OP (arrExpr->left->left))
1278 lval = valForStructElem (arrExpr->left->left->left,
1279 arrExpr->left->right);
1284 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1287 if (!IS_AST_LIT_VALUE (arrExpr->right))
1292 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1294 sprintf (buffer, "%s", lval->name);
1296 sprintf (val->name, "(%s + %d)", buffer,
1297 (int) AST_LIT_VALUE (arrExpr->right) * size);
1299 val->type = newLink ();
1300 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1302 DCL_TYPE (val->type) = CPOINTER;
1303 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1305 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1306 DCL_TYPE (val->type) = FPOINTER;
1307 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1308 DCL_TYPE (val->type) = PPOINTER;
1309 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1310 DCL_TYPE (val->type) = IPOINTER;
1311 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1312 DCL_TYPE (val->type) = EEPPOINTER;
1314 DCL_TYPE (val->type) = POINTER;
1315 val->type->next = arrExpr->left->ftype;
1316 val->etype = getSpec (val->type);
1320 /*-----------------------------------------------------------------*/
1321 /* valForStructElem - returns value with name of struct element */
1322 /*-----------------------------------------------------------------*/
1324 valForStructElem (ast * structT, ast * elemT)
1326 value *val, *lval = NULL;
1330 /* left could be furthur derefed */
1331 if (IS_AST_OP (structT))
1333 if (structT->opval.op == '[')
1334 lval = valForArray (structT);
1335 else if (structT->opval.op == '.')
1336 lval = valForStructElem (structT->left, structT->right);
1337 else if (structT->opval.op == PTR_OP &&
1338 IS_ADDRESS_OF_OP (structT->left))
1339 lval = valForStructElem (structT->left->left,
1345 if (!IS_AST_SYM_VALUE (elemT))
1348 if (!IS_STRUCT (structT->etype))
1351 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1352 AST_SYMBOL (elemT))) == NULL)
1359 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1361 sprintf (buffer, "%s", lval->name);
1363 sprintf (val->name, "(%s + %d)", buffer,
1366 val->type = newLink ();
1367 if (SPEC_SCLS (structT->etype) == S_CODE)
1369 DCL_TYPE (val->type) = CPOINTER;
1370 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1372 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1373 DCL_TYPE (val->type) = FPOINTER;
1374 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1375 DCL_TYPE (val->type) = PPOINTER;
1376 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1377 DCL_TYPE (val->type) = IPOINTER;
1378 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1379 DCL_TYPE (val->type) = EEPPOINTER;
1381 DCL_TYPE (val->type) = POINTER;
1382 val->type->next = sym->type;
1383 val->etype = getSpec (val->type);
1387 /*-----------------------------------------------------------------*/
1388 /* valForCastAggr - will return value for a cast of an aggregate */
1389 /* plus minus a constant */
1390 /*-----------------------------------------------------------------*/
1392 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1396 if (!IS_AST_SYM_VALUE (aexpr))
1398 if (!IS_AST_LIT_VALUE (cnst))
1403 sprintf (val->name, "(%s %c %d)",
1404 AST_SYMBOL (aexpr)->rname, op,
1405 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1408 val->etype = getSpec (val->type);
1412 /*-----------------------------------------------------------------*/
1413 /* valForCastAggr - will return value for a cast of an aggregate */
1414 /* with no constant */
1415 /*-----------------------------------------------------------------*/
1417 valForCastArr (ast * aexpr, sym_link * type)
1421 if (!IS_AST_SYM_VALUE (aexpr))
1426 sprintf (val->name, "(%s)",
1427 AST_SYMBOL (aexpr)->rname);
1430 val->etype = getSpec (val->type);