2 /*----------------------------------------------------------------------
3 SDCCval.c :- has routine to do all kinds of fun stuff with the
4 value wrapper & with initialiser lists.
6 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 In other words, you are welcome to use, share and improve this program.
23 You are forbidden to forbid anyone else to use, share and improve
24 what you give them. Help stamp out software-hoarding!
25 -------------------------------------------------------------------------*/
35 /*-----------------------------------------------------------------*/
36 /* newValue - allocates and returns a new value */
37 /*-----------------------------------------------------------------*/
43 val = Safe_calloc (1, sizeof (value));
48 /*-----------------------------------------------------------------*/
49 /* newiList - new initializer list */
50 /*-----------------------------------------------------------------*/
52 newiList (int type, void *ilist)
57 nilist = Safe_calloc (1, sizeof (initList));
60 nilist->lineno = yylineno;
65 nilist->init.node = (struct ast *) ilist;
69 nilist->init.deep = (struct initList *) ilist;
76 /*------------------------------------------------------------------*/
77 /* revinit - reverses the initial values for a value chain */
78 /*------------------------------------------------------------------*/
80 revinit (initList * val)
82 initList *prev, *curr, *next;
97 val->next = (void *) NULL;
101 /*------------------------------------------------------------------*/
102 /* copyIlist - copy initializer list */
103 /*------------------------------------------------------------------*/
105 copyIlist (initList * src)
107 initList *dest = NULL;
115 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
118 dest = newiList (INIT_NODE, copyAst (src->init.node));
123 dest->next = copyIlist (src->next);
128 /*------------------------------------------------------------------*/
129 /* list2int - converts the first element of the list to value */
130 /*------------------------------------------------------------------*/
132 list2int (initList * val)
136 if (i->type == INIT_DEEP)
137 return list2int (val->init.deep);
139 return floatFromVal (constExprValue (val->init.node, TRUE));
142 /*------------------------------------------------------------------*/
143 /* list2val - converts the first element of the list to value */
144 /*------------------------------------------------------------------*/
146 list2val (initList * val)
151 if (val->type == INIT_DEEP)
152 return list2val (val->init.deep);
154 return constExprValue (val->init.node, TRUE);
157 /*------------------------------------------------------------------*/
158 /* list2expr - returns the first expression in the initializer list */
159 /*------------------------------------------------------------------*/
161 list2expr (initList * ilist)
163 if (ilist->type == INIT_DEEP)
164 return list2expr (ilist->init.deep);
165 return ilist->init.node;
168 /*------------------------------------------------------------------*/
169 /* resolveIvalSym - resolve symbols in initial values */
170 /*------------------------------------------------------------------*/
172 resolveIvalSym (initList * ilist)
177 if (ilist->type == INIT_NODE)
178 ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
180 if (ilist->type == INIT_DEEP)
181 resolveIvalSym (ilist->init.deep);
183 resolveIvalSym (ilist->next);
186 /*-----------------------------------------------------------------*/
187 /* symbolVal - creates a value for a symbol */
188 /*-----------------------------------------------------------------*/
190 symbolVal (symbol * sym)
202 val->type = sym->type;
203 val->etype = getSpec (val->type);
207 sprintf (val->name, "%s", sym->rname);
209 sprintf (val->name, "_%s", sym->name);
215 /*-----------------------------------------------------------------*/
216 /* valueFromLit - creates a value from a literal */
217 /*-----------------------------------------------------------------*/
219 valueFromLit (double lit)
223 if ((((long) lit) - lit) == 0)
225 sprintf (buffer, "%ld", (long) lit);
226 return constVal (buffer);
229 sprintf (buffer, "%f", lit);
230 return constFloatVal (buffer);
233 /*-----------------------------------------------------------------*/
234 /* constFloatVal - converts a FLOAT constant to value */
235 /*-----------------------------------------------------------------*/
237 constFloatVal (char *s)
239 value *val = newValue ();
242 if (sscanf (s, "%f", &sval) != 1)
244 werror (E_INVALID_FLOAT_CONST, s);
245 return constVal ("0");
248 val->type = val->etype = newLink ();
249 val->type->class = SPECIFIER;
250 SPEC_NOUN (val->type) = V_FLOAT;
251 SPEC_SCLS (val->type) = S_LITERAL;
252 SPEC_CVAL (val->type).v_float = sval;
257 /*-----------------------------------------------------------------*/
258 /* constVal - converts a INTEGER constant into a value */
259 /*-----------------------------------------------------------------*/
264 short hex = 0, octal = 0;
269 val = newValue (); /* alloc space for value */
271 val->type = val->etype = newLink (); /* create the spcifier */
272 val->type->class = SPECIFIER;
273 SPEC_NOUN (val->type) = V_INT;
274 SPEC_SCLS (val->type) = S_LITERAL;
276 /* set the _unsigned flag if 'uU' found */
277 if (strchr (s, 'u') || strchr (s, 'U'))
278 SPEC_USIGN (val->type) = 1;
280 /* set the _long flag if 'lL' is found */
281 if (strchr (s, 'l') || strchr (s, 'L'))
282 SPEC_LONG (val->type) = 1;
284 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
286 /* set the octal flag */
287 if (!hex && *s == '0' && *(s + 1))
290 /* create the scan string */
291 scanFmt[scI++] = '%';
294 scanFmt[scI++] = 'o';
296 scanFmt[scI++] = 'x';
297 else if (SPEC_USIGN (val->type))
298 scanFmt[scI++] = 'u';
300 scanFmt[scI++] = 'd';
302 scanFmt[scI++] = '\0';
304 /* if hex or octal then set the unsigned flag */
307 SPEC_USIGN (val->type) = 1;
308 sscanf (s, scanFmt, &sval);
314 if (SPEC_LONG (val->type) || sval > 32768)
316 if (SPEC_USIGN (val->type))
317 SPEC_CVAL (val->type).v_ulong = sval;
319 SPEC_CVAL (val->type).v_long = sval;
320 SPEC_LONG (val->type) = 1;
324 if (SPEC_USIGN (val->type))
325 SPEC_CVAL (val->type).v_uint = sval;
327 SPEC_CVAL (val->type).v_int = sval;
330 // check the size and make it a short if required
332 SPEC_SHORT (val->etype) = 1;
337 /*! /fn char hexEscape(char **src)
339 /param src Pointer to 'x' from start of hex character value
342 char hexEscape(char **src)
346 unsigned long value ;
348 (*src)++ ; /* Skip over the 'x' */
349 s = *src ; /* Save for error detection */
351 value = strtol (*src, src, 16);
355 // no valid hex found
356 werror(E_INVALID_HEX);
363 werror(W_ESC_SEQ_OOR_FOR_CHAR);
369 /*------------------------------------------------------------------*/
370 /* octalEscape - process an octal constant of max three digits */
371 /* return the octal value, throw a warning for illegal octal */
372 /* adjust src to point at the last proccesed char */
373 /*------------------------------------------------------------------*/
375 char octalEscape (char **str) {
379 for (digits=0; digits<3; digits++) {
380 if (**str>='0' && **str<='7') {
381 value = value*8 + (**str-'0');
388 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
389 werror (W_ESC_SEQ_OOR_FOR_CHAR);
396 /fn int copyStr (char *dest, char *src)
398 Copies a source string to a dest buffer interpreting escape sequences
399 and special characters
401 /param dest Buffer to receive the resultant string
402 /param src Buffer containing the source string with escape sequecnes
403 /return Number of characters in output string
408 copyStr (char *dest, char *src)
411 char *OriginalDest = dest ;
417 else if (*src == '\\')
452 *dest++ = octalEscape(&src);
457 *dest++ = hexEscape(&src) ;
484 return dest - OriginalDest ;
487 /*------------------------------------------------------------------*/
488 /* strVal - converts a string constant to a value */
489 /*------------------------------------------------------------------*/
495 val = newValue (); /* get a new one */
497 /* get a declarator */
498 val->type = newLink ();
499 DCL_TYPE (val->type) = ARRAY;
500 val->type->next = val->etype = newLink ();
501 val->etype->class = SPECIFIER;
502 SPEC_NOUN (val->etype) = V_CHAR;
503 SPEC_SCLS (val->etype) = S_LITERAL;
505 SPEC_CVAL (val->etype).v_char = Safe_calloc (1, strlen (s) + 1);
506 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
512 /*------------------------------------------------------------------*/
513 /* reverseValWithType - reverses value chain with type & etype */
514 /*------------------------------------------------------------------*/
516 reverseValWithType (value * val)
524 /* save the type * etype chains */
528 /* set the current one 2b null */
529 val->type = val->etype = NULL;
530 val = reverseVal (val);
532 /* restore type & etype */
539 /*------------------------------------------------------------------*/
540 /* reverseVal - reverses the values for a value chain */
541 /*------------------------------------------------------------------*/
543 reverseVal (value * val)
545 value *prev, *curr, *next;
560 val->next = (void *) NULL;
564 /*------------------------------------------------------------------*/
565 /* copyValueChain - will copy a chain of values */
566 /*------------------------------------------------------------------*/
568 copyValueChain (value * src)
575 dest = copyValue (src);
576 dest->next = copyValueChain (src->next);
581 /*------------------------------------------------------------------*/
582 /* copyValue - copies contents of a vlue to a fresh one */
583 /*------------------------------------------------------------------*/
585 copyValue (value * src)
590 dest->sym = copySymbol (src->sym);
591 strcpy (dest->name, src->name);
592 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
593 dest->etype = (src->type ? getSpec (dest->type) : NULL);
598 /*------------------------------------------------------------------*/
599 /* charVal - converts a character constant to a value */
600 /*------------------------------------------------------------------*/
609 val->type = val->etype = newLink ();
610 val->type->class = SPECIFIER;
611 SPEC_NOUN (val->type) = V_CHAR;
612 SPEC_SCLS (val->type) = S_LITERAL;
614 s++; /* get rid of quotation */
615 /* if \ then special processing */
618 s++; /* go beyond the backslash */
622 SPEC_CVAL (val->type).v_int = '\n';
625 SPEC_CVAL (val->type).v_int = '\t';
628 SPEC_CVAL (val->type).v_int = '\v';
631 SPEC_CVAL (val->type).v_int = '\b';
634 SPEC_CVAL (val->type).v_int = '\r';
637 SPEC_CVAL (val->type).v_int = '\f';
640 SPEC_CVAL (val->type).v_int = '\a';
643 SPEC_CVAL (val->type).v_int = '\\';
646 SPEC_CVAL (val->type).v_int = '\?';
649 SPEC_CVAL (val->type).v_int = '\'';
652 SPEC_CVAL (val->type).v_int = '\"';
663 SPEC_CVAL (val->type).v_int = octalEscape(&s);
667 SPEC_CVAL (val->type).v_int = hexEscape(&s) ;
671 SPEC_CVAL (val->type).v_int = *s;
675 else /* not a backslash */
676 SPEC_CVAL (val->type).v_int = *s;
681 /*------------------------------------------------------------------*/
682 /* valFromType - creates a value from type given */
683 /*------------------------------------------------------------------*/
685 valFromType (sym_link * type)
687 value *val = newValue ();
688 val->type = copyLinkChain (type);
689 val->etype = getSpec (val->type);
693 /*------------------------------------------------------------------*/
694 /* floatFromVal - value to unsinged integer conversion */
695 /*------------------------------------------------------------------*/
697 floatFromVal (value * val)
702 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
704 werror (E_CONST_EXPECTED, val->name);
708 /* if it is not a specifier then we can assume that */
709 /* it will be an unsigned long */
710 if (!IS_SPEC (val->type))
711 return (double) SPEC_CVAL (val->etype).v_ulong;
713 if (SPEC_NOUN (val->etype) == V_FLOAT)
714 return (double) SPEC_CVAL (val->etype).v_float;
717 if (SPEC_LONG (val->etype))
719 if (SPEC_USIGN (val->etype))
720 return (double) SPEC_CVAL (val->etype).v_ulong;
722 return (double) SPEC_CVAL (val->etype).v_long;
726 if (SPEC_USIGN (val->etype))
727 return (double) SPEC_CVAL (val->etype).v_uint;
729 return (double) SPEC_CVAL (val->etype).v_int;
735 /*------------------------------------------------------------------*/
736 /* valUnaryPM - dones the unary +/- operation on a constant */
737 /*------------------------------------------------------------------*/
739 valUnaryPM (value * val)
741 /* depending on type */
742 if (SPEC_NOUN (val->etype) == V_FLOAT)
743 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
746 if (SPEC_LONG (val->etype))
748 if (SPEC_USIGN (val->etype))
749 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
751 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
755 if (SPEC_USIGN (val->etype))
756 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
758 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
765 /*------------------------------------------------------------------*/
766 /* valueComplement - complements a constant */
767 /*------------------------------------------------------------------*/
769 valComplement (value * val)
771 /* depending on type */
772 if (SPEC_LONG (val->etype))
774 if (SPEC_USIGN (val->etype))
775 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
777 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
781 if (SPEC_USIGN (val->etype))
782 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
784 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
789 /*------------------------------------------------------------------*/
790 /* valueNot - complements a constant */
791 /*------------------------------------------------------------------*/
795 /* depending on type */
796 if (SPEC_LONG (val->etype))
798 if (SPEC_USIGN (val->etype))
799 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
801 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
805 if (SPEC_USIGN (val->etype))
806 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
808 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
813 /*------------------------------------------------------------------*/
814 /* valMult - multiply constants */
815 /*------------------------------------------------------------------*/
817 valMult (value * lval, value * rval)
821 /* create a new value */
823 val->type = val->etype = newLink ();
824 val->type->class = SPECIFIER;
825 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
826 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
827 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
828 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
829 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
831 if (IS_FLOAT (val->type))
832 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
835 if (SPEC_LONG (val->type))
837 if (SPEC_USIGN (val->type))
838 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
839 (unsigned long) floatFromVal (rval);
841 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
842 (long) floatFromVal (rval);
846 if (SPEC_USIGN (val->type))
847 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
848 (unsigned) floatFromVal (rval);
850 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
851 (int) floatFromVal (rval);
857 /*------------------------------------------------------------------*/
858 /* valDiv - Divide constants */
859 /*------------------------------------------------------------------*/
861 valDiv (value * lval, value * rval)
865 if (floatFromVal (rval) == 0)
867 werror (E_DIVIDE_BY_ZERO);
871 /* create a new value */
873 val->type = val->etype = ((floatFromVal (lval) / floatFromVal (rval)) < 256 ?
874 newCharLink () : newIntLink ());
875 if (IS_FLOAT (lval->etype) || IS_FLOAT (rval->etype))
876 SPEC_NOUN (val->etype) = V_FLOAT;
877 SPEC_SCLS (val->etype) = S_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 /* valMod - Modulus constants */
909 /*------------------------------------------------------------------*/
911 valMod (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) = V_INT; /* type is int */
920 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
921 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
922 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
924 if (SPEC_LONG (val->type))
926 if (SPEC_USIGN (val->type))
927 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
928 (unsigned long) floatFromVal (rval);
930 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
931 (unsigned long) floatFromVal (rval);
935 if (SPEC_USIGN (val->type))
936 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
937 (unsigned) floatFromVal (rval);
939 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
940 (unsigned) floatFromVal (rval);
946 /*------------------------------------------------------------------*/
947 /* valPlus - Addition constants */
948 /*------------------------------------------------------------------*/
950 valPlus (value * lval, value * rval)
954 /* create a new value */
956 val->type = val->etype = newLink ();
957 val->type->class = SPECIFIER;
958 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
959 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
960 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
961 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
962 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
964 if (IS_FLOAT (val->type))
965 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
968 if (SPEC_LONG (val->type))
970 if (SPEC_USIGN (val->type))
971 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
972 (unsigned long) floatFromVal (rval);
974 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
975 (long) floatFromVal (rval);
979 if (SPEC_USIGN (val->type))
980 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
981 (unsigned) floatFromVal (rval);
983 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
984 (int) floatFromVal (rval);
990 /*------------------------------------------------------------------*/
991 /* valMinus - Addition constants */
992 /*------------------------------------------------------------------*/
994 valMinus (value * lval, value * rval)
998 /* create a new value */
1000 val->type = val->etype = newLink ();
1001 val->type->class = SPECIFIER;
1002 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1003 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1004 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1005 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1006 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1008 if (IS_FLOAT (val->type))
1009 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1012 if (SPEC_LONG (val->type))
1014 if (SPEC_USIGN (val->type))
1015 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) -
1016 (unsigned long) floatFromVal (rval);
1018 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1019 (long) floatFromVal (rval);
1023 if (SPEC_USIGN (val->type))
1024 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1025 (unsigned) floatFromVal (rval);
1027 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - (int) floatFromVal (rval);
1033 /*------------------------------------------------------------------*/
1034 /* valShift - Shift left or right */
1035 /*------------------------------------------------------------------*/
1037 valShift (value * lval, value * rval, int lr)
1041 /* create a new value */
1043 val->type = val->etype = newLink ();
1044 val->type->class = SPECIFIER;
1045 SPEC_NOUN (val->type) = V_INT; /* type is int */
1046 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1047 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1048 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1052 if (SPEC_LONG (val->type))
1054 if (SPEC_USIGN (val->type))
1055 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) <<
1056 (unsigned long) floatFromVal (rval);
1058 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) <<
1059 (long) floatFromVal (rval);
1063 if (SPEC_USIGN (val->type))
1064 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) <<
1065 (unsigned) floatFromVal (rval);
1067 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) <<
1068 (int) floatFromVal (rval);
1073 if (SPEC_LONG (val->type))
1075 if (SPEC_USIGN (val->type))
1076 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) >>
1077 (unsigned long) floatFromVal (rval);
1079 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) >>
1080 (long) floatFromVal (rval);
1084 if (SPEC_USIGN (val->type))
1085 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) >>
1086 (unsigned) floatFromVal (rval);
1088 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) >>
1089 (int) floatFromVal (rval);
1096 /*------------------------------------------------------------------*/
1097 /* valCompare- Compares two literal */
1098 /*------------------------------------------------------------------*/
1100 valCompare (value * lval, value * rval, int ctype)
1104 /* create a new value */
1106 val->type = val->etype = newCharLink ();
1107 val->type->class = SPECIFIER;
1108 SPEC_NOUN (val->type) = V_INT; /* type is int */
1109 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1114 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1118 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1122 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1126 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1130 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1134 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1142 /*------------------------------------------------------------------*/
1143 /* valBitwise - Bitwise operation */
1144 /*------------------------------------------------------------------*/
1146 valBitwise (value * lval, value * rval, int op)
1150 /* create a new value */
1152 val->type = copyLinkChain (lval->type);
1153 val->etype = getSpec (val->type);
1158 if (SPEC_LONG (val->type))
1160 if (SPEC_USIGN (val->type))
1161 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1162 (unsigned long) floatFromVal (rval);
1164 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1165 (long) floatFromVal (rval);
1169 if (SPEC_USIGN (val->type))
1170 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1171 (unsigned) floatFromVal (rval);
1173 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1178 if (SPEC_LONG (val->type))
1180 if (SPEC_USIGN (val->type))
1181 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1182 (unsigned long) floatFromVal (rval);
1184 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1185 (long) floatFromVal (rval);
1189 if (SPEC_USIGN (val->type))
1190 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1191 (unsigned) floatFromVal (rval);
1193 SPEC_CVAL (val->type).v_int =
1194 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1200 if (SPEC_LONG (val->type))
1202 if (SPEC_USIGN (val->type))
1203 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1204 (unsigned long) floatFromVal (rval);
1206 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1207 (long) floatFromVal (rval);
1211 if (SPEC_USIGN (val->type))
1212 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1213 (unsigned) floatFromVal (rval);
1215 SPEC_CVAL (val->type).v_int =
1216 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1224 /*------------------------------------------------------------------*/
1225 /* valAndOr - Generates code for and / or operation */
1226 /*------------------------------------------------------------------*/
1228 valLogicAndOr (value * lval, value * rval, int op)
1232 /* create a new value */
1234 val->type = val->etype = newCharLink ();
1235 val->type->class = SPECIFIER;
1236 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1241 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1245 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1253 /*------------------------------------------------------------------*/
1254 /* valCastLiteral - casts a literal value to another type */
1255 /*------------------------------------------------------------------*/
1257 valCastLiteral (sym_link * dtype, double fval)
1265 val->etype = getSpec (val->type = copyLinkChain (dtype));
1266 SPEC_SCLS (val->etype) = S_LITERAL;
1267 /* if it is not a specifier then we can assume that */
1268 /* it will be an unsigned long */
1269 if (!IS_SPEC (val->type))
1271 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1275 if (SPEC_NOUN (val->etype) == V_FLOAT)
1276 SPEC_CVAL (val->etype).v_float = fval;
1279 if (SPEC_LONG (val->etype))
1281 if (SPEC_USIGN (val->etype))
1282 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1284 SPEC_CVAL (val->etype).v_long = (long) fval;
1288 if (SPEC_USIGN (val->etype))
1289 SPEC_CVAL (val->etype).v_uint = (unsigned int) fval;
1291 SPEC_CVAL (val->etype).v_int = (int) fval;
1297 /*------------------------------------------------------------------*/
1298 /* getNelements - determines # of elements from init list */
1299 /*------------------------------------------------------------------*/
1301 getNelements (sym_link * type, initList * ilist)
1303 sym_link *etype = getSpec (type);
1309 if (ilist->type == INIT_DEEP)
1310 ilist = ilist->init.deep;
1312 /* if type is a character array and there is only one
1313 initialiser then get the length of the string */
1314 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1316 ast *iast = ilist->init.node;
1317 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1320 werror (E_INIT_WRONG);
1323 if (!IS_ARRAY (v->type) || !IS_CHAR (v->etype))
1325 werror (E_INIT_WRONG);
1328 return DCL_ELEM (v->type);
1335 ilist = ilist->next;
1341 /*-----------------------------------------------------------------*/
1342 /* valForArray - returns a value with name of array index */
1343 /*-----------------------------------------------------------------*/
1345 valForArray (ast * arrExpr)
1347 value *val, *lval = NULL;
1349 int size = getSize (arrExpr->left->ftype->next);
1350 /* if the right or left is an array
1352 if (IS_AST_OP (arrExpr->left))
1354 if (arrExpr->left->opval.op == '[')
1355 lval = valForArray (arrExpr->left);
1356 else if (arrExpr->left->opval.op == '.')
1357 lval = valForStructElem (arrExpr->left->left,
1358 arrExpr->left->right);
1359 else if (arrExpr->left->opval.op == PTR_OP &&
1360 IS_ADDRESS_OF_OP (arrExpr->left->left))
1361 lval = valForStructElem (arrExpr->left->left->left,
1362 arrExpr->left->right);
1367 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1370 if (!IS_AST_LIT_VALUE (arrExpr->right))
1375 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1377 sprintf (buffer, "%s", lval->name);
1379 sprintf (val->name, "(%s + %d)", buffer,
1380 (int) AST_LIT_VALUE (arrExpr->right) * size);
1382 val->type = newLink ();
1383 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1385 DCL_TYPE (val->type) = CPOINTER;
1386 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1388 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1389 DCL_TYPE (val->type) = FPOINTER;
1390 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1391 DCL_TYPE (val->type) = PPOINTER;
1392 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1393 DCL_TYPE (val->type) = IPOINTER;
1394 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1395 DCL_TYPE (val->type) = EEPPOINTER;
1397 DCL_TYPE (val->type) = POINTER;
1398 val->type->next = arrExpr->left->ftype;
1399 val->etype = getSpec (val->type);
1403 /*-----------------------------------------------------------------*/
1404 /* valForStructElem - returns value with name of struct element */
1405 /*-----------------------------------------------------------------*/
1407 valForStructElem (ast * structT, ast * elemT)
1409 value *val, *lval = NULL;
1413 /* left could be furthur derefed */
1414 if (IS_AST_OP (structT))
1416 if (structT->opval.op == '[')
1417 lval = valForArray (structT);
1418 else if (structT->opval.op == '.')
1419 lval = valForStructElem (structT->left, structT->right);
1420 else if (structT->opval.op == PTR_OP &&
1421 IS_ADDRESS_OF_OP (structT->left))
1422 lval = valForStructElem (structT->left->left,
1428 if (!IS_AST_SYM_VALUE (elemT))
1431 if (!IS_STRUCT (structT->etype))
1434 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1435 AST_SYMBOL (elemT))) == NULL)
1442 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1444 sprintf (buffer, "%s", lval->name);
1446 sprintf (val->name, "(%s + %d)", buffer,
1449 val->type = newLink ();
1450 if (SPEC_SCLS (structT->etype) == S_CODE)
1452 DCL_TYPE (val->type) = CPOINTER;
1453 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1455 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1456 DCL_TYPE (val->type) = FPOINTER;
1457 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1458 DCL_TYPE (val->type) = PPOINTER;
1459 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1460 DCL_TYPE (val->type) = IPOINTER;
1461 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1462 DCL_TYPE (val->type) = EEPPOINTER;
1464 DCL_TYPE (val->type) = POINTER;
1465 val->type->next = sym->type;
1466 val->etype = getSpec (val->type);
1470 /*-----------------------------------------------------------------*/
1471 /* valForCastAggr - will return value for a cast of an aggregate */
1472 /* plus minus a constant */
1473 /*-----------------------------------------------------------------*/
1475 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1479 if (!IS_AST_SYM_VALUE (aexpr))
1481 if (!IS_AST_LIT_VALUE (cnst))
1486 sprintf (val->name, "(%s %c %d)",
1487 AST_SYMBOL (aexpr)->rname, op,
1488 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1491 val->etype = getSpec (val->type);
1495 /*-----------------------------------------------------------------*/
1496 /* valForCastAggr - will return value for a cast of an aggregate */
1497 /* with no constant */
1498 /*-----------------------------------------------------------------*/
1500 valForCastArr (ast * aexpr, sym_link * type)
1504 if (!IS_AST_SYM_VALUE (aexpr))
1509 sprintf (val->name, "(%s)",
1510 AST_SYMBOL (aexpr)->rname);
1513 val->etype = getSpec (val->type);