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