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