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