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