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