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