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