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