fixed bug #475821
[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 (src->ftype)
263     dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
264
265   /* if this is a leaf */
266   /* if value */
267   if (src->type == EX_VALUE)
268     {
269       dest->opval.val = copyValue (src->opval.val);
270       goto exit;
271     }
272
273   /* if link */
274   if (src->type == EX_LINK)
275     {
276       dest->opval.lnk = copyLinkChain (src->opval.lnk);
277       goto exit;
278     }
279
280   dest->opval.op = src->opval.op;
281
282   /* if this is a node that has special values */
283   copyAstValues (dest, src);
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, "address 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 (IS_LITERAL(LTYPE(tree)))
2147         {
2148           werror (E_ILLEGAL_ADDR, "address of literal");
2149           goto errorTreeReturn;
2150         }
2151
2152      if (LRVAL (tree))
2153         {
2154           werror (E_LVALUE_REQUIRED, "address of");
2155           goto errorTreeReturn;
2156         }
2157       if (SPEC_SCLS (tree->left->etype) == S_CODE)
2158         {
2159           DCL_TYPE (p) = CPOINTER;
2160           DCL_PTR_CONST (p) = port->mem.code_ro;
2161         }
2162       else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2163         DCL_TYPE (p) = FPOINTER;
2164       else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2165         DCL_TYPE (p) = PPOINTER;
2166       else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2167         DCL_TYPE (p) = IPOINTER;
2168       else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2169         DCL_TYPE (p) = EEPPOINTER;
2170       else
2171         DCL_TYPE (p) = POINTER;
2172
2173       if (IS_AST_SYM_VALUE (tree->left))
2174         {
2175           AST_SYMBOL (tree->left)->addrtaken = 1;
2176           AST_SYMBOL (tree->left)->allocreq = 1;
2177         }
2178
2179       p->next = LTYPE (tree);
2180       TTYPE (tree) = p;
2181       TETYPE (tree) = getSpec (TTYPE (tree));
2182       DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
2183       DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
2184       LLVAL (tree) = 1;
2185       TLVAL (tree) = 1;
2186       return tree;
2187
2188 /*------------------------------------------------------------------*/
2189 /*----------------------------*/
2190       /*  bitwise or                */
2191 /*----------------------------*/
2192     case '|':
2193       /* if the rewrite succeeds then don't go any furthur */
2194       {
2195         ast *wtree = optimizeRRCRLC (tree);
2196         if (wtree != tree)
2197           return decorateType (wtree);
2198       }
2199 /*------------------------------------------------------------------*/
2200 /*----------------------------*/
2201       /*  bitwise xor               */
2202 /*----------------------------*/
2203     case '^':
2204       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2205         {
2206           werror (E_BITWISE_OP);
2207           werror (W_CONTINUE, "left & right types are ");
2208           printTypeChain (LTYPE (tree), stderr);
2209           fprintf (stderr, ",");
2210           printTypeChain (RTYPE (tree), stderr);
2211           fprintf (stderr, "\n");
2212           goto errorTreeReturn;
2213         }
2214
2215       /* if they are both literal then */
2216       /* rewrite the tree */
2217       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2218         {
2219           tree->type = EX_VALUE;
2220           tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2221                                         valFromType (RETYPE (tree)),
2222                                         tree->opval.op);
2223           tree->right = tree->left = NULL;
2224           TETYPE (tree) = tree->opval.val->etype;
2225           TTYPE (tree) = tree->opval.val->type;
2226           return tree;
2227         }
2228       LRVAL (tree) = RRVAL (tree) = 1;
2229       TETYPE (tree) = getSpec (TTYPE (tree) =
2230                                computeType (LTYPE (tree),
2231                                             RTYPE (tree)));
2232
2233 /*------------------------------------------------------------------*/
2234 /*----------------------------*/
2235       /*  division                  */
2236 /*----------------------------*/
2237     case '/':
2238       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2239         {
2240           werror (E_INVALID_OP, "divide");
2241           goto errorTreeReturn;
2242         }
2243       /* if they are both literal then */
2244       /* rewrite the tree */
2245       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2246         {
2247           tree->type = EX_VALUE;
2248           tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2249                                     valFromType (RETYPE (tree)));
2250           tree->right = tree->left = NULL;
2251           TETYPE (tree) = getSpec (TTYPE (tree) =
2252                                    tree->opval.val->type);
2253           return tree;
2254         }
2255       LRVAL (tree) = RRVAL (tree) = 1;
2256       TETYPE (tree) = getSpec (TTYPE (tree) =
2257                                computeType (LTYPE (tree),
2258                                             RTYPE (tree)));
2259       return tree;
2260
2261 /*------------------------------------------------------------------*/
2262 /*----------------------------*/
2263       /*            modulus         */
2264 /*----------------------------*/
2265     case '%':
2266       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2267         {
2268           werror (E_BITWISE_OP);
2269           werror (W_CONTINUE, "left & right types are ");
2270           printTypeChain (LTYPE (tree), stderr);
2271           fprintf (stderr, ",");
2272           printTypeChain (RTYPE (tree), stderr);
2273           fprintf (stderr, "\n");
2274           goto errorTreeReturn;
2275         }
2276       /* if they are both literal then */
2277       /* rewrite the tree */
2278       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2279         {
2280           tree->type = EX_VALUE;
2281           tree->opval.val = valMod (valFromType (LETYPE (tree)),
2282                                     valFromType (RETYPE (tree)));
2283           tree->right = tree->left = NULL;
2284           TETYPE (tree) = getSpec (TTYPE (tree) =
2285                                    tree->opval.val->type);
2286           return tree;
2287         }
2288       LRVAL (tree) = RRVAL (tree) = 1;
2289       TETYPE (tree) = getSpec (TTYPE (tree) =
2290                                computeType (LTYPE (tree),
2291                                             RTYPE (tree)));
2292       return tree;
2293
2294 /*------------------------------------------------------------------*/
2295 /*----------------------------*/
2296 /*  address dereference       */
2297 /*----------------------------*/
2298     case '*':                   /* can be unary  : if right is null then unary operation */
2299       if (!tree->right)
2300         {
2301           if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2302             {
2303               werror (E_PTR_REQD);
2304               goto errorTreeReturn;
2305             }
2306
2307           if (LRVAL (tree))
2308             {
2309               werror (E_LVALUE_REQUIRED, "pointer deref");
2310               goto errorTreeReturn;
2311             }
2312           TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
2313                                         LTYPE (tree)->next : NULL);
2314           TETYPE (tree) = getSpec (TTYPE (tree));
2315           SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
2316           return tree;
2317         }
2318
2319 /*------------------------------------------------------------------*/
2320 /*----------------------------*/
2321       /*      multiplication        */
2322 /*----------------------------*/
2323       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2324         {
2325           werror (E_INVALID_OP, "multiplication");
2326           goto errorTreeReturn;
2327         }
2328
2329       /* if they are both literal then */
2330       /* rewrite the tree */
2331       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2332         {
2333           tree->type = EX_VALUE;
2334           tree->opval.val = valMult (valFromType (LETYPE (tree)),
2335                                      valFromType (RETYPE (tree)));
2336           tree->right = tree->left = NULL;
2337           TETYPE (tree) = getSpec (TTYPE (tree) =
2338                                    tree->opval.val->type);
2339           return tree;
2340         }
2341
2342       /* if left is a literal exchange left & right */
2343       if (IS_LITERAL (LTYPE (tree)))
2344         {
2345           ast *tTree = tree->left;
2346           tree->left = tree->right;
2347           tree->right = tTree;
2348         }
2349
2350       LRVAL (tree) = RRVAL (tree) = 1;
2351       /* promote result to int if left & right are char
2352          this will facilitate hardware multiplies 8bit x 8bit = 16bit */
2353       if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
2354         TETYPE (tree) = getSpec (TTYPE (tree) =
2355                                  computeType (LTYPE (tree),
2356                                               RTYPE (tree)));
2357         SPEC_NOUN(TETYPE(tree)) = V_INT;
2358       } else {
2359         TETYPE (tree) = getSpec (TTYPE (tree) =
2360                                  computeType (LTYPE (tree),
2361                                               RTYPE (tree)));
2362       }
2363       return tree;
2364
2365 /*------------------------------------------------------------------*/
2366 /*----------------------------*/
2367       /*    unary '+' operator      */
2368 /*----------------------------*/
2369     case '+':
2370       /* if unary plus */
2371       if (!tree->right)
2372         {
2373           if (!IS_INTEGRAL (LTYPE (tree)))
2374             {
2375               werror (E_UNARY_OP, '+');
2376               goto errorTreeReturn;
2377             }
2378
2379           /* if left is a literal then do it */
2380           if (IS_LITERAL (LTYPE (tree)))
2381             {
2382               tree->type = EX_VALUE;
2383               tree->opval.val = valFromType (LETYPE (tree));
2384               tree->left = NULL;
2385               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2386               return tree;
2387             }
2388           LRVAL (tree) = 1;
2389           COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2390           return tree;
2391         }
2392
2393 /*------------------------------------------------------------------*/
2394 /*----------------------------*/
2395       /*      addition              */
2396 /*----------------------------*/
2397
2398       /* this is not a unary operation */
2399       /* if both pointers then problem */
2400       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2401           (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2402         {
2403           werror (E_PTR_PLUS_PTR);
2404           goto errorTreeReturn;
2405         }
2406
2407       if (!IS_ARITHMETIC (LTYPE (tree)) &&
2408           !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2409         {
2410           werror (E_PLUS_INVALID, "+");
2411           goto errorTreeReturn;
2412         }
2413
2414       if (!IS_ARITHMETIC (RTYPE (tree)) &&
2415           !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2416         {
2417           werror (E_PLUS_INVALID, "+");
2418           goto errorTreeReturn;
2419         }
2420       /* if they are both literal then */
2421       /* rewrite the tree */
2422       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2423         {
2424           tree->type = EX_VALUE;
2425           tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2426                                      valFromType (RETYPE (tree)));
2427           tree->right = tree->left = NULL;
2428           TETYPE (tree) = getSpec (TTYPE (tree) =
2429                                    tree->opval.val->type);
2430           return tree;
2431         }
2432
2433       /* if the right is a pointer or left is a literal
2434          xchange left & right */
2435       if (IS_ARRAY (RTYPE (tree)) ||
2436           IS_PTR (RTYPE (tree)) ||
2437           IS_LITERAL (LTYPE (tree)))
2438         {
2439           ast *tTree = tree->left;
2440           tree->left = tree->right;
2441           tree->right = tTree;
2442         }
2443
2444       LRVAL (tree) = RRVAL (tree) = 1;
2445       /* if the left is a pointer */
2446       if (IS_PTR (LTYPE (tree)))
2447         TETYPE (tree) = getSpec (TTYPE (tree) =
2448                                  LTYPE (tree));
2449       else
2450         TETYPE (tree) = getSpec (TTYPE (tree) =
2451                                  computeType (LTYPE (tree),
2452                                               RTYPE (tree)));
2453       return tree;
2454
2455 /*------------------------------------------------------------------*/
2456 /*----------------------------*/
2457       /*      unary '-'             */
2458 /*----------------------------*/
2459     case '-':                   /* can be unary   */
2460       /* if right is null then unary */
2461       if (!tree->right)
2462         {
2463
2464           if (!IS_ARITHMETIC (LTYPE (tree)))
2465             {
2466               werror (E_UNARY_OP, tree->opval.op);
2467               goto errorTreeReturn;
2468             }
2469
2470           /* if left is a literal then do it */
2471           if (IS_LITERAL (LTYPE (tree)))
2472             {
2473               tree->type = EX_VALUE;
2474               tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2475               tree->left = NULL;
2476               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2477               SPEC_USIGN(TETYPE(tree)) = 0;
2478               return tree;
2479             }
2480           LRVAL (tree) = 1;
2481           TTYPE (tree) = LTYPE (tree);
2482           return tree;
2483         }
2484
2485 /*------------------------------------------------------------------*/
2486 /*----------------------------*/
2487       /*    subtraction             */
2488 /*----------------------------*/
2489
2490       if (!(IS_PTR (LTYPE (tree)) ||
2491             IS_ARRAY (LTYPE (tree)) ||
2492             IS_ARITHMETIC (LTYPE (tree))))
2493         {
2494           werror (E_PLUS_INVALID, "-");
2495           goto errorTreeReturn;
2496         }
2497
2498       if (!(IS_PTR (RTYPE (tree)) ||
2499             IS_ARRAY (RTYPE (tree)) ||
2500             IS_ARITHMETIC (RTYPE (tree))))
2501         {
2502           werror (E_PLUS_INVALID, "-");
2503           goto errorTreeReturn;
2504         }
2505
2506       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2507           !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2508             IS_INTEGRAL (RTYPE (tree))))
2509         {
2510           werror (E_PLUS_INVALID, "-");
2511           goto errorTreeReturn;
2512         }
2513
2514       /* if they are both literal then */
2515       /* rewrite the tree */
2516       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2517         {
2518           tree->type = EX_VALUE;
2519           tree->opval.val = valMinus (valFromType (LETYPE (tree)),
2520                                       valFromType (RETYPE (tree)));
2521           tree->right = tree->left = NULL;
2522           TETYPE (tree) = getSpec (TTYPE (tree) =
2523                                    tree->opval.val->type);
2524           return tree;
2525         }
2526
2527       /* if the left & right are equal then zero */
2528       if (isAstEqual (tree->left, tree->right))
2529         {
2530           tree->type = EX_VALUE;
2531           tree->left = tree->right = NULL;
2532           tree->opval.val = constVal ("0");
2533           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2534           return tree;
2535         }
2536
2537       /* if both of them are pointers or arrays then */
2538       /* the result is going to be an integer        */
2539       if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
2540           (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
2541         TETYPE (tree) = TTYPE (tree) = newIntLink ();
2542       else
2543         /* if only the left is a pointer */
2544         /* then result is a pointer      */
2545       if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
2546         TETYPE (tree) = getSpec (TTYPE (tree) =
2547                                  LTYPE (tree));
2548       else
2549         TETYPE (tree) = getSpec (TTYPE (tree) =
2550                                  computeType (LTYPE (tree),
2551                                               RTYPE (tree)));
2552       LRVAL (tree) = RRVAL (tree) = 1;
2553       return tree;
2554
2555 /*------------------------------------------------------------------*/
2556 /*----------------------------*/
2557       /*    compliment              */
2558 /*----------------------------*/
2559     case '~':
2560       /* can be only integral type */
2561       if (!IS_INTEGRAL (LTYPE (tree)))
2562         {
2563           werror (E_UNARY_OP, tree->opval.op);
2564           goto errorTreeReturn;
2565         }
2566
2567       /* if left is a literal then do it */
2568       if (IS_LITERAL (LTYPE (tree)))
2569         {
2570           tree->type = EX_VALUE;
2571           tree->opval.val = valComplement (valFromType (LETYPE (tree)));
2572           tree->left = NULL;
2573           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2574           return tree;
2575         }
2576       LRVAL (tree) = 1;
2577       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2578       return tree;
2579
2580 /*------------------------------------------------------------------*/
2581 /*----------------------------*/
2582       /*           not              */
2583 /*----------------------------*/
2584     case '!':
2585       /* can be pointer */
2586       if (!IS_ARITHMETIC (LTYPE (tree)) &&
2587           !IS_PTR (LTYPE (tree)) &&
2588           !IS_ARRAY (LTYPE (tree)))
2589         {
2590           werror (E_UNARY_OP, tree->opval.op);
2591           goto errorTreeReturn;
2592         }
2593
2594       /* if left is a literal then do it */
2595       if (IS_LITERAL (LTYPE (tree)))
2596         {
2597           tree->type = EX_VALUE;
2598           tree->opval.val = valNot (valFromType (LETYPE (tree)));
2599           tree->left = NULL;
2600           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2601           return tree;
2602         }
2603       LRVAL (tree) = 1;
2604       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2605       return tree;
2606
2607 /*------------------------------------------------------------------*/
2608 /*----------------------------*/
2609       /*           shift            */
2610 /*----------------------------*/
2611     case RRC:
2612     case RLC:
2613       TTYPE (tree) = LTYPE (tree);
2614       TETYPE (tree) = LETYPE (tree);
2615       return tree;
2616
2617     case GETHBIT:
2618       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2619       return tree;
2620
2621     case LEFT_OP:
2622     case RIGHT_OP:
2623       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
2624         {
2625           werror (E_SHIFT_OP_INVALID);
2626           werror (W_CONTINUE, "left & right types are ");
2627           printTypeChain (LTYPE (tree), stderr);
2628           fprintf (stderr, ",");
2629           printTypeChain (RTYPE (tree), stderr);
2630           fprintf (stderr, "\n");
2631           goto errorTreeReturn;
2632         }
2633
2634       /* if they are both literal then */
2635       /* rewrite the tree */
2636       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2637         {
2638           tree->type = EX_VALUE;
2639           tree->opval.val = valShift (valFromType (LETYPE (tree)),
2640                                       valFromType (RETYPE (tree)),
2641                                       (tree->opval.op == LEFT_OP ? 1 : 0));
2642           tree->right = tree->left = NULL;
2643           TETYPE (tree) = getSpec (TTYPE (tree) =
2644                                    tree->opval.val->type);
2645           return tree;
2646         }
2647       /* if only the right side is a literal & we are
2648          shifting more than size of the left operand then zero */
2649       if (IS_LITERAL (RTYPE (tree)) &&
2650           ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
2651           (getSize (LTYPE (tree)) * 8))
2652         {
2653           werror (W_SHIFT_CHANGED,
2654                   (tree->opval.op == LEFT_OP ? "left" : "right"));
2655           tree->type = EX_VALUE;
2656           tree->left = tree->right = NULL;
2657           tree->opval.val = constVal ("0");
2658           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2659           return tree;
2660         }
2661       LRVAL (tree) = RRVAL (tree) = 1;
2662       if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
2663         {
2664           COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
2665         }
2666       else
2667         {
2668           COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2669         }
2670       return tree;
2671
2672       /*------------------------------------------------------------------*/
2673       /*----------------------------*/
2674       /*         casting            */
2675       /*----------------------------*/
2676     case CAST:                  /* change the type   */
2677       /* cannot cast to an aggregate type */
2678       if (IS_AGGREGATE (LTYPE (tree)))
2679         {
2680           werror (E_CAST_ILLEGAL);
2681           goto errorTreeReturn;
2682         }
2683       
2684       /* make sure the type is complete and sane */
2685       checkTypeSanity(LETYPE(tree), "(cast)");
2686
2687 #if 0
2688       /* if the right is a literal replace the tree */
2689       if (IS_LITERAL (RETYPE (tree))) {
2690               if (!IS_PTR (LTYPE (tree))) {
2691                       tree->type = EX_VALUE;
2692                       tree->opval.val =
2693                               valCastLiteral (LTYPE (tree),
2694                                               floatFromVal (valFromType (RETYPE (tree))));
2695                       tree->left = NULL;
2696                       tree->right = NULL;
2697                       TTYPE (tree) = tree->opval.val->type;
2698                       tree->values.literalFromCast = 1;
2699               } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) && 
2700                          ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */  {
2701                       sym_link *rest = LTYPE(tree)->next;
2702                       werror(W_LITERAL_GENERIC);                      
2703                       TTYPE(tree) = newLink();
2704                       DCL_TYPE(TTYPE(tree)) = FPOINTER;
2705                       TTYPE(tree)->next = rest;
2706                       tree->left->opval.lnk = TTYPE(tree);
2707                       LRVAL (tree) = 1;
2708               } else {
2709                       TTYPE (tree) = LTYPE (tree);
2710                       LRVAL (tree) = 1;
2711               }
2712       } else {
2713               TTYPE (tree) = LTYPE (tree);
2714               LRVAL (tree) = 1;
2715       }
2716 #else
2717       /* if the right is a literal replace the tree */
2718       if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
2719         tree->type = EX_VALUE;
2720         tree->opval.val =
2721           valCastLiteral (LTYPE (tree),
2722                           floatFromVal (valFromType (RETYPE (tree))));
2723         tree->left = NULL;
2724         tree->right = NULL;
2725         TTYPE (tree) = tree->opval.val->type;
2726         tree->values.literalFromCast = 1;
2727       } else {
2728         TTYPE (tree) = LTYPE (tree);
2729         LRVAL (tree) = 1;
2730       }
2731 #endif
2732
2733       TETYPE (tree) = getSpec (TTYPE (tree));
2734
2735       return tree;
2736
2737 /*------------------------------------------------------------------*/
2738 /*----------------------------*/
2739       /*       logical &&, ||       */
2740 /*----------------------------*/
2741     case AND_OP:
2742     case OR_OP:
2743       /* each must me arithmetic type or be a pointer */
2744       if (!IS_PTR (LTYPE (tree)) &&
2745           !IS_ARRAY (LTYPE (tree)) &&
2746           !IS_INTEGRAL (LTYPE (tree)))
2747         {
2748           werror (E_COMPARE_OP);
2749           goto errorTreeReturn;
2750         }
2751
2752       if (!IS_PTR (RTYPE (tree)) &&
2753           !IS_ARRAY (RTYPE (tree)) &&
2754           !IS_INTEGRAL (RTYPE (tree)))
2755         {
2756           werror (E_COMPARE_OP);
2757           goto errorTreeReturn;
2758         }
2759       /* if they are both literal then */
2760       /* rewrite the tree */
2761       if (IS_LITERAL (RTYPE (tree)) &&
2762           IS_LITERAL (LTYPE (tree)))
2763         {
2764           tree->type = EX_VALUE;
2765           tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)),
2766                                            valFromType (RETYPE (tree)),
2767                                            tree->opval.op);
2768           tree->right = tree->left = NULL;
2769           TETYPE (tree) = getSpec (TTYPE (tree) =
2770                                    tree->opval.val->type);
2771           return tree;
2772         }
2773       LRVAL (tree) = RRVAL (tree) = 1;
2774       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2775       return tree;
2776
2777 /*------------------------------------------------------------------*/
2778 /*----------------------------*/
2779       /*     comparison operators   */
2780 /*----------------------------*/
2781     case '>':
2782     case '<':
2783     case LE_OP:
2784     case GE_OP:
2785     case EQ_OP:
2786     case NE_OP:
2787       {
2788         ast *lt = optimizeCompare (tree);
2789
2790         if (tree != lt)
2791           return lt;
2792       }
2793
2794       /* if they are pointers they must be castable */
2795       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2796         {
2797           if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2798             {
2799               werror (E_COMPARE_OP);
2800               fprintf (stderr, "comparing type ");
2801               printTypeChain (LTYPE (tree), stderr);
2802               fprintf (stderr, "to type ");
2803               printTypeChain (RTYPE (tree), stderr);
2804               fprintf (stderr, "\n");
2805               goto errorTreeReturn;
2806             }
2807         }
2808       /* else they should be promotable to one another */
2809       else
2810         {
2811           if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
2812                 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
2813
2814             if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2815               {
2816                 werror (E_COMPARE_OP);
2817                 fprintf (stderr, "comparing type ");
2818                 printTypeChain (LTYPE (tree), stderr);
2819                 fprintf (stderr, "to type ");
2820                 printTypeChain (RTYPE (tree), stderr);
2821                 fprintf (stderr, "\n");
2822                 goto errorTreeReturn;
2823               }
2824         }
2825
2826       /* if they are both literal then */
2827       /* rewrite the tree */
2828       if (IS_LITERAL (RTYPE (tree)) &&
2829           IS_LITERAL (LTYPE (tree)))
2830         {
2831           tree->type = EX_VALUE;
2832           tree->opval.val = valCompare (valFromType (LETYPE (tree)),
2833                                         valFromType (RETYPE (tree)),
2834                                         tree->opval.op);
2835           tree->right = tree->left = NULL;
2836           TETYPE (tree) = getSpec (TTYPE (tree) =
2837                                    tree->opval.val->type);
2838           return tree;
2839         }
2840       LRVAL (tree) = RRVAL (tree) = 1;
2841       TTYPE (tree) = TETYPE (tree) = newCharLink ();
2842       return tree;
2843
2844 /*------------------------------------------------------------------*/
2845 /*----------------------------*/
2846       /*             sizeof         */
2847 /*----------------------------*/
2848     case SIZEOF:                /* evaluate wihout code generation */
2849       /* change the type to a integer */
2850       tree->type = EX_VALUE;
2851       sprintf (buffer, "%d", (getSize (tree->right->ftype)));
2852       tree->opval.val = constVal (buffer);
2853       tree->right = tree->left = NULL;
2854       TETYPE (tree) = getSpec (TTYPE (tree) =
2855                                tree->opval.val->type);
2856       return tree;
2857
2858       /*------------------------------------------------------------------*/
2859       /*----------------------------*/
2860       /* conditional operator  '?'  */
2861       /*----------------------------*/
2862     case '?':
2863       /* the type is value of the colon operator (on the right) */
2864       assert(IS_COLON_OP(tree->right));
2865       /* if already known then replace the tree : optimizer will do it
2866          but faster to do it here */
2867       if (IS_LITERAL (LTYPE(tree))) {
2868           if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
2869               return tree->right->left ;
2870           } else {
2871               return tree->right->right ;
2872           }
2873       } else {
2874           TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
2875           TETYPE (tree) = getSpec (TTYPE (tree));
2876       }
2877       return tree;
2878
2879     case ':':
2880       /* if they don't match we have a problem */
2881       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
2882         {
2883           werror (E_TYPE_MISMATCH, "conditional operator", " ");
2884           goto errorTreeReturn;
2885         }
2886
2887       TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree));
2888       TETYPE (tree) = getSpec (TTYPE (tree));
2889       return tree;
2890
2891
2892 /*------------------------------------------------------------------*/
2893 /*----------------------------*/
2894       /*    assignment operators    */
2895 /*----------------------------*/
2896     case MUL_ASSIGN:
2897     case DIV_ASSIGN:
2898       /* for these it must be both must be integral */
2899       if (!IS_ARITHMETIC (LTYPE (tree)) ||
2900           !IS_ARITHMETIC (RTYPE (tree)))
2901         {
2902           werror (E_OPS_INTEGRAL);
2903           goto errorTreeReturn;
2904         }
2905       RRVAL (tree) = 1;
2906       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2907
2908       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2909         werror (E_CODE_WRITE, " ");
2910
2911       if (LRVAL (tree))
2912         {
2913           werror (E_LVALUE_REQUIRED, "*= or /=");
2914           goto errorTreeReturn;
2915         }
2916       LLVAL (tree) = 1;
2917
2918       return tree;
2919
2920     case AND_ASSIGN:
2921     case OR_ASSIGN:
2922     case XOR_ASSIGN:
2923     case RIGHT_ASSIGN:
2924     case LEFT_ASSIGN:
2925       /* for these it must be both must be integral */
2926       if (!IS_INTEGRAL (LTYPE (tree)) ||
2927           !IS_INTEGRAL (RTYPE (tree)))
2928         {
2929           werror (E_OPS_INTEGRAL);
2930           goto errorTreeReturn;
2931         }
2932       RRVAL (tree) = 1;
2933       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2934
2935       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2936         werror (E_CODE_WRITE, " ");
2937
2938       if (LRVAL (tree))
2939         {
2940           werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
2941           goto errorTreeReturn;
2942         }
2943       LLVAL (tree) = 1;
2944
2945       return tree;
2946
2947 /*------------------------------------------------------------------*/
2948 /*----------------------------*/
2949       /*    -= operator             */
2950 /*----------------------------*/
2951     case SUB_ASSIGN:
2952       if (!(IS_PTR (LTYPE (tree)) ||
2953             IS_ARITHMETIC (LTYPE (tree))))
2954         {
2955           werror (E_PLUS_INVALID, "-=");
2956           goto errorTreeReturn;
2957         }
2958
2959       if (!(IS_PTR (RTYPE (tree)) ||
2960             IS_ARITHMETIC (RTYPE (tree))))
2961         {
2962           werror (E_PLUS_INVALID, "-=");
2963           goto errorTreeReturn;
2964         }
2965       RRVAL (tree) = 1;
2966       TETYPE (tree) = getSpec (TTYPE (tree) =
2967                                computeType (LTYPE (tree),
2968                                             RTYPE (tree)));
2969
2970       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
2971         werror (E_CODE_WRITE, " ");
2972
2973       if (LRVAL (tree))
2974         {
2975           werror (E_LVALUE_REQUIRED, "-=");
2976           goto errorTreeReturn;
2977         }
2978       LLVAL (tree) = 1;
2979
2980       return tree;
2981
2982 /*------------------------------------------------------------------*/
2983 /*----------------------------*/
2984       /*          += operator       */
2985 /*----------------------------*/
2986     case ADD_ASSIGN:
2987       /* this is not a unary operation */
2988       /* if both pointers then problem */
2989       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
2990         {
2991           werror (E_PTR_PLUS_PTR);
2992           goto errorTreeReturn;
2993         }
2994
2995       if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
2996         {
2997           werror (E_PLUS_INVALID, "+=");
2998           goto errorTreeReturn;
2999         }
3000
3001       if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3002         {
3003           werror (E_PLUS_INVALID, "+=");
3004           goto errorTreeReturn;
3005         }
3006       RRVAL (tree) = 1;
3007       TETYPE (tree) = getSpec (TTYPE (tree) =
3008                                computeType (LTYPE (tree),
3009                                             RTYPE (tree)));
3010
3011       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3012         werror (E_CODE_WRITE, " ");
3013
3014       if (LRVAL (tree))
3015         {
3016           werror (E_LVALUE_REQUIRED, "+=");
3017           goto errorTreeReturn;
3018         }
3019
3020       tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3021       tree->opval.op = '=';
3022
3023       return tree;
3024
3025 /*------------------------------------------------------------------*/
3026 /*----------------------------*/
3027       /*      straight assignemnt   */
3028 /*----------------------------*/
3029     case '=':
3030       /* cannot be an aggregate */
3031       if (IS_AGGREGATE (LTYPE (tree)))
3032         {
3033           werror (E_AGGR_ASSIGN);
3034           goto errorTreeReturn;
3035         }
3036
3037       /* they should either match or be castable */
3038       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3039         {
3040           werror (E_TYPE_MISMATCH, "assignment", " ");
3041           fprintf (stderr, "type --> '");
3042           printTypeChain (RTYPE (tree), stderr);
3043           fprintf (stderr, "' ");
3044           fprintf (stderr, "assigned to type --> '");
3045           printTypeChain (LTYPE (tree), stderr);
3046           fprintf (stderr, "'\n");
3047           goto errorTreeReturn;
3048         }
3049
3050       /* if the left side of the tree is of type void
3051          then report error */
3052       if (IS_VOID (LTYPE (tree)))
3053         {
3054           werror (E_CAST_ZERO);
3055           printFromToType(RTYPE(tree), LTYPE(tree));
3056         }
3057
3058       TETYPE (tree) = getSpec (TTYPE (tree) =
3059                                LTYPE (tree));
3060       RRVAL (tree) = 1;
3061       LLVAL (tree) = 1;
3062       if (!tree->initMode ) {
3063         if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3064           werror (E_CODE_WRITE, " ");
3065       }
3066       if (LRVAL (tree))
3067         {
3068           werror (E_LVALUE_REQUIRED, "=");
3069           goto errorTreeReturn;
3070         }
3071
3072       return tree;
3073
3074 /*------------------------------------------------------------------*/
3075 /*----------------------------*/
3076       /*      comma operator        */
3077 /*----------------------------*/
3078     case ',':
3079       TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3080       return tree;
3081
3082 /*------------------------------------------------------------------*/
3083 /*----------------------------*/
3084       /*       function call        */
3085 /*----------------------------*/
3086     case CALL:
3087       parmNumber = 1;
3088
3089       if (processParms (tree->left,
3090                         FUNC_ARGS(tree->left->ftype),
3091                         tree->right, &parmNumber, TRUE))
3092         goto errorTreeReturn;
3093
3094       if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree)))
3095         {
3096           //IFFUNC_ARGS(tree->left->ftype) = 
3097           //reverseVal (IFFUNC_ARGS(tree->left->ftype));
3098           reverseParms (tree->right);
3099         }
3100
3101       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3102       return tree;
3103
3104 /*------------------------------------------------------------------*/
3105 /*----------------------------*/
3106       /*     return statement       */
3107 /*----------------------------*/
3108     case RETURN:
3109       if (!tree->right)
3110         goto voidcheck;
3111
3112       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3113         {
3114           werror (W_RETURN_MISMATCH);
3115           printFromToType (RTYPE(tree), currFunc->type->next);
3116           goto errorTreeReturn;
3117         }
3118
3119       if (IS_VOID (currFunc->type->next)
3120           && tree->right &&
3121           !IS_VOID (RTYPE (tree)))
3122         {
3123           werror (E_FUNC_VOID);
3124           goto errorTreeReturn;
3125         }
3126
3127       /* if there is going to be a casing required then add it */
3128       if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3129         {
3130           tree->right =
3131             decorateType (newNode (CAST,
3132                            newAst_LINK (copyLinkChain (currFunc->type->next)),
3133                                    tree->right));
3134         }
3135
3136       RRVAL (tree) = 1;
3137       return tree;
3138
3139     voidcheck:
3140
3141       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3142         {
3143           werror (E_VOID_FUNC, currFunc->name);
3144           goto errorTreeReturn;
3145         }
3146
3147       TTYPE (tree) = TETYPE (tree) = NULL;
3148       return tree;
3149
3150 /*------------------------------------------------------------------*/
3151 /*----------------------------*/
3152       /*     switch statement       */
3153 /*----------------------------*/
3154     case SWITCH:
3155       /* the switch value must be an integer */
3156       if (!IS_INTEGRAL (LTYPE (tree)))
3157         {
3158           werror (E_SWITCH_NON_INTEGER);
3159           goto errorTreeReturn;
3160         }
3161       LRVAL (tree) = 1;
3162       TTYPE (tree) = TETYPE (tree) = NULL;
3163       return tree;
3164
3165 /*------------------------------------------------------------------*/
3166 /*----------------------------*/
3167       /* ifx Statement              */
3168 /*----------------------------*/
3169     case IFX:
3170       tree->left = backPatchLabels (tree->left,
3171                                     tree->trueLabel,
3172                                     tree->falseLabel);
3173       TTYPE (tree) = TETYPE (tree) = NULL;
3174       return tree;
3175
3176 /*------------------------------------------------------------------*/
3177 /*----------------------------*/
3178       /* for Statement              */
3179 /*----------------------------*/
3180     case FOR:
3181
3182       decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3183       decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3184       decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3185
3186       /* if the for loop is reversible then
3187          reverse it otherwise do what we normally
3188          do */
3189       {
3190         symbol *sym;
3191         ast *init, *end;
3192
3193         if (isLoopReversible (tree, &sym, &init, &end))
3194           return reverseLoop (tree, sym, init, end);
3195         else
3196           return decorateType (createFor (AST_FOR (tree, trueLabel),
3197                                           AST_FOR (tree, continueLabel),
3198                                           AST_FOR (tree, falseLabel),
3199                                           AST_FOR (tree, condLabel),
3200                                           AST_FOR (tree, initExpr),
3201                                           AST_FOR (tree, condExpr),
3202                                           AST_FOR (tree, loopExpr),
3203                                           tree->left));
3204       }
3205     default:
3206       TTYPE (tree) = TETYPE (tree) = NULL;
3207       return tree;
3208     }
3209
3210   /* some error found this tree will be killed */
3211 errorTreeReturn:
3212   TTYPE (tree) = TETYPE (tree) = newCharLink ();
3213   tree->opval.op = NULLOP;
3214   tree->isError = 1;
3215
3216   return tree;
3217 }
3218
3219 /*-----------------------------------------------------------------*/
3220 /* sizeofOp - processes size of operation                          */
3221 /*-----------------------------------------------------------------*/
3222 value *
3223 sizeofOp (sym_link * type)
3224 {
3225   char buff[10];
3226
3227   /* make sure the type is complete and sane */
3228   checkTypeSanity(type, "(sizeof)");
3229
3230   /* get the size and convert it to character  */
3231   sprintf (buff, "%d", getSize (type));
3232
3233   /* now convert into value  */
3234   return constVal (buff);
3235 }
3236
3237
3238 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3239 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
3240 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3241 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3242 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3243 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
3244 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
3245
3246 /*-----------------------------------------------------------------*/
3247 /* backPatchLabels - change and or not operators to flow control    */
3248 /*-----------------------------------------------------------------*/
3249 ast *
3250 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3251 {
3252
3253   if (!tree)
3254     return NULL;
3255
3256   if (!(IS_ANDORNOT (tree)))
3257     return tree;
3258
3259   /* if this an and */
3260   if (IS_AND (tree))
3261     {
3262       static int localLbl = 0;
3263       symbol *localLabel;
3264
3265       sprintf (buffer, "_and_%d", localLbl++);
3266       localLabel = newSymbol (buffer, NestLevel);
3267
3268       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3269
3270       /* if left is already a IFX then just change the if true label in that */
3271       if (!IS_IFX (tree->left))
3272         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3273
3274       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3275       /* right is a IFX then just join */
3276       if (IS_IFX (tree->right))
3277         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3278
3279       tree->right = createLabel (localLabel, tree->right);
3280       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3281
3282       return newNode (NULLOP, tree->left, tree->right);
3283     }
3284
3285   /* if this is an or operation */
3286   if (IS_OR (tree))
3287     {
3288       static int localLbl = 0;
3289       symbol *localLabel;
3290
3291       sprintf (buffer, "_or_%d", localLbl++);
3292       localLabel = newSymbol (buffer, NestLevel);
3293
3294       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3295
3296       /* if left is already a IFX then just change the if true label in that */
3297       if (!IS_IFX (tree->left))
3298         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3299
3300       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3301       /* right is a IFX then just join */
3302       if (IS_IFX (tree->right))
3303         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3304
3305       tree->right = createLabel (localLabel, tree->right);
3306       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3307
3308       return newNode (NULLOP, tree->left, tree->right);
3309     }
3310
3311   /* change not */
3312   if (IS_NOT (tree))
3313     {
3314       int wasnot = IS_NOT (tree->left);
3315       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3316
3317       /* if the left is already a IFX */
3318       if (!IS_IFX (tree->left))
3319         tree->left = newNode (IFX, tree->left, NULL);
3320
3321       if (wasnot)
3322         {
3323           tree->left->trueLabel = trueLabel;
3324           tree->left->falseLabel = falseLabel;
3325         }
3326       else
3327         {
3328           tree->left->trueLabel = falseLabel;
3329           tree->left->falseLabel = trueLabel;
3330         }
3331       return tree->left;
3332     }
3333
3334   if (IS_IFX (tree))
3335     {
3336       tree->trueLabel = trueLabel;
3337       tree->falseLabel = falseLabel;
3338     }
3339
3340   return tree;
3341 }
3342
3343
3344 /*-----------------------------------------------------------------*/
3345 /* createBlock - create expression tree for block                  */
3346 /*-----------------------------------------------------------------*/
3347 ast *
3348 createBlock (symbol * decl, ast * body)
3349 {
3350   ast *ex;
3351
3352   /* if the block has nothing */
3353   if (!body)
3354     return NULL;
3355
3356   ex = newNode (BLOCK, NULL, body);
3357   ex->values.sym = decl;
3358
3359   ex->right = ex->right;
3360   ex->level++;
3361   ex->lineno = 0;
3362   return ex;
3363 }
3364
3365 /*-----------------------------------------------------------------*/
3366 /* createLabel - creates the expression tree for labels            */
3367 /*-----------------------------------------------------------------*/
3368 ast *
3369 createLabel (symbol * label, ast * stmnt)
3370 {
3371   symbol *csym;
3372   char name[SDCC_NAME_MAX + 1];
3373   ast *rValue;
3374
3375   /* must create fresh symbol if the symbol name  */
3376   /* exists in the symbol table, since there can  */
3377   /* be a variable with the same name as the labl */
3378   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3379       (csym->level == label->level))
3380     label = newSymbol (label->name, label->level);
3381
3382   /* change the name before putting it in add _ */
3383   sprintf (name, "%s", label->name);
3384
3385   /* put the label in the LabelSymbol table    */
3386   /* but first check if a label of the same    */
3387   /* name exists                               */
3388   if ((csym = findSym (LabelTab, NULL, name)))
3389     werror (E_DUPLICATE_LABEL, label->name);
3390   else
3391     addSym (LabelTab, label, name, label->level, 0, 0);
3392
3393   label->islbl = 1;
3394   label->key = labelKey++;
3395   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3396   rValue->lineno = 0;
3397
3398   return rValue;
3399 }
3400
3401 /*-----------------------------------------------------------------*/
3402 /* createCase - generates the parsetree for a case statement       */
3403 /*-----------------------------------------------------------------*/
3404 ast *
3405 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3406 {
3407   char caseLbl[SDCC_NAME_MAX + 1];
3408   ast *rexpr;
3409   value *val;
3410
3411   /* if the switch statement does not exist */
3412   /* then case is out of context            */
3413   if (!swStat)
3414     {
3415       werror (E_CASE_CONTEXT);
3416       return NULL;
3417     }
3418
3419   caseVal = decorateType (resolveSymbols (caseVal));
3420   /* if not a constant then error  */
3421   if (!IS_LITERAL (caseVal->ftype))
3422     {
3423       werror (E_CASE_CONSTANT);
3424       return NULL;
3425     }
3426
3427   /* if not a integer than error */
3428   if (!IS_INTEGRAL (caseVal->ftype))
3429     {
3430       werror (E_CASE_NON_INTEGER);
3431       return NULL;
3432     }
3433
3434   /* find the end of the switch values chain   */
3435   if (!(val = swStat->values.switchVals.swVals))
3436     swStat->values.switchVals.swVals = caseVal->opval.val;
3437   else
3438     {
3439       /* also order the cases according to value */
3440       value *pval = NULL;
3441       int cVal = (int) floatFromVal (caseVal->opval.val);
3442       while (val && (int) floatFromVal (val) < cVal)
3443         {
3444           pval = val;
3445           val = val->next;
3446         }
3447
3448       /* if we reached the end then */
3449       if (!val)
3450         {
3451           pval->next = caseVal->opval.val;
3452         }
3453       else
3454         {
3455           /* we found a value greater than */
3456           /* the current value we must add this */
3457           /* before the value */
3458           caseVal->opval.val->next = val;
3459
3460           /* if this was the first in chain */
3461           if (swStat->values.switchVals.swVals == val)
3462             swStat->values.switchVals.swVals =
3463               caseVal->opval.val;
3464           else
3465             pval->next = caseVal->opval.val;
3466         }
3467
3468     }
3469
3470   /* create the case label   */
3471   sprintf (caseLbl, "_case_%d_%d",
3472            swStat->values.switchVals.swNum,
3473            (int) floatFromVal (caseVal->opval.val));
3474
3475   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3476   rexpr->lineno = 0;
3477   return rexpr;
3478 }
3479
3480 /*-----------------------------------------------------------------*/
3481 /* createDefault - creates the parse tree for the default statement */
3482 /*-----------------------------------------------------------------*/
3483 ast *
3484 createDefault (ast * swStat, ast * stmnt)
3485 {
3486   char defLbl[SDCC_NAME_MAX + 1];
3487
3488   /* if the switch statement does not exist */
3489   /* then case is out of context            */
3490   if (!swStat)
3491     {
3492       werror (E_CASE_CONTEXT);
3493       return NULL;
3494     }
3495
3496   /* turn on the default flag   */
3497   swStat->values.switchVals.swDefault = 1;
3498
3499   /* create the label  */
3500   sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3501   return createLabel (newSymbol (defLbl, 0), stmnt);
3502 }
3503
3504 /*-----------------------------------------------------------------*/
3505 /* createIf - creates the parsetree for the if statement           */
3506 /*-----------------------------------------------------------------*/
3507 ast *
3508 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3509 {
3510   static int Lblnum = 0;
3511   ast *ifTree;
3512   symbol *ifTrue, *ifFalse, *ifEnd;
3513
3514   /* if neither exists */
3515   if (!elseBody && !ifBody) {
3516     // if there are no side effects (i++, j() etc)
3517     if (!hasSEFcalls(condAst)) {
3518       return condAst;
3519     }
3520   }
3521
3522   /* create the labels */
3523   sprintf (buffer, "_iffalse_%d", Lblnum);
3524   ifFalse = newSymbol (buffer, NestLevel);
3525   /* if no else body then end == false */
3526   if (!elseBody)
3527     ifEnd = ifFalse;
3528   else
3529     {
3530       sprintf (buffer, "_ifend_%d", Lblnum);
3531       ifEnd = newSymbol (buffer, NestLevel);
3532     }
3533
3534   sprintf (buffer, "_iftrue_%d", Lblnum);
3535   ifTrue = newSymbol (buffer, NestLevel);
3536
3537   Lblnum++;
3538
3539   /* attach the ifTrue label to the top of it body */
3540   ifBody = createLabel (ifTrue, ifBody);
3541   /* attach a goto end to the ifBody if else is present */
3542   if (elseBody)
3543     {
3544       ifBody = newNode (NULLOP, ifBody,
3545                         newNode (GOTO,
3546                                  newAst_VALUE (symbolVal (ifEnd)),
3547                                  NULL));
3548       /* put the elseLabel on the else body */
3549       elseBody = createLabel (ifFalse, elseBody);
3550       /* out the end at the end of the body */
3551       elseBody = newNode (NULLOP,
3552                           elseBody,
3553                           createLabel (ifEnd, NULL));
3554     }
3555   else
3556     {
3557       ifBody = newNode (NULLOP, ifBody,
3558                         createLabel (ifFalse, NULL));
3559     }
3560   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3561   if (IS_IFX (condAst))
3562     ifTree = condAst;
3563   else
3564     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3565
3566   return newNode (NULLOP, ifTree,
3567                   newNode (NULLOP, ifBody, elseBody));
3568
3569 }
3570
3571 /*-----------------------------------------------------------------*/
3572 /* createDo - creates parse tree for do                            */
3573 /*        _dobody_n:                                               */
3574 /*            statements                                           */
3575 /*        _docontinue_n:                                           */
3576 /*            condition_expression +-> trueLabel -> _dobody_n      */
3577 /*                                 |                               */
3578 /*                                 +-> falseLabel-> _dobreak_n     */
3579 /*        _dobreak_n:                                              */
3580 /*-----------------------------------------------------------------*/
3581 ast *
3582 createDo (symbol * trueLabel, symbol * continueLabel,
3583           symbol * falseLabel, ast * condAst, ast * doBody)
3584 {
3585   ast *doTree;
3586
3587
3588   /* if the body does not exist then it is simple */
3589   if (!doBody)
3590     {
3591       condAst = backPatchLabels (condAst, continueLabel, NULL);
3592       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3593                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3594       doTree->trueLabel = continueLabel;
3595       doTree->falseLabel = NULL;
3596       return doTree;
3597     }
3598
3599   /* otherwise we have a body */
3600   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3601
3602   /* attach the body label to the top */
3603   doBody = createLabel (trueLabel, doBody);
3604   /* attach the continue label to end of body */
3605   doBody = newNode (NULLOP, doBody,
3606                     createLabel (continueLabel, NULL));
3607
3608   /* now put the break label at the end */
3609   if (IS_IFX (condAst))
3610     doTree = condAst;
3611   else
3612     doTree = newIfxNode (condAst, trueLabel, falseLabel);
3613
3614   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3615
3616   /* putting it together */
3617   return newNode (NULLOP, doBody, doTree);
3618 }
3619
3620 /*-----------------------------------------------------------------*/
3621 /* createFor - creates parse tree for 'for' statement              */
3622 /*        initExpr                                                 */
3623 /*   _forcond_n:                                                   */
3624 /*        condExpr  +-> trueLabel -> _forbody_n                    */
3625 /*                  |                                              */
3626 /*                  +-> falseLabel-> _forbreak_n                   */
3627 /*   _forbody_n:                                                   */
3628 /*        statements                                               */
3629 /*   _forcontinue_n:                                               */
3630 /*        loopExpr                                                 */
3631 /*        goto _forcond_n ;                                        */
3632 /*   _forbreak_n:                                                  */
3633 /*-----------------------------------------------------------------*/
3634 ast *
3635 createFor (symbol * trueLabel, symbol * continueLabel,
3636            symbol * falseLabel, symbol * condLabel,
3637            ast * initExpr, ast * condExpr, ast * loopExpr,
3638            ast * forBody)
3639 {
3640   ast *forTree;
3641
3642   /* if loopexpression not present then we can generate it */
3643   /* the same way as a while */
3644   if (!loopExpr)
3645     return newNode (NULLOP, initExpr,
3646                     createWhile (trueLabel, continueLabel,
3647                                  falseLabel, condExpr, forBody));
3648   /* vanilla for statement */
3649   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3650
3651   if (condExpr && !IS_IFX (condExpr))
3652     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3653
3654
3655   /* attach condition label to condition */
3656   condExpr = createLabel (condLabel, condExpr);
3657
3658   /* attach body label to body */
3659   forBody = createLabel (trueLabel, forBody);
3660
3661   /* attach continue to forLoop expression & attach */
3662   /* goto the forcond @ and of loopExpression       */
3663   loopExpr = createLabel (continueLabel,
3664                           newNode (NULLOP,
3665                                    loopExpr,
3666                                    newNode (GOTO,
3667                                        newAst_VALUE (symbolVal (condLabel)),
3668                                             NULL)));
3669   /* now start putting them together */
3670   forTree = newNode (NULLOP, initExpr, condExpr);
3671   forTree = newNode (NULLOP, forTree, forBody);
3672   forTree = newNode (NULLOP, forTree, loopExpr);
3673   /* finally add the break label */
3674   forTree = newNode (NULLOP, forTree,
3675                      createLabel (falseLabel, NULL));
3676   return forTree;
3677 }
3678
3679 /*-----------------------------------------------------------------*/
3680 /* createWhile - creates parse tree for while statement            */
3681 /*               the while statement will be created as follows    */
3682 /*                                                                 */
3683 /*      _while_continue_n:                                         */
3684 /*            condition_expression +-> trueLabel -> _while_boby_n  */
3685 /*                                 |                               */
3686 /*                                 +-> falseLabel -> _while_break_n */
3687 /*      _while_body_n:                                             */
3688 /*            statements                                           */
3689 /*            goto _while_continue_n                               */
3690 /*      _while_break_n:                                            */
3691 /*-----------------------------------------------------------------*/
3692 ast *
3693 createWhile (symbol * trueLabel, symbol * continueLabel,
3694              symbol * falseLabel, ast * condExpr, ast * whileBody)
3695 {
3696   ast *whileTree;
3697
3698   /* put the continue label */
3699   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3700   condExpr = createLabel (continueLabel, condExpr);
3701   condExpr->lineno = 0;
3702
3703   /* put the body label in front of the body */
3704   whileBody = createLabel (trueLabel, whileBody);
3705   whileBody->lineno = 0;
3706   /* put a jump to continue at the end of the body */
3707   /* and put break label at the end of the body */
3708   whileBody = newNode (NULLOP,
3709                        whileBody,
3710                        newNode (GOTO,
3711                                 newAst_VALUE (symbolVal (continueLabel)),
3712                                 createLabel (falseLabel, NULL)));
3713
3714   /* put it all together */
3715   if (IS_IFX (condExpr))
3716     whileTree = condExpr;
3717   else
3718     {
3719       whileTree = newNode (IFX, condExpr, NULL);
3720       /* put the true & false labels in place */
3721       whileTree->trueLabel = trueLabel;
3722       whileTree->falseLabel = falseLabel;
3723     }
3724
3725   return newNode (NULLOP, whileTree, whileBody);
3726 }
3727
3728 /*-----------------------------------------------------------------*/
3729 /* optimizeGetHbit - get highest order bit of the expression       */
3730 /*-----------------------------------------------------------------*/
3731 ast *
3732 optimizeGetHbit (ast * tree)
3733 {
3734   int i, j;
3735   /* if this is not a bit and */
3736   if (!IS_BITAND (tree))
3737     return tree;
3738
3739   /* will look for tree of the form
3740      ( expr >> ((sizeof expr) -1) ) & 1 */
3741   if (!IS_AST_LIT_VALUE (tree->right))
3742     return tree;
3743
3744   if (AST_LIT_VALUE (tree->right) != 1)
3745     return tree;
3746
3747   if (!IS_RIGHT_OP (tree->left))
3748     return tree;
3749
3750   if (!IS_AST_LIT_VALUE (tree->left->right))
3751     return tree;
3752
3753   if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3754       (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3755     return tree;
3756
3757   return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3758
3759 }
3760
3761 /*-----------------------------------------------------------------*/
3762 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
3763 /*-----------------------------------------------------------------*/
3764 ast *
3765 optimizeRRCRLC (ast * root)
3766 {
3767   /* will look for trees of the form
3768      (?expr << 1) | (?expr >> 7) or
3769      (?expr >> 7) | (?expr << 1) will make that
3770      into a RLC : operation ..
3771      Will also look for
3772      (?expr >> 1) | (?expr << 7) or
3773      (?expr << 7) | (?expr >> 1) will make that
3774      into a RRC operation
3775      note : by 7 I mean (number of bits required to hold the
3776      variable -1 ) */
3777   /* if the root operations is not a | operation the not */
3778   if (!IS_BITOR (root))
3779     return root;
3780
3781   /* I have to think of a better way to match patterns this sucks */
3782   /* that aside let start looking for the first case : I use a the
3783      negative check a lot to improve the efficiency */
3784   /* (?expr << 1) | (?expr >> 7) */
3785   if (IS_LEFT_OP (root->left) &&
3786       IS_RIGHT_OP (root->right))
3787     {
3788
3789       if (!SPEC_USIGN (TETYPE (root->left->left)))
3790         return root;
3791
3792       if (!IS_AST_LIT_VALUE (root->left->right) ||
3793           !IS_AST_LIT_VALUE (root->right->right))
3794         goto tryNext0;
3795
3796       /* make sure it is the same expression */
3797       if (!isAstEqual (root->left->left,
3798                        root->right->left))
3799         goto tryNext0;
3800
3801       if (AST_LIT_VALUE (root->left->right) != 1)
3802         goto tryNext0;
3803
3804       if (AST_LIT_VALUE (root->right->right) !=
3805           (getSize (TTYPE (root->left->left)) * 8 - 1))
3806         goto tryNext0;
3807
3808       /* whew got the first case : create the AST */
3809       return newNode (RLC, root->left->left, NULL);
3810     }
3811
3812 tryNext0:
3813   /* check for second case */
3814   /* (?expr >> 7) | (?expr << 1) */
3815   if (IS_LEFT_OP (root->right) &&
3816       IS_RIGHT_OP (root->left))
3817     {
3818
3819       if (!SPEC_USIGN (TETYPE (root->left->left)))
3820         return root;
3821
3822       if (!IS_AST_LIT_VALUE (root->left->right) ||
3823           !IS_AST_LIT_VALUE (root->right->right))
3824         goto tryNext1;
3825
3826       /* make sure it is the same symbol */
3827       if (!isAstEqual (root->left->left,
3828                        root->right->left))
3829         goto tryNext1;
3830
3831       if (AST_LIT_VALUE (root->right->right) != 1)
3832         goto tryNext1;
3833
3834       if (AST_LIT_VALUE (root->left->right) !=
3835           (getSize (TTYPE (root->left->left)) * 8 - 1))
3836         goto tryNext1;
3837
3838       /* whew got the first case : create the AST */
3839       return newNode (RLC, root->left->left, NULL);
3840
3841     }
3842
3843 tryNext1:
3844   /* third case for RRC */
3845   /*  (?symbol >> 1) | (?symbol << 7) */
3846   if (IS_LEFT_OP (root->right) &&
3847       IS_RIGHT_OP (root->left))
3848     {
3849
3850       if (!SPEC_USIGN (TETYPE (root->left->left)))
3851         return root;
3852
3853       if (!IS_AST_LIT_VALUE (root->left->right) ||
3854           !IS_AST_LIT_VALUE (root->right->right))
3855         goto tryNext2;
3856
3857       /* make sure it is the same symbol */
3858       if (!isAstEqual (root->left->left,
3859                        root->right->left))
3860         goto tryNext2;
3861
3862       if (AST_LIT_VALUE (root->left->right) != 1)
3863         goto tryNext2;
3864
3865       if (AST_LIT_VALUE (root->right->right) !=
3866           (getSize (TTYPE (root->left->left)) * 8 - 1))
3867         goto tryNext2;
3868
3869       /* whew got the first case : create the AST */
3870       return newNode (RRC, root->left->left, NULL);
3871
3872     }
3873 tryNext2:
3874   /* fourth and last case for now */
3875   /* (?symbol << 7) | (?symbol >> 1) */
3876   if (IS_RIGHT_OP (root->right) &&
3877       IS_LEFT_OP (root->left))
3878     {
3879
3880       if (!SPEC_USIGN (TETYPE (root->left->left)))
3881         return root;
3882
3883       if (!IS_AST_LIT_VALUE (root->left->right) ||
3884           !IS_AST_LIT_VALUE (root->right->right))
3885         return root;
3886
3887       /* make sure it is the same symbol */
3888       if (!isAstEqual (root->left->left,
3889                        root->right->left))
3890         return root;
3891
3892       if (AST_LIT_VALUE (root->right->right) != 1)
3893         return root;
3894
3895       if (AST_LIT_VALUE (root->left->right) !=
3896           (getSize (TTYPE (root->left->left)) * 8 - 1))
3897         return root;
3898
3899       /* whew got the first case : create the AST */
3900       return newNode (RRC, root->left->left, NULL);
3901
3902     }
3903
3904   /* not found return root */
3905   return root;
3906 }
3907
3908 /*-----------------------------------------------------------------*/
3909 /* optimizeCompare - otimizes compares for bit variables     */
3910 /*-----------------------------------------------------------------*/
3911 ast *
3912 optimizeCompare (ast * root)
3913 {
3914   ast *optExpr = NULL;
3915   value *vleft;
3916   value *vright;
3917   unsigned int litValue;
3918
3919   /* if nothing then return nothing */
3920   if (!root)
3921     return NULL;
3922
3923   /* if not a compare op then do leaves */
3924   if (!IS_COMPARE_OP (root))
3925     {
3926       root->left = optimizeCompare (root->left);
3927       root->right = optimizeCompare (root->right);
3928       return root;
3929     }
3930
3931   /* if left & right are the same then depending
3932      of the operation do */
3933   if (isAstEqual (root->left, root->right))
3934     {
3935       switch (root->opval.op)
3936         {
3937         case '>':
3938         case '<':
3939         case NE_OP:
3940           optExpr = newAst_VALUE (constVal ("0"));
3941           break;
3942         case GE_OP:
3943         case LE_OP:
3944         case EQ_OP:
3945           optExpr = newAst_VALUE (constVal ("1"));
3946           break;
3947         }
3948
3949       return decorateType (optExpr);
3950     }
3951
3952   vleft = (root->left->type == EX_VALUE ?
3953            root->left->opval.val : NULL);
3954
3955   vright = (root->right->type == EX_VALUE ?
3956             root->right->opval.val : NULL);
3957
3958   /* if left is a BITVAR in BITSPACE */
3959   /* and right is a LITERAL then opt- */
3960   /* imize else do nothing       */
3961   if (vleft && vright &&
3962       IS_BITVAR (vleft->etype) &&
3963       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
3964       IS_LITERAL (vright->etype))
3965     {
3966
3967       /* if right side > 1 then comparison may never succeed */
3968       if ((litValue = (int) floatFromVal (vright)) > 1)
3969         {
3970           werror (W_BAD_COMPARE);
3971           goto noOptimize;
3972         }
3973
3974       if (litValue)
3975         {
3976           switch (root->opval.op)
3977             {
3978             case '>':           /* bit value greater than 1 cannot be */
3979               werror (W_BAD_COMPARE);
3980               goto noOptimize;
3981               break;
3982
3983             case '<':           /* bit value < 1 means 0 */
3984             case NE_OP:
3985               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
3986               break;
3987
3988             case LE_OP: /* bit value <= 1 means no check */
3989               optExpr = newAst_VALUE (vright);
3990               break;
3991
3992             case GE_OP: /* bit value >= 1 means only check for = */
3993             case EQ_OP:
3994               optExpr = newAst_VALUE (vleft);
3995               break;
3996             }
3997         }
3998       else
3999         {                       /* literal is zero */
4000           switch (root->opval.op)
4001             {
4002             case '<':           /* bit value < 0 cannot be */
4003               werror (W_BAD_COMPARE);
4004               goto noOptimize;
4005               break;
4006
4007             case '>':           /* bit value > 0 means 1 */
4008             case NE_OP:
4009               optExpr = newAst_VALUE (vleft);
4010               break;
4011
4012             case LE_OP: /* bit value <= 0 means no check */
4013             case GE_OP: /* bit value >= 0 means no check */
4014               werror (W_BAD_COMPARE);
4015               goto noOptimize;
4016               break;
4017
4018             case EQ_OP: /* bit == 0 means ! of bit */
4019               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4020               break;
4021             }
4022         }
4023       return decorateType (resolveSymbols (optExpr));
4024     }                           /* end-of-if of BITVAR */
4025
4026 noOptimize:
4027   return root;
4028 }
4029 /*-----------------------------------------------------------------*/
4030 /* addSymToBlock : adds the symbol to the first block we find      */
4031 /*-----------------------------------------------------------------*/
4032 void 
4033 addSymToBlock (symbol * sym, ast * tree)
4034 {
4035   /* reached end of tree or a leaf */
4036   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4037     return;
4038
4039   /* found a block */
4040   if (IS_AST_OP (tree) &&
4041       tree->opval.op == BLOCK)
4042     {
4043
4044       symbol *lsym = copySymbol (sym);
4045
4046       lsym->next = AST_VALUES (tree, sym);
4047       AST_VALUES (tree, sym) = lsym;
4048       return;
4049     }
4050
4051   addSymToBlock (sym, tree->left);
4052   addSymToBlock (sym, tree->right);
4053 }
4054
4055 /*-----------------------------------------------------------------*/
4056 /* processRegParms - do processing for register parameters         */
4057 /*-----------------------------------------------------------------*/
4058 static void 
4059 processRegParms (value * args, ast * body)
4060 {
4061   while (args)
4062     {
4063       if (IS_REGPARM (args->etype))
4064         addSymToBlock (args->sym, body);
4065       args = args->next;
4066     }
4067 }
4068
4069 /*-----------------------------------------------------------------*/
4070 /* resetParmKey - resets the operandkeys for the symbols           */
4071 /*-----------------------------------------------------------------*/
4072 DEFSETFUNC (resetParmKey)
4073 {
4074   symbol *sym = item;
4075
4076   sym->key = 0;
4077   sym->defs = NULL;
4078   sym->uses = NULL;
4079   sym->remat = 0;
4080   return 1;
4081 }
4082
4083 /*-----------------------------------------------------------------*/
4084 /* createFunction - This is the key node that calls the iCode for  */
4085 /*                  generating the code for a function. Note code  */
4086 /*                  is generated function by function, later when  */
4087 /*                  add inter-procedural analysis this will change */
4088 /*-----------------------------------------------------------------*/
4089 ast *
4090 createFunction (symbol * name, ast * body)
4091 {
4092   ast *ex;
4093   symbol *csym;
4094   int stack = 0;
4095   sym_link *fetype;
4096   iCode *piCode = NULL;
4097
4098   /* if check function return 0 then some problem */
4099   if (checkFunction (name, NULL) == 0)
4100     return NULL;
4101
4102   /* create a dummy block if none exists */
4103   if (!body)
4104     body = newNode (BLOCK, NULL, NULL);
4105
4106   noLineno++;
4107
4108   /* check if the function name already in the symbol table */
4109   if ((csym = findSym (SymbolTab, NULL, name->name)))
4110     {
4111       name = csym;
4112       /* special case for compiler defined functions
4113          we need to add the name to the publics list : this
4114          actually means we are now compiling the compiler
4115          support routine */
4116       if (name->cdef)
4117         {
4118           addSet (&publics, name);
4119         }
4120     }
4121   else
4122     {
4123       addSymChain (name);
4124       allocVariables (name);
4125     }
4126   name->lastLine = yylineno;
4127   currFunc = name;
4128   processFuncArgs (currFunc, 0);
4129
4130   /* set the stack pointer */
4131   /* PENDING: check this for the mcs51 */
4132   stackPtr = -port->stack.direction * port->stack.call_overhead;
4133   if (IFFUNC_ISISR (name->type))
4134     stackPtr -= port->stack.direction * port->stack.isr_overhead;
4135   if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4136     stackPtr -= port->stack.direction * port->stack.reent_overhead;
4137
4138   xstackPtr = -port->stack.direction * port->stack.call_overhead;
4139
4140   fetype = getSpec (name->type);        /* get the specifier for the function */
4141   /* if this is a reentrant function then */
4142   if (IFFUNC_ISREENT (name->type))
4143     reentrant++;
4144
4145   allocParms (FUNC_ARGS(name->type));   /* allocate the parameters */
4146
4147   /* do processing for parameters that are passed in registers */
4148   processRegParms (FUNC_ARGS(name->type), body);
4149
4150   /* set the stack pointer */
4151   stackPtr = 0;
4152   xstackPtr = -1;
4153
4154   /* allocate & autoinit the block variables */
4155   processBlockVars (body, &stack, ALLOCATE);
4156
4157   /* save the stack information */
4158   if (options.useXstack)
4159     name->xstack = SPEC_STAK (fetype) = stack;
4160   else
4161     name->stack = SPEC_STAK (fetype) = stack;
4162
4163   /* name needs to be mangled */
4164   sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4165
4166   body = resolveSymbols (body); /* resolve the symbols */
4167   body = decorateType (body);   /* propagateType & do semantic checks */
4168
4169   ex = newAst_VALUE (symbolVal (name));         /* create name       */
4170   ex = newNode (FUNCTION, ex, body);
4171   ex->values.args = FUNC_ARGS(name->type);
4172   ex->decorated=1;
4173   if (options.dump_tree) PA(ex);
4174   if (fatalError)
4175     {
4176       werror (E_FUNC_NO_CODE, name->name);
4177       goto skipall;
4178     }
4179
4180   /* create the node & generate intermediate code */
4181   GcurMemmap = code;
4182   codeOutFile = code->oFile;
4183   piCode = iCodeFromAst (ex);
4184
4185   if (fatalError)
4186     {
4187       werror (E_FUNC_NO_CODE, name->name);
4188       goto skipall;
4189     }
4190
4191   eBBlockFromiCode (piCode);
4192
4193   /* if there are any statics then do them */
4194   if (staticAutos)
4195     {
4196       GcurMemmap = statsg;
4197       codeOutFile = statsg->oFile;
4198       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4199       staticAutos = NULL;
4200     }
4201
4202 skipall:
4203
4204   /* dealloc the block variables */
4205   processBlockVars (body, &stack, DEALLOCATE);
4206   /* deallocate paramaters */
4207   deallocParms (FUNC_ARGS(name->type));
4208
4209   if (IFFUNC_ISREENT (name->type))
4210     reentrant--;
4211
4212   /* we are done freeup memory & cleanup */
4213   noLineno--;
4214   labelKey = 1;
4215   name->key = 0;
4216   FUNC_HASBODY(name->type) = 1;
4217   addSet (&operKeyReset, name);
4218   applyToSet (operKeyReset, resetParmKey);
4219
4220   if (options.debug)
4221     cdbStructBlock (1, cdbFile);
4222
4223   cleanUpLevel (LabelTab, 0);
4224   cleanUpBlock (StructTab, 1);
4225   cleanUpBlock (TypedefTab, 1);
4226
4227   xstack->syms = NULL;
4228   istack->syms = NULL;
4229   return NULL;
4230 }
4231
4232
4233 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4234 /*-----------------------------------------------------------------*/
4235 /* ast_print : prints the ast (for debugging purposes)             */
4236 /*-----------------------------------------------------------------*/
4237
4238 void ast_print (ast * tree, FILE *outfile, int indent)
4239 {
4240         
4241         if (!tree) return ;
4242
4243         /* can print only decorated trees */
4244         if (!tree->decorated) return;
4245
4246         /* if any child is an error | this one is an error do nothing */
4247         if (tree->isError ||
4248             (tree->left && tree->left->isError) ||
4249             (tree->right && tree->right->isError)) {
4250                 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4251         }
4252
4253         
4254         /* print the line          */
4255         /* if not block & function */
4256         if (tree->type == EX_OP &&
4257             (tree->opval.op != FUNCTION &&
4258              tree->opval.op != BLOCK &&
4259              tree->opval.op != NULLOP)) {
4260         }
4261         
4262         if (tree->opval.op == FUNCTION) {
4263                 fprintf(outfile,"FUNCTION (%p) type (",tree);
4264                 printTypeChain (tree->ftype,outfile);
4265                 fprintf(outfile,")\n");
4266                 ast_print(tree->left,outfile,indent+4);
4267                 ast_print(tree->right,outfile,indent+4);
4268                 return ;
4269         }
4270         if (tree->opval.op == BLOCK) {
4271                 symbol *decls = tree->values.sym;
4272                 INDENT(indent+4,outfile);
4273                 fprintf(outfile,"{\n");
4274                 while (decls) {
4275                         INDENT(indent+4,outfile);
4276                         fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4277                         printTypeChain(decls->type,outfile);
4278                         fprintf(outfile,")\n");
4279                         
4280                         decls = decls->next;                    
4281                 }
4282                 ast_print(tree->right,outfile,indent+4);
4283                 INDENT(indent+4,outfile);
4284                 fprintf(outfile,"}\n");
4285                 return;
4286         }
4287         if (tree->opval.op == NULLOP) {
4288                 fprintf(outfile,"\n");
4289                 ast_print(tree->left,outfile,indent);
4290                 fprintf(outfile,"\n");
4291                 ast_print(tree->right,outfile,indent);
4292                 return ;
4293         }
4294         INDENT(indent,outfile);
4295
4296         /*------------------------------------------------------------------*/
4297         /*----------------------------*/
4298         /*   leaf has been reached    */
4299         /*----------------------------*/
4300         /* if this is of type value */
4301         /* just get the type        */
4302         if (tree->type == EX_VALUE) {
4303
4304                 if (IS_LITERAL (tree->opval.val->etype)) {                      
4305                         fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4306                                 (int) floatFromVal(tree->opval.val),
4307                                 (int) floatFromVal(tree->opval.val),
4308                                 floatFromVal(tree->opval.val));
4309                 } else if (tree->opval.val->sym) {
4310                         /* if the undefined flag is set then give error message */
4311                         if (tree->opval.val->sym->undefined) {
4312                                 fprintf(outfile,"UNDEFINED SYMBOL ");
4313                         } else {
4314                                 fprintf(outfile,"SYMBOL ");
4315                         }
4316                         fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4317                 }
4318                 if (tree->ftype) {
4319                         fprintf(outfile," type (");
4320                         printTypeChain(tree->ftype,outfile);
4321                         fprintf(outfile,")\n");
4322                 } else {
4323                         fprintf(outfile,"\n");
4324                 }
4325                 return ;
4326         }
4327
4328         /* if type link for the case of cast */
4329         if (tree->type == EX_LINK) {
4330                 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4331                 printTypeChain(tree->opval.lnk,outfile);
4332                 fprintf(outfile,")\n");
4333                 return ;
4334         }
4335
4336
4337         /* depending on type of operator do */
4338         
4339         switch (tree->opval.op) {
4340                 /*------------------------------------------------------------------*/
4341                 /*----------------------------*/
4342                 /*        array node          */
4343                 /*----------------------------*/
4344         case '[':
4345                 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4346                 printTypeChain(tree->ftype,outfile);
4347                 fprintf(outfile,")\n");
4348                 ast_print(tree->left,outfile,indent+4);
4349                 ast_print(tree->right,outfile,indent+4);
4350                 return;
4351
4352                 /*------------------------------------------------------------------*/
4353                 /*----------------------------*/
4354                 /*      struct/union          */
4355                 /*----------------------------*/
4356         case '.':
4357                 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4358                 printTypeChain(tree->ftype,outfile);
4359                 fprintf(outfile,")\n");
4360                 ast_print(tree->left,outfile,indent+4);
4361                 ast_print(tree->right,outfile,indent+4);
4362                 return ;
4363
4364                 /*------------------------------------------------------------------*/
4365                 /*----------------------------*/
4366                 /*    struct/union pointer    */
4367                 /*----------------------------*/
4368         case PTR_OP:
4369                 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4370                 printTypeChain(tree->ftype,outfile);
4371                 fprintf(outfile,")\n");
4372                 ast_print(tree->left,outfile,indent+4);
4373                 ast_print(tree->right,outfile,indent+4);
4374                 return ;
4375
4376                 /*------------------------------------------------------------------*/
4377                 /*----------------------------*/
4378                 /*  ++/-- operation           */
4379                 /*----------------------------*/
4380         case INC_OP:            /* incerement operator unary so left only */
4381                 fprintf(outfile,"INC_OP (%p) type (",tree);
4382                 printTypeChain(tree->ftype,outfile);
4383                 fprintf(outfile,")\n");
4384                 ast_print(tree->left,outfile,indent+4);
4385                 return ;
4386
4387         case DEC_OP:
4388                 fprintf(outfile,"DEC_OP (%p) type (",tree);
4389                 printTypeChain(tree->ftype,outfile);
4390                 fprintf(outfile,")\n");
4391                 ast_print(tree->left,outfile,indent+4);
4392                 return ;
4393
4394                 /*------------------------------------------------------------------*/
4395                 /*----------------------------*/
4396                 /*  bitwise and               */
4397                 /*----------------------------*/
4398         case '&':                       
4399                 if (tree->right) {
4400                         fprintf(outfile,"& (%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                 } else {
4406                         fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4407                         printTypeChain(tree->ftype,outfile);
4408                         fprintf(outfile,")\n");
4409                         ast_print(tree->left,outfile,indent+4);
4410                         ast_print(tree->right,outfile,indent+4);
4411                 }
4412                 return ;
4413                 /*----------------------------*/
4414                 /*  bitwise or                */
4415                 /*----------------------------*/
4416         case '|':
4417                 fprintf(outfile,"OR (%p) type (",tree);
4418                 printTypeChain(tree->ftype,outfile);
4419                 fprintf(outfile,")\n");
4420                 ast_print(tree->left,outfile,indent+4);
4421                 ast_print(tree->right,outfile,indent+4);
4422                 return ;
4423                 /*------------------------------------------------------------------*/
4424                 /*----------------------------*/
4425                 /*  bitwise xor               */
4426                 /*----------------------------*/
4427         case '^':
4428                 fprintf(outfile,"XOR (%p) type (",tree);
4429                 printTypeChain(tree->ftype,outfile);
4430                 fprintf(outfile,")\n");
4431                 ast_print(tree->left,outfile,indent+4);
4432                 ast_print(tree->right,outfile,indent+4);
4433                 return ;
4434                 
4435                 /*------------------------------------------------------------------*/
4436                 /*----------------------------*/
4437                 /*  division                  */
4438                 /*----------------------------*/
4439         case '/':
4440                 fprintf(outfile,"DIV (%p) type (",tree);
4441                 printTypeChain(tree->ftype,outfile);
4442                 fprintf(outfile,")\n");
4443                 ast_print(tree->left,outfile,indent+4);
4444                 ast_print(tree->right,outfile,indent+4);
4445                 return ;
4446                 /*------------------------------------------------------------------*/
4447                 /*----------------------------*/
4448                 /*            modulus         */
4449                 /*----------------------------*/
4450         case '%':
4451                 fprintf(outfile,"MOD (%p) type (",tree);
4452                 printTypeChain(tree->ftype,outfile);
4453                 fprintf(outfile,")\n");
4454                 ast_print(tree->left,outfile,indent+4);
4455                 ast_print(tree->right,outfile,indent+4);
4456                 return ;
4457
4458                 /*------------------------------------------------------------------*/
4459                 /*----------------------------*/
4460                 /*  address dereference       */
4461                 /*----------------------------*/
4462         case '*':                       /* can be unary  : if right is null then unary operation */
4463                 if (!tree->right) {
4464                         fprintf(outfile,"DEREF (%p) type (",tree);
4465                         printTypeChain(tree->ftype,outfile);
4466                         fprintf(outfile,")\n");
4467                         ast_print(tree->left,outfile,indent+4);
4468                         return ;
4469                 }                       
4470                 /*------------------------------------------------------------------*/
4471                 /*----------------------------*/
4472                 /*      multiplication        */
4473                 /*----------------------------*/                
4474                 fprintf(outfile,"MULT (%p) type (",tree);
4475                 printTypeChain(tree->ftype,outfile);
4476                 fprintf(outfile,")\n");
4477                 ast_print(tree->left,outfile,indent+4);
4478                 ast_print(tree->right,outfile,indent+4);
4479                 return ;
4480
4481
4482                 /*------------------------------------------------------------------*/
4483                 /*----------------------------*/
4484                 /*    unary '+' operator      */
4485                 /*----------------------------*/
4486         case '+':
4487                 /* if unary plus */
4488                 if (!tree->right) {
4489                         fprintf(outfile,"UPLUS (%p) type (",tree);
4490                         printTypeChain(tree->ftype,outfile);
4491                         fprintf(outfile,")\n");
4492                         ast_print(tree->left,outfile,indent+4);
4493                 } else {
4494                         /*------------------------------------------------------------------*/
4495                         /*----------------------------*/
4496                         /*      addition              */
4497                         /*----------------------------*/
4498                         fprintf(outfile,"ADD (%p) type (",tree);
4499                         printTypeChain(tree->ftype,outfile);
4500                         fprintf(outfile,")\n");
4501                         ast_print(tree->left,outfile,indent+4);
4502                         ast_print(tree->right,outfile,indent+4);
4503                 }
4504                 return;
4505                 /*------------------------------------------------------------------*/
4506                 /*----------------------------*/
4507                 /*      unary '-'             */
4508                 /*----------------------------*/
4509         case '-':                       /* can be unary   */
4510                 if (!tree->right) {
4511                         fprintf(outfile,"UMINUS (%p) type (",tree);
4512                         printTypeChain(tree->ftype,outfile);
4513                         fprintf(outfile,")\n");
4514                         ast_print(tree->left,outfile,indent+4);
4515                 } else {
4516                         /*------------------------------------------------------------------*/
4517                         /*----------------------------*/
4518                         /*      subtraction           */
4519                         /*----------------------------*/
4520                         fprintf(outfile,"SUB (%p) type (",tree);
4521                         printTypeChain(tree->ftype,outfile);
4522                         fprintf(outfile,")\n");
4523                         ast_print(tree->left,outfile,indent+4);
4524                         ast_print(tree->right,outfile,indent+4);
4525                 }
4526                 return;
4527                 /*------------------------------------------------------------------*/
4528                 /*----------------------------*/
4529                 /*    compliment              */
4530                 /*----------------------------*/
4531         case '~':
4532                 fprintf(outfile,"COMPL (%p) type (",tree);
4533                 printTypeChain(tree->ftype,outfile);
4534                 fprintf(outfile,")\n");
4535                 ast_print(tree->left,outfile,indent+4);
4536                 return ;
4537                 /*------------------------------------------------------------------*/
4538                 /*----------------------------*/
4539                 /*           not              */
4540                 /*----------------------------*/
4541         case '!':
4542                 fprintf(outfile,"NOT (%p) type (",tree);
4543                 printTypeChain(tree->ftype,outfile);
4544                 fprintf(outfile,")\n");
4545                 ast_print(tree->left,outfile,indent+4);
4546                 return ;
4547                 /*------------------------------------------------------------------*/
4548                 /*----------------------------*/
4549                 /*           shift            */
4550                 /*----------------------------*/
4551         case RRC:
4552                 fprintf(outfile,"RRC (%p) type (",tree);
4553                 printTypeChain(tree->ftype,outfile);
4554                 fprintf(outfile,")\n");
4555                 ast_print(tree->left,outfile,indent+4);
4556                 return ;
4557
4558         case RLC:
4559                 fprintf(outfile,"RLC (%p) type (",tree);
4560                 printTypeChain(tree->ftype,outfile);
4561                 fprintf(outfile,")\n");
4562                 ast_print(tree->left,outfile,indent+4);
4563                 return ;
4564         case GETHBIT:
4565                 fprintf(outfile,"GETHBIT (%p) type (",tree);
4566                 printTypeChain(tree->ftype,outfile);
4567                 fprintf(outfile,")\n");
4568                 ast_print(tree->left,outfile,indent+4);
4569                 return ;
4570         case LEFT_OP:
4571                 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4572                 printTypeChain(tree->ftype,outfile);
4573                 fprintf(outfile,")\n");
4574                 ast_print(tree->left,outfile,indent+4);
4575                 ast_print(tree->right,outfile,indent+4);
4576                 return ;
4577         case RIGHT_OP:
4578                 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4579                 printTypeChain(tree->ftype,outfile);
4580                 fprintf(outfile,")\n");
4581                 ast_print(tree->left,outfile,indent+4);
4582                 ast_print(tree->right,outfile,indent+4);
4583                 return ;
4584                 /*------------------------------------------------------------------*/
4585                 /*----------------------------*/
4586                 /*         casting            */
4587                 /*----------------------------*/
4588         case CAST:                      /* change the type   */
4589                 fprintf(outfile,"CAST (%p) type (",tree);
4590                 printTypeChain(tree->ftype,outfile);
4591                 fprintf(outfile,")\n");
4592                 ast_print(tree->right,outfile,indent+4);
4593                 return ;
4594                 
4595         case AND_OP:
4596                 fprintf(outfile,"ANDAND (%p) type (",tree);
4597                 printTypeChain(tree->ftype,outfile);
4598                 fprintf(outfile,")\n");
4599                 ast_print(tree->left,outfile,indent+4);
4600                 ast_print(tree->right,outfile,indent+4);
4601                 return ;
4602         case OR_OP:
4603                 fprintf(outfile,"OROR (%p) type (",tree);
4604                 printTypeChain(tree->ftype,outfile);
4605                 fprintf(outfile,")\n");
4606                 ast_print(tree->left,outfile,indent+4);
4607                 ast_print(tree->right,outfile,indent+4);
4608                 return ;
4609                 
4610                 /*------------------------------------------------------------------*/
4611                 /*----------------------------*/
4612                 /*     comparison operators   */
4613                 /*----------------------------*/
4614         case '>':
4615                 fprintf(outfile,"GT(>) (%p) type (",tree);
4616                 printTypeChain(tree->ftype,outfile);
4617                 fprintf(outfile,")\n");
4618                 ast_print(tree->left,outfile,indent+4);
4619                 ast_print(tree->right,outfile,indent+4);
4620                 return ;
4621         case '<':
4622                 fprintf(outfile,"LT(<) (%p) type (",tree);
4623                 printTypeChain(tree->ftype,outfile);
4624                 fprintf(outfile,")\n");
4625                 ast_print(tree->left,outfile,indent+4);
4626                 ast_print(tree->right,outfile,indent+4);
4627                 return ;
4628         case LE_OP:
4629                 fprintf(outfile,"LE(<=) (%p) type (",tree);
4630                 printTypeChain(tree->ftype,outfile);
4631                 fprintf(outfile,")\n");
4632                 ast_print(tree->left,outfile,indent+4);
4633                 ast_print(tree->right,outfile,indent+4);
4634                 return ;
4635         case GE_OP:
4636                 fprintf(outfile,"GE(>=) (%p) type (",tree);
4637                 printTypeChain(tree->ftype,outfile);
4638                 fprintf(outfile,")\n");
4639                 ast_print(tree->left,outfile,indent+4);
4640                 ast_print(tree->right,outfile,indent+4);
4641                 return ;
4642         case EQ_OP:
4643                 fprintf(outfile,"EQ(==) (%p) type (",tree);
4644                 printTypeChain(tree->ftype,outfile);
4645                 fprintf(outfile,")\n");
4646                 ast_print(tree->left,outfile,indent+4);
4647                 ast_print(tree->right,outfile,indent+4);
4648                 return ;
4649         case NE_OP:
4650                 fprintf(outfile,"NE(!=) (%p) type (",tree);
4651                 printTypeChain(tree->ftype,outfile);
4652                 fprintf(outfile,")\n");
4653                 ast_print(tree->left,outfile,indent+4);
4654                 ast_print(tree->right,outfile,indent+4);
4655                 /*------------------------------------------------------------------*/
4656                 /*----------------------------*/
4657                 /*             sizeof         */
4658                 /*----------------------------*/
4659         case SIZEOF:            /* evaluate wihout code generation */
4660                 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4661                 return ;
4662
4663                 /*------------------------------------------------------------------*/
4664                 /*----------------------------*/
4665                 /* conditional operator  '?'  */
4666                 /*----------------------------*/
4667         case '?':
4668                 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4669                 printTypeChain(tree->ftype,outfile);
4670                 fprintf(outfile,")\n");
4671                 ast_print(tree->left,outfile,indent+4);
4672                 ast_print(tree->right,outfile,indent+4);
4673                 return;
4674
4675         case ':':
4676                 fprintf(outfile,"COLON(:) (%p) type (",tree);
4677                 printTypeChain(tree->ftype,outfile);
4678                 fprintf(outfile,")\n");
4679                 ast_print(tree->left,outfile,indent+4);
4680                 ast_print(tree->right,outfile,indent+4);
4681                 return ;
4682                 
4683                 /*------------------------------------------------------------------*/
4684                 /*----------------------------*/
4685                 /*    assignment operators    */
4686                 /*----------------------------*/
4687         case MUL_ASSIGN:
4688                 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4689                 printTypeChain(tree->ftype,outfile);
4690                 fprintf(outfile,")\n");
4691                 ast_print(tree->left,outfile,indent+4);
4692                 ast_print(tree->right,outfile,indent+4);
4693                 return;
4694         case DIV_ASSIGN:
4695                 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4696                 printTypeChain(tree->ftype,outfile);
4697                 fprintf(outfile,")\n");
4698                 ast_print(tree->left,outfile,indent+4);
4699                 ast_print(tree->right,outfile,indent+4);
4700                 return;
4701         case AND_ASSIGN:
4702                 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4703                 printTypeChain(tree->ftype,outfile);
4704                 fprintf(outfile,")\n");
4705                 ast_print(tree->left,outfile,indent+4);
4706                 ast_print(tree->right,outfile,indent+4);
4707                 return;
4708         case OR_ASSIGN:
4709                 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4710                 printTypeChain(tree->ftype,outfile);
4711                 fprintf(outfile,")\n");
4712                 ast_print(tree->left,outfile,indent+4);
4713                 ast_print(tree->right,outfile,indent+4);
4714                 return;
4715         case XOR_ASSIGN:
4716                 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4717                 printTypeChain(tree->ftype,outfile);
4718                 fprintf(outfile,")\n");
4719                 ast_print(tree->left,outfile,indent+4);
4720                 ast_print(tree->right,outfile,indent+4);
4721                 return;
4722         case RIGHT_ASSIGN:
4723                 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4724                 printTypeChain(tree->ftype,outfile);
4725                 fprintf(outfile,")\n");
4726                 ast_print(tree->left,outfile,indent+4);
4727                 ast_print(tree->right,outfile,indent+4);
4728                 return;
4729         case LEFT_ASSIGN:
4730                 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4731                 printTypeChain(tree->ftype,outfile);
4732                 fprintf(outfile,")\n");
4733                 ast_print(tree->left,outfile,indent+4);
4734                 ast_print(tree->right,outfile,indent+4);
4735                 return;
4736                 /*------------------------------------------------------------------*/
4737                 /*----------------------------*/
4738                 /*    -= operator             */
4739                 /*----------------------------*/
4740         case SUB_ASSIGN:
4741                 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4742                 printTypeChain(tree->ftype,outfile);
4743                 fprintf(outfile,")\n");
4744                 ast_print(tree->left,outfile,indent+4);
4745                 ast_print(tree->right,outfile,indent+4);
4746                 return;
4747                 /*------------------------------------------------------------------*/
4748                 /*----------------------------*/
4749                 /*          += operator       */
4750                 /*----------------------------*/
4751         case ADD_ASSIGN:
4752                 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4753                 printTypeChain(tree->ftype,outfile);
4754                 fprintf(outfile,")\n");
4755                 ast_print(tree->left,outfile,indent+4);
4756                 ast_print(tree->right,outfile,indent+4);
4757                 return;
4758                 /*------------------------------------------------------------------*/
4759                 /*----------------------------*/
4760                 /*      straight assignemnt   */
4761                 /*----------------------------*/
4762         case '=':
4763                 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4764                 printTypeChain(tree->ftype,outfile);
4765                 fprintf(outfile,")\n");
4766                 ast_print(tree->left,outfile,indent+4);
4767                 ast_print(tree->right,outfile,indent+4);
4768                 return;     
4769                 /*------------------------------------------------------------------*/
4770                 /*----------------------------*/
4771                 /*      comma operator        */
4772                 /*----------------------------*/
4773         case ',':
4774                 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4775                 printTypeChain(tree->ftype,outfile);
4776                 fprintf(outfile,")\n");
4777                 ast_print(tree->left,outfile,indent+4);
4778                 ast_print(tree->right,outfile,indent+4);
4779                 return;
4780                 /*------------------------------------------------------------------*/
4781                 /*----------------------------*/
4782                 /*       function call        */
4783                 /*----------------------------*/
4784         case CALL:
4785         case PCALL:
4786                 fprintf(outfile,"CALL (%p) type (",tree);
4787                 printTypeChain(tree->ftype,outfile);
4788                 fprintf(outfile,")\n");
4789                 ast_print(tree->left,outfile,indent+4);
4790                 ast_print(tree->right,outfile,indent+4);
4791                 return;
4792         case PARAM:
4793                 fprintf(outfile,"PARM ");
4794                 ast_print(tree->left,outfile,indent+4);
4795                 if (tree->right && !IS_AST_PARAM(tree->right)) {
4796                         fprintf(outfile,"PARM ");
4797                         ast_print(tree->right,outfile,indent+4);
4798                 }
4799                 return ;
4800                 /*------------------------------------------------------------------*/
4801                 /*----------------------------*/
4802                 /*     return statement       */
4803                 /*----------------------------*/
4804         case RETURN:
4805                 fprintf(outfile,"RETURN (%p) type (",tree);
4806                 printTypeChain(tree->right->ftype,outfile);
4807                 fprintf(outfile,")\n");
4808                 ast_print(tree->right,outfile,indent+4);
4809                 return ;
4810                 /*------------------------------------------------------------------*/
4811                 /*----------------------------*/
4812                 /*     label statement        */
4813                 /*----------------------------*/
4814         case LABEL :
4815                 fprintf(outfile,"LABEL (%p)",tree);
4816                 ast_print(tree->left,outfile,indent+4);
4817                 ast_print(tree->right,outfile,indent);
4818                 return;
4819                 /*------------------------------------------------------------------*/
4820                 /*----------------------------*/
4821                 /*     switch statement       */
4822                 /*----------------------------*/
4823         case SWITCH:
4824                 {
4825                         value *val;
4826                         fprintf(outfile,"SWITCH (%p) ",tree);
4827                         ast_print(tree->left,outfile,0);
4828                         for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4829                                 INDENT(indent+4,outfile);
4830                                 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4831                                         (int) floatFromVal(val),
4832                                         tree->values.switchVals.swNum,
4833                                         (int) floatFromVal(val));
4834                         }
4835                         ast_print(tree->right,outfile,indent);
4836                 }
4837                 return ;
4838                 /*------------------------------------------------------------------*/
4839                 /*----------------------------*/
4840                 /* ifx Statement              */
4841                 /*----------------------------*/
4842         case IFX:
4843                 fprintf(outfile,"IF (%p) \n",tree);
4844                 ast_print(tree->left,outfile,indent+4);
4845                 if (tree->trueLabel) {
4846                         INDENT(indent,outfile);
4847                         fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4848                 }
4849                 if (tree->falseLabel) {
4850                         INDENT(indent,outfile);
4851                         fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4852                 }
4853                 ast_print(tree->right,outfile,indent+4);
4854                 return ;
4855                 /*------------------------------------------------------------------*/
4856                 /*----------------------------*/
4857                 /* for Statement              */
4858                 /*----------------------------*/
4859         case FOR:
4860                 fprintf(outfile,"FOR (%p) \n",tree);
4861                 if (AST_FOR( tree, initExpr)) {
4862                         INDENT(indent+4,outfile);
4863                         fprintf(outfile,"INIT EXPR ");
4864                         ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4865                 }
4866                 if (AST_FOR( tree, condExpr)) {
4867                         INDENT(indent+4,outfile);
4868                         fprintf(outfile,"COND EXPR ");
4869                         ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4870                 }
4871                 if (AST_FOR( tree, loopExpr)) {
4872                         INDENT(indent+4,outfile);
4873                         fprintf(outfile,"LOOP EXPR ");
4874                         ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4875                 }
4876                 fprintf(outfile,"FOR LOOP BODY \n");
4877                 ast_print(tree->left,outfile,indent+4);
4878                 return ;
4879         default:
4880             return ;
4881         }
4882 }
4883
4884 void PA(ast *t)
4885 {
4886         ast_print(t,stdout,1);
4887 }