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