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