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