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