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