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