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