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