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