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