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