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