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