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