fixed
[fw/sdcc] / src / SDCCval.c
1 /*----------------------------------------------------------------------
2     SDCCval.c :- has routine to do all kinds of fun stuff with the
3                 value wrapper & with initialiser lists.
4
5     Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6
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
10     later version.
11
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.
16
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.
20
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 -------------------------------------------------------------------------*/
25
26 #include "common.h"
27 #include <math.h>
28 #include <stdlib.h>
29 #include <limits.h>
30 #include "newalloc.h"
31
32 int cNestLevel;
33
34 /*-----------------------------------------------------------------*/
35 /* newValue - allocates and returns a new value        */
36 /*-----------------------------------------------------------------*/
37 value *
38 newValue ()
39 {
40   value *val;
41
42   val = Safe_alloc (sizeof (value));
43
44   return val;
45 }
46
47 /*-----------------------------------------------------------------*/
48 /* newiList - new initializer list                                 */
49 /*-----------------------------------------------------------------*/
50 initList *
51 newiList (int type, void *ilist)
52 {
53   initList *nilist;
54
55
56   nilist = Safe_alloc (sizeof (initList));
57
58   nilist->type = type;
59   nilist->lineno = yylineno;
60
61   switch (type)
62     {
63     case INIT_NODE:
64       nilist->init.node = (struct ast *) ilist;
65       break;
66
67     case INIT_DEEP:
68       nilist->init.deep = (struct initList *) ilist;
69       break;
70     }
71
72   return nilist;
73 }
74
75 /*------------------------------------------------------------------*/
76 /* revinit   - reverses the initial values for a value  chain        */
77 /*------------------------------------------------------------------*/
78 initList *
79 revinit (initList * val)
80 {
81   initList *prev, *curr, *next;
82
83   if (!val)
84     return NULL;
85
86   prev = val;
87   curr = val->next;
88
89   while (curr)
90     {
91       next = curr->next;
92       curr->next = prev;
93       prev = curr;
94       curr = next;
95     }
96   val->next = (void *) NULL;
97   return prev;
98 }
99
100 bool
101 convertIListToConstList(initList *src, literalList **lList)
102 {
103     initList    *iLoop;
104     literalList *head, *last, *newL;
105     
106     head = last = NULL;
107     
108     if (!src || src->type != INIT_DEEP)
109     {
110         return FALSE;
111     }
112     
113     iLoop =  src->init.deep;
114     
115     while (iLoop)
116     {
117         if (iLoop->type != INIT_NODE)
118         {
119             return FALSE;
120         }
121         
122         if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node))))
123         {
124             return FALSE;
125         }
126         iLoop = iLoop->next;
127     }
128     
129     // We've now established that the initializer list contains only literal values.
130     
131     iLoop = src->init.deep;
132     while (iLoop)
133     {
134         double val = AST_LIT_VALUE(iLoop->init.node);
135         
136         if (last && last->literalValue == val)
137         {
138             last->count++;
139         }
140         else
141         {
142             newL = Safe_alloc(sizeof(literalList));
143             newL->literalValue = val;
144             newL->count = 1;
145             newL->next = NULL;
146             
147             if (last)
148             {
149                 last->next = newL;
150             }
151             else
152             {
153                 head = newL;
154             }
155             last = newL;
156         }
157         iLoop = iLoop->next;
158     }
159     
160     if (!head)    
161     {
162         return FALSE;
163     }
164     
165     *lList = head;
166     return TRUE;
167 }
168
169 literalList *
170 copyLiteralList(literalList *src)
171 {
172     literalList *head, *prev, *newL;
173     
174     head = prev = NULL;
175     
176     while (src)
177     {
178         newL = Safe_alloc(sizeof(literalList));
179         
180         newL->literalValue = src->literalValue;
181         newL->count = src->count;
182         newL->next = NULL;
183         
184         if (prev)
185         {
186             prev->next = newL;
187         }
188         else
189         {
190             head = newL;
191         }
192         prev = newL;
193         src = src->next;
194     }
195     
196     return head;
197 }
198
199
200
201 /*------------------------------------------------------------------*/
202 /* copyIlist - copy initializer list            */
203 /*------------------------------------------------------------------*/
204 initList *
205 copyIlist (initList * src)
206 {
207   initList *dest = NULL;
208
209   if (!src)
210     return NULL;
211
212   switch (src->type)
213     {
214     case INIT_DEEP:
215       dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
216       break;
217     case INIT_NODE:
218       dest = newiList (INIT_NODE, copyAst (src->init.node));
219       break;
220     }
221
222   if (src->next)
223     dest->next = copyIlist (src->next);
224
225   return dest;
226 }
227
228 /*------------------------------------------------------------------*/
229 /* list2int - converts the first element of the list to value       */
230 /*------------------------------------------------------------------*/
231 double 
232 list2int (initList * val)
233 {
234   initList *i = val;
235
236   if (i->type == INIT_DEEP)
237     return list2int (val->init.deep);
238
239   return floatFromVal (constExprValue (val->init.node, TRUE));
240 }
241
242 /*------------------------------------------------------------------*/
243 /* list2val - converts the first element of the list to value       */
244 /*------------------------------------------------------------------*/
245 value *
246 list2val (initList * val)
247 {
248   if (!val)
249     return NULL;
250
251   if (val->type == INIT_DEEP)
252     return list2val (val->init.deep);
253
254   return constExprValue (val->init.node, TRUE);
255 }
256
257 /*------------------------------------------------------------------*/
258 /* list2expr - returns the first expression in the initializer list */
259 /*------------------------------------------------------------------*/
260 ast *
261 list2expr (initList * ilist)
262 {
263   if (ilist->type == INIT_DEEP)
264     return list2expr (ilist->init.deep);
265   return ilist->init.node;
266 }
267
268 /*------------------------------------------------------------------*/
269 /* resolveIvalSym - resolve symbols in initial values               */
270 /*------------------------------------------------------------------*/
271 void 
272 resolveIvalSym (initList * ilist)
273 {
274   if (!ilist)
275     return;
276
277   if (ilist->type == INIT_NODE)
278     ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
279
280   if (ilist->type == INIT_DEEP)
281     resolveIvalSym (ilist->init.deep);
282
283   resolveIvalSym (ilist->next);
284 }
285
286 /*-----------------------------------------------------------------*/
287 /* symbolVal - creates a value for a symbol              */
288 /*-----------------------------------------------------------------*/
289 value *
290 symbolVal (symbol * sym)
291 {
292   value *val;
293
294   if (!sym)
295     return NULL;
296
297   val = newValue ();
298   val->sym = sym;
299
300   if (sym->type)
301     {
302       val->type = sym->type;
303       val->etype = getSpec (val->type);
304     }
305
306   if (*sym->rname)
307     sprintf (val->name, "%s", sym->rname);
308   else
309     sprintf (val->name, "_%s", sym->name);
310
311
312   return val;
313 }
314
315 /*--------------------------------------------------------------------*/
316 /* cheapestVal - convert a val to the cheapest as possible value      */
317 /*--------------------------------------------------------------------*/
318 value *cheapestVal (value *val) {
319   long sval=0;
320   unsigned long uval=0;
321
322   if (IS_FLOAT(val->type) || IS_CHAR(val->type))
323     return val;
324
325   if (SPEC_LONG(val->type)) {
326     if (SPEC_USIGN(val->type)) {
327       uval=SPEC_CVAL(val->type).v_ulong;
328     } else {
329       sval=SPEC_CVAL(val->type).v_long;
330     }
331   } else {
332     if (SPEC_USIGN(val->type)) {
333       uval=SPEC_CVAL(val->type).v_uint;
334     } else {
335       sval=SPEC_CVAL(val->type).v_int;
336     }
337   }
338
339   if (SPEC_USIGN(val->type)) {
340     if (uval<=0xffff) {
341       SPEC_LONG(val->type)=0;
342       SPEC_CVAL(val->type).v_uint = uval;
343       if (uval<=0xff) {
344         SPEC_NOUN(val->type)=V_CHAR;
345       }
346     }
347   } else { // not unsigned
348     if (sval<0) {
349       if (sval>=-32768) {
350         SPEC_LONG(val->type)=0;
351         SPEC_CVAL(val->type).v_int = sval;
352         if (sval>=-128) {
353           SPEC_NOUN(val->type)=V_CHAR;
354         }
355       }
356     } else { // sval>=0
357       SPEC_USIGN(val->type)=1;
358       if (sval<=65535) {
359         SPEC_LONG(val->type)=0;
360         SPEC_CVAL(val->type).v_int = sval;
361         if (sval<=255) {
362           SPEC_NOUN(val->type)=V_CHAR;
363         }
364       }
365     }
366   }
367   return val;
368 }
369
370 /*-----------------------------------------------------------------*/
371 /* valueFromLit - creates a value from a literal                   */
372 /*-----------------------------------------------------------------*/
373 value *
374 valueFromLit (double lit)
375 {
376   char buffer[50];
377
378   if ((((long) lit) - lit) == 0)
379     {
380       sprintf (buffer, "%ld", (long) lit);
381       return constVal (buffer);
382     }
383
384   sprintf (buffer, "%f", lit);
385   return constFloatVal (buffer);
386 }
387
388 /*-----------------------------------------------------------------*/
389 /* constFloatVal - converts a FLOAT constant to value              */
390 /*-----------------------------------------------------------------*/
391 value *
392 constFloatVal (char *s)
393 {
394   value *val = newValue ();
395   double sval;
396
397   if (sscanf (s, "%lf", &sval) != 1)
398     {
399       werror (E_INVALID_FLOAT_CONST, s);
400       return constVal ("0");
401     }
402
403   val->type = val->etype = newLink ();
404   val->type->class = SPECIFIER;
405   SPEC_NOUN (val->type) = V_FLOAT;
406   SPEC_SCLS (val->type) = S_LITERAL;
407   SPEC_CVAL (val->type).v_float = sval;
408
409   return val;
410 }
411
412 /*-----------------------------------------------------------------*/
413 /* constVal - converts an INTEGER constant into a cheapest value   */
414 /*-----------------------------------------------------------------*/
415 value *constVal (char *s)
416 {
417   value *val;
418   short hex = 0, octal = 0;
419   char scanFmt[10];
420   int scI = 0;
421   double dval;
422
423   val = newValue ();            /* alloc space for value   */
424
425   val->type = val->etype = newLink ();  /* create the spcifier */
426   val->type->class = SPECIFIER;
427   SPEC_SCLS (val->type) = S_LITERAL;
428   // let's start with an unsigned char
429   SPEC_NOUN (val->type) = V_CHAR;
430   SPEC_USIGN (val->type) = 1;
431
432   hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
433
434   /* set the octal flag   */
435   if (!hex && *s == '0' && *(s + 1))
436     octal = 1;
437
438   /* create the scan string */
439   scanFmt[scI++] = '%';
440
441   scanFmt[scI++] = 'l';
442
443   if (octal)
444     scanFmt[scI++] = 'o';
445   else if (hex)
446     scanFmt[scI++] = 'x';
447   else
448     scanFmt[scI++] = 'f';
449
450   scanFmt[scI++] = '\0';
451
452   if (octal || hex) {
453     unsigned long sval;
454     sscanf (s, scanFmt, &sval);
455     dval=sval;
456   } else {
457     sscanf (s, scanFmt, &dval);
458   }
459
460   /* Setup the flags first */
461   /* set the _long flag if 'lL' is found */
462   if (strchr (s, 'l') || strchr (s, 'L')) {
463     SPEC_NOUN (val->type) = V_INT;
464     SPEC_LONG (val->type) = 1;
465   }
466
467   if (dval<0) { // "-28u" will still be signed and negative
468     SPEC_USIGN (val->type) = 0;
469     if (dval<-128) { // check if we have to promote to int
470       SPEC_NOUN (val->type) = V_INT;
471     }
472     if (dval<-32768) { // check if we have to promote to long int
473       SPEC_LONG (val->type) = 1;
474     }
475   } else { // >=0
476     if (dval>0xff) { // check if we have to promote to int
477       SPEC_NOUN (val->type) = V_INT;
478     }
479     if (dval>0xffff) { // check if we have to promote to long int
480       SPEC_LONG (val->type) = 1;
481     }
482   }
483
484   if (SPEC_LONG (val->type))
485     {
486       if (SPEC_USIGN (val->type))
487         {
488           SPEC_CVAL (val->type).v_ulong = dval;
489         }
490       else
491         {
492           SPEC_CVAL (val->type).v_long = dval;
493         }
494     }
495   else
496     {
497       if (SPEC_USIGN (val->type))
498         {
499           SPEC_CVAL (val->type).v_uint = dval;
500         }
501       else
502         {
503           SPEC_CVAL (val->type).v_int = dval;
504         }
505     }
506
507   return val;
508 }
509
510 /*! /fn char hexEscape(char **src)
511
512     /param src Pointer to 'x' from start of hex character value
513 */
514
515 unsigned char hexEscape(char **src)
516 {
517   char *s ;
518   unsigned long value ;
519   
520   (*src)++ ;    /* Skip over the 'x' */
521   s = *src ;    /* Save for error detection */
522   
523   value = strtol (*src, src, 16);
524   
525   if (s == *src) {
526       // no valid hex found
527       werror(E_INVALID_HEX);
528   } else {
529     if (value > 255) {
530       werror(W_ESC_SEQ_OOR_FOR_CHAR);
531     }
532   }
533   return (char) value;
534 }
535
536 /*------------------------------------------------------------------*/
537 /* octalEscape - process an octal constant of max three digits      */
538 /* return the octal value, throw a warning for illegal octal        */
539 /* adjust src to point at the last proccesed char                   */
540 /*------------------------------------------------------------------*/
541
542 unsigned char octalEscape (char **str) {
543   int digits;
544   unsigned value=0;
545
546   for (digits=0; digits<3; digits++) {
547     if (**str>='0' && **str<='7') {
548       value = value*8 + (**str-'0');
549       (*str)++;
550     } else {
551       break;
552     }
553   }
554   if (digits) {
555     if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
556       werror (W_ESC_SEQ_OOR_FOR_CHAR);
557     }
558   }
559   return value;
560 }
561
562 /*! 
563   /fn int copyStr (char *dest, char *src)
564   
565   Copies a source string to a dest buffer interpreting escape sequences
566   and special characters
567
568   /param dest Buffer to receive the resultant string
569   /param src  Buffer containing the source string with escape sequecnes
570   /return Number of characters in output string
571
572 */
573
574 int 
575 copyStr (char *dest, char *src)
576
577 {
578   char *OriginalDest = dest ;
579
580   while (*src)
581     {
582       if (*src == '\"')
583         src++;
584       else if (*src == '\\')
585         {
586           src++;
587           switch (*src)
588             {
589             case 'n':
590               *dest++ = '\n';
591               break;
592             case 't':
593               *dest++ = '\t';
594               break;
595             case 'v':
596               *dest++ = '\v';
597               break;
598             case 'b':
599               *dest++ = '\b';
600               break;
601             case 'r':
602               *dest++ = '\r';
603               break;
604             case 'f':
605               *dest++ = '\f';
606               break;
607             case 'a':
608               *dest++ = '\a';
609               break;
610
611             case '0':
612             case '1':
613             case '2':
614             case '3':
615             case '4':
616             case '5':
617             case '6':
618             case '7':
619               *dest++ = octalEscape(&src);
620               src-- ;
621               break;
622
623             case 'x': 
624               *dest++ = hexEscape(&src) ;
625               src-- ;
626               break ;
627
628             case '\\':
629               *dest++ = '\\';
630               break;
631             case '\?':
632               *dest++ = '\?';
633               break;
634             case '\'':
635               *dest++ = '\'';
636               break;
637             case '\"':
638               *dest++ = '\"';
639               break;
640             default:
641               *dest++ = *src;
642             }
643           src++;
644         }
645       else
646         *dest++ = *src++;
647     }
648
649   *dest++ = '\0';
650
651   return dest - OriginalDest ;
652 }
653
654 /*------------------------------------------------------------------*/
655 /* strVal - converts a string constant to a value       */
656 /*------------------------------------------------------------------*/
657 value *
658 strVal (char *s)
659 {
660   value *val;
661
662   val = newValue ();            /* get a new one */
663
664   /* get a declarator */
665   val->type = newLink ();
666   DCL_TYPE (val->type) = ARRAY;
667   val->type->next = val->etype = newLink ();
668   val->etype->class = SPECIFIER;
669   SPEC_NOUN (val->etype) = V_CHAR;
670   SPEC_SCLS (val->etype) = S_LITERAL;
671
672   SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
673   DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
674
675   return val;
676 }
677
678
679 /*------------------------------------------------------------------*/
680 /* reverseValWithType - reverses value chain with type & etype      */
681 /*------------------------------------------------------------------*/
682 value *
683 reverseValWithType (value * val)
684 {
685   sym_link *type;
686   sym_link *etype;
687
688   if (!val)
689     return NULL;
690
691   /* save the type * etype chains */
692   type = val->type;
693   etype = val->etype;
694
695   /* set the current one 2b null */
696   val->type = val->etype = NULL;
697   val = reverseVal (val);
698
699   /* restore type & etype */
700   val->type = type;
701   val->etype = etype;
702
703   return val;
704 }
705
706 /*------------------------------------------------------------------*/
707 /* reverseVal - reverses the values for a value  chain        */
708 /*------------------------------------------------------------------*/
709 value *
710 reverseVal (value * val)
711 {
712   value *prev, *curr, *next;
713
714   if (!val)
715     return NULL;
716
717   prev = val;
718   curr = val->next;
719
720   while (curr)
721     {
722       next = curr->next;
723       curr->next = prev;
724       prev = curr;
725       curr = next;
726     }
727   val->next = (void *) NULL;
728   return prev;
729 }
730
731 /*------------------------------------------------------------------*/
732 /* copyValueChain - will copy a chain of values                     */
733 /*------------------------------------------------------------------*/
734 value *
735 copyValueChain (value * src)
736 {
737   value *dest;
738
739   if (!src)
740     return NULL;
741
742   dest = copyValue (src);
743   dest->next = copyValueChain (src->next);
744
745   return dest;
746 }
747
748 /*------------------------------------------------------------------*/
749 /* copyValue - copies contents of a value to a fresh one            */
750 /*------------------------------------------------------------------*/
751 value *
752 copyValue (value * src)
753 {
754   value *dest;
755
756   dest = newValue ();
757   dest->sym = copySymbol (src->sym);
758   strcpy (dest->name, src->name);
759   dest->type = (src->type ? copyLinkChain (src->type) : NULL);
760   dest->etype = (src->type ? getSpec (dest->type) : NULL);
761
762   return dest;
763 }
764
765 /*------------------------------------------------------------------*/
766 /* charVal - converts a character constant to a value       */
767 /*------------------------------------------------------------------*/
768 value *
769 charVal (char *s)
770 {
771   value *val;
772 //  unsigned uValue ;
773
774   val = newValue ();
775
776   val->type = val->etype = newLink ();
777   val->type->class = SPECIFIER;
778   SPEC_NOUN (val->type) = V_CHAR;
779   SPEC_USIGN(val->type) = 1;
780   SPEC_SCLS (val->type) = S_LITERAL;
781
782   s++;                          /* get rid of quotation */
783   /* if \ then special processing */
784   if (*s == '\\')
785     {
786       s++;                      /* go beyond the backslash  */
787       switch (*s)
788         {
789         case 'n':
790           SPEC_CVAL (val->type).v_int = '\n';
791           break;
792         case 't':
793           SPEC_CVAL (val->type).v_int = '\t';
794           break;
795         case 'v':
796           SPEC_CVAL (val->type).v_int = '\v';
797           break;
798         case 'b':
799           SPEC_CVAL (val->type).v_int = '\b';
800           break;
801         case 'r':
802           SPEC_CVAL (val->type).v_int = '\r';
803           break;
804         case 'f':
805           SPEC_CVAL (val->type).v_int = '\f';
806           break;
807         case 'a':
808           SPEC_CVAL (val->type).v_int = '\a';
809           break;
810         case '\\':
811           SPEC_CVAL (val->type).v_int = '\\';
812           break;
813         case '\?':
814           SPEC_CVAL (val->type).v_int = '\?';
815           break;
816         case '\'':
817           SPEC_CVAL (val->type).v_int = '\'';
818           break;
819         case '\"':
820           SPEC_CVAL (val->type).v_int = '\"';
821           break;
822
823         case '0' :
824         case '1' :
825         case '2' :
826         case '3' :
827         case '4' :
828         case '5' :
829         case '6' :
830         case '7' :
831           SPEC_CVAL (val->type).v_uint = octalEscape(&s);
832           break;
833
834         case 'x':
835           SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
836           break;
837
838         default:
839           SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
840           break;
841         }
842     }
843   else                          /* not a backslash */
844     SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
845
846   return val;
847 }
848
849 /*------------------------------------------------------------------*/
850 /* valFromType - creates a value from type given                    */
851 /*------------------------------------------------------------------*/
852 value *
853 valFromType (sym_link * type)
854 {
855   value *val = newValue ();
856   val->type = copyLinkChain (type);
857   val->etype = getSpec (val->type);
858   return val;
859 }
860
861 /*------------------------------------------------------------------*/
862 /* floatFromVal - value to double float conversion                  */
863 /*------------------------------------------------------------------*/
864 double 
865 floatFromVal (value * val)
866 {
867   if (!val)
868     return 0;
869
870   if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
871     {
872       werror (E_CONST_EXPECTED, val->name);
873       return 0;
874     }
875
876   /* if it is not a specifier then we can assume that */
877   /* it will be an unsigned long                      */
878   if (!IS_SPEC (val->type))
879     return (double) SPEC_CVAL (val->etype).v_ulong;
880
881   if (SPEC_NOUN (val->etype) == V_FLOAT)
882     return (double) SPEC_CVAL (val->etype).v_float;
883
884   if (SPEC_LONG (val->etype))
885     {
886       if (SPEC_USIGN (val->etype))
887         return (double) SPEC_CVAL (val->etype).v_ulong;
888       else
889         return (double) SPEC_CVAL (val->etype).v_long;
890     }
891   
892   if (SPEC_NOUN (val->etype) == V_INT) {
893     if (SPEC_USIGN (val->etype))
894       return (double) SPEC_CVAL (val->etype).v_uint;
895     else
896       return (double) SPEC_CVAL (val->etype).v_int;
897   }
898
899   if (SPEC_NOUN (val->etype) == V_CHAR) {
900     if (SPEC_USIGN (val->etype))
901       return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
902     else
903       return (double) (signed char)SPEC_CVAL (val->etype).v_int;
904   }
905
906   if (IS_BITVAR(val->etype)) {
907     return (double) SPEC_CVAL (val->etype).v_ulong;
908   }
909
910   if (SPEC_NOUN (val->etype) == V_VOID) {
911     return (double) SPEC_CVAL (val->etype).v_ulong;
912   }
913
914   // we are lost !
915   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
916           "floatFromVal: unknown value");
917   return 0;
918 }
919
920
921 /*------------------------------------------------------------------*/
922 /* valUnaryPM - does the unary +/- operation on a constant          */
923 /*------------------------------------------------------------------*/
924 value *
925 valUnaryPM (value * val)
926 {
927   /* depending on type */
928   if (SPEC_NOUN (val->etype) == V_FLOAT)
929     SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
930   else
931     {
932       if (SPEC_LONG (val->etype))
933         {
934           if (SPEC_USIGN (val->etype))
935             SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
936           else
937             SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
938         }
939       else
940         {
941           if (SPEC_USIGN (val->etype))
942             SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
943           else
944             SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
945         }
946     }
947   // -(unsigned 3) now really is signed
948   SPEC_USIGN(val->etype)=0;
949   return val;
950 }
951
952 /*------------------------------------------------------------------*/
953 /* valueComplement - complements a constant                         */
954 /*------------------------------------------------------------------*/
955 value *
956 valComplement (value * val)
957 {
958   /* depending on type */
959   if (SPEC_LONG (val->etype))
960     {
961       if (SPEC_USIGN (val->etype))
962         SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
963       else
964         SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
965     }
966   else
967     {
968       if (SPEC_USIGN (val->etype))
969         SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
970       else
971         SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
972     }
973   // ~(unsigned 3) now really is signed
974   SPEC_USIGN(val->etype)=0;
975   return val;
976 }
977
978 /*------------------------------------------------------------------*/
979 /* valueNot - complements a constant                                */
980 /*------------------------------------------------------------------*/
981 value *
982 valNot (value * val)
983 {
984   /* depending on type */
985   if (SPEC_LONG (val->etype))
986     {
987       if (SPEC_USIGN (val->etype))
988         SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
989       else
990         SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
991     }
992   else
993     {
994       if (SPEC_USIGN (val->etype))
995         SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
996       else
997         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
998     }
999   return val;
1000 }
1001
1002 /*------------------------------------------------------------------*/
1003 /* valMult - multiply constants                                     */
1004 /*------------------------------------------------------------------*/
1005 value *
1006 valMult (value * lval, value * rval)
1007 {
1008   value *val;
1009
1010   /* create a new value */
1011   val = newValue ();
1012   val->type = val->etype = newLink ();
1013   val->type->class = SPECIFIER;
1014   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1015                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1016   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1017   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1018   SPEC_LONG (val->type) = 1;
1019
1020   if (IS_FLOAT (val->type))
1021     SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1022   else
1023     {
1024       if (SPEC_LONG (val->type))
1025         {
1026           if (SPEC_USIGN (val->type))
1027             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
1028               (unsigned long) floatFromVal (rval);
1029           else
1030             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
1031               (long) floatFromVal (rval);
1032         }
1033     }
1034   return cheapestVal(val);
1035 }
1036
1037 /*------------------------------------------------------------------*/
1038 /* valDiv  - Divide   constants                                     */
1039 /*------------------------------------------------------------------*/
1040 value *
1041 valDiv (value * lval, value * rval)
1042 {
1043   value *val;
1044
1045   if (floatFromVal (rval) == 0)
1046     {
1047       werror (E_DIVIDE_BY_ZERO);
1048       return rval;
1049     }
1050
1051   /* create a new value */
1052   val = newValue ();
1053   val->type = val->etype = newLink();
1054   val->type->class = SPECIFIER;
1055   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1056                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1057   SPEC_SCLS (val->etype) = S_LITERAL;
1058   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1059   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1060
1061   if (IS_FLOAT (val->type))
1062     SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1063   else
1064     {
1065       if (SPEC_LONG (val->type))
1066         {
1067           if (SPEC_USIGN (val->type))
1068             SPEC_CVAL (val->type).v_ulong = 
1069               (unsigned long) floatFromVal (lval) /
1070               (unsigned long) floatFromVal (rval);
1071           else
1072             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1073               (long) floatFromVal (rval);
1074         }
1075       else
1076         {
1077           if (SPEC_USIGN (val->type)) {
1078             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1079               (unsigned) floatFromVal (rval);
1080           } else {
1081             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1082               (int) floatFromVal (rval);
1083           }
1084         }
1085     }
1086   return cheapestVal(val);
1087 }
1088
1089 /*------------------------------------------------------------------*/
1090 /* valMod  - Modulus  constants                                     */
1091 /*------------------------------------------------------------------*/
1092 value *
1093 valMod (value * lval, value * rval)
1094 {
1095   value *val;
1096
1097   /* create a new value */
1098   val = newValue ();
1099   val->type = val->etype = newLink ();
1100   val->type->class = SPECIFIER;
1101   SPEC_NOUN (val->type) = V_INT;        /* type is int */
1102   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1103   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1104   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1105
1106   if (SPEC_LONG (val->type))
1107     {
1108       if (SPEC_USIGN (val->type))
1109         SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1110           (unsigned long) floatFromVal (rval);
1111       else
1112         SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1113           (unsigned long) floatFromVal (rval);
1114     }
1115   else
1116     {
1117       if (SPEC_USIGN (val->type)) {
1118         SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1119           (unsigned) floatFromVal (rval);
1120       } else {
1121         SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1122           (unsigned) floatFromVal (rval);
1123       }
1124     }
1125
1126   return cheapestVal(val);
1127 }
1128
1129 /*------------------------------------------------------------------*/
1130 /* valPlus - Addition constants                                     */
1131 /*------------------------------------------------------------------*/
1132 value *
1133 valPlus (value * lval, value * rval)
1134 {
1135   value *val;
1136
1137   /* create a new value */
1138   val = newValue ();
1139   val->type = val->etype = newLink ();
1140   val->type->class = SPECIFIER;
1141   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1142                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1143   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1144   SPEC_USIGN (val->type) = 
1145     SPEC_USIGN (lval->etype) &&
1146     SPEC_USIGN (rval->etype) &&
1147     (floatFromVal(lval)+floatFromVal(rval))>=0;
1148     
1149   SPEC_LONG (val->type) = 1;
1150
1151   if (IS_FLOAT (val->type))
1152     SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1153   else
1154     {
1155       if (SPEC_LONG (val->type))
1156         {
1157           if (SPEC_USIGN (val->type))
1158             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1159               (unsigned long) floatFromVal (rval);
1160           else
1161             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1162               (long) floatFromVal (rval);
1163         }
1164     }
1165   return cheapestVal(val);
1166 }
1167
1168 /*------------------------------------------------------------------*/
1169 /* valMinus - Addition constants                                    */
1170 /*------------------------------------------------------------------*/
1171 value *
1172 valMinus (value * lval, value * rval)
1173 {
1174   value *val;
1175
1176   /* create a new value */
1177   val = newValue ();
1178   val->type = val->etype = newLink ();
1179   val->type->class = SPECIFIER;
1180   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1181                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1182   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1183   SPEC_USIGN (val->type) = 
1184     SPEC_USIGN (lval->etype) &&
1185     SPEC_USIGN (rval->etype) &&
1186     (floatFromVal(lval)-floatFromVal(rval))>=0;
1187
1188   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1189
1190   if (IS_FLOAT (val->type))
1191     SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1192   else
1193     {
1194       if (SPEC_LONG (val->type))
1195         {
1196           if (SPEC_USIGN (val->type)) {
1197             SPEC_CVAL (val->type).v_ulong = 
1198               (unsigned long) floatFromVal (lval) -
1199               (unsigned long) floatFromVal (rval);
1200           } else {
1201             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1202               (long) floatFromVal (rval);
1203           }
1204         }
1205       else
1206         {
1207           if (SPEC_USIGN (val->type)) {
1208             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1209               (unsigned) floatFromVal (rval);
1210           } else {
1211             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - 
1212               (int) floatFromVal (rval);
1213           }
1214         }
1215     }
1216   return cheapestVal(val);
1217 }
1218
1219 /*------------------------------------------------------------------*/
1220 /* valShift - Shift left or right                                   */
1221 /*------------------------------------------------------------------*/
1222 value *
1223 valShift (value * lval, value * rval, int lr)
1224 {
1225   value *val;
1226
1227   /* create a new value */
1228   val = newValue ();
1229   val->type = val->etype = newIntLink ();
1230   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1231   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1232   SPEC_LONG (val->type) = 1;
1233
1234   if (SPEC_LONG (val->type))
1235     {
1236       if (SPEC_USIGN (val->type))
1237         SPEC_CVAL (val->type).v_ulong = lr ? 
1238           (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1239           (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1240       else
1241         SPEC_CVAL (val->type).v_long = lr ?
1242           (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1243           (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1244     }
1245
1246   return cheapestVal(val);
1247 }
1248
1249 /*------------------------------------------------------------------*/
1250 /* valCompare- Compares two literal                                 */
1251 /*------------------------------------------------------------------*/
1252 value *
1253 valCompare (value * lval, value * rval, int ctype)
1254 {
1255   value *val;
1256
1257   /* create a new value */
1258   val = newValue ();
1259   val->type = val->etype = newCharLink ();
1260   val->type->class = SPECIFIER;
1261   SPEC_NOUN (val->type) = V_CHAR;       /* type is char */
1262   SPEC_USIGN (val->type) = 1;
1263   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1264
1265   switch (ctype)
1266     {
1267     case '<':
1268       SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1269       break;
1270
1271     case '>':
1272       SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1273       break;
1274
1275     case LE_OP:
1276       SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1277       break;
1278
1279     case GE_OP:
1280       SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1281       break;
1282
1283     case EQ_OP:
1284       SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1285       break;
1286
1287     case NE_OP:
1288       SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1289       break;
1290
1291     }
1292
1293   return val;
1294 }
1295
1296 /*------------------------------------------------------------------*/
1297 /* valBitwise - Bitwise operation                                   */
1298 /*------------------------------------------------------------------*/
1299 value *
1300 valBitwise (value * lval, value * rval, int op)
1301 {
1302   value *val;
1303
1304   /* create a new value */
1305   val = newValue ();
1306   val->type = copyLinkChain (lval->type);
1307   val->etype = getSpec (val->type);
1308
1309   switch (op)
1310     {
1311     case '&':
1312       if (SPEC_LONG (val->type))
1313         {
1314           if (SPEC_USIGN (val->type))
1315             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1316               (unsigned long) floatFromVal (rval);
1317           else
1318             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1319               (long) floatFromVal (rval);
1320         }
1321       else
1322         {
1323           if (SPEC_USIGN (val->type))
1324             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1325               (unsigned) floatFromVal (rval);
1326           else
1327             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1328         }
1329       break;
1330
1331     case '|':
1332       if (SPEC_LONG (val->type))
1333         {
1334           if (SPEC_USIGN (val->type))
1335             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1336               (unsigned long) floatFromVal (rval);
1337           else
1338             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1339               (long) floatFromVal (rval);
1340         }
1341       else
1342         {
1343           if (SPEC_USIGN (val->type))
1344             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1345               (unsigned) floatFromVal (rval);
1346           else
1347             SPEC_CVAL (val->type).v_int =
1348               (int) floatFromVal (lval) | (int) floatFromVal (rval);
1349         }
1350
1351       break;
1352
1353     case '^':
1354       if (SPEC_LONG (val->type))
1355         {
1356           if (SPEC_USIGN (val->type))
1357             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1358               (unsigned long) floatFromVal (rval);
1359           else
1360             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1361               (long) floatFromVal (rval);
1362         }
1363       else
1364         {
1365           if (SPEC_USIGN (val->type))
1366             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1367               (unsigned) floatFromVal (rval);
1368           else
1369             SPEC_CVAL (val->type).v_int =
1370               (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1371         }
1372       break;
1373     }
1374
1375   return cheapestVal(val);
1376 }
1377
1378 /*------------------------------------------------------------------*/
1379 /* valAndOr   - Generates code for and / or operation               */
1380 /*------------------------------------------------------------------*/
1381 value *
1382 valLogicAndOr (value * lval, value * rval, int op)
1383 {
1384   value *val;
1385
1386   /* create a new value */
1387   val = newValue ();
1388   val->type = val->etype = newCharLink ();
1389   val->type->class = SPECIFIER;
1390   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1391   SPEC_USIGN (val->type) = 0;
1392
1393   switch (op)
1394     {
1395     case AND_OP:
1396       SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1397       break;
1398
1399     case OR_OP:
1400       SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1401       break;
1402     }
1403
1404
1405   return val;
1406 }
1407
1408 /*------------------------------------------------------------------*/
1409 /* valCastLiteral - casts a literal value to another type           */
1410 /*------------------------------------------------------------------*/
1411 value *
1412 valCastLiteral (sym_link * dtype, double fval)
1413 {
1414   value *val;
1415
1416   if (!dtype)
1417     return NULL;
1418
1419   val = newValue ();
1420   val->etype = getSpec (val->type = copyLinkChain (dtype));
1421   SPEC_SCLS (val->etype) = S_LITERAL;
1422   /* if it is not a specifier then we can assume that */
1423   /* it will be an unsigned long                      */
1424   if (!IS_SPEC (val->type)) {
1425       SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1426       return val;
1427   }
1428
1429   if (SPEC_NOUN (val->etype) == V_FLOAT)
1430       SPEC_CVAL (val->etype).v_float = fval;
1431   else {
1432       unsigned long l = fval;
1433       if (SPEC_LONG (val->etype)) {
1434           if (SPEC_USIGN (val->etype))
1435               SPEC_CVAL (val->etype).v_ulong = (unsigned long) l;
1436           else
1437               SPEC_CVAL (val->etype).v_long = (long) l;
1438       } else {
1439           if (SPEC_USIGN (val->etype))
1440               SPEC_CVAL (val->etype).v_uint = (unsigned short)l;
1441           else
1442               SPEC_CVAL (val->etype).v_int = (short)l;
1443       }
1444   }
1445   return val;
1446 }
1447
1448 /*------------------------------------------------------------------*/
1449 /* getNelements - determines # of elements from init list           */
1450 /*------------------------------------------------------------------*/
1451 int 
1452 getNelements (sym_link * type, initList * ilist)
1453 {
1454   sym_link *etype = getSpec (type);
1455   int i;
1456
1457   if (!ilist)
1458     return 0;
1459
1460   while (ilist->type == INIT_DEEP)
1461     ilist = ilist->init.deep;
1462
1463   /* if type is a character array and there is only one
1464      (string) initialiser then get the length of the string */
1465   if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1466     {
1467       ast *iast = ilist->init.node;
1468       value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1469       if (!v)
1470         {
1471           werror (E_CONST_EXPECTED);
1472           return 0;
1473         }
1474
1475       if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1476         // yep, it's a string
1477         {
1478           return DCL_ELEM (v->type);
1479         }
1480     }
1481
1482   i = 0;
1483   while (ilist)
1484     {
1485       i++;
1486       ilist = ilist->next;
1487     }
1488
1489   return i;
1490 }
1491
1492 /*-----------------------------------------------------------------*/
1493 /* valForArray - returns a value with name of array index          */
1494 /*-----------------------------------------------------------------*/
1495 value *
1496 valForArray (ast * arrExpr)
1497 {
1498   value *val, *lval = NULL;
1499   char buffer[128];
1500   int size = getSize (arrExpr->left->ftype->next);
1501   /* if the right or left is an array
1502      resolve it first */
1503   if (IS_AST_OP (arrExpr->left))
1504     {
1505       if (arrExpr->left->opval.op == '[')
1506         lval = valForArray (arrExpr->left);
1507       else if (arrExpr->left->opval.op == '.')
1508         lval = valForStructElem (arrExpr->left->left,
1509                                  arrExpr->left->right);
1510       else if (arrExpr->left->opval.op == PTR_OP &&
1511                IS_ADDRESS_OF_OP (arrExpr->left->left))
1512         lval = valForStructElem (arrExpr->left->left->left,
1513                                  arrExpr->left->right);
1514       else
1515         return NULL;
1516
1517     }
1518   else if (!IS_AST_SYM_VALUE (arrExpr->left))
1519     return NULL;
1520
1521   if (!IS_AST_LIT_VALUE (arrExpr->right))
1522     return NULL;
1523
1524   val = newValue ();
1525   if (!lval)
1526     sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1527   else
1528     sprintf (buffer, "%s", lval->name);
1529
1530   sprintf (val->name, "(%s + %d)", buffer,
1531            (int) AST_LIT_VALUE (arrExpr->right) * size);
1532
1533   val->type = newLink ();
1534   if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1535     {
1536       DCL_TYPE (val->type) = CPOINTER;
1537       DCL_PTR_CONST (val->type) = port->mem.code_ro;
1538     }
1539   else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1540     DCL_TYPE (val->type) = FPOINTER;
1541   else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1542     DCL_TYPE (val->type) = PPOINTER;
1543   else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1544     DCL_TYPE (val->type) = IPOINTER;
1545   else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1546     DCL_TYPE (val->type) = EEPPOINTER;
1547   else
1548     DCL_TYPE (val->type) = POINTER;
1549   val->type->next = arrExpr->left->ftype;
1550   val->etype = getSpec (val->type);
1551   return val;
1552 }
1553
1554 /*-----------------------------------------------------------------*/
1555 /* valForStructElem - returns value with name of struct element    */
1556 /*-----------------------------------------------------------------*/
1557 value *
1558 valForStructElem (ast * structT, ast * elemT)
1559 {
1560   value *val, *lval = NULL;
1561   char buffer[128];
1562   symbol *sym;
1563
1564   /* left could be furthur derefed */
1565   if (IS_AST_OP (structT))
1566     {
1567       if (structT->opval.op == '[')
1568         lval = valForArray (structT);
1569       else if (structT->opval.op == '.')
1570         lval = valForStructElem (structT->left, structT->right);
1571       else if (structT->opval.op == PTR_OP &&
1572                IS_ADDRESS_OF_OP (structT->left))
1573         lval = valForStructElem (structT->left->left,
1574                                  structT->right);
1575       else
1576         return NULL;
1577     }
1578
1579   if (!IS_AST_SYM_VALUE (elemT))
1580     return NULL;
1581
1582   if (!IS_STRUCT (structT->etype))
1583     return NULL;
1584
1585   if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1586                                AST_SYMBOL (elemT))) == NULL)
1587     {
1588       return NULL;
1589     }
1590
1591   val = newValue ();
1592   if (!lval)
1593     sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1594   else
1595     sprintf (buffer, "%s", lval->name);
1596
1597   sprintf (val->name, "(%s + %d)", buffer,
1598            (int) sym->offset);
1599
1600   val->type = newLink ();
1601   if (SPEC_SCLS (structT->etype) == S_CODE)
1602     {
1603       DCL_TYPE (val->type) = CPOINTER;
1604       DCL_PTR_CONST (val->type) = port->mem.code_ro;
1605     }
1606   else if (SPEC_SCLS (structT->etype) == S_XDATA)
1607     DCL_TYPE (val->type) = FPOINTER;
1608   else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1609     DCL_TYPE (val->type) = PPOINTER;
1610   else if (SPEC_SCLS (structT->etype) == S_IDATA)
1611     DCL_TYPE (val->type) = IPOINTER;
1612   else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1613     DCL_TYPE (val->type) = EEPPOINTER;
1614   else
1615     DCL_TYPE (val->type) = POINTER;
1616   val->type->next = sym->type;
1617   val->etype = getSpec (val->type);
1618   return val;
1619 }
1620
1621 /*-----------------------------------------------------------------*/
1622 /* valForCastAggr - will return value for a cast of an aggregate   */
1623 /*                  plus minus a constant                          */
1624 /*-----------------------------------------------------------------*/
1625 value *
1626 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1627 {
1628   value *val;
1629
1630   if (!IS_AST_SYM_VALUE (aexpr))
1631     return NULL;
1632   if (!IS_AST_LIT_VALUE (cnst))
1633     return NULL;
1634
1635   val = newValue ();
1636
1637   sprintf (val->name, "(%s %c %d)",
1638            AST_SYMBOL (aexpr)->rname, op,
1639            getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1640
1641   val->type = type;
1642   val->etype = getSpec (val->type);
1643   return val;
1644 }
1645
1646 /*-----------------------------------------------------------------*/
1647 /* valForCastAggr - will return value for a cast of an aggregate   */
1648 /*                  with no constant                               */
1649 /*-----------------------------------------------------------------*/
1650 value *
1651 valForCastArr (ast * aexpr, sym_link * type)
1652 {
1653   value *val;
1654
1655   if (!IS_AST_SYM_VALUE (aexpr))
1656     return NULL;
1657
1658   val = newValue ();
1659
1660   sprintf (val->name, "(%s)",
1661            AST_SYMBOL (aexpr)->rname);
1662
1663   val->type = type;
1664   val->etype = getSpec (val->type);
1665   return val;
1666 }