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