can reverse a loop even if function call is present as long
[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->left->ftype))
1240         return valCastLiteral (cexpr->ftype,
1241                                floatFromVal (cexpr->left->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           fprintf (stderr, "type --> '");
3099           printTypeChain (RTYPE (tree), stderr);
3100           fprintf (stderr, "' ");
3101           fprintf (stderr, "assigned to type --> '");
3102           printTypeChain (LTYPE (tree), stderr);
3103           fprintf (stderr, "'\n");
3104           goto errorTreeReturn;
3105         }
3106
3107       /* if the left side of the tree is of type void
3108          then report error */
3109       if (IS_VOID (LTYPE (tree)))
3110         {
3111           werror (E_CAST_ZERO);
3112           printFromToType(RTYPE(tree), LTYPE(tree));
3113         }
3114
3115       TETYPE (tree) = getSpec (TTYPE (tree) =
3116                                LTYPE (tree));
3117       RRVAL (tree) = 1;
3118       LLVAL (tree) = 1;
3119       if (!tree->initMode ) {
3120         if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
3121           werror (E_CODE_WRITE, " ");
3122       }
3123       if (LRVAL (tree))
3124         {
3125           werror (E_LVALUE_REQUIRED, "=");
3126           goto errorTreeReturn;
3127         }
3128
3129       return tree;
3130
3131       /*------------------------------------------------------------------*/
3132       /*----------------------------*/
3133       /*      comma operator        */
3134       /*----------------------------*/
3135     case ',':
3136       TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3137       return tree;
3138
3139       /*------------------------------------------------------------------*/
3140       /*----------------------------*/
3141       /*       function call        */
3142       /*----------------------------*/
3143     case CALL:
3144       parmNumber = 1;
3145
3146       if (processParms (tree->left,
3147                         FUNC_ARGS(tree->left->ftype),
3148                         tree->right, &parmNumber, TRUE)) {
3149         goto errorTreeReturn;
3150       }
3151
3152       if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) && 
3153           !IFFUNC_ISBUILTIN(LTYPE(tree)))
3154         {
3155           //FUNC_ARGS(tree->left->ftype) = 
3156           //reverseVal (FUNC_ARGS(tree->left->ftype));
3157           reverseParms (tree->right);
3158         }
3159
3160       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
3161       return tree;
3162
3163       /*------------------------------------------------------------------*/
3164       /*----------------------------*/
3165       /*     return statement       */
3166       /*----------------------------*/
3167     case RETURN:
3168       if (!tree->right)
3169         goto voidcheck;
3170
3171       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3172         {
3173           werror (W_RETURN_MISMATCH);
3174           printFromToType (RTYPE(tree), currFunc->type->next);
3175           goto errorTreeReturn;
3176         }
3177
3178       if (IS_VOID (currFunc->type->next)
3179           && tree->right &&
3180           !IS_VOID (RTYPE (tree)))
3181         {
3182           werror (E_FUNC_VOID);
3183           goto errorTreeReturn;
3184         }
3185
3186       /* if there is going to be a casing required then add it */
3187       if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3188         {
3189           tree->right =
3190             decorateType (newNode (CAST,
3191                            newAst_LINK (copyLinkChain (currFunc->type->next)),
3192                                    tree->right));
3193         }
3194
3195       RRVAL (tree) = 1;
3196       return tree;
3197
3198     voidcheck:
3199
3200       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3201         {
3202           werror (E_VOID_FUNC, currFunc->name);
3203           goto errorTreeReturn;
3204         }
3205
3206       TTYPE (tree) = TETYPE (tree) = NULL;
3207       return tree;
3208
3209       /*------------------------------------------------------------------*/
3210       /*----------------------------*/
3211       /*     switch statement       */
3212       /*----------------------------*/
3213     case SWITCH:
3214       /* the switch value must be an integer */
3215       if (!IS_INTEGRAL (LTYPE (tree)))
3216         {
3217           werror (E_SWITCH_NON_INTEGER);
3218           goto errorTreeReturn;
3219         }
3220       LRVAL (tree) = 1;
3221       TTYPE (tree) = TETYPE (tree) = NULL;
3222       return tree;
3223
3224       /*------------------------------------------------------------------*/
3225       /*----------------------------*/
3226       /* ifx Statement              */
3227       /*----------------------------*/
3228     case IFX:
3229       tree->left = backPatchLabels (tree->left,
3230                                     tree->trueLabel,
3231                                     tree->falseLabel);
3232       TTYPE (tree) = TETYPE (tree) = NULL;
3233       return tree;
3234
3235       /*------------------------------------------------------------------*/
3236       /*----------------------------*/
3237       /* for Statement              */
3238       /*----------------------------*/
3239     case FOR:
3240
3241       decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3242       decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3243       decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3244
3245       /* if the for loop is reversible then
3246          reverse it otherwise do what we normally
3247          do */
3248       {
3249         symbol *sym;
3250         ast *init, *end;
3251
3252         if (isLoopReversible (tree, &sym, &init, &end))
3253           return reverseLoop (tree, sym, init, end);
3254         else
3255           return decorateType (createFor (AST_FOR (tree, trueLabel),
3256                                           AST_FOR (tree, continueLabel),
3257                                           AST_FOR (tree, falseLabel),
3258                                           AST_FOR (tree, condLabel),
3259                                           AST_FOR (tree, initExpr),
3260                                           AST_FOR (tree, condExpr),
3261                                           AST_FOR (tree, loopExpr),
3262                                           tree->left));
3263       }
3264     default:
3265       TTYPE (tree) = TETYPE (tree) = NULL;
3266       return tree;
3267     }
3268
3269   /* some error found this tree will be killed */
3270 errorTreeReturn:
3271   TTYPE (tree) = TETYPE (tree) = newCharLink ();
3272   tree->opval.op = NULLOP;
3273   tree->isError = 1;
3274
3275   return tree;
3276 }
3277
3278 /*-----------------------------------------------------------------*/
3279 /* sizeofOp - processes size of operation                          */
3280 /*-----------------------------------------------------------------*/
3281 value *
3282 sizeofOp (sym_link * type)
3283 {
3284   char buff[10];
3285
3286   /* make sure the type is complete and sane */
3287   checkTypeSanity(type, "(sizeof)");
3288
3289   /* get the size and convert it to character  */
3290   sprintf (buff, "%d", getSize (type));
3291
3292   /* now convert into value  */
3293   return constVal (buff);
3294 }
3295
3296
3297 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3298 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
3299 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3300 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3301 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3302 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
3303 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
3304
3305 /*-----------------------------------------------------------------*/
3306 /* backPatchLabels - change and or not operators to flow control    */
3307 /*-----------------------------------------------------------------*/
3308 ast *
3309 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3310 {
3311
3312   if (!tree)
3313     return NULL;
3314
3315   if (!(IS_ANDORNOT (tree)))
3316     return tree;
3317
3318   /* if this an and */
3319   if (IS_AND (tree))
3320     {
3321       static int localLbl = 0;
3322       symbol *localLabel;
3323
3324       sprintf (buffer, "_and_%d", localLbl++);
3325       localLabel = newSymbol (buffer, NestLevel);
3326
3327       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3328
3329       /* if left is already a IFX then just change the if true label in that */
3330       if (!IS_IFX (tree->left))
3331         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3332
3333       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3334       /* right is a IFX then just join */
3335       if (IS_IFX (tree->right))
3336         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3337
3338       tree->right = createLabel (localLabel, tree->right);
3339       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3340
3341       return newNode (NULLOP, tree->left, tree->right);
3342     }
3343
3344   /* if this is an or operation */
3345   if (IS_OR (tree))
3346     {
3347       static int localLbl = 0;
3348       symbol *localLabel;
3349
3350       sprintf (buffer, "_or_%d", localLbl++);
3351       localLabel = newSymbol (buffer, NestLevel);
3352
3353       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3354
3355       /* if left is already a IFX then just change the if true label in that */
3356       if (!IS_IFX (tree->left))
3357         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3358
3359       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3360       /* right is a IFX then just join */
3361       if (IS_IFX (tree->right))
3362         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3363
3364       tree->right = createLabel (localLabel, tree->right);
3365       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3366
3367       return newNode (NULLOP, tree->left, tree->right);
3368     }
3369
3370   /* change not */
3371   if (IS_NOT (tree))
3372     {
3373       int wasnot = IS_NOT (tree->left);
3374       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3375
3376       /* if the left is already a IFX */
3377       if (!IS_IFX (tree->left))
3378         tree->left = newNode (IFX, tree->left, NULL);
3379
3380       if (wasnot)
3381         {
3382           tree->left->trueLabel = trueLabel;
3383           tree->left->falseLabel = falseLabel;
3384         }
3385       else
3386         {
3387           tree->left->trueLabel = falseLabel;
3388           tree->left->falseLabel = trueLabel;
3389         }
3390       return tree->left;
3391     }
3392
3393   if (IS_IFX (tree))
3394     {
3395       tree->trueLabel = trueLabel;
3396       tree->falseLabel = falseLabel;
3397     }
3398
3399   return tree;
3400 }
3401
3402
3403 /*-----------------------------------------------------------------*/
3404 /* createBlock - create expression tree for block                  */
3405 /*-----------------------------------------------------------------*/
3406 ast *
3407 createBlock (symbol * decl, ast * body)
3408 {
3409   ast *ex;
3410
3411   /* if the block has nothing */
3412   if (!body)
3413     return NULL;
3414
3415   ex = newNode (BLOCK, NULL, body);
3416   ex->values.sym = decl;
3417
3418   ex->right = ex->right;
3419   ex->level++;
3420   ex->lineno = 0;
3421   return ex;
3422 }
3423
3424 /*-----------------------------------------------------------------*/
3425 /* createLabel - creates the expression tree for labels            */
3426 /*-----------------------------------------------------------------*/
3427 ast *
3428 createLabel (symbol * label, ast * stmnt)
3429 {
3430   symbol *csym;
3431   char name[SDCC_NAME_MAX + 1];
3432   ast *rValue;
3433
3434   /* must create fresh symbol if the symbol name  */
3435   /* exists in the symbol table, since there can  */
3436   /* be a variable with the same name as the labl */
3437   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3438       (csym->level == label->level))
3439     label = newSymbol (label->name, label->level);
3440
3441   /* change the name before putting it in add _ */
3442   sprintf (name, "%s", label->name);
3443
3444   /* put the label in the LabelSymbol table    */
3445   /* but first check if a label of the same    */
3446   /* name exists                               */
3447   if ((csym = findSym (LabelTab, NULL, name)))
3448     werror (E_DUPLICATE_LABEL, label->name);
3449   else
3450     addSym (LabelTab, label, name, label->level, 0, 0);
3451
3452   label->islbl = 1;
3453   label->key = labelKey++;
3454   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3455   rValue->lineno = 0;
3456
3457   return rValue;
3458 }
3459
3460 /*-----------------------------------------------------------------*/
3461 /* createCase - generates the parsetree for a case statement       */
3462 /*-----------------------------------------------------------------*/
3463 ast *
3464 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3465 {
3466   char caseLbl[SDCC_NAME_MAX + 1];
3467   ast *rexpr;
3468   value *val;
3469
3470   /* if the switch statement does not exist */
3471   /* then case is out of context            */
3472   if (!swStat)
3473     {
3474       werror (E_CASE_CONTEXT);
3475       return NULL;
3476     }
3477
3478   caseVal = decorateType (resolveSymbols (caseVal));
3479   /* if not a constant then error  */
3480   if (!IS_LITERAL (caseVal->ftype))
3481     {
3482       werror (E_CASE_CONSTANT);
3483       return NULL;
3484     }
3485
3486   /* if not a integer than error */
3487   if (!IS_INTEGRAL (caseVal->ftype))
3488     {
3489       werror (E_CASE_NON_INTEGER);
3490       return NULL;
3491     }
3492
3493   /* find the end of the switch values chain   */
3494   if (!(val = swStat->values.switchVals.swVals))
3495     swStat->values.switchVals.swVals = caseVal->opval.val;
3496   else
3497     {
3498       /* also order the cases according to value */
3499       value *pval = NULL;
3500       int cVal = (int) floatFromVal (caseVal->opval.val);
3501       while (val && (int) floatFromVal (val) < cVal)
3502         {
3503           pval = val;
3504           val = val->next;
3505         }
3506
3507       /* if we reached the end then */
3508       if (!val)
3509         {
3510           pval->next = caseVal->opval.val;
3511         }
3512       else
3513         {
3514           /* we found a value greater than */
3515           /* the current value we must add this */
3516           /* before the value */
3517           caseVal->opval.val->next = val;
3518
3519           /* if this was the first in chain */
3520           if (swStat->values.switchVals.swVals == val)
3521             swStat->values.switchVals.swVals =
3522               caseVal->opval.val;
3523           else
3524             pval->next = caseVal->opval.val;
3525         }
3526
3527     }
3528
3529   /* create the case label   */
3530   sprintf (caseLbl, "_case_%d_%d",
3531            swStat->values.switchVals.swNum,
3532            (int) floatFromVal (caseVal->opval.val));
3533
3534   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3535   rexpr->lineno = 0;
3536   return rexpr;
3537 }
3538
3539 /*-----------------------------------------------------------------*/
3540 /* createDefault - creates the parse tree for the default statement */
3541 /*-----------------------------------------------------------------*/
3542 ast *
3543 createDefault (ast * swStat, ast * stmnt)
3544 {
3545   char defLbl[SDCC_NAME_MAX + 1];
3546
3547   /* if the switch statement does not exist */
3548   /* then case is out of context            */
3549   if (!swStat)
3550     {
3551       werror (E_CASE_CONTEXT);
3552       return NULL;
3553     }
3554
3555   /* turn on the default flag   */
3556   swStat->values.switchVals.swDefault = 1;
3557
3558   /* create the label  */
3559   sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3560   return createLabel (newSymbol (defLbl, 0), stmnt);
3561 }
3562
3563 /*-----------------------------------------------------------------*/
3564 /* createIf - creates the parsetree for the if statement           */
3565 /*-----------------------------------------------------------------*/
3566 ast *
3567 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3568 {
3569   static int Lblnum = 0;
3570   ast *ifTree;
3571   symbol *ifTrue, *ifFalse, *ifEnd;
3572
3573   /* if neither exists */
3574   if (!elseBody && !ifBody) {
3575     // if there are no side effects (i++, j() etc)
3576     if (!hasSEFcalls(condAst)) {
3577       return condAst;
3578     }
3579   }
3580
3581   /* create the labels */
3582   sprintf (buffer, "_iffalse_%d", Lblnum);
3583   ifFalse = newSymbol (buffer, NestLevel);
3584   /* if no else body then end == false */
3585   if (!elseBody)
3586     ifEnd = ifFalse;
3587   else
3588     {
3589       sprintf (buffer, "_ifend_%d", Lblnum);
3590       ifEnd = newSymbol (buffer, NestLevel);
3591     }
3592
3593   sprintf (buffer, "_iftrue_%d", Lblnum);
3594   ifTrue = newSymbol (buffer, NestLevel);
3595
3596   Lblnum++;
3597
3598   /* attach the ifTrue label to the top of it body */
3599   ifBody = createLabel (ifTrue, ifBody);
3600   /* attach a goto end to the ifBody if else is present */
3601   if (elseBody)
3602     {
3603       ifBody = newNode (NULLOP, ifBody,
3604                         newNode (GOTO,
3605                                  newAst_VALUE (symbolVal (ifEnd)),
3606                                  NULL));
3607       /* put the elseLabel on the else body */
3608       elseBody = createLabel (ifFalse, elseBody);
3609       /* out the end at the end of the body */
3610       elseBody = newNode (NULLOP,
3611                           elseBody,
3612                           createLabel (ifEnd, NULL));
3613     }
3614   else
3615     {
3616       ifBody = newNode (NULLOP, ifBody,
3617                         createLabel (ifFalse, NULL));
3618     }
3619   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3620   if (IS_IFX (condAst))
3621     ifTree = condAst;
3622   else
3623     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3624
3625   return newNode (NULLOP, ifTree,
3626                   newNode (NULLOP, ifBody, elseBody));
3627
3628 }
3629
3630 /*-----------------------------------------------------------------*/
3631 /* createDo - creates parse tree for do                            */
3632 /*        _dobody_n:                                               */
3633 /*            statements                                           */
3634 /*        _docontinue_n:                                           */
3635 /*            condition_expression +-> trueLabel -> _dobody_n      */
3636 /*                                 |                               */
3637 /*                                 +-> falseLabel-> _dobreak_n     */
3638 /*        _dobreak_n:                                              */
3639 /*-----------------------------------------------------------------*/
3640 ast *
3641 createDo (symbol * trueLabel, symbol * continueLabel,
3642           symbol * falseLabel, ast * condAst, ast * doBody)
3643 {
3644   ast *doTree;
3645
3646
3647   /* if the body does not exist then it is simple */
3648   if (!doBody)
3649     {
3650       condAst = backPatchLabels (condAst, continueLabel, NULL);
3651       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3652                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3653       doTree->trueLabel = continueLabel;
3654       doTree->falseLabel = NULL;
3655       return doTree;
3656     }
3657
3658   /* otherwise we have a body */
3659   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3660
3661   /* attach the body label to the top */
3662   doBody = createLabel (trueLabel, doBody);
3663   /* attach the continue label to end of body */
3664   doBody = newNode (NULLOP, doBody,
3665                     createLabel (continueLabel, NULL));
3666
3667   /* now put the break label at the end */
3668   if (IS_IFX (condAst))
3669     doTree = condAst;
3670   else
3671     doTree = newIfxNode (condAst, trueLabel, falseLabel);
3672
3673   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3674
3675   /* putting it together */
3676   return newNode (NULLOP, doBody, doTree);
3677 }
3678
3679 /*-----------------------------------------------------------------*/
3680 /* createFor - creates parse tree for 'for' statement              */
3681 /*        initExpr                                                 */
3682 /*   _forcond_n:                                                   */
3683 /*        condExpr  +-> trueLabel -> _forbody_n                    */
3684 /*                  |                                              */
3685 /*                  +-> falseLabel-> _forbreak_n                   */
3686 /*   _forbody_n:                                                   */
3687 /*        statements                                               */
3688 /*   _forcontinue_n:                                               */
3689 /*        loopExpr                                                 */
3690 /*        goto _forcond_n ;                                        */
3691 /*   _forbreak_n:                                                  */
3692 /*-----------------------------------------------------------------*/
3693 ast *
3694 createFor (symbol * trueLabel, symbol * continueLabel,
3695            symbol * falseLabel, symbol * condLabel,
3696            ast * initExpr, ast * condExpr, ast * loopExpr,
3697            ast * forBody)
3698 {
3699   ast *forTree;
3700
3701   /* if loopexpression not present then we can generate it */
3702   /* the same way as a while */
3703   if (!loopExpr)
3704     return newNode (NULLOP, initExpr,
3705                     createWhile (trueLabel, continueLabel,
3706                                  falseLabel, condExpr, forBody));
3707   /* vanilla for statement */
3708   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3709
3710   if (condExpr && !IS_IFX (condExpr))
3711     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3712
3713
3714   /* attach condition label to condition */
3715   condExpr = createLabel (condLabel, condExpr);
3716
3717   /* attach body label to body */
3718   forBody = createLabel (trueLabel, forBody);
3719
3720   /* attach continue to forLoop expression & attach */
3721   /* goto the forcond @ and of loopExpression       */
3722   loopExpr = createLabel (continueLabel,
3723                           newNode (NULLOP,
3724                                    loopExpr,
3725                                    newNode (GOTO,
3726                                        newAst_VALUE (symbolVal (condLabel)),
3727                                             NULL)));
3728   /* now start putting them together */
3729   forTree = newNode (NULLOP, initExpr, condExpr);
3730   forTree = newNode (NULLOP, forTree, forBody);
3731   forTree = newNode (NULLOP, forTree, loopExpr);
3732   /* finally add the break label */
3733   forTree = newNode (NULLOP, forTree,
3734                      createLabel (falseLabel, NULL));
3735   return forTree;
3736 }
3737
3738 /*-----------------------------------------------------------------*/
3739 /* createWhile - creates parse tree for while statement            */
3740 /*               the while statement will be created as follows    */
3741 /*                                                                 */
3742 /*      _while_continue_n:                                         */
3743 /*            condition_expression +-> trueLabel -> _while_boby_n  */
3744 /*                                 |                               */
3745 /*                                 +-> falseLabel -> _while_break_n */
3746 /*      _while_body_n:                                             */
3747 /*            statements                                           */
3748 /*            goto _while_continue_n                               */
3749 /*      _while_break_n:                                            */
3750 /*-----------------------------------------------------------------*/
3751 ast *
3752 createWhile (symbol * trueLabel, symbol * continueLabel,
3753              symbol * falseLabel, ast * condExpr, ast * whileBody)
3754 {
3755   ast *whileTree;
3756
3757   /* put the continue label */
3758   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3759   condExpr = createLabel (continueLabel, condExpr);
3760   condExpr->lineno = 0;
3761
3762   /* put the body label in front of the body */
3763   whileBody = createLabel (trueLabel, whileBody);
3764   whileBody->lineno = 0;
3765   /* put a jump to continue at the end of the body */
3766   /* and put break label at the end of the body */
3767   whileBody = newNode (NULLOP,
3768                        whileBody,
3769                        newNode (GOTO,
3770                                 newAst_VALUE (symbolVal (continueLabel)),
3771                                 createLabel (falseLabel, NULL)));
3772
3773   /* put it all together */
3774   if (IS_IFX (condExpr))
3775     whileTree = condExpr;
3776   else
3777     {
3778       whileTree = newNode (IFX, condExpr, NULL);
3779       /* put the true & false labels in place */
3780       whileTree->trueLabel = trueLabel;
3781       whileTree->falseLabel = falseLabel;
3782     }
3783
3784   return newNode (NULLOP, whileTree, whileBody);
3785 }
3786
3787 /*-----------------------------------------------------------------*/
3788 /* optimizeGetHbit - get highest order bit of the expression       */
3789 /*-----------------------------------------------------------------*/
3790 ast *
3791 optimizeGetHbit (ast * tree)
3792 {
3793   int i, j;
3794   /* if this is not a bit and */
3795   if (!IS_BITAND (tree))
3796     return tree;
3797
3798   /* will look for tree of the form
3799      ( expr >> ((sizeof expr) -1) ) & 1 */
3800   if (!IS_AST_LIT_VALUE (tree->right))
3801     return tree;
3802
3803   if (AST_LIT_VALUE (tree->right) != 1)
3804     return tree;
3805
3806   if (!IS_RIGHT_OP (tree->left))
3807     return tree;
3808
3809   if (!IS_AST_LIT_VALUE (tree->left->right))
3810     return tree;
3811
3812   if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3813       (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3814     return tree;
3815
3816   return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3817
3818 }
3819
3820 /*-----------------------------------------------------------------*/
3821 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
3822 /*-----------------------------------------------------------------*/
3823 ast *
3824 optimizeRRCRLC (ast * root)
3825 {
3826   /* will look for trees of the form
3827      (?expr << 1) | (?expr >> 7) or
3828      (?expr >> 7) | (?expr << 1) will make that
3829      into a RLC : operation ..
3830      Will also look for
3831      (?expr >> 1) | (?expr << 7) or
3832      (?expr << 7) | (?expr >> 1) will make that
3833      into a RRC operation
3834      note : by 7 I mean (number of bits required to hold the
3835      variable -1 ) */
3836   /* if the root operations is not a | operation the not */
3837   if (!IS_BITOR (root))
3838     return root;
3839
3840   /* I have to think of a better way to match patterns this sucks */
3841   /* that aside let start looking for the first case : I use a the
3842      negative check a lot to improve the efficiency */
3843   /* (?expr << 1) | (?expr >> 7) */
3844   if (IS_LEFT_OP (root->left) &&
3845       IS_RIGHT_OP (root->right))
3846     {
3847
3848       if (!SPEC_USIGN (TETYPE (root->left->left)))
3849         return root;
3850
3851       if (!IS_AST_LIT_VALUE (root->left->right) ||
3852           !IS_AST_LIT_VALUE (root->right->right))
3853         goto tryNext0;
3854
3855       /* make sure it is the same expression */
3856       if (!isAstEqual (root->left->left,
3857                        root->right->left))
3858         goto tryNext0;
3859
3860       if (AST_LIT_VALUE (root->left->right) != 1)
3861         goto tryNext0;
3862
3863       if (AST_LIT_VALUE (root->right->right) !=
3864           (getSize (TTYPE (root->left->left)) * 8 - 1))
3865         goto tryNext0;
3866
3867       /* whew got the first case : create the AST */
3868       return newNode (RLC, root->left->left, NULL);
3869     }
3870
3871 tryNext0:
3872   /* check for second case */
3873   /* (?expr >> 7) | (?expr << 1) */
3874   if (IS_LEFT_OP (root->right) &&
3875       IS_RIGHT_OP (root->left))
3876     {
3877
3878       if (!SPEC_USIGN (TETYPE (root->left->left)))
3879         return root;
3880
3881       if (!IS_AST_LIT_VALUE (root->left->right) ||
3882           !IS_AST_LIT_VALUE (root->right->right))
3883         goto tryNext1;
3884
3885       /* make sure it is the same symbol */
3886       if (!isAstEqual (root->left->left,
3887                        root->right->left))
3888         goto tryNext1;
3889
3890       if (AST_LIT_VALUE (root->right->right) != 1)
3891         goto tryNext1;
3892
3893       if (AST_LIT_VALUE (root->left->right) !=
3894           (getSize (TTYPE (root->left->left)) * 8 - 1))
3895         goto tryNext1;
3896
3897       /* whew got the first case : create the AST */
3898       return newNode (RLC, root->left->left, NULL);
3899
3900     }
3901
3902 tryNext1:
3903   /* third case for RRC */
3904   /*  (?symbol >> 1) | (?symbol << 7) */
3905   if (IS_LEFT_OP (root->right) &&
3906       IS_RIGHT_OP (root->left))
3907     {
3908
3909       if (!SPEC_USIGN (TETYPE (root->left->left)))
3910         return root;
3911
3912       if (!IS_AST_LIT_VALUE (root->left->right) ||
3913           !IS_AST_LIT_VALUE (root->right->right))
3914         goto tryNext2;
3915
3916       /* make sure it is the same symbol */
3917       if (!isAstEqual (root->left->left,
3918                        root->right->left))
3919         goto tryNext2;
3920
3921       if (AST_LIT_VALUE (root->left->right) != 1)
3922         goto tryNext2;
3923
3924       if (AST_LIT_VALUE (root->right->right) !=
3925           (getSize (TTYPE (root->left->left)) * 8 - 1))
3926         goto tryNext2;
3927
3928       /* whew got the first case : create the AST */
3929       return newNode (RRC, root->left->left, NULL);
3930
3931     }
3932 tryNext2:
3933   /* fourth and last case for now */
3934   /* (?symbol << 7) | (?symbol >> 1) */
3935   if (IS_RIGHT_OP (root->right) &&
3936       IS_LEFT_OP (root->left))
3937     {
3938
3939       if (!SPEC_USIGN (TETYPE (root->left->left)))
3940         return root;
3941
3942       if (!IS_AST_LIT_VALUE (root->left->right) ||
3943           !IS_AST_LIT_VALUE (root->right->right))
3944         return root;
3945
3946       /* make sure it is the same symbol */
3947       if (!isAstEqual (root->left->left,
3948                        root->right->left))
3949         return root;
3950
3951       if (AST_LIT_VALUE (root->right->right) != 1)
3952         return root;
3953
3954       if (AST_LIT_VALUE (root->left->right) !=
3955           (getSize (TTYPE (root->left->left)) * 8 - 1))
3956         return root;
3957
3958       /* whew got the first case : create the AST */
3959       return newNode (RRC, root->left->left, NULL);
3960
3961     }
3962
3963   /* not found return root */
3964   return root;
3965 }
3966
3967 /*-----------------------------------------------------------------*/
3968 /* optimizeCompare - otimizes compares for bit variables     */
3969 /*-----------------------------------------------------------------*/
3970 static ast *
3971 optimizeCompare (ast * root)
3972 {
3973   ast *optExpr = NULL;
3974   value *vleft;
3975   value *vright;
3976   unsigned int litValue;
3977
3978   /* if nothing then return nothing */
3979   if (!root)
3980     return NULL;
3981
3982   /* if not a compare op then do leaves */
3983   if (!IS_COMPARE_OP (root))
3984     {
3985       root->left = optimizeCompare (root->left);
3986       root->right = optimizeCompare (root->right);
3987       return root;
3988     }
3989
3990   /* if left & right are the same then depending
3991      of the operation do */
3992   if (isAstEqual (root->left, root->right))
3993     {
3994       switch (root->opval.op)
3995         {
3996         case '>':
3997         case '<':
3998         case NE_OP:
3999           optExpr = newAst_VALUE (constVal ("0"));
4000           break;
4001         case GE_OP:
4002         case LE_OP:
4003         case EQ_OP:
4004           optExpr = newAst_VALUE (constVal ("1"));
4005           break;
4006         }
4007
4008       return decorateType (optExpr);
4009     }
4010
4011   vleft = (root->left->type == EX_VALUE ?
4012            root->left->opval.val : NULL);
4013
4014   vright = (root->right->type == EX_VALUE ?
4015             root->right->opval.val : NULL);
4016
4017   /* if left is a BITVAR in BITSPACE */
4018   /* and right is a LITERAL then opt- */
4019   /* imize else do nothing       */
4020   if (vleft && vright &&
4021       IS_BITVAR (vleft->etype) &&
4022       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4023       IS_LITERAL (vright->etype))
4024     {
4025
4026       /* if right side > 1 then comparison may never succeed */
4027       if ((litValue = (int) floatFromVal (vright)) > 1)
4028         {
4029           werror (W_BAD_COMPARE);
4030           goto noOptimize;
4031         }
4032
4033       if (litValue)
4034         {
4035           switch (root->opval.op)
4036             {
4037             case '>':           /* bit value greater than 1 cannot be */
4038               werror (W_BAD_COMPARE);
4039               goto noOptimize;
4040               break;
4041
4042             case '<':           /* bit value < 1 means 0 */
4043             case NE_OP:
4044               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4045               break;
4046
4047             case LE_OP: /* bit value <= 1 means no check */
4048               optExpr = newAst_VALUE (vright);
4049               break;
4050
4051             case GE_OP: /* bit value >= 1 means only check for = */
4052             case EQ_OP:
4053               optExpr = newAst_VALUE (vleft);
4054               break;
4055             }
4056         }
4057       else
4058         {                       /* literal is zero */
4059           switch (root->opval.op)
4060             {
4061             case '<':           /* bit value < 0 cannot be */
4062               werror (W_BAD_COMPARE);
4063               goto noOptimize;
4064               break;
4065
4066             case '>':           /* bit value > 0 means 1 */
4067             case NE_OP:
4068               optExpr = newAst_VALUE (vleft);
4069               break;
4070
4071             case LE_OP: /* bit value <= 0 means no check */
4072             case GE_OP: /* bit value >= 0 means no check */
4073               werror (W_BAD_COMPARE);
4074               goto noOptimize;
4075               break;
4076
4077             case EQ_OP: /* bit == 0 means ! of bit */
4078               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4079               break;
4080             }
4081         }
4082       return decorateType (resolveSymbols (optExpr));
4083     }                           /* end-of-if of BITVAR */
4084
4085 noOptimize:
4086   return root;
4087 }
4088 /*-----------------------------------------------------------------*/
4089 /* addSymToBlock : adds the symbol to the first block we find      */
4090 /*-----------------------------------------------------------------*/
4091 void 
4092 addSymToBlock (symbol * sym, ast * tree)
4093 {
4094   /* reached end of tree or a leaf */
4095   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4096     return;
4097
4098   /* found a block */
4099   if (IS_AST_OP (tree) &&
4100       tree->opval.op == BLOCK)
4101     {
4102
4103       symbol *lsym = copySymbol (sym);
4104
4105       lsym->next = AST_VALUES (tree, sym);
4106       AST_VALUES (tree, sym) = lsym;
4107       return;
4108     }
4109
4110   addSymToBlock (sym, tree->left);
4111   addSymToBlock (sym, tree->right);
4112 }
4113
4114 /*-----------------------------------------------------------------*/
4115 /* processRegParms - do processing for register parameters         */
4116 /*-----------------------------------------------------------------*/
4117 static void 
4118 processRegParms (value * args, ast * body)
4119 {
4120   while (args)
4121     {
4122       if (IS_REGPARM (args->etype))
4123         addSymToBlock (args->sym, body);
4124       args = args->next;
4125     }
4126 }
4127
4128 /*-----------------------------------------------------------------*/
4129 /* resetParmKey - resets the operandkeys for the symbols           */
4130 /*-----------------------------------------------------------------*/
4131 DEFSETFUNC (resetParmKey)
4132 {
4133   symbol *sym = item;
4134
4135   sym->key = 0;
4136   sym->defs = NULL;
4137   sym->uses = NULL;
4138   sym->remat = 0;
4139   return 1;
4140 }
4141
4142 /*-----------------------------------------------------------------*/
4143 /* createFunction - This is the key node that calls the iCode for  */
4144 /*                  generating the code for a function. Note code  */
4145 /*                  is generated function by function, later when  */
4146 /*                  add inter-procedural analysis this will change */
4147 /*-----------------------------------------------------------------*/
4148 ast *
4149 createFunction (symbol * name, ast * body)
4150 {
4151   ast *ex;
4152   symbol *csym;
4153   int stack = 0;
4154   sym_link *fetype;
4155   iCode *piCode = NULL;
4156
4157   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4158     fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4159
4160   /* if check function return 0 then some problem */
4161   if (checkFunction (name, NULL) == 0)
4162     return NULL;
4163
4164   /* create a dummy block if none exists */
4165   if (!body)
4166     body = newNode (BLOCK, NULL, NULL);
4167
4168   noLineno++;
4169
4170   /* check if the function name already in the symbol table */
4171   if ((csym = findSym (SymbolTab, NULL, name->name)))
4172     {
4173       name = csym;
4174       /* special case for compiler defined functions
4175          we need to add the name to the publics list : this
4176          actually means we are now compiling the compiler
4177          support routine */
4178       if (name->cdef)
4179         {
4180           addSet (&publics, name);
4181         }
4182     }
4183   else
4184     {
4185       addSymChain (name);
4186       allocVariables (name);
4187     }
4188   name->lastLine = yylineno;
4189   currFunc = name;
4190
4191   /* set the stack pointer */
4192   /* PENDING: check this for the mcs51 */
4193   stackPtr = -port->stack.direction * port->stack.call_overhead;
4194   if (IFFUNC_ISISR (name->type))
4195     stackPtr -= port->stack.direction * port->stack.isr_overhead;
4196   if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4197     stackPtr -= port->stack.direction * port->stack.reent_overhead;
4198
4199   xstackPtr = -port->stack.direction * port->stack.call_overhead;
4200
4201   fetype = getSpec (name->type);        /* get the specifier for the function */
4202   /* if this is a reentrant function then */
4203   if (IFFUNC_ISREENT (name->type))
4204     reentrant++;
4205
4206   allocParms (FUNC_ARGS(name->type));   /* allocate the parameters */
4207
4208   /* do processing for parameters that are passed in registers */
4209   processRegParms (FUNC_ARGS(name->type), body);
4210
4211   /* set the stack pointer */
4212   stackPtr = 0;
4213   xstackPtr = -1;
4214
4215   /* allocate & autoinit the block variables */
4216   processBlockVars (body, &stack, ALLOCATE);
4217
4218   /* save the stack information */
4219   if (options.useXstack)
4220     name->xstack = SPEC_STAK (fetype) = stack;
4221   else
4222     name->stack = SPEC_STAK (fetype) = stack;
4223
4224   /* name needs to be mangled */
4225   sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4226
4227   body = resolveSymbols (body); /* resolve the symbols */
4228   body = decorateType (body);   /* propagateType & do semantic checks */
4229
4230   ex = newAst_VALUE (symbolVal (name)); /* create name */
4231   ex = newNode (FUNCTION, ex, body);
4232   ex->values.args = FUNC_ARGS(name->type);
4233   ex->decorated=1;
4234   if (options.dump_tree) PA(ex);
4235   if (fatalError)
4236     {
4237       werror (E_FUNC_NO_CODE, name->name);
4238       goto skipall;
4239     }
4240
4241   /* create the node & generate intermediate code */
4242   GcurMemmap = code;
4243   codeOutFile = code->oFile;
4244   piCode = iCodeFromAst (ex);
4245
4246   if (fatalError)
4247     {
4248       werror (E_FUNC_NO_CODE, name->name);
4249       goto skipall;
4250     }
4251
4252   eBBlockFromiCode (piCode);
4253
4254   /* if there are any statics then do them */
4255   if (staticAutos)
4256     {
4257       GcurMemmap = statsg;
4258       codeOutFile = statsg->oFile;
4259       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4260       staticAutos = NULL;
4261     }
4262
4263 skipall:
4264
4265   /* dealloc the block variables */
4266   processBlockVars (body, &stack, DEALLOCATE);
4267   /* deallocate paramaters */
4268   deallocParms (FUNC_ARGS(name->type));
4269
4270   if (IFFUNC_ISREENT (name->type))
4271     reentrant--;
4272
4273   /* we are done freeup memory & cleanup */
4274   noLineno--;
4275   if (port->reset_labelKey) labelKey = 1;
4276   name->key = 0;
4277   FUNC_HASBODY(name->type) = 1;
4278   addSet (&operKeyReset, name);
4279   applyToSet (operKeyReset, resetParmKey);
4280
4281   if (options.debug)
4282     cdbStructBlock (1, cdbFile);
4283
4284   cleanUpLevel (LabelTab, 0);
4285   cleanUpBlock (StructTab, 1);
4286   cleanUpBlock (TypedefTab, 1);
4287
4288   xstack->syms = NULL;
4289   istack->syms = NULL;
4290   return NULL;
4291 }
4292
4293
4294 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4295 /*-----------------------------------------------------------------*/
4296 /* ast_print : prints the ast (for debugging purposes)             */
4297 /*-----------------------------------------------------------------*/
4298
4299 void ast_print (ast * tree, FILE *outfile, int indent)
4300 {
4301         
4302         if (!tree) return ;
4303
4304         /* can print only decorated trees */
4305         if (!tree->decorated) return;
4306
4307         /* if any child is an error | this one is an error do nothing */
4308         if (tree->isError ||
4309             (tree->left && tree->left->isError) ||
4310             (tree->right && tree->right->isError)) {
4311                 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4312         }
4313
4314         
4315         /* print the line          */
4316         /* if not block & function */
4317         if (tree->type == EX_OP &&
4318             (tree->opval.op != FUNCTION &&
4319              tree->opval.op != BLOCK &&
4320              tree->opval.op != NULLOP)) {
4321         }
4322         
4323         if (tree->opval.op == FUNCTION) {
4324                 int arg=0;
4325                 value *args=FUNC_ARGS(tree->left->opval.val->type);
4326                 fprintf(outfile,"FUNCTION (%s=%p) type (", 
4327                         tree->left->opval.val->name, tree);
4328                 printTypeChain (tree->ftype,outfile);
4329                 fprintf(outfile,") args (");
4330                 do {
4331                   if (arg) {
4332                     fprintf (outfile, ", ");
4333                   }
4334                   printTypeChain (args ? args->type : NULL, outfile);
4335                   arg++;
4336                   args= args ? args->next : NULL;
4337                 } while (args);
4338                 fprintf(outfile,")\n");
4339                 ast_print(tree->left,outfile,indent);
4340                 ast_print(tree->right,outfile,indent);
4341                 return ;
4342         }
4343         if (tree->opval.op == BLOCK) {
4344                 symbol *decls = tree->values.sym;
4345                 INDENT(indent,outfile);
4346                 fprintf(outfile,"{\n");
4347                 while (decls) {
4348                         INDENT(indent+2,outfile);
4349                         fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
4350                                 decls->name, decls);
4351                         printTypeChain(decls->type,outfile);
4352                         fprintf(outfile,")\n");
4353                         
4354                         decls = decls->next;                    
4355                 }
4356                 ast_print(tree->right,outfile,indent+2);
4357                 INDENT(indent,outfile);
4358                 fprintf(outfile,"}\n");
4359                 return;
4360         }
4361         if (tree->opval.op == NULLOP) {
4362                 fprintf(outfile,"\n");
4363                 ast_print(tree->left,outfile,indent);
4364                 fprintf(outfile,"\n");
4365                 ast_print(tree->right,outfile,indent);
4366                 return ;
4367         }
4368         INDENT(indent,outfile);
4369
4370         /*------------------------------------------------------------------*/
4371         /*----------------------------*/
4372         /*   leaf has been reached    */
4373         /*----------------------------*/
4374         /* if this is of type value */
4375         /* just get the type        */
4376         if (tree->type == EX_VALUE) {
4377
4378                 if (IS_LITERAL (tree->opval.val->etype)) {                      
4379                         fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4380                                 (int) floatFromVal(tree->opval.val),
4381                                 (int) floatFromVal(tree->opval.val),
4382                                 floatFromVal(tree->opval.val));
4383                 } else if (tree->opval.val->sym) {
4384                         /* if the undefined flag is set then give error message */
4385                         if (tree->opval.val->sym->undefined) {
4386                                 fprintf(outfile,"UNDEFINED SYMBOL ");
4387                         } else {
4388                                 fprintf(outfile,"SYMBOL ");
4389                         }
4390                         fprintf(outfile,"(%s=%p)",
4391                                 tree->opval.val->sym->name,tree);
4392                 }
4393                 if (tree->ftype) {
4394                         fprintf(outfile," type (");
4395                         printTypeChain(tree->ftype,outfile);
4396                         fprintf(outfile,")\n");
4397                 } else {
4398                         fprintf(outfile,"\n");
4399                 }
4400                 return ;
4401         }
4402
4403         /* if type link for the case of cast */
4404         if (tree->type == EX_LINK) {
4405                 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4406                 printTypeChain(tree->opval.lnk,outfile);
4407                 fprintf(outfile,")\n");
4408                 return ;
4409         }
4410
4411
4412         /* depending on type of operator do */
4413         
4414         switch (tree->opval.op) {
4415                 /*------------------------------------------------------------------*/
4416                 /*----------------------------*/
4417                 /*        array node          */
4418                 /*----------------------------*/
4419         case '[':
4420                 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4421                 printTypeChain(tree->ftype,outfile);
4422                 fprintf(outfile,")\n");
4423                 ast_print(tree->left,outfile,indent+2);
4424                 ast_print(tree->right,outfile,indent+2);
4425                 return;
4426
4427                 /*------------------------------------------------------------------*/
4428                 /*----------------------------*/
4429                 /*      struct/union          */
4430                 /*----------------------------*/
4431         case '.':
4432                 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4433                 printTypeChain(tree->ftype,outfile);
4434                 fprintf(outfile,")\n");
4435                 ast_print(tree->left,outfile,indent+2);
4436                 ast_print(tree->right,outfile,indent+2);
4437                 return ;
4438
4439                 /*------------------------------------------------------------------*/
4440                 /*----------------------------*/
4441                 /*    struct/union pointer    */
4442                 /*----------------------------*/
4443         case PTR_OP:
4444                 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4445                 printTypeChain(tree->ftype,outfile);
4446                 fprintf(outfile,")\n");
4447                 ast_print(tree->left,outfile,indent+2);
4448                 ast_print(tree->right,outfile,indent+2);
4449                 return ;
4450
4451                 /*------------------------------------------------------------------*/
4452                 /*----------------------------*/
4453                 /*  ++/-- operation           */
4454                 /*----------------------------*/
4455         case INC_OP:            /* incerement operator unary so left only */
4456                 fprintf(outfile,"INC_OP (%p) type (",tree);
4457                 printTypeChain(tree->ftype,outfile);
4458                 fprintf(outfile,")\n");
4459                 ast_print(tree->left,outfile,indent+2);
4460                 return ;
4461
4462         case DEC_OP:
4463                 fprintf(outfile,"DEC_OP (%p) type (",tree);
4464                 printTypeChain(tree->ftype,outfile);
4465                 fprintf(outfile,")\n");
4466                 ast_print(tree->left,outfile,indent+2);
4467                 return ;
4468
4469                 /*------------------------------------------------------------------*/
4470                 /*----------------------------*/
4471                 /*  bitwise and               */
4472                 /*----------------------------*/
4473         case '&':                       
4474                 if (tree->right) {
4475                         fprintf(outfile,"& (%p) type (",tree);
4476                         printTypeChain(tree->ftype,outfile);
4477                         fprintf(outfile,")\n");
4478                         ast_print(tree->left,outfile,indent+2);
4479                         ast_print(tree->right,outfile,indent+2);
4480                 } else {
4481                         fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4482                         printTypeChain(tree->ftype,outfile);
4483                         fprintf(outfile,")\n");
4484                         ast_print(tree->left,outfile,indent+2);
4485                         ast_print(tree->right,outfile,indent+2);
4486                 }
4487                 return ;
4488                 /*----------------------------*/
4489                 /*  bitwise or                */
4490                 /*----------------------------*/
4491         case '|':
4492                 fprintf(outfile,"OR (%p) type (",tree);
4493                 printTypeChain(tree->ftype,outfile);
4494                 fprintf(outfile,")\n");
4495                 ast_print(tree->left,outfile,indent+2);
4496                 ast_print(tree->right,outfile,indent+2);
4497                 return ;
4498                 /*------------------------------------------------------------------*/
4499                 /*----------------------------*/
4500                 /*  bitwise xor               */
4501                 /*----------------------------*/
4502         case '^':
4503                 fprintf(outfile,"XOR (%p) type (",tree);
4504                 printTypeChain(tree->ftype,outfile);
4505                 fprintf(outfile,")\n");
4506                 ast_print(tree->left,outfile,indent+2);
4507                 ast_print(tree->right,outfile,indent+2);
4508                 return ;
4509                 
4510                 /*------------------------------------------------------------------*/
4511                 /*----------------------------*/
4512                 /*  division                  */
4513                 /*----------------------------*/
4514         case '/':
4515                 fprintf(outfile,"DIV (%p) type (",tree);
4516                 printTypeChain(tree->ftype,outfile);
4517                 fprintf(outfile,")\n");
4518                 ast_print(tree->left,outfile,indent+2);
4519                 ast_print(tree->right,outfile,indent+2);
4520                 return ;
4521                 /*------------------------------------------------------------------*/
4522                 /*----------------------------*/
4523                 /*            modulus         */
4524                 /*----------------------------*/
4525         case '%':
4526                 fprintf(outfile,"MOD (%p) type (",tree);
4527                 printTypeChain(tree->ftype,outfile);
4528                 fprintf(outfile,")\n");
4529                 ast_print(tree->left,outfile,indent+2);
4530                 ast_print(tree->right,outfile,indent+2);
4531                 return ;
4532
4533                 /*------------------------------------------------------------------*/
4534                 /*----------------------------*/
4535                 /*  address dereference       */
4536                 /*----------------------------*/
4537         case '*':                       /* can be unary  : if right is null then unary operation */
4538                 if (!tree->right) {
4539                         fprintf(outfile,"DEREF (%p) type (",tree);
4540                         printTypeChain(tree->ftype,outfile);
4541                         fprintf(outfile,")\n");
4542                         ast_print(tree->left,outfile,indent+2);
4543                         return ;
4544                 }                       
4545                 /*------------------------------------------------------------------*/
4546                 /*----------------------------*/
4547                 /*      multiplication        */
4548                 /*----------------------------*/                
4549                 fprintf(outfile,"MULT (%p) type (",tree);
4550                 printTypeChain(tree->ftype,outfile);
4551                 fprintf(outfile,")\n");
4552                 ast_print(tree->left,outfile,indent+2);
4553                 ast_print(tree->right,outfile,indent+2);
4554                 return ;
4555
4556
4557                 /*------------------------------------------------------------------*/
4558                 /*----------------------------*/
4559                 /*    unary '+' operator      */
4560                 /*----------------------------*/
4561         case '+':
4562                 /* if unary plus */
4563                 if (!tree->right) {
4564                         fprintf(outfile,"UPLUS (%p) type (",tree);
4565                         printTypeChain(tree->ftype,outfile);
4566                         fprintf(outfile,")\n");
4567                         ast_print(tree->left,outfile,indent+2);
4568                 } else {
4569                         /*------------------------------------------------------------------*/
4570                         /*----------------------------*/
4571                         /*      addition              */
4572                         /*----------------------------*/
4573                         fprintf(outfile,"ADD (%p) type (",tree);
4574                         printTypeChain(tree->ftype,outfile);
4575                         fprintf(outfile,")\n");
4576                         ast_print(tree->left,outfile,indent+2);
4577                         ast_print(tree->right,outfile,indent+2);
4578                 }
4579                 return;
4580                 /*------------------------------------------------------------------*/
4581                 /*----------------------------*/
4582                 /*      unary '-'             */
4583                 /*----------------------------*/
4584         case '-':                       /* can be unary   */
4585                 if (!tree->right) {
4586                         fprintf(outfile,"UMINUS (%p) type (",tree);
4587                         printTypeChain(tree->ftype,outfile);
4588                         fprintf(outfile,")\n");
4589                         ast_print(tree->left,outfile,indent+2);
4590                 } else {
4591                         /*------------------------------------------------------------------*/
4592                         /*----------------------------*/
4593                         /*      subtraction           */
4594                         /*----------------------------*/
4595                         fprintf(outfile,"SUB (%p) type (",tree);
4596                         printTypeChain(tree->ftype,outfile);
4597                         fprintf(outfile,")\n");
4598                         ast_print(tree->left,outfile,indent+2);
4599                         ast_print(tree->right,outfile,indent+2);
4600                 }
4601                 return;
4602                 /*------------------------------------------------------------------*/
4603                 /*----------------------------*/
4604                 /*    compliment              */
4605                 /*----------------------------*/
4606         case '~':
4607                 fprintf(outfile,"COMPL (%p) type (",tree);
4608                 printTypeChain(tree->ftype,outfile);
4609                 fprintf(outfile,")\n");
4610                 ast_print(tree->left,outfile,indent+2);
4611                 return ;
4612                 /*------------------------------------------------------------------*/
4613                 /*----------------------------*/
4614                 /*           not              */
4615                 /*----------------------------*/
4616         case '!':
4617                 fprintf(outfile,"NOT (%p) type (",tree);
4618                 printTypeChain(tree->ftype,outfile);
4619                 fprintf(outfile,")\n");
4620                 ast_print(tree->left,outfile,indent+2);
4621                 return ;
4622                 /*------------------------------------------------------------------*/
4623                 /*----------------------------*/
4624                 /*           shift            */
4625                 /*----------------------------*/
4626         case RRC:
4627                 fprintf(outfile,"RRC (%p) type (",tree);
4628                 printTypeChain(tree->ftype,outfile);
4629                 fprintf(outfile,")\n");
4630                 ast_print(tree->left,outfile,indent+2);
4631                 return ;
4632
4633         case RLC:
4634                 fprintf(outfile,"RLC (%p) type (",tree);
4635                 printTypeChain(tree->ftype,outfile);
4636                 fprintf(outfile,")\n");
4637                 ast_print(tree->left,outfile,indent+2);
4638                 return ;
4639         case GETHBIT:
4640                 fprintf(outfile,"GETHBIT (%p) type (",tree);
4641                 printTypeChain(tree->ftype,outfile);
4642                 fprintf(outfile,")\n");
4643                 ast_print(tree->left,outfile,indent+2);
4644                 return ;
4645         case LEFT_OP:
4646                 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4647                 printTypeChain(tree->ftype,outfile);
4648                 fprintf(outfile,")\n");
4649                 ast_print(tree->left,outfile,indent+2);
4650                 ast_print(tree->right,outfile,indent+2);
4651                 return ;
4652         case RIGHT_OP:
4653                 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4654                 printTypeChain(tree->ftype,outfile);
4655                 fprintf(outfile,")\n");
4656                 ast_print(tree->left,outfile,indent+2);
4657                 ast_print(tree->right,outfile,indent+2);
4658                 return ;
4659                 /*------------------------------------------------------------------*/
4660                 /*----------------------------*/
4661                 /*         casting            */
4662                 /*----------------------------*/
4663         case CAST:                      /* change the type   */
4664                 fprintf(outfile,"CAST (%p) from type (",tree);
4665                 printTypeChain(tree->right->ftype,outfile);
4666                 fprintf(outfile,") to type (");
4667                 printTypeChain(tree->ftype,outfile);
4668                 fprintf(outfile,")\n");
4669                 ast_print(tree->right,outfile,indent+2);
4670                 return ;
4671                 
4672         case AND_OP:
4673                 fprintf(outfile,"ANDAND (%p) type (",tree);
4674                 printTypeChain(tree->ftype,outfile);
4675                 fprintf(outfile,")\n");
4676                 ast_print(tree->left,outfile,indent+2);
4677                 ast_print(tree->right,outfile,indent+2);
4678                 return ;
4679         case OR_OP:
4680                 fprintf(outfile,"OROR (%p) type (",tree);
4681                 printTypeChain(tree->ftype,outfile);
4682                 fprintf(outfile,")\n");
4683                 ast_print(tree->left,outfile,indent+2);
4684                 ast_print(tree->right,outfile,indent+2);
4685                 return ;
4686                 
4687                 /*------------------------------------------------------------------*/
4688                 /*----------------------------*/
4689                 /*     comparison operators   */
4690                 /*----------------------------*/
4691         case '>':
4692                 fprintf(outfile,"GT(>) (%p) type (",tree);
4693                 printTypeChain(tree->ftype,outfile);
4694                 fprintf(outfile,")\n");
4695                 ast_print(tree->left,outfile,indent+2);
4696                 ast_print(tree->right,outfile,indent+2);
4697                 return ;
4698         case '<':
4699                 fprintf(outfile,"LT(<) (%p) type (",tree);
4700                 printTypeChain(tree->ftype,outfile);
4701                 fprintf(outfile,")\n");
4702                 ast_print(tree->left,outfile,indent+2);
4703                 ast_print(tree->right,outfile,indent+2);
4704                 return ;
4705         case LE_OP:
4706                 fprintf(outfile,"LE(<=) (%p) type (",tree);
4707                 printTypeChain(tree->ftype,outfile);
4708                 fprintf(outfile,")\n");
4709                 ast_print(tree->left,outfile,indent+2);
4710                 ast_print(tree->right,outfile,indent+2);
4711                 return ;
4712         case GE_OP:
4713                 fprintf(outfile,"GE(>=) (%p) type (",tree);
4714                 printTypeChain(tree->ftype,outfile);
4715                 fprintf(outfile,")\n");
4716                 ast_print(tree->left,outfile,indent+2);
4717                 ast_print(tree->right,outfile,indent+2);
4718                 return ;
4719         case EQ_OP:
4720                 fprintf(outfile,"EQ(==) (%p) type (",tree);
4721                 printTypeChain(tree->ftype,outfile);
4722                 fprintf(outfile,")\n");
4723                 ast_print(tree->left,outfile,indent+2);
4724                 ast_print(tree->right,outfile,indent+2);
4725                 return ;
4726         case NE_OP:
4727                 fprintf(outfile,"NE(!=) (%p) type (",tree);
4728                 printTypeChain(tree->ftype,outfile);
4729                 fprintf(outfile,")\n");
4730                 ast_print(tree->left,outfile,indent+2);
4731                 ast_print(tree->right,outfile,indent+2);
4732                 /*------------------------------------------------------------------*/
4733                 /*----------------------------*/
4734                 /*             sizeof         */
4735                 /*----------------------------*/
4736         case SIZEOF:            /* evaluate wihout code generation */
4737                 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4738                 return ;
4739
4740                 /*------------------------------------------------------------------*/
4741                 /*----------------------------*/
4742                 /* conditional operator  '?'  */
4743                 /*----------------------------*/
4744         case '?':
4745                 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4746                 printTypeChain(tree->ftype,outfile);
4747                 fprintf(outfile,")\n");
4748                 ast_print(tree->left,outfile,indent+2);
4749                 ast_print(tree->right,outfile,indent+2);
4750                 return;
4751
4752         case ':':
4753                 fprintf(outfile,"COLON(:) (%p) type (",tree);
4754                 printTypeChain(tree->ftype,outfile);
4755                 fprintf(outfile,")\n");
4756                 ast_print(tree->left,outfile,indent+2);
4757                 ast_print(tree->right,outfile,indent+2);
4758                 return ;
4759                 
4760                 /*------------------------------------------------------------------*/
4761                 /*----------------------------*/
4762                 /*    assignment operators    */
4763                 /*----------------------------*/
4764         case MUL_ASSIGN:
4765                 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4766                 printTypeChain(tree->ftype,outfile);
4767                 fprintf(outfile,")\n");
4768                 ast_print(tree->left,outfile,indent+2);
4769                 ast_print(tree->right,outfile,indent+2);
4770                 return;
4771         case DIV_ASSIGN:
4772                 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4773                 printTypeChain(tree->ftype,outfile);
4774                 fprintf(outfile,")\n");
4775                 ast_print(tree->left,outfile,indent+2);
4776                 ast_print(tree->right,outfile,indent+2);
4777                 return;
4778         case AND_ASSIGN:
4779                 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4780                 printTypeChain(tree->ftype,outfile);
4781                 fprintf(outfile,")\n");
4782                 ast_print(tree->left,outfile,indent+2);
4783                 ast_print(tree->right,outfile,indent+2);
4784                 return;
4785         case OR_ASSIGN:
4786                 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4787                 printTypeChain(tree->ftype,outfile);
4788                 fprintf(outfile,")\n");
4789                 ast_print(tree->left,outfile,indent+2);
4790                 ast_print(tree->right,outfile,indent+2);
4791                 return;
4792         case XOR_ASSIGN:
4793                 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4794                 printTypeChain(tree->ftype,outfile);
4795                 fprintf(outfile,")\n");
4796                 ast_print(tree->left,outfile,indent+2);
4797                 ast_print(tree->right,outfile,indent+2);
4798                 return;
4799         case RIGHT_ASSIGN:
4800                 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4801                 printTypeChain(tree->ftype,outfile);
4802                 fprintf(outfile,")\n");
4803                 ast_print(tree->left,outfile,indent+2);
4804                 ast_print(tree->right,outfile,indent+2);
4805                 return;
4806         case LEFT_ASSIGN:
4807                 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4808                 printTypeChain(tree->ftype,outfile);
4809                 fprintf(outfile,")\n");
4810                 ast_print(tree->left,outfile,indent+2);
4811                 ast_print(tree->right,outfile,indent+2);
4812                 return;
4813                 /*------------------------------------------------------------------*/
4814                 /*----------------------------*/
4815                 /*    -= operator             */
4816                 /*----------------------------*/
4817         case SUB_ASSIGN:
4818                 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4819                 printTypeChain(tree->ftype,outfile);
4820                 fprintf(outfile,")\n");
4821                 ast_print(tree->left,outfile,indent+2);
4822                 ast_print(tree->right,outfile,indent+2);
4823                 return;
4824                 /*------------------------------------------------------------------*/
4825                 /*----------------------------*/
4826                 /*          += operator       */
4827                 /*----------------------------*/
4828         case ADD_ASSIGN:
4829                 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4830                 printTypeChain(tree->ftype,outfile);
4831                 fprintf(outfile,")\n");
4832                 ast_print(tree->left,outfile,indent+2);
4833                 ast_print(tree->right,outfile,indent+2);
4834                 return;
4835                 /*------------------------------------------------------------------*/
4836                 /*----------------------------*/
4837                 /*      straight assignemnt   */
4838                 /*----------------------------*/
4839         case '=':
4840                 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4841                 printTypeChain(tree->ftype,outfile);
4842                 fprintf(outfile,")\n");
4843                 ast_print(tree->left,outfile,indent+2);
4844                 ast_print(tree->right,outfile,indent+2);
4845                 return;     
4846                 /*------------------------------------------------------------------*/
4847                 /*----------------------------*/
4848                 /*      comma operator        */
4849                 /*----------------------------*/
4850         case ',':
4851                 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4852                 printTypeChain(tree->ftype,outfile);
4853                 fprintf(outfile,")\n");
4854                 ast_print(tree->left,outfile,indent+2);
4855                 ast_print(tree->right,outfile,indent+2);
4856                 return;
4857                 /*------------------------------------------------------------------*/
4858                 /*----------------------------*/
4859                 /*       function call        */
4860                 /*----------------------------*/
4861         case CALL:
4862         case PCALL:
4863                 fprintf(outfile,"CALL (%p) type (",tree);
4864                 printTypeChain(tree->ftype,outfile);
4865                 fprintf(outfile,")\n");
4866                 ast_print(tree->left,outfile,indent+2);
4867                 ast_print(tree->right,outfile,indent+2);
4868                 return;
4869         case PARAM:
4870                 fprintf(outfile,"PARMS\n");
4871                 ast_print(tree->left,outfile,indent+2);
4872                 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
4873                         ast_print(tree->right,outfile,indent+2);
4874                 }
4875                 return ;
4876                 /*------------------------------------------------------------------*/
4877                 /*----------------------------*/
4878                 /*     return statement       */
4879                 /*----------------------------*/
4880         case RETURN:
4881                 fprintf(outfile,"RETURN (%p) type (",tree);
4882                 if (tree->right) {
4883                     printTypeChain(tree->right->ftype,outfile);
4884                 }
4885                 fprintf(outfile,")\n");
4886                 ast_print(tree->right,outfile,indent+2);
4887                 return ;
4888                 /*------------------------------------------------------------------*/
4889                 /*----------------------------*/
4890                 /*     label statement        */
4891                 /*----------------------------*/
4892         case LABEL :
4893                 fprintf(outfile,"LABEL (%p)\n",tree);
4894                 ast_print(tree->left,outfile,indent+2);
4895                 ast_print(tree->right,outfile,indent);
4896                 return;
4897                 /*------------------------------------------------------------------*/
4898                 /*----------------------------*/
4899                 /*     switch statement       */
4900                 /*----------------------------*/
4901         case SWITCH:
4902                 {
4903                         value *val;
4904                         fprintf(outfile,"SWITCH (%p) ",tree);
4905                         ast_print(tree->left,outfile,0);
4906                         for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4907                                 INDENT(indent+2,outfile);
4908                                 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4909                                         (int) floatFromVal(val),
4910                                         tree->values.switchVals.swNum,
4911                                         (int) floatFromVal(val));
4912                         }
4913                         ast_print(tree->right,outfile,indent);
4914                 }
4915                 return ;
4916                 /*------------------------------------------------------------------*/
4917                 /*----------------------------*/
4918                 /* ifx Statement              */
4919                 /*----------------------------*/
4920         case IFX:
4921                 fprintf(outfile,"IF (%p) \n",tree);
4922                 ast_print(tree->left,outfile,indent+2);
4923                 if (tree->trueLabel) {
4924                         INDENT(indent,outfile);
4925                         fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
4926                 }
4927                 if (tree->falseLabel) {
4928                         INDENT(indent,outfile);
4929                         fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4930                 }
4931                 ast_print(tree->right,outfile,indent+2);
4932                 return ;
4933                 /*------------------------------------------------------------------*/
4934                 /*----------------------------*/
4935                 /* for Statement              */
4936                 /*----------------------------*/
4937         case FOR:
4938                 fprintf(outfile,"FOR (%p) \n",tree);
4939                 if (AST_FOR( tree, initExpr)) {
4940                         INDENT(indent+2,outfile);
4941                         fprintf(outfile,"INIT EXPR ");
4942                         ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
4943                 }
4944                 if (AST_FOR( tree, condExpr)) {
4945                         INDENT(indent+2,outfile);
4946                         fprintf(outfile,"COND EXPR ");
4947                         ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
4948                 }
4949                 if (AST_FOR( tree, loopExpr)) {
4950                         INDENT(indent+2,outfile);
4951                         fprintf(outfile,"LOOP EXPR ");
4952                         ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
4953                 }
4954                 fprintf(outfile,"FOR LOOP BODY \n");
4955                 ast_print(tree->left,outfile,indent+2);
4956                 return ;
4957         default:
4958             return ;
4959         }
4960 }
4961
4962 void PA(ast *t)
4963 {
4964         ast_print(t,stdout,0);
4965 }