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