made one more function "static"
[fw/sdcc] / src / SDCCast.c
1 /*-------------------------------------------------------------------------
2   SDCCast.c - source file for parser support & all ast related routines
3
4              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20    In other words, you are welcome to use, share and improve this program.
21    You are forbidden to forbid anyone else to use, share and improve
22    what you give them.   Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
24
25 #include "common.h"
26
27 int currLineno = 0;
28 set *astList = NULL;
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
31 int labelKey = 1;
32
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
45 #define ALLOCATE 1
46 #define DEALLOCATE 2
47
48 int noLineno = 0;
49 int noAlloc = 0;
50 symbol *currFunc;
51 static ast *createIval (ast *, sym_link *, initList *, ast *);
52 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
53 static ast *optimizeCompare (ast *);
54 ast *optimizeRRCRLC (ast *);
55 ast *optimizeGetHbit (ast *);
56 ast *backPatchLabels (ast *, symbol *, symbol *);
57 void PA(ast *t);
58 int inInitMode = 0;
59 memmap *GcurMemmap=NULL;  /* points to the memmap that's currently active */
60 FILE *codeOutFile;
61 int 
62 ptt (ast * tree)
63 {
64   printTypeChain (tree->ftype, stdout);
65   return 0;
66 }
67
68
69 /*-----------------------------------------------------------------*/
70 /* newAst - creates a fresh node for an expression tree            */
71 /*-----------------------------------------------------------------*/
72 static ast *
73 newAst_ (unsigned type)
74 {
75   ast *ex;
76   static int oldLineno = 0;
77
78   ex = Safe_alloc ( sizeof (ast));
79
80   ex->type = type;
81   ex->lineno = (noLineno ? oldLineno : yylineno);
82   ex->filename = currFname;
83   ex->level = NestLevel;
84   ex->block = currBlockno;
85   ex->initMode = inInitMode;
86   return ex;
87 }
88
89 ast *
90 newAst_VALUE (value * val)
91 {
92   ast *ex = newAst_ (EX_VALUE);
93   ex->opval.val = val;
94   return ex;
95 }
96
97 ast *
98 newAst_OP (unsigned op)
99 {
100   ast *ex = newAst_ (EX_OP);
101   ex->opval.op = op;
102   return ex;
103 }
104
105 ast *
106 newAst_LINK (sym_link * val)
107 {
108   ast *ex = newAst_ (EX_LINK);
109   ex->opval.lnk = val;
110   return ex;
111 }
112
113 ast *
114 newAst_STMNT (unsigned val)
115 {
116   ast *ex = newAst_ (EX_STMNT);
117   ex->opval.stmnt = val;
118   return ex;
119 }
120
121 /*-----------------------------------------------------------------*/
122 /* newNode - creates a new node                                    */
123 /*-----------------------------------------------------------------*/
124 ast *
125 newNode (long op, ast * left, ast * right)
126 {
127   ast *ex;
128
129   ex = newAst_OP (op);
130   ex->left = left;
131   ex->right = right;
132
133   return ex;
134 }
135
136 /*-----------------------------------------------------------------*/
137 /* newIfxNode - creates a new Ifx Node                             */
138 /*-----------------------------------------------------------------*/
139 ast *
140 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
141 {
142   ast *ifxNode;
143
144   /* if this is a literal then we already know the result */
145   if (condAst->etype && IS_LITERAL (condAst->etype))
146     {
147       /* then depending on the expression value */
148       if (floatFromVal (condAst->opval.val))
149         ifxNode = newNode (GOTO,
150                            newAst_VALUE (symbolVal (trueLabel)),
151                            NULL);
152       else
153         ifxNode = newNode (GOTO,
154                            newAst_VALUE (symbolVal (falseLabel)),
155                            NULL);
156     }
157   else
158     {
159       ifxNode = newNode (IFX, condAst, NULL);
160       ifxNode->trueLabel = trueLabel;
161       ifxNode->falseLabel = falseLabel;
162     }
163
164   return ifxNode;
165 }
166
167 /*-----------------------------------------------------------------*/
168 /* copyAstValues - copies value portion of ast if needed     */
169 /*-----------------------------------------------------------------*/
170 void 
171 copyAstValues (ast * dest, ast * src)
172 {
173   switch (src->opval.op)
174     {
175     case BLOCK:
176       dest->values.sym = copySymbolChain (src->values.sym);
177       break;
178
179     case SWITCH:
180       dest->values.switchVals.swVals =
181         copyValue (src->values.switchVals.swVals);
182       dest->values.switchVals.swDefault =
183         src->values.switchVals.swDefault;
184       dest->values.switchVals.swNum =
185         src->values.switchVals.swNum;
186       break;
187
188     case INLINEASM:
189       dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
190       strcpy (dest->values.inlineasm, src->values.inlineasm);
191       break;
192
193     case ARRAYINIT:
194         dest->values.constlist = copyLiteralList(src->values.constlist);
195         break;
196         
197     case FOR:
198       AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
199       AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
200       AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
201       AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
202       AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
203       AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
204       AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
205     }
206
207 }
208
209 /*-----------------------------------------------------------------*/
210 /* copyAst - makes a copy of a given astession                     */
211 /*-----------------------------------------------------------------*/
212 ast *
213 copyAst (ast * src)
214 {
215   ast *dest;
216
217   if (!src)
218     return NULL;
219
220   dest = Safe_alloc ( sizeof (ast));
221
222   dest->type = src->type;
223   dest->lineno = src->lineno;
224   dest->level = src->level;
225   dest->funcName = src->funcName;
226
227   if (src->ftype)
228     dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
229
230   /* if this is a leaf */
231   /* if value */
232   if (src->type == EX_VALUE)
233     {
234       dest->opval.val = copyValue (src->opval.val);
235       goto exit;
236     }
237
238   /* if link */
239   if (src->type == EX_LINK)
240     {
241       dest->opval.lnk = copyLinkChain (src->opval.lnk);
242       goto exit;
243     }
244
245   dest->opval.op = src->opval.op;
246
247   /* if this is a node that has special values */
248   copyAstValues (dest, src);
249
250   dest->trueLabel = copySymbol (src->trueLabel);
251   dest->falseLabel = copySymbol (src->falseLabel);
252   dest->left = copyAst (src->left);
253   dest->right = copyAst (src->right);
254 exit:
255   return dest;
256
257 }
258
259 /*-----------------------------------------------------------------*/
260 /* hasSEFcalls - returns TRUE if tree has a function call          */
261 /*-----------------------------------------------------------------*/
262 bool 
263 hasSEFcalls (ast * tree)
264 {
265   if (!tree)
266     return FALSE;
267
268   if (tree->type == EX_OP &&
269       (tree->opval.op == CALL ||
270        tree->opval.op == PCALL ||
271        tree->opval.op == '=' ||
272        tree->opval.op == INC_OP ||
273        tree->opval.op == DEC_OP))
274     return TRUE;
275
276   return (hasSEFcalls (tree->left) |
277           hasSEFcalls (tree->right));
278 }
279
280 /*-----------------------------------------------------------------*/
281 /* isAstEqual - compares two asts & returns 1 if they are equal    */
282 /*-----------------------------------------------------------------*/
283 int 
284 isAstEqual (ast * t1, ast * t2)
285 {
286   if (!t1 && !t2)
287     return 1;
288
289   if (!t1 || !t2)
290     return 0;
291
292   /* match type */
293   if (t1->type != t2->type)
294     return 0;
295
296   switch (t1->type)
297     {
298     case EX_OP:
299       if (t1->opval.op != t2->opval.op)
300         return 0;
301       return (isAstEqual (t1->left, t2->left) &&
302               isAstEqual (t1->right, t2->right));
303       break;
304
305     case EX_VALUE:
306       if (t1->opval.val->sym)
307         {
308           if (!t2->opval.val->sym)
309             return 0;
310           else
311             return isSymbolEqual (t1->opval.val->sym,
312                                   t2->opval.val->sym);
313         }
314       else
315         {
316           if (t2->opval.val->sym)
317             return 0;
318           else
319             return (floatFromVal (t1->opval.val) ==
320                     floatFromVal (t2->opval.val));
321         }
322       break;
323
324       /* only compare these two types */
325     default:
326       return 0;
327     }
328
329   return 0;
330 }
331
332 /*-----------------------------------------------------------------*/
333 /* resolveSymbols - resolve symbols from the symbol table          */
334 /*-----------------------------------------------------------------*/
335 ast *
336 resolveSymbols (ast * tree)
337 {
338   /* walk the entire tree and check for values */
339   /* with symbols if we find one then replace  */
340   /* symbol with that from the symbol table    */
341
342   if (tree == NULL)
343     return tree;
344
345   /* print the line          */
346   /* if not block & function */
347   if (tree->type == EX_OP &&
348       (tree->opval.op != FUNCTION &&
349        tree->opval.op != BLOCK &&
350        tree->opval.op != NULLOP))
351     {
352       filename = tree->filename;
353       lineno = tree->lineno;
354     }
355
356   /* make sure we resolve the true & false labels for ifx */
357   if (tree->type == EX_OP && tree->opval.op == IFX)
358     {
359       symbol *csym;
360
361       if (tree->trueLabel)
362         {
363           if ((csym = findSym (LabelTab, tree->trueLabel,
364                                tree->trueLabel->name)))
365             tree->trueLabel = csym;
366           else
367             werror (E_LABEL_UNDEF, tree->trueLabel->name);
368         }
369
370       if (tree->falseLabel)
371         {
372           if ((csym = findSym (LabelTab,
373                                tree->falseLabel,
374                                tree->falseLabel->name)))
375             tree->falseLabel = csym;
376           else
377             werror (E_LABEL_UNDEF, tree->falseLabel->name);
378         }
379
380     }
381
382   /* if this is a label resolve it from the labelTab */
383   if (IS_AST_VALUE (tree) &&
384       tree->opval.val->sym &&
385       tree->opval.val->sym->islbl)
386     {
387
388       symbol *csym = findSym (LabelTab, tree->opval.val->sym,
389                               tree->opval.val->sym->name);
390
391       if (!csym)
392         werror (E_LABEL_UNDEF, tree->opval.val->sym->name);
393       else
394         tree->opval.val->sym = csym;
395
396       goto resolveChildren;
397     }
398
399   /* do only for leafs */
400   if (IS_AST_VALUE (tree) &&
401       tree->opval.val->sym &&
402       !tree->opval.val->sym->implicit)
403     {
404
405       symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
406
407       /* if found in the symbol table & they r not the same */
408       if (csym && tree->opval.val->sym != csym)
409         {
410           tree->opval.val->sym = csym;
411           tree->opval.val->type = csym->type;
412           tree->opval.val->etype = csym->etype;
413         }
414
415       /* if not found in the symbol table */
416       /* mark it as undefined assume it is */
417       /* an integer in data space         */
418       if (!csym && !tree->opval.val->sym->implicit)
419         {
420
421           /* if this is a function name then */
422           /* mark it as returning an int     */
423           if (tree->funcName)
424             {
425               tree->opval.val->sym->type = newLink ();
426               DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
427               tree->opval.val->sym->type->next =
428                 tree->opval.val->sym->etype = newIntLink ();
429               tree->opval.val->etype = tree->opval.val->etype;
430               tree->opval.val->type = tree->opval.val->sym->type;
431               werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name);
432               allocVariables (tree->opval.val->sym);
433             }
434           else
435             {
436               tree->opval.val->sym->undefined = 1;
437               tree->opval.val->type =
438                 tree->opval.val->etype = newIntLink ();
439               tree->opval.val->sym->type =
440                 tree->opval.val->sym->etype = newIntLink ();
441             }
442         }
443     }
444
445 resolveChildren:
446   resolveSymbols (tree->left);
447   resolveSymbols (tree->right);
448
449   return tree;
450 }
451
452 /*-----------------------------------------------------------------*/
453 /* setAstLineno - walks a ast tree & sets the line number          */
454 /*-----------------------------------------------------------------*/
455 int 
456 setAstLineno (ast * tree, int lineno)
457 {
458   if (!tree)
459     return 0;
460
461   tree->lineno = lineno;
462   setAstLineno (tree->left, lineno);
463   setAstLineno (tree->right, lineno);
464   return 0;
465 }
466
467 /*-----------------------------------------------------------------*/
468 /* funcOfType :- function of type with name                        */
469 /*-----------------------------------------------------------------*/
470 symbol *
471 funcOfType (char *name, sym_link * type, sym_link * argType,
472             int nArgs, int rent)
473 {
474   symbol *sym;
475   /* create the symbol */
476   sym = newSymbol (name, 0);
477
478   /* setup return value */
479   sym->type = newLink ();
480   DCL_TYPE (sym->type) = FUNCTION;
481   sym->type->next = copyLinkChain (type);
482   sym->etype = getSpec (sym->type);
483   FUNC_ISREENT(sym->type) = rent;
484
485   /* if arguments required */
486   if (nArgs)
487     {
488       value *args;
489       args = FUNC_ARGS(sym->type) = newValue ();
490
491       while (nArgs--)
492         {
493           args->type = copyLinkChain (argType);
494           args->etype = getSpec (args->type);
495           SPEC_EXTR(args->etype)=1;
496           if (!nArgs)
497             break;
498           args = args->next = newValue ();
499         }
500     }
501
502   /* save it */
503   addSymChain (sym);
504   sym->cdef = 1;
505   allocVariables (sym);
506   return sym;
507
508 }
509
510 /*-----------------------------------------------------------------*/
511 /* funcOfTypeVarg :- function of type with name and argtype        */
512 /*-----------------------------------------------------------------*/
513 symbol *
514 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
515 {
516   
517     symbol *sym;
518     int i ;
519     /* create the symbol */
520     sym = newSymbol (name, 0);
521     
522     /* setup return value */
523     sym->type = newLink ();
524     DCL_TYPE (sym->type) = FUNCTION;
525     sym->type->next = typeFromStr(rtype);
526     sym->etype = getSpec (sym->type);
527     
528     /* if arguments required */
529     if (nArgs) {
530         value *args;
531         args = FUNC_ARGS(sym->type) = newValue ();
532         
533         for ( i = 0 ; i < nArgs ; i++ ) {
534             args->type = typeFromStr(atypes[i]);
535             args->etype = getSpec (args->type);
536             SPEC_EXTR(args->etype)=1;
537             if ((i + 1) == nArgs) break;
538             args = args->next = newValue ();
539         }
540     }
541     
542     /* save it */
543     addSymChain (sym);
544     sym->cdef = 1;
545     allocVariables (sym);
546     return sym;
547
548 }
549
550 /*-----------------------------------------------------------------*/
551 /* reverseParms - will reverse a parameter tree                    */
552 /*-----------------------------------------------------------------*/
553 static void 
554 reverseParms (ast * ptree)
555 {
556   ast *ttree;
557   if (!ptree)
558     return;
559
560   /* top down if we find a nonParm tree then quit */
561   if (ptree->type == EX_OP && ptree->opval.op == PARAM)
562     {
563       ttree = ptree->left;
564       ptree->left = ptree->right;
565       ptree->right = ttree;
566       reverseParms (ptree->left);
567       reverseParms (ptree->right);
568     }
569
570   return;
571 }
572
573 /*-----------------------------------------------------------------*/
574 /* processParms  - makes sure the parameters are okay and do some  */
575 /*                 processing with them                            */
576 /*-----------------------------------------------------------------*/
577 int 
578 processParms (ast * func,
579               value *defParm,
580               ast * actParm,
581               int *parmNumber, // unused, although updated
582               bool rightmost)
583 {
584   /* if none of them exist */
585   if (!defParm && !actParm)
586     return 0;
587
588   if (defParm) {
589     if (getenv("DEBUG_SANITY")) {
590       fprintf (stderr, "processParms: %s ", defParm->name);
591     }
592     /* make sure the type is complete and sane */
593     checkTypeSanity(defParm->etype, defParm->name);
594   }
595
596   /* if the function is being called via a pointer &   */
597   /* it has not been defined a reentrant then we cannot */
598   /* have parameters                                   */
599   if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
600     {
601       werror (W_NONRENT_ARGS);
602       return 1;
603     }
604
605   /* if defined parameters ended but actual parameters */
606   /* exist and this is not defined as a variable arg   */
607   if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
608     {
609       werror (E_TOO_MANY_PARMS);
610       return 1;
611     }
612
613   /* if defined parameters present but no actual parameters */
614   if (defParm && !actParm)
615     {
616       werror (E_TOO_FEW_PARMS);
617       return 1;
618     }
619
620   if (IS_VOID(actParm->ftype)) {
621     werror (E_VOID_VALUE_USED);
622     return 1;
623   }
624
625   /* If this is a varargs function... */
626   if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
627     {
628       ast *newType = NULL;
629       sym_link *ftype;
630
631       if (IS_CAST_OP (actParm)
632           || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
633         {
634           /* Parameter was explicitly typecast; don't touch it. */
635           return 0;
636         }
637
638       ftype = actParm->ftype;
639           
640       /* If it's a small integer, upcast to int. */
641       if (IS_INTEGRAL (ftype)
642           && (getSize (ftype) < (unsigned) INTSIZE))
643         {
644           newType = newAst_LINK(INTTYPE);
645         }
646
647       if (IS_PTR(ftype) && !IS_GENPTR(ftype))
648         {
649           newType = newAst_LINK (copyLinkChain(ftype));
650           DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
651         }
652
653       if (IS_AGGREGATE (ftype))
654         {
655           newType = newAst_LINK (copyLinkChain (ftype));
656           DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
657         }
658       if (newType)
659         {
660           /* cast required; change this op to a cast. */
661           ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
662
663           actParm->type = EX_OP;
664           actParm->opval.op = CAST;
665           actParm->left = newType;
666           actParm->right = parmCopy;
667           decorateType (actParm);
668         }
669       else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
670         {
671           return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
672           processParms (func, NULL, actParm->right, parmNumber, rightmost));
673         }
674       return 0;
675     }
676
677   /* if defined parameters ended but actual has not & */
678   /* reentrant */
679   if (!defParm && actParm &&
680       (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
681     return 0;
682
683   resolveSymbols (actParm);
684   /* if this is a PARAM node then match left & right */
685   if (actParm->type == EX_OP && actParm->opval.op == PARAM)
686     {
687       return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
688               processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
689     }
690   else
691     {
692       /* If we have found a value node by following only right-hand links,
693        * then we know that there are no more values after us.
694        *
695        * Therefore, if there are more defined parameters, the caller didn't
696        * supply enough.
697        */
698       if (rightmost && defParm->next)
699         {
700           werror (E_TOO_FEW_PARMS);
701           return 1;
702         }
703     }
704
705   /* the parameter type must be at least castable */
706   if (compareType (defParm->type, actParm->ftype) == 0) {
707     werror (E_INCOMPAT_TYPES);
708     printFromToType (actParm->ftype, defParm->type);
709     return 1;
710   }
711
712   /* if the parameter is castable then add the cast */
713   if (compareType (defParm->type, actParm->ftype) < 0)
714     {
715       ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
716
717       /* now change the current one to a cast */
718       actParm->type = EX_OP;
719       actParm->opval.op = CAST;
720       actParm->left = newAst_LINK (defParm->type);
721       actParm->right = pTree;
722       actParm->etype = defParm->etype;
723       actParm->ftype = defParm->type;
724       actParm->decorated=0; /* force typechecking */
725       decorateType (actParm);
726     }
727
728   /* make a copy and change the regparm type to the defined parm */
729   actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
730   SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
731   (*parmNumber)++;
732   return 0;
733 }
734 /*-----------------------------------------------------------------*/
735 /* createIvalType - generates ival for basic types                 */
736 /*-----------------------------------------------------------------*/
737 static ast *
738 createIvalType (ast * sym, sym_link * type, initList * ilist)
739 {
740   ast *iExpr;
741
742   /* if initList is deep */
743   if (ilist->type == INIT_DEEP)
744     ilist = ilist->init.deep;
745
746   iExpr = decorateType (resolveSymbols (list2expr (ilist)));
747   return decorateType (newNode ('=', sym, iExpr));
748 }
749
750 /*-----------------------------------------------------------------*/
751 /* createIvalStruct - generates initial value for structures       */
752 /*-----------------------------------------------------------------*/
753 static ast *
754 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
755 {
756   ast *rast = NULL;
757   ast *lAst;
758   symbol *sflds;
759   initList *iloop;
760
761   sflds = SPEC_STRUCT (type)->fields;
762   if (ilist->type != INIT_DEEP)
763     {
764       werror (E_INIT_STRUCT, "");
765       return NULL;
766     }
767
768   iloop = ilist->init.deep;
769
770   for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
771     {
772       /* if we have come to end */
773       if (!iloop)
774         break;
775       sflds->implicit = 1;
776       lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
777       lAst = decorateType (resolveSymbols (lAst));
778       rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
779     }
780
781   if (iloop) {
782     werror (W_EXCESS_INITIALIZERS, "struct", 
783             sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
784   }
785
786   return rast;
787 }
788
789
790 /*-----------------------------------------------------------------*/
791 /* createIvalArray - generates code for array initialization       */
792 /*-----------------------------------------------------------------*/
793 static ast *
794 createIvalArray (ast * sym, sym_link * type, initList * ilist)
795 {
796   ast *rast = NULL;
797   initList *iloop;
798   int lcnt = 0, size = 0;
799   literalList *literalL;
800
801   /* take care of the special   case  */
802   /* array of characters can be init  */
803   /* by a string                      */
804   if (IS_CHAR (type->next))
805     if ((rast = createIvalCharPtr (sym,
806                                    type,
807                         decorateType (resolveSymbols (list2expr (ilist))))))
808
809       return decorateType (resolveSymbols (rast));
810
811     /* not the special case             */
812     if (ilist->type != INIT_DEEP)
813     {
814         werror (E_INIT_STRUCT, "");
815         return NULL;
816     }
817
818     iloop = ilist->init.deep;
819     lcnt = DCL_ELEM (type);
820
821     if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
822     {
823         ast *aSym;
824
825         aSym = decorateType (resolveSymbols(sym));
826         
827         rast = newNode(ARRAYINIT, aSym, NULL);
828         rast->values.constlist = literalL;
829         
830         // Make sure size is set to length of initializer list.
831         while (iloop)
832         {
833             size++;
834             iloop = iloop->next;
835         }
836         
837         if (lcnt && size > lcnt)
838         {
839             // Array size was specified, and we have more initializers than needed.
840             char *name=sym->opval.val->sym->name;
841             int lineno=sym->opval.val->sym->lineDef;
842             
843             werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
844         }
845     }
846     else
847     {
848         for (;;)
849         {
850             ast *aSym;
851             
852             aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
853             aSym = decorateType (resolveSymbols (aSym));
854             rast = createIval (aSym, type->next, iloop, rast);
855             iloop = (iloop ? iloop->next : NULL);
856             if (!iloop)
857             {
858                 break;
859             }
860             
861             /* no of elements given and we    */
862             /* have generated for all of them */
863             if (!--lcnt) 
864             {
865                 // there has to be a better way
866                 char *name=sym->opval.val->sym->name;
867                 int lineno=sym->opval.val->sym->lineDef;
868                 werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
869                 
870                 break;
871             }
872         }
873     }
874
875     /* if we have not been given a size  */
876     if (!DCL_ELEM (type))
877     {
878         DCL_ELEM (type) = size;
879     }
880
881     return decorateType (resolveSymbols (rast));
882 }
883
884
885 /*-----------------------------------------------------------------*/
886 /* createIvalCharPtr - generates initial values for char pointers  */
887 /*-----------------------------------------------------------------*/
888 static ast *
889 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
890 {
891   ast *rast = NULL;
892
893   /* if this is a pointer & right is a literal array then */
894   /* just assignment will do                              */
895   if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
896                          SPEC_SCLS (iexpr->etype) == S_CODE)
897                         && IS_ARRAY (iexpr->ftype)))
898     return newNode ('=', sym, iexpr);
899
900   /* left side is an array so we have to assign each */
901   /* element                                         */
902   if ((IS_LITERAL (iexpr->etype) ||
903        SPEC_SCLS (iexpr->etype) == S_CODE)
904       && IS_ARRAY (iexpr->ftype))
905     {
906       /* for each character generate an assignment */
907       /* to the array element */
908       char *s = SPEC_CVAL (iexpr->etype).v_char;
909       int i = 0;
910
911       while (*s)
912         {
913           rast = newNode (NULLOP,
914                           rast,
915                           newNode ('=',
916                                    newNode ('[', sym,
917                                    newAst_VALUE (valueFromLit ((float) i))),
918                                    newAst_VALUE (valueFromLit (*s))));
919           i++;
920           s++;
921         }
922       rast = newNode (NULLOP,
923                       rast,
924                       newNode ('=',
925                                newNode ('[', sym,
926                                    newAst_VALUE (valueFromLit ((float) i))),
927                                newAst_VALUE (valueFromLit (*s))));
928       return decorateType (resolveSymbols (rast));
929     }
930
931   return NULL;
932 }
933
934 /*-----------------------------------------------------------------*/
935 /* createIvalPtr - generates initial value for pointers            */
936 /*-----------------------------------------------------------------*/
937 static ast *
938 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
939 {
940   ast *rast;
941   ast *iexpr;
942
943   /* if deep then   */
944   if (ilist->type == INIT_DEEP)
945     ilist = ilist->init.deep;
946
947   iexpr = decorateType (resolveSymbols (list2expr (ilist)));
948
949   /* if character pointer */
950   if (IS_CHAR (type->next))
951     if ((rast = createIvalCharPtr (sym, type, iexpr)))
952       return rast;
953
954   return newNode ('=', sym, iexpr);
955 }
956
957 /*-----------------------------------------------------------------*/
958 /* createIval - generates code for initial value                   */
959 /*-----------------------------------------------------------------*/
960 static ast *
961 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
962 {
963   ast *rast = NULL;
964
965   if (!ilist)
966     return NULL;
967
968   /* if structure then    */
969   if (IS_STRUCT (type))
970     rast = createIvalStruct (sym, type, ilist);
971   else
972     /* if this is a pointer */
973   if (IS_PTR (type))
974     rast = createIvalPtr (sym, type, ilist);
975   else
976     /* if this is an array   */
977   if (IS_ARRAY (type))
978     rast = createIvalArray (sym, type, ilist);
979   else
980     /* if type is SPECIFIER */
981   if (IS_SPEC (type))
982     rast = createIvalType (sym, type, ilist);
983   
984   if (wid)
985     return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
986   else
987     return decorateType (resolveSymbols (rast));
988 }
989
990 /*-----------------------------------------------------------------*/
991 /* initAggregates - initialises aggregate variables with initv     */
992 /*-----------------------------------------------------------------*/
993 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
994   return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
995 }
996
997 /*-----------------------------------------------------------------*/
998 /* gatherAutoInit - creates assignment expressions for initial     */
999 /*    values                 */
1000 /*-----------------------------------------------------------------*/
1001 static ast *
1002 gatherAutoInit (symbol * autoChain)
1003 {
1004   ast *init = NULL;
1005   ast *work;
1006   symbol *sym;
1007
1008   inInitMode = 1;
1009   for (sym = autoChain; sym; sym = sym->next)
1010     {
1011
1012       /* resolve the symbols in the ival */
1013       if (sym->ival)
1014         resolveIvalSym (sym->ival);
1015
1016       /* if this is a static variable & has an */
1017       /* initial value the code needs to be lifted */
1018       /* here to the main portion since they can be */
1019       /* initialised only once at the start    */
1020       if (IS_STATIC (sym->etype) && sym->ival &&
1021           SPEC_SCLS (sym->etype) != S_CODE)
1022         {
1023           symbol *newSym;
1024           
1025           /* insert the symbol into the symbol table */
1026           /* with level = 0 & name = rname       */
1027           newSym = copySymbol (sym);
1028           addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1029
1030           /* now lift the code to main */
1031           if (IS_AGGREGATE (sym->type)) {
1032             work = initAggregates (sym, sym->ival, NULL);
1033           } else {
1034             if (getNelements(sym->type, sym->ival)>1) {
1035               werror (W_EXCESS_INITIALIZERS, "scalar", 
1036                       sym->name, sym->lineDef);
1037             }
1038             work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1039                             list2expr (sym->ival));
1040           }
1041
1042           setAstLineno (work, sym->lineDef);
1043
1044           sym->ival = NULL;
1045           if (staticAutos)
1046             staticAutos = newNode (NULLOP, staticAutos, work);
1047           else
1048             staticAutos = work;
1049
1050           continue;
1051         }
1052
1053       /* if there is an initial value */
1054       if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1055         {
1056           if (IS_AGGREGATE (sym->type)) {
1057             work = initAggregates (sym, sym->ival, NULL);
1058           } else {
1059             if (getNelements(sym->type, sym->ival)>1) {
1060               werror (W_EXCESS_INITIALIZERS, "scalar", 
1061                       sym->name, sym->lineDef);
1062             }
1063             work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1064                             list2expr (sym->ival));
1065           }
1066
1067           setAstLineno (work, sym->lineDef);
1068           sym->ival = NULL;
1069           if (init)
1070             init = newNode (NULLOP, init, work);
1071           else
1072             init = work;
1073         }
1074     }
1075   inInitMode = 0;
1076   return init;
1077 }
1078
1079 /*-----------------------------------------------------------------*/
1080 /* stringToSymbol - creates a symbol from a literal string         */
1081 /*-----------------------------------------------------------------*/
1082 static value *
1083 stringToSymbol (value * val)
1084 {
1085   char name[SDCC_NAME_MAX + 1];
1086   static int charLbl = 0;
1087   symbol *sym;
1088
1089   sprintf (name, "_str_%d", charLbl++);
1090   sym = newSymbol (name, 0);    /* make it @ level 0 */
1091   strcpy (sym->rname, name);
1092
1093   /* copy the type from the value passed */
1094   sym->type = copyLinkChain (val->type);
1095   sym->etype = getSpec (sym->type);
1096   /* change to storage class & output class */
1097   SPEC_SCLS (sym->etype) = S_CODE;
1098   SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1099   SPEC_STAT (sym->etype) = 1;
1100   /* make the level & block = 0 */
1101   sym->block = sym->level = 0;
1102   sym->isstrlit = 1;
1103   /* create an ival */
1104   sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1105   if (noAlloc == 0)
1106     {
1107       /* allocate it */
1108       addSymChain (sym);
1109       allocVariables (sym);
1110     }
1111   sym->ival = NULL;
1112   return symbolVal (sym);
1113
1114 }
1115
1116 /*-----------------------------------------------------------------*/
1117 /* processBlockVars - will go thru the ast looking for block if    */
1118 /*                    a block is found then will allocate the syms */
1119 /*                    will also gather the auto inits present      */
1120 /*-----------------------------------------------------------------*/
1121 ast *
1122 processBlockVars (ast * tree, int *stack, int action)
1123 {
1124   if (!tree)
1125     return NULL;
1126
1127   /* if this is a block */
1128   if (tree->type == EX_OP && tree->opval.op == BLOCK)
1129     {
1130       ast *autoInit;
1131
1132       if (action == ALLOCATE)
1133         {
1134           *stack += allocVariables (tree->values.sym);
1135           autoInit = gatherAutoInit (tree->values.sym);
1136
1137           /* if there are auto inits then do them */
1138           if (autoInit)
1139             tree->left = newNode (NULLOP, autoInit, tree->left);
1140         }
1141       else                      /* action is deallocate */
1142         deallocLocal (tree->values.sym);
1143     }
1144
1145   processBlockVars (tree->left, stack, action);
1146   processBlockVars (tree->right, stack, action);
1147   return tree;
1148 }
1149
1150 /*-------------------------------------------------------------*/
1151 /* constExprTree - returns TRUE if this tree is a constant     */
1152 /*                 expression                                  */
1153 /*-------------------------------------------------------------*/
1154 bool constExprTree (ast *cexpr) {
1155
1156   if (!cexpr) {
1157     return TRUE;
1158   }
1159
1160   cexpr = decorateType (resolveSymbols (cexpr));
1161   
1162   switch (cexpr->type) 
1163     {
1164     case EX_VALUE:
1165       return (IS_AST_LIT_VALUE(cexpr));
1166     case EX_LINK:
1167       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1168               "unexpected link in expression tree\n");
1169       return FALSE;
1170     case EX_OP:
1171       if (cexpr->opval.op==CAST) {
1172         // jwk: cast ignored, maybe we should throw a warning here
1173         return constExprTree(cexpr->right);
1174       }
1175       if (cexpr->opval.op=='&') { 
1176         return TRUE;
1177       }
1178       if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1179         return FALSE;
1180       }
1181       if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1182         return TRUE;
1183       }
1184     }
1185   return FALSE;
1186 }  
1187     
1188 /*-----------------------------------------------------------------*/
1189 /* constExprValue - returns the value of a constant expression     */
1190 /*                  or NULL if it is not a constant expression     */
1191 /*-----------------------------------------------------------------*/
1192 value *
1193 constExprValue (ast * cexpr, int check)
1194 {
1195   cexpr = decorateType (resolveSymbols (cexpr));
1196
1197   /* if this is not a constant then */
1198   if (!IS_LITERAL (cexpr->ftype))
1199     {
1200       /* then check if this is a literal array
1201          in code segment */
1202       if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1203           SPEC_CVAL (cexpr->etype).v_char &&
1204           IS_ARRAY (cexpr->ftype))
1205         {
1206           value *val = valFromType (cexpr->ftype);
1207           SPEC_SCLS (val->etype) = S_LITERAL;
1208           val->sym = cexpr->opval.val->sym;
1209           val->sym->type = copyLinkChain (cexpr->ftype);
1210           val->sym->etype = getSpec (val->sym->type);
1211           strcpy (val->name, cexpr->opval.val->sym->rname);
1212           return val;
1213         }
1214
1215       /* if we are casting a literal value then */
1216       if (IS_AST_OP (cexpr) &&
1217           cexpr->opval.op == CAST &&
1218           IS_LITERAL (cexpr->left->ftype))
1219         return valCastLiteral (cexpr->ftype,
1220                                floatFromVal (cexpr->left->opval.val));
1221
1222       if (IS_AST_VALUE (cexpr))
1223         return cexpr->opval.val;
1224
1225       if (check)
1226         werror (E_CONST_EXPECTED, "found expression");
1227
1228       return NULL;
1229     }
1230
1231   /* return the value */
1232   return cexpr->opval.val;
1233
1234 }
1235
1236 /*-----------------------------------------------------------------*/
1237 /* isLabelInAst - will return true if a given label is found       */
1238 /*-----------------------------------------------------------------*/
1239 bool 
1240 isLabelInAst (symbol * label, ast * tree)
1241 {
1242   if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1243     return FALSE;
1244
1245   if (IS_AST_OP (tree) &&
1246       tree->opval.op == LABEL &&
1247       isSymbolEqual (AST_SYMBOL (tree->left), label))
1248     return TRUE;
1249
1250   return isLabelInAst (label, tree->right) &&
1251     isLabelInAst (label, tree->left);
1252
1253 }
1254
1255 /*-----------------------------------------------------------------*/
1256 /* isLoopCountable - return true if the loop count can be determi- */
1257 /* -ned at compile time .                                          */
1258 /*-----------------------------------------------------------------*/
1259 bool 
1260 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1261                  symbol ** sym, ast ** init, ast ** end)
1262 {
1263
1264   /* the loop is considered countable if the following
1265      conditions are true :-
1266
1267      a) initExpr :- <sym> = <const>
1268      b) condExpr :- <sym> < <const1>
1269      c) loopExpr :- <sym> ++
1270    */
1271
1272   /* first check the initExpr */
1273   if (IS_AST_OP (initExpr) &&
1274       initExpr->opval.op == '=' &&      /* is assignment */
1275       IS_AST_SYM_VALUE (initExpr->left))
1276     {                           /* left is a symbol */
1277
1278       *sym = AST_SYMBOL (initExpr->left);
1279       *init = initExpr->right;
1280     }
1281   else
1282     return FALSE;
1283
1284   /* for now the symbol has to be of
1285      integral type */
1286   if (!IS_INTEGRAL ((*sym)->type))
1287     return FALSE;
1288
1289   /* now check condExpr */
1290   if (IS_AST_OP (condExpr))
1291     {
1292
1293       switch (condExpr->opval.op)
1294         {
1295         case '<':
1296           if (IS_AST_SYM_VALUE (condExpr->left) &&
1297               isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1298               IS_AST_LIT_VALUE (condExpr->right))
1299             {
1300               *end = condExpr->right;
1301               break;
1302             }
1303           return FALSE;
1304
1305         case '!':
1306           if (IS_AST_OP (condExpr->left) &&
1307               condExpr->left->opval.op == '>' &&
1308               IS_AST_LIT_VALUE (condExpr->left->right) &&
1309               IS_AST_SYM_VALUE (condExpr->left->left) &&
1310               isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1311             {
1312
1313               *end = newNode ('+', condExpr->left->right,
1314                               newAst_VALUE (constVal ("1")));
1315               break;
1316             }
1317           return FALSE;
1318
1319         default:
1320           return FALSE;
1321         }
1322
1323     }
1324
1325   /* check loop expression is of the form <sym>++ */
1326   if (!IS_AST_OP (loopExpr))
1327     return FALSE;
1328
1329   /* check if <sym> ++ */
1330   if (loopExpr->opval.op == INC_OP)
1331     {
1332
1333       if (loopExpr->left)
1334         {
1335           /* pre */
1336           if (IS_AST_SYM_VALUE (loopExpr->left) &&
1337               isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1338             return TRUE;
1339
1340         }
1341       else
1342         {
1343           /* post */
1344           if (IS_AST_SYM_VALUE (loopExpr->right) &&
1345               isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1346             return TRUE;
1347         }
1348
1349     }
1350   else
1351     {
1352       /* check for += */
1353       if (loopExpr->opval.op == ADD_ASSIGN)
1354         {
1355
1356           if (IS_AST_SYM_VALUE (loopExpr->left) &&
1357               isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1358               IS_AST_LIT_VALUE (loopExpr->right) &&
1359               (int) AST_LIT_VALUE (loopExpr->right) != 1)
1360             return TRUE;
1361         }
1362     }
1363
1364   return FALSE;
1365 }
1366
1367 /*-----------------------------------------------------------------*/
1368 /* astHasVolatile - returns true if ast contains any volatile      */
1369 /*-----------------------------------------------------------------*/
1370 bool 
1371 astHasVolatile (ast * tree)
1372 {
1373   if (!tree)
1374     return FALSE;
1375
1376   if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1377     return TRUE;
1378
1379   if (IS_AST_OP (tree))
1380     return astHasVolatile (tree->left) ||
1381       astHasVolatile (tree->right);
1382   else
1383     return FALSE;
1384 }
1385
1386 /*-----------------------------------------------------------------*/
1387 /* astHasPointer - return true if the ast contains any ptr variable */
1388 /*-----------------------------------------------------------------*/
1389 bool 
1390 astHasPointer (ast * tree)
1391 {
1392   if (!tree)
1393     return FALSE;
1394
1395   if (IS_AST_LINK (tree))
1396     return TRUE;
1397
1398   /* if we hit an array expression then check
1399      only the left side */
1400   if (IS_AST_OP (tree) && tree->opval.op == '[')
1401     return astHasPointer (tree->left);
1402
1403   if (IS_AST_VALUE (tree))
1404     return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1405
1406   return astHasPointer (tree->left) ||
1407     astHasPointer (tree->right);
1408
1409 }
1410
1411 /*-----------------------------------------------------------------*/
1412 /* astHasSymbol - return true if the ast has the given symbol      */
1413 /*-----------------------------------------------------------------*/
1414 bool 
1415 astHasSymbol (ast * tree, symbol * sym)
1416 {
1417   if (!tree || IS_AST_LINK (tree))
1418     return FALSE;
1419
1420   if (IS_AST_VALUE (tree))
1421     {
1422       if (IS_AST_SYM_VALUE (tree))
1423         return isSymbolEqual (AST_SYMBOL (tree), sym);
1424       else
1425         return FALSE;
1426     }
1427   
1428   return astHasSymbol (tree->left, sym) ||
1429     astHasSymbol (tree->right, sym);
1430 }
1431
1432 /*-----------------------------------------------------------------*/
1433 /* astHasDeref - return true if the ast has an indirect access     */
1434 /*-----------------------------------------------------------------*/
1435 static bool 
1436 astHasDeref (ast * tree)
1437 {
1438   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1439     return FALSE;
1440
1441   if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1442   
1443   return astHasDeref (tree->left) || astHasDeref (tree->right);
1444 }
1445
1446 /*-----------------------------------------------------------------*/
1447 /* isConformingBody - the loop body has to conform to a set of rules */
1448 /* for the loop to be considered reversible read on for rules      */
1449 /*-----------------------------------------------------------------*/
1450 bool 
1451 isConformingBody (ast * pbody, symbol * sym, ast * body)
1452 {
1453
1454   /* we are going to do a pre-order traversal of the
1455      tree && check for the following conditions. (essentially
1456      a set of very shallow tests )
1457      a) the sym passed does not participate in
1458      any arithmetic operation
1459      b) There are no function calls
1460      c) all jumps are within the body
1461      d) address of loop control variable not taken
1462      e) if an assignment has a pointer on the
1463      left hand side make sure right does not have
1464      loop control variable */
1465
1466   /* if we reach the end or a leaf then true */
1467   if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1468     return TRUE;
1469
1470
1471   /* if anything else is "volatile" */
1472   if (IS_VOLATILE (TETYPE (pbody)))
1473     return FALSE;
1474
1475   /* we will walk the body in a pre-order traversal for
1476      efficiency sake */
1477   switch (pbody->opval.op)
1478     {
1479 /*------------------------------------------------------------------*/
1480     case '[':
1481       return isConformingBody (pbody->right, sym, body);
1482
1483 /*------------------------------------------------------------------*/
1484     case PTR_OP:
1485     case '.':
1486       return TRUE;
1487
1488 /*------------------------------------------------------------------*/
1489     case INC_OP:                /* incerement operator unary so left only */
1490     case DEC_OP:
1491
1492       /* sure we are not sym is not modified */
1493       if (pbody->left &&
1494           IS_AST_SYM_VALUE (pbody->left) &&
1495           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1496         return FALSE;
1497
1498       if (pbody->right &&
1499           IS_AST_SYM_VALUE (pbody->right) &&
1500           isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1501         return FALSE;
1502
1503       return TRUE;
1504
1505 /*------------------------------------------------------------------*/
1506
1507     case '*':                   /* can be unary  : if right is null then unary operation */
1508     case '+':
1509     case '-':
1510     case '&':
1511
1512       /* if right is NULL then unary operation  */
1513 /*------------------------------------------------------------------*/
1514 /*----------------------------*/
1515       /*  address of                */
1516 /*----------------------------*/
1517       if (!pbody->right)
1518         {
1519           if (IS_AST_SYM_VALUE (pbody->left) &&
1520               isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1521             return FALSE;
1522           else
1523             return isConformingBody (pbody->left, sym, body);
1524         }
1525       else
1526         {
1527           if (astHasSymbol (pbody->left, sym) ||
1528               astHasSymbol (pbody->right, sym))
1529             return FALSE;
1530         }
1531
1532
1533 /*------------------------------------------------------------------*/
1534     case '|':
1535     case '^':
1536     case '/':
1537     case '%':
1538     case LEFT_OP:
1539     case RIGHT_OP:
1540
1541       if (IS_AST_SYM_VALUE (pbody->left) &&
1542           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1543         return FALSE;
1544
1545       if (IS_AST_SYM_VALUE (pbody->right) &&
1546           isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1547         return FALSE;
1548
1549       return isConformingBody (pbody->left, sym, body) &&
1550         isConformingBody (pbody->right, sym, body);
1551
1552     case '~':
1553     case '!':
1554     case RRC:
1555     case RLC:
1556     case GETHBIT:
1557       if (IS_AST_SYM_VALUE (pbody->left) &&
1558           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1559         return FALSE;
1560       return isConformingBody (pbody->left, sym, body);
1561
1562 /*------------------------------------------------------------------*/
1563
1564     case AND_OP:
1565     case OR_OP:
1566     case '>':
1567     case '<':
1568     case LE_OP:
1569     case GE_OP:
1570     case EQ_OP:
1571     case NE_OP:
1572     case '?':
1573     case ':':
1574     case SIZEOF:                /* evaluate wihout code generation */
1575
1576       return isConformingBody (pbody->left, sym, body) &&
1577         isConformingBody (pbody->right, sym, body);
1578
1579 /*------------------------------------------------------------------*/
1580     case '=':
1581
1582       /* if left has a pointer & right has loop
1583          control variable then we cannot */
1584       if (astHasPointer (pbody->left) &&
1585           astHasSymbol (pbody->right, sym))
1586         return FALSE;
1587       if (astHasVolatile (pbody->left))
1588         return FALSE;
1589
1590       if (IS_AST_SYM_VALUE (pbody->left) &&
1591           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1592         return FALSE;
1593
1594       if (astHasVolatile (pbody->left))
1595         return FALSE;
1596       
1597       if (astHasDeref(pbody->right)) return FALSE;
1598
1599       return isConformingBody (pbody->left, sym, body) &&
1600         isConformingBody (pbody->right, sym, body);
1601
1602     case MUL_ASSIGN:
1603     case DIV_ASSIGN:
1604     case AND_ASSIGN:
1605     case OR_ASSIGN:
1606     case XOR_ASSIGN:
1607     case RIGHT_ASSIGN:
1608     case LEFT_ASSIGN:
1609     case SUB_ASSIGN:
1610     case ADD_ASSIGN:
1611       assert ("Parser should not have generated this\n");
1612
1613 /*------------------------------------------------------------------*/
1614 /*----------------------------*/
1615       /*      comma operator        */
1616 /*----------------------------*/
1617     case ',':
1618       return isConformingBody (pbody->left, sym, body) &&
1619         isConformingBody (pbody->right, sym, body);
1620
1621 /*------------------------------------------------------------------*/
1622 /*----------------------------*/
1623       /*       function call        */
1624 /*----------------------------*/
1625     case CALL:
1626       return FALSE;
1627
1628 /*------------------------------------------------------------------*/
1629 /*----------------------------*/
1630       /*     return statement       */
1631 /*----------------------------*/
1632     case RETURN:
1633       return FALSE;
1634
1635     case GOTO:
1636       if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1637         return TRUE;
1638       else
1639         return FALSE;
1640     case SWITCH:
1641       if (astHasSymbol (pbody->left, sym))
1642         return FALSE;
1643
1644     default:
1645       break;
1646     }
1647
1648   return isConformingBody (pbody->left, sym, body) &&
1649     isConformingBody (pbody->right, sym, body);
1650
1651
1652
1653 }
1654
1655 /*-----------------------------------------------------------------*/
1656 /* isLoopReversible - takes a for loop as input && returns true    */
1657 /* if the for loop is reversible. If yes will set the value of     */
1658 /* the loop control var & init value & termination value           */
1659 /*-----------------------------------------------------------------*/
1660 bool 
1661 isLoopReversible (ast * loop, symbol ** loopCntrl,
1662                   ast ** init, ast ** end)
1663 {
1664   /* if option says don't do it then don't */
1665   if (optimize.noLoopReverse)
1666     return 0;
1667   /* there are several tests to determine this */
1668
1669   /* for loop has to be of the form
1670      for ( <sym> = <const1> ;
1671      [<sym> < <const2>]  ;
1672      [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1673      forBody */
1674   if (!isLoopCountable (AST_FOR (loop, initExpr),
1675                         AST_FOR (loop, condExpr),
1676                         AST_FOR (loop, loopExpr),
1677                         loopCntrl, init, end))
1678     return 0;
1679
1680   /* now do some serious checking on the body of the loop
1681    */
1682
1683   return isConformingBody (loop->left, *loopCntrl, loop->left);
1684
1685 }
1686
1687 /*-----------------------------------------------------------------*/
1688 /* replLoopSym - replace the loop sym by loop sym -1               */
1689 /*-----------------------------------------------------------------*/
1690 static void 
1691 replLoopSym (ast * body, symbol * sym)
1692 {
1693   /* reached end */
1694   if (!body || IS_AST_LINK (body))
1695     return;
1696
1697   if (IS_AST_SYM_VALUE (body))
1698     {
1699
1700       if (isSymbolEqual (AST_SYMBOL (body), sym))
1701         {
1702
1703           body->type = EX_OP;
1704           body->opval.op = '-';
1705           body->left = newAst_VALUE (symbolVal (sym));
1706           body->right = newAst_VALUE (constVal ("1"));
1707
1708         }
1709
1710       return;
1711
1712     }
1713
1714   replLoopSym (body->left, sym);
1715   replLoopSym (body->right, sym);
1716
1717 }
1718
1719 /*-----------------------------------------------------------------*/
1720 /* reverseLoop - do the actual loop reversal                       */
1721 /*-----------------------------------------------------------------*/
1722 ast *
1723 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1724 {
1725   ast *rloop;
1726
1727   /* create the following tree
1728      <sym> = loopCount ;
1729      for_continue:
1730      forbody
1731      <sym> -= 1;
1732      if (sym) goto for_continue ;
1733      <sym> = end */
1734
1735   /* put it together piece by piece */
1736   rloop = newNode (NULLOP,
1737                    createIf (newAst_VALUE (symbolVal (sym)),
1738                              newNode (GOTO,
1739                    newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1740                                       NULL), NULL),
1741                    newNode ('=',
1742                             newAst_VALUE (symbolVal (sym)),
1743                             end));
1744
1745   replLoopSym (loop->left, sym);
1746
1747   rloop = newNode (NULLOP,
1748                    newNode ('=',
1749                             newAst_VALUE (symbolVal (sym)),
1750                             newNode ('-', end, init)),
1751                    createLabel (AST_FOR (loop, continueLabel),
1752                                 newNode (NULLOP,
1753                                          loop->left,
1754                                          newNode (NULLOP,
1755                                                   newNode (SUB_ASSIGN,
1756                                              newAst_VALUE (symbolVal (sym)),
1757                                              newAst_VALUE (constVal ("1"))),
1758                                                   rloop))));
1759
1760   return decorateType (rloop);
1761
1762 }
1763
1764 /*-----------------------------------------------------------------*/
1765 /* decorateType - compute type for this tree also does type cheking */
1766 /*          this is done bottom up, since type have to flow upwards */
1767 /*          it also does constant folding, and paramater checking  */
1768 /*-----------------------------------------------------------------*/
1769 ast *
1770 decorateType (ast * tree)
1771 {
1772   int parmNumber;
1773   sym_link *p;
1774
1775   if (!tree)
1776     return tree;
1777
1778   /* if already has type then do nothing */
1779   if (tree->decorated)
1780     return tree;
1781
1782   tree->decorated = 1;
1783
1784   /* print the line          */
1785   /* if not block & function */
1786   if (tree->type == EX_OP &&
1787       (tree->opval.op != FUNCTION &&
1788        tree->opval.op != BLOCK &&
1789        tree->opval.op != NULLOP))
1790     {
1791       filename = tree->filename;
1792       lineno = tree->lineno;
1793     }
1794
1795   /* if any child is an error | this one is an error do nothing */
1796   if (tree->isError ||
1797       (tree->left && tree->left->isError) ||
1798       (tree->right && tree->right->isError))
1799     return tree;
1800
1801 /*------------------------------------------------------------------*/
1802 /*----------------------------*/
1803   /*   leaf has been reached    */
1804 /*----------------------------*/
1805   /* if this is of type value */
1806   /* just get the type        */
1807   if (tree->type == EX_VALUE)
1808     {
1809
1810       if (IS_LITERAL (tree->opval.val->etype))
1811         {
1812
1813           /* if this is a character array then declare it */
1814           if (IS_ARRAY (tree->opval.val->type))
1815             tree->opval.val = stringToSymbol (tree->opval.val);
1816
1817           /* otherwise just copy the type information */
1818           COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1819           return tree;
1820         }
1821
1822       if (tree->opval.val->sym)
1823         {
1824           /* if the undefined flag is set then give error message */
1825           if (tree->opval.val->sym->undefined)
1826             {
1827               werror (E_ID_UNDEF, tree->opval.val->sym->name);
1828               /* assume int */
1829               TTYPE (tree) = TETYPE (tree) =
1830                 tree->opval.val->type = tree->opval.val->sym->type =
1831                 tree->opval.val->etype = tree->opval.val->sym->etype =
1832                 copyLinkChain (INTTYPE);
1833             }
1834           else
1835             {
1836
1837               /* if impilicit i.e. struct/union member then no type */
1838               if (tree->opval.val->sym->implicit)
1839                 TTYPE (tree) = TETYPE (tree) = NULL;
1840
1841               else
1842                 {
1843
1844                   /* else copy the type */
1845                   COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
1846
1847                   /* and mark it as referenced */
1848                   tree->opval.val->sym->isref = 1;
1849                 }
1850             }
1851         }
1852
1853       return tree;
1854     }
1855
1856   /* if type link for the case of cast */
1857   if (tree->type == EX_LINK)
1858     {
1859       COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
1860       return tree;
1861     }
1862
1863   {
1864     ast *dtl, *dtr;
1865
1866     dtl = decorateType (tree->left);
1867     /* delay right side for '?' operator since conditional macro expansions might
1868        rely on this */
1869     dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
1870
1871     /* this is to take care of situations
1872        when the tree gets rewritten */
1873     if (dtl != tree->left)
1874       tree->left = dtl;
1875     if (dtr != tree->right)
1876       tree->right = dtr;
1877   }
1878
1879   /* depending on type of operator do */
1880
1881   switch (tree->opval.op)
1882     {
1883         /*------------------------------------------------------------------*/
1884         /*----------------------------*/
1885         /*        array node          */
1886         /*----------------------------*/
1887     case '[':
1888
1889       /* determine which is the array & which the index */
1890       if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
1891         {
1892
1893           ast *tempTree = tree->left;
1894           tree->left = tree->right;
1895           tree->right = tempTree;
1896         }
1897
1898       /* first check if this is a array or a pointer */
1899       if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
1900         {
1901           werror (E_NEED_ARRAY_PTR, "[]");
1902           goto errorTreeReturn;
1903         }
1904
1905       /* check if the type of the idx */
1906       if (!IS_INTEGRAL (RTYPE (tree)))
1907         {
1908           werror (E_IDX_NOT_INT);
1909           goto errorTreeReturn;
1910         }
1911
1912       /* if the left is an rvalue then error */
1913       if (LRVAL (tree))
1914         {
1915           werror (E_LVALUE_REQUIRED, "array access");
1916           goto errorTreeReturn;
1917         }
1918       RRVAL (tree) = 1;
1919       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
1920       if (IS_PTR(LTYPE(tree))) {
1921               SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
1922       }
1923       return tree;
1924
1925       /*------------------------------------------------------------------*/
1926       /*----------------------------*/
1927       /*      struct/union          */
1928       /*----------------------------*/
1929     case '.':
1930       /* if this is not a structure */
1931       if (!IS_STRUCT (LTYPE (tree)))
1932         {
1933           werror (E_STRUCT_UNION, ".");
1934           goto errorTreeReturn;
1935         }
1936       TTYPE (tree) = structElemType (LTYPE (tree),
1937                                      (tree->right->type == EX_VALUE ?
1938                                tree->right->opval.val : NULL));
1939       TETYPE (tree) = getSpec (TTYPE (tree));
1940       return tree;
1941
1942       /*------------------------------------------------------------------*/
1943       /*----------------------------*/
1944       /*    struct/union pointer    */
1945       /*----------------------------*/
1946     case PTR_OP:
1947       /* if not pointer to a structure */
1948       if (!IS_PTR (LTYPE (tree)))
1949         {
1950           werror (E_PTR_REQD);
1951           goto errorTreeReturn;
1952         }
1953
1954       if (!IS_STRUCT (LTYPE (tree)->next))
1955         {
1956           werror (E_STRUCT_UNION, "->");
1957           goto errorTreeReturn;
1958         }
1959
1960       TTYPE (tree) = structElemType (LTYPE (tree)->next,
1961                                      (tree->right->type == EX_VALUE ?
1962                                tree->right->opval.val : NULL));
1963       TETYPE (tree) = getSpec (TTYPE (tree));
1964
1965       /* adjust the storage class */
1966       switch (DCL_TYPE(tree->left->ftype)) {
1967       case POINTER:
1968         break;
1969       case FPOINTER:
1970         SPEC_SCLS(TETYPE(tree)) = S_XDATA; 
1971         break;
1972       case CPOINTER:
1973         SPEC_SCLS(TETYPE(tree)) = S_CODE; 
1974         break;
1975       case GPOINTER:
1976         break;
1977       case PPOINTER:
1978         SPEC_SCLS(TETYPE(tree)) = S_XSTACK; 
1979         break;
1980       case IPOINTER:
1981         SPEC_SCLS(TETYPE(tree)) = S_IDATA;
1982         break;
1983       case EEPPOINTER:
1984         SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
1985         break;
1986       case UPOINTER:
1987       case ARRAY:
1988       case FUNCTION:
1989       }
1990
1991       return tree;
1992
1993       /*------------------------------------------------------------------*/
1994       /*----------------------------*/
1995       /*  ++/-- operation           */
1996       /*----------------------------*/
1997     case INC_OP:                /* incerement operator unary so left only */
1998     case DEC_OP:
1999       {
2000         sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2001         COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2002         if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
2003           werror (E_CODE_WRITE, "++/--");
2004
2005         if (tree->right)
2006           RLVAL (tree) = 1;
2007         else
2008           LLVAL (tree) = 1;
2009         return tree;
2010       }
2011
2012       /*------------------------------------------------------------------*/
2013       /*----------------------------*/
2014       /*  bitwise and               */
2015       /*----------------------------*/
2016     case '&':                   /* can be unary   */
2017       /* if right is NULL then unary operation  */
2018       if (tree->right)          /* not an unary operation */
2019         {
2020
2021           if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2022             {
2023               werror (E_BITWISE_OP);
2024               werror (W_CONTINUE, "left & right types are ");
2025               printTypeChain (LTYPE (tree), stderr);
2026               fprintf (stderr, ",");
2027               printTypeChain (RTYPE (tree), stderr);
2028               fprintf (stderr, "\n");
2029               goto errorTreeReturn;
2030             }
2031
2032           /* if they are both literal */
2033           if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2034             {
2035               tree->type = EX_VALUE;
2036               tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2037                                           valFromType (RETYPE (tree)), '&');
2038
2039               tree->right = tree->left = NULL;
2040               TETYPE (tree) = tree->opval.val->etype;
2041               TTYPE (tree) = tree->opval.val->type;
2042               return tree;
2043             }
2044
2045           /* see if this is a GETHBIT operation if yes
2046              then return that */
2047           {
2048             ast *otree = optimizeGetHbit (tree);
2049
2050             if (otree != tree)
2051               return decorateType (otree);
2052           }
2053
2054           TTYPE (tree) =
2055             computeType (LTYPE (tree), RTYPE (tree));
2056           TETYPE (tree) = getSpec (TTYPE (tree));
2057
2058           LRVAL (tree) = RRVAL (tree) = 1;
2059           return tree;
2060         }
2061
2062       /*------------------------------------------------------------------*/
2063       /*----------------------------*/
2064       /*  address of                */
2065       /*----------------------------*/
2066       p = newLink ();
2067       p->class = DECLARATOR;
2068       /* if bit field then error */
2069       if (IS_BITVAR (tree->left->etype))
2070         {
2071           werror (E_ILLEGAL_ADDR, "address of bit variable");
2072           goto errorTreeReturn;
2073         }
2074
2075       if (SPEC_SCLS (tree->left->etype) == S_REGISTER)
2076         {
2077           werror (E_ILLEGAL_ADDR, "address of register variable");
2078           goto errorTreeReturn;
2079         }
2080
2081       if (IS_FUNC (LTYPE (tree)))
2082         {
2083           werror (E_ILLEGAL_ADDR, "address of function");
2084           goto errorTreeReturn;
2085         }
2086
2087       if (IS_LITERAL(LTYPE(tree)))
2088         {
2089           werror (E_ILLEGAL_ADDR, "address of literal");
2090           goto errorTreeReturn;
2091         }
2092
2093      if (LRVAL (tree))
2094         {
2095           werror (E_LVALUE_REQUIRED, "address of");
2096           goto errorTreeReturn;
2097         }
2098       if (SPEC_SCLS (tree->left->etype) == S_CODE)
2099         {
2100           DCL_TYPE (p) = CPOINTER;
2101           DCL_PTR_CONST (p) = port->mem.code_ro;
2102         }
2103       else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2104         DCL_TYPE (p) = FPOINTER;
2105       else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2106         DCL_TYPE (p) = PPOINTER;
2107       else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2108         DCL_TYPE (p) = IPOINTER;
2109       else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2110         DCL_TYPE (p) = EEPPOINTER;
2111       else if (SPEC_OCLS(tree->left->etype))
2112           DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2113       else
2114           DCL_TYPE (p) = POINTER;
2115
2116       if (IS_AST_SYM_VALUE (tree->left))
2117         {
2118           AST_SYMBOL (tree->left)->addrtaken = 1;
2119           AST_SYMBOL (tree->left)->allocreq = 1;
2120         }
2121
2122       p->next = LTYPE (tree);
2123       TTYPE (tree) = p;
2124       TETYPE (tree) = getSpec (TTYPE (tree));
2125       DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2126       DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2127       LLVAL (tree) = 1;
2128       TLVAL (tree) = 1;
2129       return tree;
2130
2131       /*------------------------------------------------------------------*/
2132       /*----------------------------*/
2133       /*  bitwise or                */
2134       /*----------------------------*/
2135     case '|':
2136       /* if the rewrite succeeds then don't go any furthur */
2137       {
2138         ast *wtree = optimizeRRCRLC (tree);
2139         if (wtree != tree)
2140           return decorateType (wtree);
2141       }
2142       /*------------------------------------------------------------------*/
2143       /*----------------------------*/
2144       /*  bitwise xor               */
2145       /*----------------------------*/
2146     case '^':
2147       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2148         {
2149           werror (E_BITWISE_OP);
2150           werror (W_CONTINUE, "left & right types are ");
2151           printTypeChain (LTYPE (tree), stderr);
2152           fprintf (stderr, ",");
2153           printTypeChain (RTYPE (tree), stderr);
2154           fprintf (stderr, "\n");
2155           goto errorTreeReturn;
2156         }
2157
2158       /* if they are both literal then */
2159       /* rewrite the tree */
2160       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2161         {
2162           tree->type = EX_VALUE;
2163           tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2164                                         valFromType (RETYPE (tree)),
2165                                         tree->opval.op);
2166           tree->right = tree->left = NULL;
2167           TETYPE (tree) = tree->opval.val->etype;
2168           TTYPE (tree) = tree->opval.val->type;
2169           return tree;
2170         }
2171       LRVAL (tree) = RRVAL (tree) = 1;
2172       TETYPE (tree) = getSpec (TTYPE (tree) =
2173                                computeType (LTYPE (tree),
2174                                             RTYPE (tree)));
2175
2176       /*------------------------------------------------------------------*/
2177       /*----------------------------*/
2178       /*  division                  */
2179       /*----------------------------*/
2180     case '/':
2181       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2182         {
2183           werror (E_INVALID_OP, "divide");
2184           goto errorTreeReturn;
2185         }
2186       /* if they are both literal then */
2187       /* rewrite the tree */
2188       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2189         {
2190           tree->type = EX_VALUE;
2191           tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2192                                     valFromType (RETYPE (tree)));
2193           tree->right = tree->left = NULL;
2194           TETYPE (tree) = getSpec (TTYPE (tree) =
2195                                    tree->opval.val->type);
2196           return tree;
2197         }
2198       LRVAL (tree) = RRVAL (tree) = 1;
2199       TETYPE (tree) = getSpec (TTYPE (tree) =
2200                                computeType (LTYPE (tree),
2201                                             RTYPE (tree)));
2202       return tree;
2203
2204       /*------------------------------------------------------------------*/
2205       /*----------------------------*/
2206       /*            modulus         */
2207       /*----------------------------*/
2208     case '%':
2209       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2210         {
2211           werror (E_BITWISE_OP);
2212           werror (W_CONTINUE, "left & right types are ");
2213           printTypeChain (LTYPE (tree), stderr);
2214           fprintf (stderr, ",");
2215           printTypeChain (RTYPE (tree), stderr);
2216           fprintf (stderr, "\n");
2217           goto errorTreeReturn;
2218         }
2219       /* if they are both literal then */
2220       /* rewrite the tree */
2221       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2222         {
2223           tree->type = EX_VALUE;
2224           tree->opval.val = valMod (valFromType (LETYPE (tree)),
2225                                     valFromType (RETYPE (tree)));
2226           tree->right = tree->left = NULL;
2227           TETYPE (tree) = getSpec (TTYPE (tree) =
2228                                    tree->opval.val->type);
2229           return tree;
2230         }
2231       LRVAL (tree) = RRVAL (tree) = 1;
2232       TETYPE (tree) = getSpec (TTYPE (tree) =
2233                                computeType (LTYPE (tree),
2234                                             RTYPE (tree)));
2235       return tree;
2236
2237       /*------------------------------------------------------------------*/
2238       /*----------------------------*/
2239       /*  address dereference       */
2240       /*----------------------------*/
2241     case '*':                   /* can be unary  : if right is null then unary operation */
2242       if (!tree->right)
2243         {
2244           if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2245             {
2246               werror (E_PTR_REQD);
2247               goto errorTreeReturn;
2248             }
2249
2250           if (LRVAL (tree))
2251             {
2252               werror (E_LVALUE_REQUIRED, "pointer deref");
2253               goto errorTreeReturn;
2254             }
2255           TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2256                                         LTYPE (tree)->next : NULL);
2257           TETYPE (tree) = getSpec (TTYPE (tree));
2258           SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2259           return tree;
2260         }
2261
2262       /*------------------------------------------------------------------*/
2263       /*----------------------------*/
2264       /*      multiplication        */
2265       /*----------------------------*/
2266       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2267         {
2268           werror (E_INVALID_OP, "multiplication");
2269           goto errorTreeReturn;
2270         }
2271
2272       /* if they are both literal then */
2273       /* rewrite the tree */
2274       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2275         {
2276           tree->type = EX_VALUE;
2277           tree->opval.val = valMult (valFromType (LETYPE (tree)),
2278                                      valFromType (RETYPE (tree)));
2279           tree->right = tree->left = NULL;
2280           TETYPE (tree) = getSpec (TTYPE (tree) =
2281                                    tree->opval.val->type);
2282           return tree;
2283         }
2284
2285       /* if left is a literal exchange left & right */
2286       if (IS_LITERAL (LTYPE (tree)))
2287         {
2288           ast *tTree = tree->left;
2289           tree->left = tree->right;
2290           tree->right = tTree;
2291         }
2292
2293       LRVAL (tree) = RRVAL (tree) = 1;
2294       /* promote result to int if left & right are char
2295          this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2296       if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2297         TETYPE (tree) = getSpec (TTYPE (tree) =
2298                                  computeType (LTYPE (tree),
2299                                               RTYPE (tree)));
2300         SPEC_NOUN(TETYPE(tree)) = V_INT;
2301       } else {
2302         TETYPE (tree) = getSpec (TTYPE (tree) =
2303                                  computeType (LTYPE (tree),
2304                                               RTYPE (tree)));
2305       }
2306       return tree;
2307
2308       /*------------------------------------------------------------------*/
2309       /*----------------------------*/
2310       /*    unary '+' operator      */
2311       /*----------------------------*/
2312     case '+':
2313       /* if unary plus */
2314       if (!tree->right)
2315         {
2316           if (!IS_INTEGRAL (LTYPE (tree)))
2317             {
2318               werror (E_UNARY_OP, '+');
2319               goto errorTreeReturn;
2320             }
2321
2322           /* if left is a literal then do it */
2323           if (IS_LITERAL (LTYPE (tree)))
2324             {
2325               tree->type = EX_VALUE;
2326               tree->opval.val = valFromType (LETYPE (tree));
2327               tree->left = NULL;
2328               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2329               return tree;
2330             }
2331           LRVAL (tree) = 1;
2332           COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2333           return tree;
2334         }
2335
2336       /*------------------------------------------------------------------*/
2337       /*----------------------------*/
2338       /*      addition              */
2339       /*----------------------------*/
2340
2341       /* this is not a unary operation */
2342       /* if both pointers then problem */
2343       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2344           (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2345         {
2346           werror (E_PTR_PLUS_PTR);
2347           goto errorTreeReturn;
2348         }
2349
2350       if (!IS_ARITHMETIC (LTYPE (tree)) &&
2351           !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2352         {
2353           werror (E_PLUS_INVALID, "+");
2354           goto errorTreeReturn;
2355         }
2356
2357       if (!IS_ARITHMETIC (RTYPE (tree)) &&
2358           !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2359         {
2360           werror (E_PLUS_INVALID, "+");
2361           goto errorTreeReturn;
2362         }
2363       /* if they are both literal then */
2364       /* rewrite the tree */
2365       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2366         {
2367           tree->type = EX_VALUE;
2368           tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2369                                      valFromType (RETYPE (tree)));
2370           tree->right = tree->left = NULL;
2371           TETYPE (tree) = getSpec (TTYPE (tree) =
2372                                    tree->opval.val->type);
2373           return tree;
2374         }
2375
2376       /* if the right is a pointer or left is a literal
2377          xchange left & right */
2378       if (IS_ARRAY (RTYPE (tree)) ||
2379           IS_PTR (RTYPE (tree)) ||
2380           IS_LITERAL (LTYPE (tree)))
2381         {
2382           ast *tTree = tree->left;
2383           tree->left = tree->right;
2384           tree->right = tTree;
2385         }
2386
2387       LRVAL (tree) = RRVAL (tree) = 1;
2388       /* if the left is a pointer */
2389       if (IS_PTR (LTYPE (tree)))
2390         TETYPE (tree) = getSpec (TTYPE (tree) =
2391                                  LTYPE (tree));
2392       else
2393         TETYPE (tree) = getSpec (TTYPE (tree) =
2394                                  computeType (LTYPE (tree),
2395                                               RTYPE (tree)));
2396       return tree;
2397
2398       /*------------------------------------------------------------------*/
2399       /*----------------------------*/
2400       /*      unary '-'             */
2401       /*----------------------------*/
2402     case '-':                   /* can be unary   */
2403       /* if right is null then unary */
2404       if (!tree->right)
2405         {
2406
2407           if (!IS_ARITHMETIC (LTYPE (tree)))
2408             {
2409               werror (E_UNARY_OP, tree->opval.op);
2410               goto errorTreeReturn;
2411             }
2412
2413           /* if left is a literal then do it */
2414           if (IS_LITERAL (LTYPE (tree)))
2415             {
2416               tree->type = EX_VALUE;
2417               tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2418               tree->left = NULL;
2419               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2420               SPEC_USIGN(TETYPE(tree)) = 0;
2421               return tree;
2422             }
2423           LRVAL (tree) = 1;
2424           TTYPE (tree) = LTYPE (tree);
2425           return tree;
2426         }
2427
2428       /*------------------------------------------------------------------*/
2429       /*----------------------------*/
2430       /*    subtraction             */
2431       /*----------------------------*/
2432
2433       if (!(IS_PTR (LTYPE (tree)) ||
2434             IS_ARRAY (LTYPE (tree)) ||
2435             IS_ARITHMETIC (LTYPE (tree))))
2436         {
2437           werror (E_PLUS_INVALID, "-");
2438           goto errorTreeReturn;
2439         }
2440
2441       if (!(IS_PTR (RTYPE (tree)) ||
2442             IS_ARRAY (RTYPE (tree)) ||
2443             IS_ARITHMETIC (RTYPE (tree))))
2444         {
2445           werror (E_PLUS_INVALID, "-");
2446           goto errorTreeReturn;
2447         }
2448
2449       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2450           !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2451             IS_INTEGRAL (RTYPE (tree))))
2452         {
2453           werror (E_PLUS_INVALID, "-");
2454           goto errorTreeReturn;
2455         }
2456
2457       /* if they are both literal then */
2458       /* rewrite the tree */
2459       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2460         {
2461           tree->type = EX_VALUE;
2462           tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2463                                       valFromType (RETYPE (tree)));
2464           tree->right = tree->left = NULL;
2465           TETYPE (tree) = getSpec (TTYPE (tree) =
2466                                    tree->opval.val->type);
2467           return tree;
2468         }
2469
2470       /* if the left & right are equal then zero */
2471       if (isAstEqual (tree->left, tree->right))
2472         {
2473           tree->type = EX_VALUE;
2474           tree->left = tree->right = NULL;
2475           tree->opval.val = constVal ("0");
2476           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2477           return tree;
2478         }
2479
2480       /* if both of them are pointers or arrays then */
2481       /* the result is going to be an integer        */
2482       if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2483           (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2484         TETYPE (tree) = TTYPE (tree) = newIntLink ();
2485       else
2486         /* if only the left is a pointer */
2487         /* then result is a pointer      */
2488       if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2489         TETYPE (tree) = getSpec (TTYPE (tree) =
2490                                  LTYPE (tree));
2491       else
2492         TETYPE (tree) = getSpec (TTYPE (tree) =
2493                                  computeType (LTYPE (tree),
2494                                               RTYPE (tree)));
2495       LRVAL (tree) = RRVAL (tree) = 1;
2496       return tree;
2497
2498       /*------------------------------------------------------------------*/
2499       /*----------------------------*/
2500       /*    compliment              */
2501       /*----------------------------*/
2502     case '~':
2503       /* can be only integral type */
2504       if (!IS_INTEGRAL (LTYPE (tree)))
2505         {
2506           werror (E_UNARY_OP, tree->opval.op);
2507           goto errorTreeReturn;
2508         }
2509
2510       /* if left is a literal then do it */
2511       if (IS_LITERAL (LTYPE (tree)))
2512         {
2513           tree->type = EX_VALUE;
2514           tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2515           tree->left = NULL;
2516           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2517           return tree;
2518         }
2519       LRVAL (tree) = 1;
2520       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2521       return tree;
2522
2523       /*------------------------------------------------------------------*/
2524       /*----------------------------*/
2525       /*           not              */
2526       /*----------------------------*/
2527     case '!':
2528       /* can be pointer */
2529       if (!IS_ARITHMETIC (LTYPE (tree)) &&
2530           !IS_PTR (LTYPE (tree)) &&
2531           !IS_ARRAY (LTYPE (tree)))
2532         {
2533           werror (E_UNARY_OP, tree->opval.op);
2534           goto errorTreeReturn;
2535         }
2536
2537       /* if left is a literal then do it */
2538       if (IS_LITERAL (LTYPE (tree)))
2539         {
2540           tree->type = EX_VALUE;
2541           tree->opval.val = valNot (valFromType (LETYPE (tree)));
2542           tree->left = NULL;
2543           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2544           return tree;
2545         }
2546       LRVAL (tree) = 1;
2547       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2548       return tree;
2549
2550       /*------------------------------------------------------------------*/
2551       /*----------------------------*/
2552       /*           shift            */
2553       /*----------------------------*/
2554     case RRC:
2555     case RLC:
2556       TTYPE (tree) = LTYPE (tree);
2557       TETYPE (tree) = LETYPE (tree);
2558       return tree;
2559
2560     case GETHBIT:
2561       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2562       return tree;
2563
2564     case LEFT_OP:
2565     case RIGHT_OP:
2566       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2567         {
2568           werror (E_SHIFT_OP_INVALID);
2569           werror (W_CONTINUE, "left & right types are ");
2570           printTypeChain (LTYPE (tree), stderr);
2571           fprintf (stderr, ",");
2572           printTypeChain (RTYPE (tree), stderr);
2573           fprintf (stderr, "\n");
2574           goto errorTreeReturn;
2575         }
2576
2577       /* if they are both literal then */
2578       /* rewrite the tree */
2579       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2580         {
2581           tree->type = EX_VALUE;
2582           tree->opval.val = valShift (valFromType (LETYPE (tree)),
2583                                       valFromType (RETYPE (tree)),
2584                                       (tree->opval.op == LEFT_OP ? 1 : 0));
2585           tree->right = tree->left = NULL;
2586           TETYPE (tree) = getSpec (TTYPE (tree) =
2587                                    tree->opval.val->type);
2588           return tree;
2589         }
2590       /* if only the right side is a literal & we are
2591          shifting more than size of the left operand then zero */
2592       if (IS_LITERAL (RTYPE (tree)) &&
2593           ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2594           (getSize (LTYPE (tree)) * 8))
2595         {
2596           werror (W_SHIFT_CHANGED,
2597                   (tree->opval.op == LEFT_OP ? "left" : "right"));
2598           tree->type = EX_VALUE;
2599           tree->left = tree->right = NULL;
2600           tree->opval.val = constVal ("0");
2601           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2602           return tree;
2603         }
2604       LRVAL (tree) = RRVAL (tree) = 1;
2605       if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2606         {
2607           COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2608         }
2609       else
2610         {
2611           COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2612         }
2613       return tree;
2614
2615       /*------------------------------------------------------------------*/
2616       /*----------------------------*/
2617       /*         casting            */
2618       /*----------------------------*/
2619     case CAST:                  /* change the type   */
2620       /* cannot cast to an aggregate type */
2621       if (IS_AGGREGATE (LTYPE (tree)))
2622         {
2623           werror (E_CAST_ILLEGAL);
2624           goto errorTreeReturn;
2625         }
2626       
2627       /* make sure the type is complete and sane */
2628       checkTypeSanity(LETYPE(tree), "(cast)");
2629
2630 #if 0
2631       /* if the right is a literal replace the tree */
2632       if (IS_LITERAL (RETYPE (tree))) {
2633               if (!IS_PTR (LTYPE (tree))) {
2634                       tree->type = EX_VALUE;
2635                       tree->opval.val =
2636                               valCastLiteral (LTYPE (tree),
2637                                               floatFromVal (valFromType (RETYPE (tree))));
2638                       tree->left = NULL;
2639                       tree->right = NULL;
2640                       TTYPE (tree) = tree->opval.val->type;
2641                       tree->values.literalFromCast = 1;
2642               } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) && 
2643                          ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */  {
2644                       sym_link *rest = LTYPE(tree)->next;
2645                       werror(W_LITERAL_GENERIC);                      
2646                       TTYPE(tree) = newLink();
2647                       DCL_TYPE(TTYPE(tree)) = FPOINTER;
2648                       TTYPE(tree)->next = rest;
2649                       tree->left->opval.lnk = TTYPE(tree);
2650                       LRVAL (tree) = 1;
2651               } else {
2652                       TTYPE (tree) = LTYPE (tree);
2653                       LRVAL (tree) = 1;
2654               }
2655       } else {
2656               TTYPE (tree) = LTYPE (tree);
2657               LRVAL (tree) = 1;
2658       }
2659 #else
2660       /* if pointer to struct then check names */
2661       if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
2662           IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
2663           strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) {
2664               werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag);
2665       }
2666       /* if the right is a literal replace the tree */
2667       if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2668         tree->type = EX_VALUE;
2669         tree->opval.val =
2670           valCastLiteral (LTYPE (tree),
2671                           floatFromVal (valFromType (RETYPE (tree))));
2672         tree->left = NULL;
2673         tree->right = NULL;
2674         TTYPE (tree) = tree->opval.val->type;
2675         tree->values.literalFromCast = 1;
2676       } else {
2677         TTYPE (tree) = LTYPE (tree);
2678         LRVAL (tree) = 1;
2679       }
2680 #endif      
2681       TETYPE (tree) = getSpec (TTYPE (tree));
2682
2683       return tree;
2684
2685       /*------------------------------------------------------------------*/
2686       /*----------------------------*/
2687       /*       logical &&, ||       */
2688       /*----------------------------*/
2689     case AND_OP:
2690     case OR_OP:
2691       /* each must me arithmetic type or be a pointer */
2692       if (!IS_PTR (LTYPE (tree)) &&
2693           !IS_ARRAY (LTYPE (tree)) &&
2694           !IS_INTEGRAL (LTYPE (tree)))
2695         {
2696           werror (E_COMPARE_OP);
2697           goto errorTreeReturn;
2698         }
2699
2700       if (!IS_PTR (RTYPE (tree)) &&
2701           !IS_ARRAY (RTYPE (tree)) &&
2702           !IS_INTEGRAL (RTYPE (tree)))
2703         {
2704           werror (E_COMPARE_OP);
2705           goto errorTreeReturn;
2706         }
2707       /* if they are both literal then */
2708       /* rewrite the tree */
2709       if (IS_LITERAL (RTYPE (tree)) &&
2710           IS_LITERAL (LTYPE (tree)))
2711         {
2712           tree->type = EX_VALUE;
2713           tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2714                                            valFromType (RETYPE (tree)),
2715                                            tree->opval.op);
2716           tree->right = tree->left = NULL;
2717           TETYPE (tree) = getSpec (TTYPE (tree) =
2718                                    tree->opval.val->type);
2719           return tree;
2720         }
2721       LRVAL (tree) = RRVAL (tree) = 1;
2722       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2723       return tree;
2724
2725       /*------------------------------------------------------------------*/
2726       /*----------------------------*/
2727       /*     comparison operators   */
2728       /*----------------------------*/
2729     case '>':
2730     case '<':
2731     case LE_OP:
2732     case GE_OP:
2733     case EQ_OP:
2734     case NE_OP:
2735       {
2736         ast *lt = optimizeCompare (tree);
2737
2738         if (tree != lt)
2739           return lt;
2740       }
2741
2742       /* if they are pointers they must be castable */
2743       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2744         {
2745           if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2746             {
2747               werror (E_COMPARE_OP);
2748               fprintf (stderr, "comparing type ");
2749               printTypeChain (LTYPE (tree), stderr);
2750               fprintf (stderr, "to type ");
2751               printTypeChain (RTYPE (tree), stderr);
2752               fprintf (stderr, "\n");
2753               goto errorTreeReturn;
2754             }
2755         }
2756       /* else they should be promotable to one another */
2757       else
2758         {
2759           if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2760                 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2761
2762             if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2763               {
2764                 werror (E_COMPARE_OP);
2765                 fprintf (stderr, "comparing type ");
2766                 printTypeChain (LTYPE (tree), stderr);
2767                 fprintf (stderr, "to type ");
2768                 printTypeChain (RTYPE (tree), stderr);
2769                 fprintf (stderr, "\n");
2770                 goto errorTreeReturn;
2771               }
2772         }
2773       /* if unsigned value < 0  then always false */
2774       /* if (unsigned value) > 0 then (unsigned value) */
2775       if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) && 
2776           ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
2777
2778           if (tree->opval.op == '<') {
2779               return tree->right;
2780           }
2781           if (tree->opval.op == '>') {
2782               return tree->left;
2783           }
2784       }
2785       /* if they are both literal then */
2786       /* rewrite the tree */
2787       if (IS_LITERAL (RTYPE (tree)) &&
2788           IS_LITERAL (LTYPE (tree)))
2789         {
2790           tree->type = EX_VALUE;
2791           tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2792                                         valFromType (RETYPE (tree)),
2793                                         tree->opval.op);
2794           tree->right = tree->left = NULL;
2795           TETYPE (tree) = getSpec (TTYPE (tree) =
2796                                    tree->opval.val->type);
2797           return tree;
2798         }
2799       LRVAL (tree) = RRVAL (tree) = 1;
2800       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2801       return tree;
2802
2803       /*------------------------------------------------------------------*/
2804       /*----------------------------*/
2805       /*             sizeof         */
2806       /*----------------------------*/
2807     case SIZEOF:                /* evaluate wihout code generation */
2808       /* change the type to a integer */
2809       tree->type = EX_VALUE;
2810       sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2811       tree->opval.val = constVal (buffer);
2812       tree->right = tree->left = NULL;
2813       TETYPE (tree) = getSpec (TTYPE (tree) =
2814                                tree->opval.val->type);
2815       return tree;
2816
2817       /*------------------------------------------------------------------*/
2818       /*----------------------------*/
2819       /*             typeof         */
2820       /*----------------------------*/
2821     case TYPEOF:
2822         /* return typeof enum value */
2823         tree->type = EX_VALUE;
2824         {
2825             int typeofv = 0;
2826             if (IS_SPEC(tree->right->ftype)) {
2827                 switch (SPEC_NOUN(tree->right->ftype)) {
2828                 case V_INT:
2829                     if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
2830                     else typeofv = TYPEOF_INT;
2831                     break;
2832                 case V_FLOAT:
2833                     typeofv = TYPEOF_FLOAT;
2834                     break;
2835                 case V_CHAR:
2836                     typeofv = TYPEOF_CHAR;
2837                     break;
2838                 case V_VOID:
2839                     typeofv = TYPEOF_VOID;
2840                     break;
2841                 case V_STRUCT:
2842                     typeofv = TYPEOF_STRUCT;
2843                     break;
2844                 case V_BIT:
2845                     typeofv = TYPEOF_BIT;
2846                     break;
2847                 case V_SBIT:
2848                     typeofv = TYPEOF_SBIT;
2849                     break;
2850                 default:
2851                     break;
2852                 }
2853             } else {
2854                 switch (DCL_TYPE(tree->right->ftype)) {
2855                 case POINTER:
2856                     typeofv = TYPEOF_POINTER;
2857                     break;
2858                 case FPOINTER:
2859                     typeofv = TYPEOF_FPOINTER;
2860                     break;
2861                 case CPOINTER:
2862                     typeofv = TYPEOF_CPOINTER;
2863                     break;
2864                 case GPOINTER:
2865                     typeofv = TYPEOF_GPOINTER;
2866                     break;
2867                 case PPOINTER:
2868                     typeofv = TYPEOF_PPOINTER;
2869                     break;
2870                 case IPOINTER:
2871                     typeofv = TYPEOF_IPOINTER;
2872                     break;
2873                 case ARRAY:
2874                     typeofv = TYPEOF_ARRAY;
2875                     break;
2876                 case FUNCTION:
2877                     typeofv = TYPEOF_FUNCTION;
2878                     break;
2879                 default:
2880                     break;
2881                 }
2882             }
2883             sprintf (buffer, "%d", typeofv);
2884             tree->opval.val = constVal (buffer);
2885             tree->right = tree->left = NULL;
2886             TETYPE (tree) = getSpec (TTYPE (tree) =
2887                                      tree->opval.val->type);
2888         }
2889         return tree;
2890       /*------------------------------------------------------------------*/
2891       /*----------------------------*/
2892       /* conditional operator  '?'  */
2893       /*----------------------------*/
2894     case '?':
2895       /* the type is value of the colon operator (on the right) */
2896       assert(IS_COLON_OP(tree->right));
2897       /* if already known then replace the tree : optimizer will do it
2898          but faster to do it here */
2899       if (IS_LITERAL (LTYPE(tree))) {     
2900           if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2901               return decorateType(tree->right->left) ;
2902           } else {
2903               return decorateType(tree->right->right) ;
2904           }
2905       } else {
2906           tree->right = decorateType(tree->right);
2907           TTYPE (tree) = RTYPE(tree);
2908           TETYPE (tree) = getSpec (TTYPE (tree));
2909       }
2910       return tree;
2911
2912     case ':':
2913       /* if they don't match we have a problem */
2914       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2915         {
2916           werror (E_TYPE_MISMATCH, "conditional operator", " ");
2917           goto errorTreeReturn;
2918         }
2919
2920       TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2921       TETYPE (tree) = getSpec (TTYPE (tree));
2922       return tree;
2923
2924
2925       /*------------------------------------------------------------------*/
2926       /*----------------------------*/
2927       /*    assignment operators    */
2928       /*----------------------------*/
2929     case MUL_ASSIGN:
2930     case DIV_ASSIGN:
2931       /* for these it must be both must be integral */
2932       if (!IS_ARITHMETIC (LTYPE (tree)) ||
2933           !IS_ARITHMETIC (RTYPE (tree)))
2934         {
2935           werror (E_OPS_INTEGRAL);
2936           goto errorTreeReturn;
2937         }
2938       RRVAL (tree) = 1;
2939       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2940
2941       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2942         werror (E_CODE_WRITE, " ");
2943
2944       if (LRVAL (tree))
2945         {
2946           werror (E_LVALUE_REQUIRED, "*= or /=");
2947           goto errorTreeReturn;
2948         }
2949       LLVAL (tree) = 1;
2950
2951       return tree;
2952
2953     case AND_ASSIGN:
2954     case OR_ASSIGN:
2955     case XOR_ASSIGN:
2956     case RIGHT_ASSIGN:
2957     case LEFT_ASSIGN:
2958       /* for these it must be both must be integral */
2959       if (!IS_INTEGRAL (LTYPE (tree)) ||
2960           !IS_INTEGRAL (RTYPE (tree)))
2961         {
2962           werror (E_OPS_INTEGRAL);
2963           goto errorTreeReturn;
2964         }
2965       RRVAL (tree) = 1;
2966       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2967
2968       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2969         werror (E_CODE_WRITE, " ");
2970
2971       if (LRVAL (tree))
2972         {
2973           werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2974           goto errorTreeReturn;
2975         }
2976       LLVAL (tree) = 1;
2977
2978       return tree;
2979
2980       /*------------------------------------------------------------------*/
2981       /*----------------------------*/
2982       /*    -= operator             */
2983       /*----------------------------*/
2984     case SUB_ASSIGN:
2985       if (!(IS_PTR (LTYPE (tree)) ||
2986             IS_ARITHMETIC (LTYPE (tree))))
2987         {
2988           werror (E_PLUS_INVALID, "-=");
2989           goto errorTreeReturn;
2990         }
2991
2992       if (!(IS_PTR (RTYPE (tree)) ||
2993             IS_ARITHMETIC (RTYPE (tree))))
2994         {
2995           werror (E_PLUS_INVALID, "-=");
2996           goto errorTreeReturn;
2997         }
2998       RRVAL (tree) = 1;
2999       TETYPE (tree) = getSpec (TTYPE (tree) =
3000                                computeType (LTYPE (tree),
3001                                             RTYPE (tree)));
3002
3003       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3004         werror (E_CODE_WRITE, " ");
3005
3006       if (LRVAL (tree))
3007         {
3008           werror (E_LVALUE_REQUIRED, "-=");
3009           goto errorTreeReturn;
3010         }
3011       LLVAL (tree) = 1;
3012
3013       return tree;
3014
3015       /*------------------------------------------------------------------*/
3016       /*----------------------------*/
3017       /*          += operator       */
3018       /*----------------------------*/
3019     case ADD_ASSIGN:
3020       /* this is not a unary operation */
3021       /* if both pointers then problem */
3022       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3023         {
3024           werror (E_PTR_PLUS_PTR);
3025           goto errorTreeReturn;
3026         }
3027
3028       if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3029         {
3030           werror (E_PLUS_INVALID, "+=");
3031           goto errorTreeReturn;
3032         }
3033
3034       if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3035         {
3036           werror (E_PLUS_INVALID, "+=");
3037           goto errorTreeReturn;
3038         }
3039       RRVAL (tree) = 1;
3040       TETYPE (tree) = getSpec (TTYPE (tree) =
3041                                computeType (LTYPE (tree),
3042                                             RTYPE (tree)));
3043
3044       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3045         werror (E_CODE_WRITE, " ");
3046
3047       if (LRVAL (tree))
3048         {
3049           werror (E_LVALUE_REQUIRED, "+=");
3050           goto errorTreeReturn;
3051         }
3052
3053       tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3054       tree->opval.op = '=';
3055
3056       return tree;
3057
3058       /*------------------------------------------------------------------*/
3059       /*----------------------------*/
3060       /*      straight assignemnt   */
3061       /*----------------------------*/
3062     case '=':
3063       /* cannot be an aggregate */
3064       if (IS_AGGREGATE (LTYPE (tree)))
3065         {
3066           werror (E_AGGR_ASSIGN);
3067           goto errorTreeReturn;
3068         }
3069
3070       /* they should either match or be castable */
3071       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3072         {
3073           werror (E_TYPE_MISMATCH, "assignment", " ");
3074           fprintf (stderr, "type --> '");
3075           printTypeChain (RTYPE (tree), stderr);
3076           fprintf (stderr, "' ");
3077           fprintf (stderr, "assigned to type --> '");
3078           printTypeChain (LTYPE (tree), stderr);
3079           fprintf (stderr, "'\n");
3080           goto errorTreeReturn;
3081         }
3082
3083       /* if the left side of the tree is of type void
3084          then report error */
3085       if (IS_VOID (LTYPE (tree)))
3086         {
3087           werror (E_CAST_ZERO);
3088           printFromToType(RTYPE(tree), LTYPE(tree));
3089         }
3090
3091       TETYPE (tree) = getSpec (TTYPE (tree) =
3092                                LTYPE (tree));
3093       RRVAL (tree) = 1;
3094       LLVAL (tree) = 1;
3095       if (!tree->initMode ) {
3096         if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3097           werror (E_CODE_WRITE, " ");
3098       }
3099       if (LRVAL (tree))
3100         {
3101           werror (E_LVALUE_REQUIRED, "=");
3102           goto errorTreeReturn;
3103         }
3104
3105       return tree;
3106
3107       /*------------------------------------------------------------------*/
3108       /*----------------------------*/
3109       /*      comma operator        */
3110       /*----------------------------*/
3111     case ',':
3112       TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3113       return tree;
3114
3115       /*------------------------------------------------------------------*/
3116       /*----------------------------*/
3117       /*       function call        */
3118       /*----------------------------*/
3119     case CALL:
3120       parmNumber = 1;
3121
3122       if (processParms (tree->left,
3123                         FUNC_ARGS(tree->left->ftype),
3124                         tree->right, &parmNumber, TRUE)) {
3125         goto errorTreeReturn;
3126       }
3127
3128       if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) && 
3129           !IFFUNC_ISBUILTIN(LTYPE(tree)))
3130         {
3131           //FUNC_ARGS(tree->left->ftype) = 
3132           //reverseVal (FUNC_ARGS(tree->left->ftype));
3133           reverseParms (tree->right);
3134         }
3135
3136       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3137       return tree;
3138
3139       /*------------------------------------------------------------------*/
3140       /*----------------------------*/
3141       /*     return statement       */
3142       /*----------------------------*/
3143     case RETURN:
3144       if (!tree->right)
3145         goto voidcheck;
3146
3147       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3148         {
3149           werror (W_RETURN_MISMATCH);
3150           printFromToType (RTYPE(tree), currFunc->type->next);
3151           goto errorTreeReturn;
3152         }
3153
3154       if (IS_VOID (currFunc->type->next)
3155           && tree->right &&
3156           !IS_VOID (RTYPE (tree)))
3157         {
3158           werror (E_FUNC_VOID);
3159           goto errorTreeReturn;
3160         }
3161
3162       /* if there is going to be a casing required then add it */
3163       if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3164         {
3165           tree->right =
3166             decorateType (newNode (CAST,
3167                            newAst_LINK (copyLinkChain (currFunc->type->next)),
3168                                    tree->right));
3169         }
3170
3171       RRVAL (tree) = 1;
3172       return tree;
3173
3174     voidcheck:
3175
3176       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3177         {
3178           werror (E_VOID_FUNC, currFunc->name);
3179           goto errorTreeReturn;
3180         }
3181
3182       TTYPE (tree) = TETYPE (tree) = NULL;
3183       return tree;
3184
3185       /*------------------------------------------------------------------*/
3186       /*----------------------------*/
3187       /*     switch statement       */
3188       /*----------------------------*/
3189     case SWITCH:
3190       /* the switch value must be an integer */
3191       if (!IS_INTEGRAL (LTYPE (tree)))
3192         {
3193           werror (E_SWITCH_NON_INTEGER);
3194           goto errorTreeReturn;
3195         }
3196       LRVAL (tree) = 1;
3197       TTYPE (tree) = TETYPE (tree) = NULL;
3198       return tree;
3199
3200       /*------------------------------------------------------------------*/
3201       /*----------------------------*/
3202       /* ifx Statement              */
3203       /*----------------------------*/
3204     case IFX:
3205       tree->left = backPatchLabels (tree->left,
3206                                     tree->trueLabel,
3207                                     tree->falseLabel);
3208       TTYPE (tree) = TETYPE (tree) = NULL;
3209       return tree;
3210
3211       /*------------------------------------------------------------------*/
3212       /*----------------------------*/
3213       /* for Statement              */
3214       /*----------------------------*/
3215     case FOR:
3216
3217       decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3218       decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3219       decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3220
3221       /* if the for loop is reversible then
3222          reverse it otherwise do what we normally
3223          do */
3224       {
3225         symbol *sym;
3226         ast *init, *end;
3227
3228         if (isLoopReversible (tree, &sym, &init, &end))
3229           return reverseLoop (tree, sym, init, end);
3230         else
3231           return decorateType (createFor (AST_FOR (tree, trueLabel),
3232                                           AST_FOR (tree, continueLabel),
3233                                           AST_FOR (tree, falseLabel),
3234                                           AST_FOR (tree, condLabel),
3235                                           AST_FOR (tree, initExpr),
3236                                           AST_FOR (tree, condExpr),
3237                                           AST_FOR (tree, loopExpr),
3238                                           tree->left));
3239       }
3240     default:
3241       TTYPE (tree) = TETYPE (tree) = NULL;
3242       return tree;
3243     }
3244
3245   /* some error found this tree will be killed */
3246 errorTreeReturn:
3247   TTYPE (tree) = TETYPE (tree) = newCharLink ();
3248   tree->opval.op = NULLOP;
3249   tree->isError = 1;
3250
3251   return tree;
3252 }
3253
3254 /*-----------------------------------------------------------------*/
3255 /* sizeofOp - processes size of operation                          */
3256 /*-----------------------------------------------------------------*/
3257 value *
3258 sizeofOp (sym_link * type)
3259 {
3260   char buff[10];
3261
3262   /* make sure the type is complete and sane */
3263   checkTypeSanity(type, "(sizeof)");
3264
3265   /* get the size and convert it to character  */
3266   sprintf (buff, "%d", getSize (type));
3267
3268   /* now convert into value  */
3269   return constVal (buff);
3270 }
3271
3272
3273 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3274 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
3275 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3276 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3277 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3278 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
3279 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
3280
3281 /*-----------------------------------------------------------------*/
3282 /* backPatchLabels - change and or not operators to flow control    */
3283 /*-----------------------------------------------------------------*/
3284 ast *
3285 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3286 {
3287
3288   if (!tree)
3289     return NULL;
3290
3291   if (!(IS_ANDORNOT (tree)))
3292     return tree;
3293
3294   /* if this an and */
3295   if (IS_AND (tree))
3296     {
3297       static int localLbl = 0;
3298       symbol *localLabel;
3299
3300       sprintf (buffer, "_and_%d", localLbl++);
3301       localLabel = newSymbol (buffer, NestLevel);
3302
3303       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3304
3305       /* if left is already a IFX then just change the if true label in that */
3306       if (!IS_IFX (tree->left))
3307         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3308
3309       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3310       /* right is a IFX then just join */
3311       if (IS_IFX (tree->right))
3312         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3313
3314       tree->right = createLabel (localLabel, tree->right);
3315       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3316
3317       return newNode (NULLOP, tree->left, tree->right);
3318     }
3319
3320   /* if this is an or operation */
3321   if (IS_OR (tree))
3322     {
3323       static int localLbl = 0;
3324       symbol *localLabel;
3325
3326       sprintf (buffer, "_or_%d", localLbl++);
3327       localLabel = newSymbol (buffer, NestLevel);
3328
3329       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3330
3331       /* if left is already a IFX then just change the if true label in that */
3332       if (!IS_IFX (tree->left))
3333         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3334
3335       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3336       /* right is a IFX then just join */
3337       if (IS_IFX (tree->right))
3338         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3339
3340       tree->right = createLabel (localLabel, tree->right);
3341       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3342
3343       return newNode (NULLOP, tree->left, tree->right);
3344     }
3345
3346   /* change not */
3347   if (IS_NOT (tree))
3348     {
3349       int wasnot = IS_NOT (tree->left);
3350       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3351
3352       /* if the left is already a IFX */
3353       if (!IS_IFX (tree->left))
3354         tree->left = newNode (IFX, tree->left, NULL);
3355
3356       if (wasnot)
3357         {
3358           tree->left->trueLabel = trueLabel;
3359           tree->left->falseLabel = falseLabel;
3360         }
3361       else
3362         {
3363           tree->left->trueLabel = falseLabel;
3364           tree->left->falseLabel = trueLabel;
3365         }
3366       return tree->left;
3367     }
3368
3369   if (IS_IFX (tree))
3370     {
3371       tree->trueLabel = trueLabel;
3372       tree->falseLabel = falseLabel;
3373     }
3374
3375   return tree;
3376 }
3377
3378
3379 /*-----------------------------------------------------------------*/
3380 /* createBlock - create expression tree for block                  */
3381 /*-----------------------------------------------------------------*/
3382 ast *
3383 createBlock (symbol * decl, ast * body)
3384 {
3385   ast *ex;
3386
3387   /* if the block has nothing */
3388   if (!body)
3389     return NULL;
3390
3391   ex = newNode (BLOCK, NULL, body);
3392   ex->values.sym = decl;
3393
3394   ex->right = ex->right;
3395   ex->level++;
3396   ex->lineno = 0;
3397   return ex;
3398 }
3399
3400 /*-----------------------------------------------------------------*/
3401 /* createLabel - creates the expression tree for labels            */
3402 /*-----------------------------------------------------------------*/
3403 ast *
3404 createLabel (symbol * label, ast * stmnt)
3405 {
3406   symbol *csym;
3407   char name[SDCC_NAME_MAX + 1];
3408   ast *rValue;
3409
3410   /* must create fresh symbol if the symbol name  */
3411   /* exists in the symbol table, since there can  */
3412   /* be a variable with the same name as the labl */
3413   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3414       (csym->level == label->level))
3415     label = newSymbol (label->name, label->level);
3416
3417   /* change the name before putting it in add _ */
3418   sprintf (name, "%s", label->name);
3419
3420   /* put the label in the LabelSymbol table    */
3421   /* but first check if a label of the same    */
3422   /* name exists                               */
3423   if ((csym = findSym (LabelTab, NULL, name)))
3424     werror (E_DUPLICATE_LABEL, label->name);
3425   else
3426     addSym (LabelTab, label, name, label->level, 0, 0);
3427
3428   label->islbl = 1;
3429   label->key = labelKey++;
3430   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3431   rValue->lineno = 0;
3432
3433   return rValue;
3434 }
3435
3436 /*-----------------------------------------------------------------*/
3437 /* createCase - generates the parsetree for a case statement       */
3438 /*-----------------------------------------------------------------*/
3439 ast *
3440 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3441 {
3442   char caseLbl[SDCC_NAME_MAX + 1];
3443   ast *rexpr;
3444   value *val;
3445
3446   /* if the switch statement does not exist */
3447   /* then case is out of context            */
3448   if (!swStat)
3449     {
3450       werror (E_CASE_CONTEXT);
3451       return NULL;
3452     }
3453
3454   caseVal = decorateType (resolveSymbols (caseVal));
3455   /* if not a constant then error  */
3456   if (!IS_LITERAL (caseVal->ftype))
3457     {
3458       werror (E_CASE_CONSTANT);
3459       return NULL;
3460     }
3461
3462   /* if not a integer than error */
3463   if (!IS_INTEGRAL (caseVal->ftype))
3464     {
3465       werror (E_CASE_NON_INTEGER);
3466       return NULL;
3467     }
3468
3469   /* find the end of the switch values chain   */
3470   if (!(val = swStat->values.switchVals.swVals))
3471     swStat->values.switchVals.swVals = caseVal->opval.val;
3472   else
3473     {
3474       /* also order the cases according to value */
3475       value *pval = NULL;
3476       int cVal = (int) floatFromVal (caseVal->opval.val);
3477       while (val && (int) floatFromVal (val) < cVal)
3478         {
3479           pval = val;
3480           val = val->next;
3481         }
3482
3483       /* if we reached the end then */
3484       if (!val)
3485         {
3486           pval->next = caseVal->opval.val;
3487         }
3488       else
3489         {
3490           /* we found a value greater than */
3491           /* the current value we must add this */
3492           /* before the value */
3493           caseVal->opval.val->next = val;
3494
3495           /* if this was the first in chain */
3496           if (swStat->values.switchVals.swVals == val)
3497             swStat->values.switchVals.swVals =
3498               caseVal->opval.val;
3499           else
3500             pval->next = caseVal->opval.val;
3501         }
3502
3503     }
3504
3505   /* create the case label   */
3506   sprintf (caseLbl, "_case_%d_%d",
3507            swStat->values.switchVals.swNum,
3508            (int) floatFromVal (caseVal->opval.val));
3509
3510   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3511   rexpr->lineno = 0;
3512   return rexpr;
3513 }
3514
3515 /*-----------------------------------------------------------------*/
3516 /* createDefault - creates the parse tree for the default statement */
3517 /*-----------------------------------------------------------------*/
3518 ast *
3519 createDefault (ast * swStat, ast * stmnt)
3520 {
3521   char defLbl[SDCC_NAME_MAX + 1];
3522
3523   /* if the switch statement does not exist */
3524   /* then case is out of context            */
3525   if (!swStat)
3526     {
3527       werror (E_CASE_CONTEXT);
3528       return NULL;
3529     }
3530
3531   /* turn on the default flag   */
3532   swStat->values.switchVals.swDefault = 1;
3533
3534   /* create the label  */
3535   sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3536   return createLabel (newSymbol (defLbl, 0), stmnt);
3537 }
3538
3539 /*-----------------------------------------------------------------*/
3540 /* createIf - creates the parsetree for the if statement           */
3541 /*-----------------------------------------------------------------*/
3542 ast *
3543 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3544 {
3545   static int Lblnum = 0;
3546   ast *ifTree;
3547   symbol *ifTrue, *ifFalse, *ifEnd;
3548
3549   /* if neither exists */
3550   if (!elseBody && !ifBody) {
3551     // if there are no side effects (i++, j() etc)
3552     if (!hasSEFcalls(condAst)) {
3553       return condAst;
3554     }
3555   }
3556
3557   /* create the labels */
3558   sprintf (buffer, "_iffalse_%d", Lblnum);
3559   ifFalse = newSymbol (buffer, NestLevel);
3560   /* if no else body then end == false */
3561   if (!elseBody)
3562     ifEnd = ifFalse;
3563   else
3564     {
3565       sprintf (buffer, "_ifend_%d", Lblnum);
3566       ifEnd = newSymbol (buffer, NestLevel);
3567     }
3568
3569   sprintf (buffer, "_iftrue_%d", Lblnum);
3570   ifTrue = newSymbol (buffer, NestLevel);
3571
3572   Lblnum++;
3573
3574   /* attach the ifTrue label to the top of it body */
3575   ifBody = createLabel (ifTrue, ifBody);
3576   /* attach a goto end to the ifBody if else is present */
3577   if (elseBody)
3578     {
3579       ifBody = newNode (NULLOP, ifBody,
3580                         newNode (GOTO,
3581                                  newAst_VALUE (symbolVal (ifEnd)),
3582                                  NULL));
3583       /* put the elseLabel on the else body */
3584       elseBody = createLabel (ifFalse, elseBody);
3585       /* out the end at the end of the body */
3586       elseBody = newNode (NULLOP,
3587                           elseBody,
3588                           createLabel (ifEnd, NULL));
3589     }
3590   else
3591     {
3592       ifBody = newNode (NULLOP, ifBody,
3593                         createLabel (ifFalse, NULL));
3594     }
3595   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3596   if (IS_IFX (condAst))
3597     ifTree = condAst;
3598   else
3599     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3600
3601   return newNode (NULLOP, ifTree,
3602                   newNode (NULLOP, ifBody, elseBody));
3603
3604 }
3605
3606 /*-----------------------------------------------------------------*/
3607 /* createDo - creates parse tree for do                            */
3608 /*        _dobody_n:                                               */
3609 /*            statements                                           */
3610 /*        _docontinue_n:                                           */
3611 /*            condition_expression +-> trueLabel -> _dobody_n      */
3612 /*                                 |                               */
3613 /*                                 +-> falseLabel-> _dobreak_n     */
3614 /*        _dobreak_n:                                              */
3615 /*-----------------------------------------------------------------*/
3616 ast *
3617 createDo (symbol * trueLabel, symbol * continueLabel,
3618           symbol * falseLabel, ast * condAst, ast * doBody)
3619 {
3620   ast *doTree;
3621
3622
3623   /* if the body does not exist then it is simple */
3624   if (!doBody)
3625     {
3626       condAst = backPatchLabels (condAst, continueLabel, NULL);
3627       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3628                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3629       doTree->trueLabel = continueLabel;
3630       doTree->falseLabel = NULL;
3631       return doTree;
3632     }
3633
3634   /* otherwise we have a body */
3635   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3636
3637   /* attach the body label to the top */
3638   doBody = createLabel (trueLabel, doBody);
3639   /* attach the continue label to end of body */
3640   doBody = newNode (NULLOP, doBody,
3641                     createLabel (continueLabel, NULL));
3642
3643   /* now put the break label at the end */
3644   if (IS_IFX (condAst))
3645     doTree = condAst;
3646   else
3647     doTree = newIfxNode (condAst, trueLabel, falseLabel);
3648
3649   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3650
3651   /* putting it together */
3652   return newNode (NULLOP, doBody, doTree);
3653 }
3654
3655 /*-----------------------------------------------------------------*/
3656 /* createFor - creates parse tree for 'for' statement              */
3657 /*        initExpr                                                 */
3658 /*   _forcond_n:                                                   */
3659 /*        condExpr  +-> trueLabel -> _forbody_n                    */
3660 /*                  |                                              */
3661 /*                  +-> falseLabel-> _forbreak_n                   */
3662 /*   _forbody_n:                                                   */
3663 /*        statements                                               */
3664 /*   _forcontinue_n:                                               */
3665 /*        loopExpr                                                 */
3666 /*        goto _forcond_n ;                                        */
3667 /*   _forbreak_n:                                                  */
3668 /*-----------------------------------------------------------------*/
3669 ast *
3670 createFor (symbol * trueLabel, symbol * continueLabel,
3671            symbol * falseLabel, symbol * condLabel,
3672            ast * initExpr, ast * condExpr, ast * loopExpr,
3673            ast * forBody)
3674 {
3675   ast *forTree;
3676
3677   /* if loopexpression not present then we can generate it */
3678   /* the same way as a while */
3679   if (!loopExpr)
3680     return newNode (NULLOP, initExpr,
3681                     createWhile (trueLabel, continueLabel,
3682                                  falseLabel, condExpr, forBody));
3683   /* vanilla for statement */
3684   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3685
3686   if (condExpr && !IS_IFX (condExpr))
3687     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3688
3689
3690   /* attach condition label to condition */
3691   condExpr = createLabel (condLabel, condExpr);
3692
3693   /* attach body label to body */
3694   forBody = createLabel (trueLabel, forBody);
3695
3696   /* attach continue to forLoop expression & attach */
3697   /* goto the forcond @ and of loopExpression       */
3698   loopExpr = createLabel (continueLabel,
3699                           newNode (NULLOP,
3700                                    loopExpr,
3701                                    newNode (GOTO,
3702                                        newAst_VALUE (symbolVal (condLabel)),
3703                                             NULL)));
3704   /* now start putting them together */
3705   forTree = newNode (NULLOP, initExpr, condExpr);
3706   forTree = newNode (NULLOP, forTree, forBody);
3707   forTree = newNode (NULLOP, forTree, loopExpr);
3708   /* finally add the break label */
3709   forTree = newNode (NULLOP, forTree,
3710                      createLabel (falseLabel, NULL));
3711   return forTree;
3712 }
3713
3714 /*-----------------------------------------------------------------*/
3715 /* createWhile - creates parse tree for while statement            */
3716 /*               the while statement will be created as follows    */
3717 /*                                                                 */
3718 /*      _while_continue_n:                                         */
3719 /*            condition_expression +-> trueLabel -> _while_boby_n  */
3720 /*                                 |                               */
3721 /*                                 +-> falseLabel -> _while_break_n */
3722 /*      _while_body_n:                                             */
3723 /*            statements                                           */
3724 /*            goto _while_continue_n                               */
3725 /*      _while_break_n:                                            */
3726 /*-----------------------------------------------------------------*/
3727 ast *
3728 createWhile (symbol * trueLabel, symbol * continueLabel,
3729              symbol * falseLabel, ast * condExpr, ast * whileBody)
3730 {
3731   ast *whileTree;
3732
3733   /* put the continue label */
3734   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3735   condExpr = createLabel (continueLabel, condExpr);
3736   condExpr->lineno = 0;
3737
3738   /* put the body label in front of the body */
3739   whileBody = createLabel (trueLabel, whileBody);
3740   whileBody->lineno = 0;
3741   /* put a jump to continue at the end of the body */
3742   /* and put break label at the end of the body */
3743   whileBody = newNode (NULLOP,
3744                        whileBody,
3745                        newNode (GOTO,
3746                                 newAst_VALUE (symbolVal (continueLabel)),
3747                                 createLabel (falseLabel, NULL)));
3748
3749   /* put it all together */
3750   if (IS_IFX (condExpr))
3751     whileTree = condExpr;
3752   else
3753     {
3754       whileTree = newNode (IFX, condExpr, NULL);
3755       /* put the true & false labels in place */
3756       whileTree->trueLabel = trueLabel;
3757       whileTree->falseLabel = falseLabel;
3758     }
3759
3760   return newNode (NULLOP, whileTree, whileBody);
3761 }
3762
3763 /*-----------------------------------------------------------------*/
3764 /* optimizeGetHbit - get highest order bit of the expression       */
3765 /*-----------------------------------------------------------------*/
3766 ast *
3767 optimizeGetHbit (ast * tree)
3768 {
3769   int i, j;
3770   /* if this is not a bit and */
3771   if (!IS_BITAND (tree))
3772     return tree;
3773
3774   /* will look for tree of the form
3775      ( expr >> ((sizeof expr) -1) ) & 1 */
3776   if (!IS_AST_LIT_VALUE (tree->right))
3777     return tree;
3778
3779   if (AST_LIT_VALUE (tree->right) != 1)
3780     return tree;
3781
3782   if (!IS_RIGHT_OP (tree->left))
3783     return tree;
3784
3785   if (!IS_AST_LIT_VALUE (tree->left->right))
3786     return tree;
3787
3788   if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3789       (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3790     return tree;
3791
3792   return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3793
3794 }
3795
3796 /*-----------------------------------------------------------------*/
3797 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
3798 /*-----------------------------------------------------------------*/
3799 ast *
3800 optimizeRRCRLC (ast * root)
3801 {
3802   /* will look for trees of the form
3803      (?expr << 1) | (?expr >> 7) or
3804      (?expr >> 7) | (?expr << 1) will make that
3805      into a RLC : operation ..
3806      Will also look for
3807      (?expr >> 1) | (?expr << 7) or
3808      (?expr << 7) | (?expr >> 1) will make that
3809      into a RRC operation
3810      note : by 7 I mean (number of bits required to hold the
3811      variable -1 ) */
3812   /* if the root operations is not a | operation the not */
3813   if (!IS_BITOR (root))
3814     return root;
3815
3816   /* I have to think of a better way to match patterns this sucks */
3817   /* that aside let start looking for the first case : I use a the
3818      negative check a lot to improve the efficiency */
3819   /* (?expr << 1) | (?expr >> 7) */
3820   if (IS_LEFT_OP (root->left) &&
3821       IS_RIGHT_OP (root->right))
3822     {
3823
3824       if (!SPEC_USIGN (TETYPE (root->left->left)))
3825         return root;
3826
3827       if (!IS_AST_LIT_VALUE (root->left->right) ||
3828           !IS_AST_LIT_VALUE (root->right->right))
3829         goto tryNext0;
3830
3831       /* make sure it is the same expression */
3832       if (!isAstEqual (root->left->left,
3833                        root->right->left))
3834         goto tryNext0;
3835
3836       if (AST_LIT_VALUE (root->left->right) != 1)
3837         goto tryNext0;
3838
3839       if (AST_LIT_VALUE (root->right->right) !=
3840           (getSize (TTYPE (root->left->left)) * 8 - 1))
3841         goto tryNext0;
3842
3843       /* whew got the first case : create the AST */
3844       return newNode (RLC, root->left->left, NULL);
3845     }
3846
3847 tryNext0:
3848   /* check for second case */
3849   /* (?expr >> 7) | (?expr << 1) */
3850   if (IS_LEFT_OP (root->right) &&
3851       IS_RIGHT_OP (root->left))
3852     {
3853
3854       if (!SPEC_USIGN (TETYPE (root->left->left)))
3855         return root;
3856
3857       if (!IS_AST_LIT_VALUE (root->left->right) ||
3858           !IS_AST_LIT_VALUE (root->right->right))
3859         goto tryNext1;
3860
3861       /* make sure it is the same symbol */
3862       if (!isAstEqual (root->left->left,
3863                        root->right->left))
3864         goto tryNext1;
3865
3866       if (AST_LIT_VALUE (root->right->right) != 1)
3867         goto tryNext1;
3868
3869       if (AST_LIT_VALUE (root->left->right) !=
3870           (getSize (TTYPE (root->left->left)) * 8 - 1))
3871         goto tryNext1;
3872
3873       /* whew got the first case : create the AST */
3874       return newNode (RLC, root->left->left, NULL);
3875
3876     }
3877
3878 tryNext1:
3879   /* third case for RRC */
3880   /*  (?symbol >> 1) | (?symbol << 7) */
3881   if (IS_LEFT_OP (root->right) &&
3882       IS_RIGHT_OP (root->left))
3883     {
3884
3885       if (!SPEC_USIGN (TETYPE (root->left->left)))
3886         return root;
3887
3888       if (!IS_AST_LIT_VALUE (root->left->right) ||
3889           !IS_AST_LIT_VALUE (root->right->right))
3890         goto tryNext2;
3891
3892       /* make sure it is the same symbol */
3893       if (!isAstEqual (root->left->left,
3894                        root->right->left))
3895         goto tryNext2;
3896
3897       if (AST_LIT_VALUE (root->left->right) != 1)
3898         goto tryNext2;
3899
3900       if (AST_LIT_VALUE (root->right->right) !=
3901           (getSize (TTYPE (root->left->left)) * 8 - 1))
3902         goto tryNext2;
3903
3904       /* whew got the first case : create the AST */
3905       return newNode (RRC, root->left->left, NULL);
3906
3907     }
3908 tryNext2:
3909   /* fourth and last case for now */
3910   /* (?symbol << 7) | (?symbol >> 1) */
3911   if (IS_RIGHT_OP (root->right) &&
3912       IS_LEFT_OP (root->left))
3913     {
3914
3915       if (!SPEC_USIGN (TETYPE (root->left->left)))
3916         return root;
3917
3918       if (!IS_AST_LIT_VALUE (root->left->right) ||
3919           !IS_AST_LIT_VALUE (root->right->right))
3920         return root;
3921
3922       /* make sure it is the same symbol */
3923       if (!isAstEqual (root->left->left,
3924                        root->right->left))
3925         return root;
3926
3927       if (AST_LIT_VALUE (root->right->right) != 1)
3928         return root;
3929
3930       if (AST_LIT_VALUE (root->left->right) !=
3931           (getSize (TTYPE (root->left->left)) * 8 - 1))
3932         return root;
3933
3934       /* whew got the first case : create the AST */
3935       return newNode (RRC, root->left->left, NULL);
3936
3937     }
3938
3939   /* not found return root */
3940   return root;
3941 }
3942
3943 /*-----------------------------------------------------------------*/
3944 /* optimizeCompare - otimizes compares for bit variables     */
3945 /*-----------------------------------------------------------------*/
3946 static ast *
3947 optimizeCompare (ast * root)
3948 {
3949   ast *optExpr = NULL;
3950   value *vleft;
3951   value *vright;
3952   unsigned int litValue;
3953
3954   /* if nothing then return nothing */
3955   if (!root)
3956     return NULL;
3957
3958   /* if not a compare op then do leaves */
3959   if (!IS_COMPARE_OP (root))
3960     {
3961       root->left = optimizeCompare (root->left);
3962       root->right = optimizeCompare (root->right);
3963       return root;
3964     }
3965
3966   /* if left & right are the same then depending
3967      of the operation do */
3968   if (isAstEqual (root->left, root->right))
3969     {
3970       switch (root->opval.op)
3971         {
3972         case '>':
3973         case '<':
3974         case NE_OP:
3975           optExpr = newAst_VALUE (constVal ("0"));
3976           break;
3977         case GE_OP:
3978         case LE_OP:
3979         case EQ_OP:
3980           optExpr = newAst_VALUE (constVal ("1"));
3981           break;
3982         }
3983
3984       return decorateType (optExpr);
3985     }
3986
3987   vleft = (root->left->type == EX_VALUE ?
3988            root->left->opval.val : NULL);
3989
3990   vright = (root->right->type == EX_VALUE ?
3991             root->right->opval.val : NULL);
3992
3993   /* if left is a BITVAR in BITSPACE */
3994   /* and right is a LITERAL then opt- */
3995   /* imize else do nothing       */
3996   if (vleft && vright &&
3997       IS_BITVAR (vleft->etype) &&
3998       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3999       IS_LITERAL (vright->etype))
4000     {
4001
4002       /* if right side > 1 then comparison may never succeed */
4003       if ((litValue = (int) floatFromVal (vright)) > 1)
4004         {
4005           werror (W_BAD_COMPARE);
4006           goto noOptimize;
4007         }
4008
4009       if (litValue)
4010         {
4011           switch (root->opval.op)
4012             {
4013             case '>':           /* bit value greater than 1 cannot be */
4014               werror (W_BAD_COMPARE);
4015               goto noOptimize;
4016               break;
4017
4018             case '<':           /* bit value < 1 means 0 */
4019             case NE_OP:
4020               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4021               break;
4022
4023             case LE_OP: /* bit value <= 1 means no check */
4024               optExpr = newAst_VALUE (vright);
4025               break;
4026
4027             case GE_OP: /* bit value >= 1 means only check for = */
4028             case EQ_OP:
4029               optExpr = newAst_VALUE (vleft);
4030               break;
4031             }
4032         }
4033       else
4034         {                       /* literal is zero */
4035           switch (root->opval.op)
4036             {
4037             case '<':           /* bit value < 0 cannot be */
4038               werror (W_BAD_COMPARE);
4039               goto noOptimize;
4040               break;
4041
4042             case '>':           /* bit value > 0 means 1 */
4043             case NE_OP:
4044               optExpr = newAst_VALUE (vleft);
4045               break;
4046
4047             case LE_OP: /* bit value <= 0 means no check */
4048             case GE_OP: /* bit value >= 0 means no check */
4049               werror (W_BAD_COMPARE);
4050               goto noOptimize;
4051               break;
4052
4053             case EQ_OP: /* bit == 0 means ! of bit */
4054               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4055               break;
4056             }
4057         }
4058       return decorateType (resolveSymbols (optExpr));
4059     }                           /* end-of-if of BITVAR */
4060
4061 noOptimize:
4062   return root;
4063 }
4064 /*-----------------------------------------------------------------*/
4065 /* addSymToBlock : adds the symbol to the first block we find      */
4066 /*-----------------------------------------------------------------*/
4067 void 
4068 addSymToBlock (symbol * sym, ast * tree)
4069 {
4070   /* reached end of tree or a leaf */
4071   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4072     return;
4073
4074   /* found a block */
4075   if (IS_AST_OP (tree) &&
4076       tree->opval.op == BLOCK)
4077     {
4078
4079       symbol *lsym = copySymbol (sym);
4080
4081       lsym->next = AST_VALUES (tree, sym);
4082       AST_VALUES (tree, sym) = lsym;
4083       return;
4084     }
4085
4086   addSymToBlock (sym, tree->left);
4087   addSymToBlock (sym, tree->right);
4088 }
4089
4090 /*-----------------------------------------------------------------*/
4091 /* processRegParms - do processing for register parameters         */
4092 /*-----------------------------------------------------------------*/
4093 static void 
4094 processRegParms (value * args, ast * body)
4095 {
4096   while (args)
4097     {
4098       if (IS_REGPARM (args->etype))
4099         addSymToBlock (args->sym, body);
4100       args = args->next;
4101     }
4102 }
4103
4104 /*-----------------------------------------------------------------*/
4105 /* resetParmKey - resets the operandkeys for the symbols           */
4106 /*-----------------------------------------------------------------*/
4107 DEFSETFUNC (resetParmKey)
4108 {
4109   symbol *sym = item;
4110
4111   sym->key = 0;
4112   sym->defs = NULL;
4113   sym->uses = NULL;
4114   sym->remat = 0;
4115   return 1;
4116 }
4117
4118 /*-----------------------------------------------------------------*/
4119 /* createFunction - This is the key node that calls the iCode for  */
4120 /*                  generating the code for a function. Note code  */
4121 /*                  is generated function by function, later when  */
4122 /*                  add inter-procedural analysis this will change */
4123 /*-----------------------------------------------------------------*/
4124 ast *
4125 createFunction (symbol * name, ast * body)
4126 {
4127   ast *ex;
4128   symbol *csym;
4129   int stack = 0;
4130   sym_link *fetype;
4131   iCode *piCode = NULL;
4132
4133   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4134     fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4135
4136   /* if check function return 0 then some problem */
4137   if (checkFunction (name, NULL) == 0)
4138     return NULL;
4139
4140   /* create a dummy block if none exists */
4141   if (!body)
4142     body = newNode (BLOCK, NULL, NULL);
4143
4144   noLineno++;
4145
4146   /* check if the function name already in the symbol table */
4147   if ((csym = findSym (SymbolTab, NULL, name->name)))
4148     {
4149       name = csym;
4150       /* special case for compiler defined functions
4151          we need to add the name to the publics list : this
4152          actually means we are now compiling the compiler
4153          support routine */
4154       if (name->cdef)
4155         {
4156           addSet (&publics, name);
4157         }
4158     }
4159   else
4160     {
4161       addSymChain (name);
4162       allocVariables (name);
4163     }
4164   name->lastLine = yylineno;
4165   currFunc = name;
4166
4167   /* set the stack pointer */
4168   /* PENDING: check this for the mcs51 */
4169   stackPtr = -port->stack.direction * port->stack.call_overhead;
4170   if (IFFUNC_ISISR (name->type))
4171     stackPtr -= port->stack.direction * port->stack.isr_overhead;
4172   if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4173     stackPtr -= port->stack.direction * port->stack.reent_overhead;
4174
4175   xstackPtr = -port->stack.direction * port->stack.call_overhead;
4176
4177   fetype = getSpec (name->type);        /* get the specifier for the function */
4178   /* if this is a reentrant function then */
4179   if (IFFUNC_ISREENT (name->type))
4180     reentrant++;
4181
4182   allocParms (FUNC_ARGS(name->type));   /* allocate the parameters */
4183
4184   /* do processing for parameters that are passed in registers */
4185   processRegParms (FUNC_ARGS(name->type), body);
4186
4187   /* set the stack pointer */
4188   stackPtr = 0;
4189   xstackPtr = -1;
4190
4191   /* allocate & autoinit the block variables */
4192   processBlockVars (body, &stack, ALLOCATE);
4193
4194   /* save the stack information */
4195   if (options.useXstack)
4196     name->xstack = SPEC_STAK (fetype) = stack;
4197   else
4198     name->stack = SPEC_STAK (fetype) = stack;
4199
4200   /* name needs to be mangled */
4201   sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4202
4203   body = resolveSymbols (body); /* resolve the symbols */
4204   body = decorateType (body);   /* propagateType & do semantic checks */
4205
4206   ex = newAst_VALUE (symbolVal (name)); /* create name */
4207   ex = newNode (FUNCTION, ex, body);
4208   ex->values.args = FUNC_ARGS(name->type);
4209   ex->decorated=1;
4210   if (options.dump_tree) PA(ex);
4211   if (fatalError)
4212     {
4213       werror (E_FUNC_NO_CODE, name->name);
4214       goto skipall;
4215     }
4216
4217   /* create the node & generate intermediate code */
4218   GcurMemmap = code;
4219   codeOutFile = code->oFile;
4220   piCode = iCodeFromAst (ex);
4221
4222   if (fatalError)
4223     {
4224       werror (E_FUNC_NO_CODE, name->name);
4225       goto skipall;
4226     }
4227
4228   eBBlockFromiCode (piCode);
4229
4230   /* if there are any statics then do them */
4231   if (staticAutos)
4232     {
4233       GcurMemmap = statsg;
4234       codeOutFile = statsg->oFile;
4235       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4236       staticAutos = NULL;
4237     }
4238
4239 skipall:
4240
4241   /* dealloc the block variables */
4242   processBlockVars (body, &stack, DEALLOCATE);
4243   /* deallocate paramaters */
4244   deallocParms (FUNC_ARGS(name->type));
4245
4246   if (IFFUNC_ISREENT (name->type))
4247     reentrant--;
4248
4249   /* we are done freeup memory & cleanup */
4250   noLineno--;
4251   if (port->reset_labelKey) labelKey = 1;
4252   name->key = 0;
4253   FUNC_HASBODY(name->type) = 1;
4254   addSet (&operKeyReset, name);
4255   applyToSet (operKeyReset, resetParmKey);
4256
4257   if (options.debug)
4258     cdbStructBlock (1, cdbFile);
4259
4260   cleanUpLevel (LabelTab, 0);
4261   cleanUpBlock (StructTab, 1);
4262   cleanUpBlock (TypedefTab, 1);
4263
4264   xstack->syms = NULL;
4265   istack->syms = NULL;
4266   return NULL;
4267 }
4268
4269
4270 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4271 /*-----------------------------------------------------------------*/
4272 /* ast_print : prints the ast (for debugging purposes)             */
4273 /*-----------------------------------------------------------------*/
4274
4275 void ast_print (ast * tree, FILE *outfile, int indent)
4276 {
4277         
4278         if (!tree) return ;
4279
4280         /* can print only decorated trees */
4281         if (!tree->decorated) return;
4282
4283         /* if any child is an error | this one is an error do nothing */
4284         if (tree->isError ||
4285             (tree->left && tree->left->isError) ||
4286             (tree->right && tree->right->isError)) {
4287                 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4288         }
4289
4290         
4291         /* print the line          */
4292         /* if not block & function */
4293         if (tree->type == EX_OP &&
4294             (tree->opval.op != FUNCTION &&
4295              tree->opval.op != BLOCK &&
4296              tree->opval.op != NULLOP)) {
4297         }
4298         
4299         if (tree->opval.op == FUNCTION) {
4300                 int arg=0;
4301                 value *args=FUNC_ARGS(tree->left->opval.val->type);
4302                 fprintf(outfile,"FUNCTION (%s=%p) type (", 
4303                         tree->left->opval.val->name, tree);
4304                 printTypeChain (tree->ftype,outfile);
4305                 fprintf(outfile,") args (");
4306                 do {
4307                   if (arg) {
4308                     fprintf (outfile, ", ");
4309                   }
4310                   printTypeChain (args ? args->type : NULL, outfile);
4311                   arg++;
4312                   args= args ? args->next : NULL;
4313                 } while (args);
4314                 fprintf(outfile,")\n");
4315                 ast_print(tree->left,outfile,indent);
4316                 ast_print(tree->right,outfile,indent);
4317                 return ;
4318         }
4319         if (tree->opval.op == BLOCK) {
4320                 symbol *decls = tree->values.sym;
4321                 INDENT(indent,outfile);
4322                 fprintf(outfile,"{\n");
4323                 while (decls) {
4324                         INDENT(indent+2,outfile);
4325                         fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4326                                 decls->name, decls);
4327                         printTypeChain(decls->type,outfile);
4328                         fprintf(outfile,")\n");
4329                         
4330                         decls = decls->next;                    
4331                 }
4332                 ast_print(tree->right,outfile,indent+2);
4333                 INDENT(indent,outfile);
4334                 fprintf(outfile,"}\n");
4335                 return;
4336         }
4337         if (tree->opval.op == NULLOP) {
4338                 fprintf(outfile,"\n");
4339                 ast_print(tree->left,outfile,indent);
4340                 fprintf(outfile,"\n");
4341                 ast_print(tree->right,outfile,indent);
4342                 return ;
4343         }
4344         INDENT(indent,outfile);
4345
4346         /*------------------------------------------------------------------*/
4347         /*----------------------------*/
4348         /*   leaf has been reached    */
4349         /*----------------------------*/
4350         /* if this is of type value */
4351         /* just get the type        */
4352         if (tree->type == EX_VALUE) {
4353
4354                 if (IS_LITERAL (tree->opval.val->etype)) {                      
4355                         fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4356                                 (int) floatFromVal(tree->opval.val),
4357                                 (int) floatFromVal(tree->opval.val),
4358                                 floatFromVal(tree->opval.val));
4359                 } else if (tree->opval.val->sym) {
4360                         /* if the undefined flag is set then give error message */
4361                         if (tree->opval.val->sym->undefined) {
4362                                 fprintf(outfile,"UNDEFINED SYMBOL ");
4363                         } else {
4364                                 fprintf(outfile,"SYMBOL ");
4365                         }
4366                         fprintf(outfile,"(%s=%p)",
4367                                 tree->opval.val->sym->name,tree);
4368                 }
4369                 if (tree->ftype) {
4370                         fprintf(outfile," type (");
4371                         printTypeChain(tree->ftype,outfile);
4372                         fprintf(outfile,")\n");
4373                 } else {
4374                         fprintf(outfile,"\n");
4375                 }
4376                 return ;
4377         }
4378
4379         /* if type link for the case of cast */
4380         if (tree->type == EX_LINK) {
4381                 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4382                 printTypeChain(tree->opval.lnk,outfile);
4383                 fprintf(outfile,")\n");
4384                 return ;
4385         }
4386
4387
4388         /* depending on type of operator do */
4389         
4390         switch (tree->opval.op) {
4391                 /*------------------------------------------------------------------*/
4392                 /*----------------------------*/
4393                 /*        array node          */
4394                 /*----------------------------*/
4395         case '[':
4396                 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4397                 printTypeChain(tree->ftype,outfile);
4398                 fprintf(outfile,")\n");
4399                 ast_print(tree->left,outfile,indent+2);
4400                 ast_print(tree->right,outfile,indent+2);
4401                 return;
4402
4403                 /*------------------------------------------------------------------*/
4404                 /*----------------------------*/
4405                 /*      struct/union          */
4406                 /*----------------------------*/
4407         case '.':
4408                 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4409                 printTypeChain(tree->ftype,outfile);
4410                 fprintf(outfile,")\n");
4411                 ast_print(tree->left,outfile,indent+2);
4412                 ast_print(tree->right,outfile,indent+2);
4413                 return ;
4414
4415                 /*------------------------------------------------------------------*/
4416                 /*----------------------------*/
4417                 /*    struct/union pointer    */
4418                 /*----------------------------*/
4419         case PTR_OP:
4420                 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4421                 printTypeChain(tree->ftype,outfile);
4422                 fprintf(outfile,")\n");
4423                 ast_print(tree->left,outfile,indent+2);
4424                 ast_print(tree->right,outfile,indent+2);
4425                 return ;
4426
4427                 /*------------------------------------------------------------------*/
4428                 /*----------------------------*/
4429                 /*  ++/-- operation           */
4430                 /*----------------------------*/
4431         case INC_OP:            /* incerement operator unary so left only */
4432                 fprintf(outfile,"INC_OP (%p) type (",tree);
4433                 printTypeChain(tree->ftype,outfile);
4434                 fprintf(outfile,")\n");
4435                 ast_print(tree->left,outfile,indent+2);
4436                 return ;
4437
4438         case DEC_OP:
4439                 fprintf(outfile,"DEC_OP (%p) type (",tree);
4440                 printTypeChain(tree->ftype,outfile);
4441                 fprintf(outfile,")\n");
4442                 ast_print(tree->left,outfile,indent+2);
4443                 return ;
4444
4445                 /*------------------------------------------------------------------*/
4446                 /*----------------------------*/
4447                 /*  bitwise and               */
4448                 /*----------------------------*/
4449         case '&':                       
4450                 if (tree->right) {
4451                         fprintf(outfile,"& (%p) type (",tree);
4452                         printTypeChain(tree->ftype,outfile);
4453                         fprintf(outfile,")\n");
4454                         ast_print(tree->left,outfile,indent+2);
4455                         ast_print(tree->right,outfile,indent+2);
4456                 } else {
4457                         fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4458                         printTypeChain(tree->ftype,outfile);
4459                         fprintf(outfile,")\n");
4460                         ast_print(tree->left,outfile,indent+2);
4461                         ast_print(tree->right,outfile,indent+2);
4462                 }
4463                 return ;
4464                 /*----------------------------*/
4465                 /*  bitwise or                */
4466                 /*----------------------------*/
4467         case '|':
4468                 fprintf(outfile,"OR (%p) type (",tree);
4469                 printTypeChain(tree->ftype,outfile);
4470                 fprintf(outfile,")\n");
4471                 ast_print(tree->left,outfile,indent+2);
4472                 ast_print(tree->right,outfile,indent+2);
4473                 return ;
4474                 /*------------------------------------------------------------------*/
4475                 /*----------------------------*/
4476                 /*  bitwise xor               */
4477                 /*----------------------------*/
4478         case '^':
4479                 fprintf(outfile,"XOR (%p) type (",tree);
4480                 printTypeChain(tree->ftype,outfile);
4481                 fprintf(outfile,")\n");
4482                 ast_print(tree->left,outfile,indent+2);
4483                 ast_print(tree->right,outfile,indent+2);
4484                 return ;
4485                 
4486                 /*------------------------------------------------------------------*/
4487                 /*----------------------------*/
4488                 /*  division                  */
4489                 /*----------------------------*/
4490         case '/':
4491                 fprintf(outfile,"DIV (%p) type (",tree);
4492                 printTypeChain(tree->ftype,outfile);
4493                 fprintf(outfile,")\n");
4494                 ast_print(tree->left,outfile,indent+2);
4495                 ast_print(tree->right,outfile,indent+2);
4496                 return ;
4497                 /*------------------------------------------------------------------*/
4498                 /*----------------------------*/
4499                 /*            modulus         */
4500                 /*----------------------------*/
4501         case '%':
4502                 fprintf(outfile,"MOD (%p) type (",tree);
4503                 printTypeChain(tree->ftype,outfile);
4504                 fprintf(outfile,")\n");
4505                 ast_print(tree->left,outfile,indent+2);
4506                 ast_print(tree->right,outfile,indent+2);
4507                 return ;
4508
4509                 /*------------------------------------------------------------------*/
4510                 /*----------------------------*/
4511                 /*  address dereference       */
4512                 /*----------------------------*/
4513         case '*':                       /* can be unary  : if right is null then unary operation */
4514                 if (!tree->right) {
4515                         fprintf(outfile,"DEREF (%p) type (",tree);
4516                         printTypeChain(tree->ftype,outfile);
4517                         fprintf(outfile,")\n");
4518                         ast_print(tree->left,outfile,indent+2);
4519                         return ;
4520                 }                       
4521                 /*------------------------------------------------------------------*/
4522                 /*----------------------------*/
4523                 /*      multiplication        */
4524                 /*----------------------------*/                
4525                 fprintf(outfile,"MULT (%p) type (",tree);
4526                 printTypeChain(tree->ftype,outfile);
4527                 fprintf(outfile,")\n");
4528                 ast_print(tree->left,outfile,indent+2);
4529                 ast_print(tree->right,outfile,indent+2);
4530                 return ;
4531
4532
4533                 /*------------------------------------------------------------------*/
4534                 /*----------------------------*/
4535                 /*    unary '+' operator      */
4536                 /*----------------------------*/
4537         case '+':
4538                 /* if unary plus */
4539                 if (!tree->right) {
4540                         fprintf(outfile,"UPLUS (%p) type (",tree);
4541                         printTypeChain(tree->ftype,outfile);
4542                         fprintf(outfile,")\n");
4543                         ast_print(tree->left,outfile,indent+2);
4544                 } else {
4545                         /*------------------------------------------------------------------*/
4546                         /*----------------------------*/
4547                         /*      addition              */
4548                         /*----------------------------*/
4549                         fprintf(outfile,"ADD (%p) type (",tree);
4550                         printTypeChain(tree->ftype,outfile);
4551                         fprintf(outfile,")\n");
4552                         ast_print(tree->left,outfile,indent+2);
4553                         ast_print(tree->right,outfile,indent+2);
4554                 }
4555                 return;
4556                 /*------------------------------------------------------------------*/
4557                 /*----------------------------*/
4558                 /*      unary '-'             */
4559                 /*----------------------------*/
4560         case '-':                       /* can be unary   */
4561                 if (!tree->right) {
4562                         fprintf(outfile,"UMINUS (%p) type (",tree);
4563                         printTypeChain(tree->ftype,outfile);
4564                         fprintf(outfile,")\n");
4565                         ast_print(tree->left,outfile,indent+2);
4566                 } else {
4567                         /*------------------------------------------------------------------*/
4568                         /*----------------------------*/
4569                         /*      subtraction           */
4570                         /*----------------------------*/
4571                         fprintf(outfile,"SUB (%p) type (",tree);
4572                         printTypeChain(tree->ftype,outfile);
4573                         fprintf(outfile,")\n");
4574                         ast_print(tree->left,outfile,indent+2);
4575                         ast_print(tree->right,outfile,indent+2);
4576                 }
4577                 return;
4578                 /*------------------------------------------------------------------*/
4579                 /*----------------------------*/
4580                 /*    compliment              */
4581                 /*----------------------------*/
4582         case '~':
4583                 fprintf(outfile,"COMPL (%p) type (",tree);
4584                 printTypeChain(tree->ftype,outfile);
4585                 fprintf(outfile,")\n");
4586                 ast_print(tree->left,outfile,indent+2);
4587                 return ;
4588                 /*------------------------------------------------------------------*/
4589                 /*----------------------------*/
4590                 /*           not              */
4591                 /*----------------------------*/
4592         case '!':
4593                 fprintf(outfile,"NOT (%p) type (",tree);
4594                 printTypeChain(tree->ftype,outfile);
4595                 fprintf(outfile,")\n");
4596                 ast_print(tree->left,outfile,indent+2);
4597                 return ;
4598                 /*------------------------------------------------------------------*/
4599                 /*----------------------------*/
4600                 /*           shift            */
4601                 /*----------------------------*/
4602         case RRC:
4603                 fprintf(outfile,"RRC (%p) type (",tree);
4604                 printTypeChain(tree->ftype,outfile);
4605                 fprintf(outfile,")\n");
4606                 ast_print(tree->left,outfile,indent+2);
4607                 return ;
4608
4609         case RLC:
4610                 fprintf(outfile,"RLC (%p) type (",tree);
4611                 printTypeChain(tree->ftype,outfile);
4612                 fprintf(outfile,")\n");
4613                 ast_print(tree->left,outfile,indent+2);
4614                 return ;
4615         case GETHBIT:
4616                 fprintf(outfile,"GETHBIT (%p) type (",tree);
4617                 printTypeChain(tree->ftype,outfile);
4618                 fprintf(outfile,")\n");
4619                 ast_print(tree->left,outfile,indent+2);
4620                 return ;
4621         case LEFT_OP:
4622                 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4623                 printTypeChain(tree->ftype,outfile);
4624                 fprintf(outfile,")\n");
4625                 ast_print(tree->left,outfile,indent+2);
4626                 ast_print(tree->right,outfile,indent+2);
4627                 return ;
4628         case RIGHT_OP:
4629                 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4630                 printTypeChain(tree->ftype,outfile);
4631                 fprintf(outfile,")\n");
4632                 ast_print(tree->left,outfile,indent+2);
4633                 ast_print(tree->right,outfile,indent+2);
4634                 return ;
4635                 /*------------------------------------------------------------------*/
4636                 /*----------------------------*/
4637                 /*         casting            */
4638                 /*----------------------------*/
4639         case CAST:                      /* change the type   */
4640                 fprintf(outfile,"CAST (%p) from type (",tree);
4641                 printTypeChain(tree->right->ftype,outfile);
4642                 fprintf(outfile,") to type (");
4643                 printTypeChain(tree->ftype,outfile);
4644                 fprintf(outfile,")\n");
4645                 ast_print(tree->right,outfile,indent+2);
4646                 return ;
4647                 
4648         case AND_OP:
4649                 fprintf(outfile,"ANDAND (%p) type (",tree);
4650                 printTypeChain(tree->ftype,outfile);
4651                 fprintf(outfile,")\n");
4652                 ast_print(tree->left,outfile,indent+2);
4653                 ast_print(tree->right,outfile,indent+2);
4654                 return ;
4655         case OR_OP:
4656                 fprintf(outfile,"OROR (%p) type (",tree);
4657                 printTypeChain(tree->ftype,outfile);
4658                 fprintf(outfile,")\n");
4659                 ast_print(tree->left,outfile,indent+2);
4660                 ast_print(tree->right,outfile,indent+2);
4661                 return ;
4662                 
4663                 /*------------------------------------------------------------------*/
4664                 /*----------------------------*/
4665                 /*     comparison operators   */
4666                 /*----------------------------*/
4667         case '>':
4668                 fprintf(outfile,"GT(>) (%p) type (",tree);
4669                 printTypeChain(tree->ftype,outfile);
4670                 fprintf(outfile,")\n");
4671                 ast_print(tree->left,outfile,indent+2);
4672                 ast_print(tree->right,outfile,indent+2);
4673                 return ;
4674         case '<':
4675                 fprintf(outfile,"LT(<) (%p) type (",tree);
4676                 printTypeChain(tree->ftype,outfile);
4677                 fprintf(outfile,")\n");
4678                 ast_print(tree->left,outfile,indent+2);
4679                 ast_print(tree->right,outfile,indent+2);
4680                 return ;
4681         case LE_OP:
4682                 fprintf(outfile,"LE(<=) (%p) type (",tree);
4683                 printTypeChain(tree->ftype,outfile);
4684                 fprintf(outfile,")\n");
4685                 ast_print(tree->left,outfile,indent+2);
4686                 ast_print(tree->right,outfile,indent+2);
4687                 return ;
4688         case GE_OP:
4689                 fprintf(outfile,"GE(>=) (%p) type (",tree);
4690                 printTypeChain(tree->ftype,outfile);
4691                 fprintf(outfile,")\n");
4692                 ast_print(tree->left,outfile,indent+2);
4693                 ast_print(tree->right,outfile,indent+2);
4694                 return ;
4695         case EQ_OP:
4696                 fprintf(outfile,"EQ(==) (%p) type (",tree);
4697                 printTypeChain(tree->ftype,outfile);
4698                 fprintf(outfile,")\n");
4699                 ast_print(tree->left,outfile,indent+2);
4700                 ast_print(tree->right,outfile,indent+2);
4701                 return ;
4702         case NE_OP:
4703                 fprintf(outfile,"NE(!=) (%p) type (",tree);
4704                 printTypeChain(tree->ftype,outfile);
4705                 fprintf(outfile,")\n");
4706                 ast_print(tree->left,outfile,indent+2);
4707                 ast_print(tree->right,outfile,indent+2);
4708                 /*------------------------------------------------------------------*/
4709                 /*----------------------------*/
4710                 /*             sizeof         */
4711                 /*----------------------------*/
4712         case SIZEOF:            /* evaluate wihout code generation */
4713                 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4714                 return ;
4715
4716                 /*------------------------------------------------------------------*/
4717                 /*----------------------------*/
4718                 /* conditional operator  '?'  */
4719                 /*----------------------------*/
4720         case '?':
4721                 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4722                 printTypeChain(tree->ftype,outfile);
4723                 fprintf(outfile,")\n");
4724                 ast_print(tree->left,outfile,indent+2);
4725                 ast_print(tree->right,outfile,indent+2);
4726                 return;
4727
4728         case ':':
4729                 fprintf(outfile,"COLON(:) (%p) type (",tree);
4730                 printTypeChain(tree->ftype,outfile);
4731                 fprintf(outfile,")\n");
4732                 ast_print(tree->left,outfile,indent+2);
4733                 ast_print(tree->right,outfile,indent+2);
4734                 return ;
4735                 
4736                 /*------------------------------------------------------------------*/
4737                 /*----------------------------*/
4738                 /*    assignment operators    */
4739                 /*----------------------------*/
4740         case MUL_ASSIGN:
4741                 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4742                 printTypeChain(tree->ftype,outfile);
4743                 fprintf(outfile,")\n");
4744                 ast_print(tree->left,outfile,indent+2);
4745                 ast_print(tree->right,outfile,indent+2);
4746                 return;
4747         case DIV_ASSIGN:
4748                 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4749                 printTypeChain(tree->ftype,outfile);
4750                 fprintf(outfile,")\n");
4751                 ast_print(tree->left,outfile,indent+2);
4752                 ast_print(tree->right,outfile,indent+2);
4753                 return;
4754         case AND_ASSIGN:
4755                 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4756                 printTypeChain(tree->ftype,outfile);
4757                 fprintf(outfile,")\n");
4758                 ast_print(tree->left,outfile,indent+2);
4759                 ast_print(tree->right,outfile,indent+2);
4760                 return;
4761         case OR_ASSIGN:
4762                 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4763                 printTypeChain(tree->ftype,outfile);
4764                 fprintf(outfile,")\n");
4765                 ast_print(tree->left,outfile,indent+2);
4766                 ast_print(tree->right,outfile,indent+2);
4767                 return;
4768         case XOR_ASSIGN:
4769                 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4770                 printTypeChain(tree->ftype,outfile);
4771                 fprintf(outfile,")\n");
4772                 ast_print(tree->left,outfile,indent+2);
4773                 ast_print(tree->right,outfile,indent+2);
4774                 return;
4775         case RIGHT_ASSIGN:
4776                 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4777                 printTypeChain(tree->ftype,outfile);
4778                 fprintf(outfile,")\n");
4779                 ast_print(tree->left,outfile,indent+2);
4780                 ast_print(tree->right,outfile,indent+2);
4781                 return;
4782         case LEFT_ASSIGN:
4783                 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4784                 printTypeChain(tree->ftype,outfile);
4785                 fprintf(outfile,")\n");
4786                 ast_print(tree->left,outfile,indent+2);
4787                 ast_print(tree->right,outfile,indent+2);
4788                 return;
4789                 /*------------------------------------------------------------------*/
4790                 /*----------------------------*/
4791                 /*    -= operator             */
4792                 /*----------------------------*/
4793         case SUB_ASSIGN:
4794                 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4795                 printTypeChain(tree->ftype,outfile);
4796                 fprintf(outfile,")\n");
4797                 ast_print(tree->left,outfile,indent+2);
4798                 ast_print(tree->right,outfile,indent+2);
4799                 return;
4800                 /*------------------------------------------------------------------*/
4801                 /*----------------------------*/
4802                 /*          += operator       */
4803                 /*----------------------------*/
4804         case ADD_ASSIGN:
4805                 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4806                 printTypeChain(tree->ftype,outfile);
4807                 fprintf(outfile,")\n");
4808                 ast_print(tree->left,outfile,indent+2);
4809                 ast_print(tree->right,outfile,indent+2);
4810                 return;
4811                 /*------------------------------------------------------------------*/
4812                 /*----------------------------*/
4813                 /*      straight assignemnt   */
4814                 /*----------------------------*/
4815         case '=':
4816                 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4817                 printTypeChain(tree->ftype,outfile);
4818                 fprintf(outfile,")\n");
4819                 ast_print(tree->left,outfile,indent+2);
4820                 ast_print(tree->right,outfile,indent+2);
4821                 return;     
4822                 /*------------------------------------------------------------------*/
4823                 /*----------------------------*/
4824                 /*      comma operator        */
4825                 /*----------------------------*/
4826         case ',':
4827                 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4828                 printTypeChain(tree->ftype,outfile);
4829                 fprintf(outfile,")\n");
4830                 ast_print(tree->left,outfile,indent+2);
4831                 ast_print(tree->right,outfile,indent+2);
4832                 return;
4833                 /*------------------------------------------------------------------*/
4834                 /*----------------------------*/
4835                 /*       function call        */
4836                 /*----------------------------*/
4837         case CALL:
4838         case PCALL:
4839                 fprintf(outfile,"CALL (%p) type (",tree);
4840                 printTypeChain(tree->ftype,outfile);
4841                 fprintf(outfile,")\n");
4842                 ast_print(tree->left,outfile,indent+2);
4843                 ast_print(tree->right,outfile,indent+2);
4844                 return;
4845         case PARAM:
4846                 fprintf(outfile,"PARMS\n");
4847                 ast_print(tree->left,outfile,indent+2);
4848                 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4849                         ast_print(tree->right,outfile,indent+2);
4850                 }
4851                 return ;
4852                 /*------------------------------------------------------------------*/
4853                 /*----------------------------*/
4854                 /*     return statement       */
4855                 /*----------------------------*/
4856         case RETURN:
4857                 fprintf(outfile,"RETURN (%p) type (",tree);
4858                 printTypeChain(tree->right->ftype,outfile);
4859                 fprintf(outfile,")\n");
4860                 ast_print(tree->right,outfile,indent+2);
4861                 return ;
4862                 /*------------------------------------------------------------------*/
4863                 /*----------------------------*/
4864                 /*     label statement        */
4865                 /*----------------------------*/
4866         case LABEL :
4867                 fprintf(outfile,"LABEL (%p)\n",tree);
4868                 ast_print(tree->left,outfile,indent+2);
4869                 ast_print(tree->right,outfile,indent);
4870                 return;
4871                 /*------------------------------------------------------------------*/
4872                 /*----------------------------*/
4873                 /*     switch statement       */
4874                 /*----------------------------*/
4875         case SWITCH:
4876                 {
4877                         value *val;
4878                         fprintf(outfile,"SWITCH (%p) ",tree);
4879                         ast_print(tree->left,outfile,0);
4880                         for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4881                                 INDENT(indent+2,outfile);
4882                                 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4883                                         (int) floatFromVal(val),
4884                                         tree->values.switchVals.swNum,
4885                                         (int) floatFromVal(val));
4886                         }
4887                         ast_print(tree->right,outfile,indent);
4888                 }
4889                 return ;
4890                 /*------------------------------------------------------------------*/
4891                 /*----------------------------*/
4892                 /* ifx Statement              */
4893                 /*----------------------------*/
4894         case IFX:
4895                 fprintf(outfile,"IF (%p) \n",tree);
4896                 ast_print(tree->left,outfile,indent+2);
4897                 if (tree->trueLabel) {
4898                         INDENT(indent,outfile);
4899                         fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4900                 }
4901                 if (tree->falseLabel) {
4902                         INDENT(indent,outfile);
4903                         fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4904                 }
4905                 ast_print(tree->right,outfile,indent+2);
4906                 return ;
4907                 /*------------------------------------------------------------------*/
4908                 /*----------------------------*/
4909                 /* for Statement              */
4910                 /*----------------------------*/
4911         case FOR:
4912                 fprintf(outfile,"FOR (%p) \n",tree);
4913                 if (AST_FOR( tree, initExpr)) {
4914                         INDENT(indent+2,outfile);
4915                         fprintf(outfile,"INIT EXPR ");
4916                         ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4917                 }
4918                 if (AST_FOR( tree, condExpr)) {
4919                         INDENT(indent+2,outfile);
4920                         fprintf(outfile,"COND EXPR ");
4921                         ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4922                 }
4923                 if (AST_FOR( tree, loopExpr)) {
4924                         INDENT(indent+2,outfile);
4925                         fprintf(outfile,"LOOP EXPR ");
4926                         ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
4927                 }
4928                 fprintf(outfile,"FOR LOOP BODY \n");
4929                 ast_print(tree->left,outfile,indent+2);
4930                 return ;
4931         default:
4932             return ;
4933         }
4934 }
4935
4936 void PA(ast *t)
4937 {
4938         ast_print(t,stdout,0);
4939 }