X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCast.c;h=441bedc9105bed4feccc0f20c93d5192574fbd07;hb=92c02b20c217e7cf8cc20d667816fdc4c71b9e99;hp=7c8885be1742d683dd440b7343d008c9ecb8dca7;hpb=5d167d3be2f170ad7e6add486d6245530f7fdbf5;p=fw%2Fsdcc diff --git a/src/SDCCast.c b/src/SDCCast.c index 7c8885be..441bedc9 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -23,7 +23,6 @@ -------------------------------------------------------------------------*/ #include "common.h" -#include "newalloc.h" int currLineno = 0; set *astList = NULL; @@ -46,7 +45,6 @@ int labelKey = 1; #define ALLOCATE 1 #define DEALLOCATE 2 -char buffer[1024]; int noLineno = 0; int noAlloc = 0; symbol *currFunc; @@ -55,6 +53,7 @@ ast *createIvalCharPtr (ast *, sym_link *, ast *); ast *optimizeRRCRLC (ast *); ast *optimizeGetHbit (ast *); ast *backPatchLabels (ast *, symbol *, symbol *); +void PA(ast *t); int inInitMode = 0; memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */ FILE *codeOutFile; @@ -76,7 +75,7 @@ newAst (int type, void *op) ast *ex; static int oldLineno = 0; - Safe_calloc (1, ex, sizeof (ast)); + ex = Safe_alloc ( sizeof (ast)); ex->type = type; ex->lineno = (noLineno ? oldLineno : yylineno); @@ -111,7 +110,7 @@ newAst_ (unsigned type) ast *ex; static int oldLineno = 0; - ex = Safe_calloc (1, sizeof (ast)); + ex = Safe_alloc ( sizeof (ast)); ex->type = type; ex->lineno = (noLineno ? oldLineno : yylineno); @@ -180,7 +179,6 @@ newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel) /* if this is a literal then we already know the result */ if (condAst->etype && IS_LITERAL (condAst->etype)) { - /* then depending on the expression value */ if (floatFromVal (condAst->opval.val)) ifxNode = newNode (GOTO, @@ -223,9 +221,14 @@ copyAstValues (ast * dest, ast * src) break; case INLINEASM: - dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1); + dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1); strcpy (dest->values.inlineasm, src->values.inlineasm); + break; + case ARRAYINIT: + dest->values.constlist = copyLiteralList(src->values.constlist); + break; + case FOR: AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel)); AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel)); @@ -249,13 +252,15 @@ copyAst (ast * src) if (!src) return NULL; - dest = Safe_calloc (1, sizeof (ast)); + dest = Safe_alloc ( sizeof (ast)); dest->type = src->type; dest->lineno = src->lineno; dest->level = src->level; dest->funcName = src->funcName; - dest->argSym = src->argSym; + + if (src->ftype) + dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype)); /* if this is a leaf */ /* if value */ @@ -277,9 +282,6 @@ copyAst (ast * src) /* if this is a node that has special values */ copyAstValues (dest, src); - if (src->ftype) - dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype)); - dest->trueLabel = copySymbol (src->trueLabel); dest->falseLabel = copySymbol (src->falseLabel); dest->left = copyAst (src->left); @@ -462,6 +464,7 @@ resolveSymbols (ast * tree) tree->opval.val->etype = tree->opval.val->etype; tree->opval.val->type = tree->opval.val->sym->type; werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name); + allocVariables (tree->opval.val->sym); } else { @@ -536,20 +539,24 @@ funcOfType (char *name, sym_link * type, sym_link * argType, int nArgs, int rent) { symbol *sym; - int argStack = 0; /* create the symbol */ sym = newSymbol (name, 0); + /* setup return value */ + sym->type = newLink (); + DCL_TYPE (sym->type) = FUNCTION; + sym->type->next = copyLinkChain (type); + sym->etype = getSpec (sym->type); + FUNC_ISREENT(sym->type) = rent; + /* if arguments required */ if (nArgs) { - value *args; - args = sym->args = newValue (); + args = FUNC_ARGS(sym->type) = newValue (); while (nArgs--) { - argStack += getSize (type); args->type = copyLinkChain (argType); args->etype = getSpec (args->type); if (!nArgs) @@ -558,17 +565,9 @@ funcOfType (char *name, sym_link * type, sym_link * argType, } } - /* setup return value */ - sym->type = newLink (); - DCL_TYPE (sym->type) = FUNCTION; - sym->type->next = copyLinkChain (type); - sym->etype = getSpec (sym->type); - SPEC_RENT (sym->etype) = rent; - /* save it */ addSymChain (sym); sym->cdef = 1; - sym->argStack = (rent ? argStack : 0); allocVariables (sym); return sym; @@ -603,31 +602,35 @@ reverseParms (ast * ptree) /*-----------------------------------------------------------------*/ int processParms (ast * func, - value * defParm, + value *defParm, ast * actParm, - int *parmNumber, + int *parmNumber, // unused, although updated bool rightmost) { - sym_link *fetype = func->etype; - /* if none of them exist */ if (!defParm && !actParm) return 0; + if (defParm) { + if (getenv("DEBUG_SANITY")) { + fprintf (stderr, "processParms: %s ", defParm->name); + } + /* make sure the type is complete and sane */ + checkTypeSanity(defParm->etype, defParm->name); + } + /* if the function is being called via a pointer & */ /* it has not been defined a reentrant then we cannot */ /* have parameters */ - if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto) + if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto) { - werror (E_NONRENT_ARGS); + werror (W_NONRENT_ARGS); return 1; } /* if defined parameters ended but actual parameters */ /* exist and this is not defined as a variable arg */ - /* also check if statckAuto option is specified */ - if ((!defParm) && actParm && (!func->hasVargs) && - !options.stackAuto && !IS_RENT (fetype)) + if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype)) { werror (E_TOO_MANY_PARMS); return 1; @@ -640,10 +643,16 @@ processParms (ast * func, return 1; } + if (IS_VOID(actParm->ftype)) { + werror (E_VOID_VALUE_USED); + return 1; + } + /* If this is a varargs function... */ - if (!defParm && actParm && func->hasVargs) + if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype)) { ast *newType = NULL; + sym_link *ftype; if (IS_CAST_OP (actParm) || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast)) @@ -652,29 +661,43 @@ processParms (ast * func, return 0; } + /* The ternary ('?') operator is weird: the ftype of the + * operator is the type of the condition, but it will return a + * (possibly) different type. + */ + if (IS_TERNARY_OP(actParm)) + { + assert(IS_COLON_OP(actParm->right)); + assert(actParm->right->left); + ftype = actParm->right->left->ftype; + } + else + { + ftype = actParm->ftype; + } + /* If it's a small integer, upcast to int. */ - if (IS_INTEGRAL (actParm->ftype) - && getSize (actParm->ftype) < (unsigned) INTSIZE) + if (IS_INTEGRAL (ftype) + && (getSize (ftype) < (unsigned) INTSIZE)) { - newType = newAst_LINK (INTTYPE); + newType = newAst_LINK(INTTYPE); } - if (IS_PTR (actParm->ftype) && !IS_GENPTR (actParm->ftype)) + if (IS_PTR(ftype) && !IS_GENPTR(ftype)) { - newType = newAst_LINK (copyLinkChain (actParm->ftype)); + newType = newAst_LINK (copyLinkChain(ftype)); DCL_TYPE (newType->opval.lnk) = GPOINTER; } - if (IS_AGGREGATE (actParm->ftype)) + if (IS_AGGREGATE (ftype)) { - newType = newAst_LINK (copyLinkChain (actParm->ftype)); + newType = newAst_LINK (copyLinkChain (ftype)); DCL_TYPE (newType->opval.lnk) = GPOINTER; } - if (newType) { /* cast required; change this op to a cast. */ - ast *parmCopy = resolveSymbols (copyAst (actParm)); + ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm))); actParm->type = EX_OP; actParm->opval.op = CAST; @@ -691,9 +714,9 @@ processParms (ast * func, } /* if defined parameters ended but actual has not & */ - /* stackAuto */ + /* reentrant */ if (!defParm && actParm && - (options.stackAuto || IS_RENT (fetype))) + (options.stackAuto || IFFUNC_ISREENT (func->ftype))) return 0; resolveSymbols (actParm); @@ -719,21 +742,16 @@ processParms (ast * func, } /* the parameter type must be at least castable */ - if (checkType (defParm->type, actParm->ftype) == 0) - { - werror (E_TYPE_MISMATCH_PARM, *parmNumber); - werror (E_CONTINUE, "defined type "); - printTypeChain (defParm->type, stderr); - fprintf (stderr, "\n"); - werror (E_CONTINUE, "actual type "); - printTypeChain (actParm->ftype, stderr); - fprintf (stderr, "\n"); - } + if (compareType (defParm->type, actParm->ftype) == 0) { + werror (E_INCOMPAT_TYPES); + printFromToType (actParm->ftype, defParm->type); + return 1; + } /* if the parameter is castable then add the cast */ - if (checkType (defParm->type, actParm->ftype) < 0) + if (compareType (defParm->type, actParm->ftype) < 0) { - ast *pTree = resolveSymbols (copyAst (actParm)); + ast *pTree = decorateType(resolveSymbols (copyAst (actParm))); /* now change the current one to a cast */ actParm->type = EX_OP; @@ -742,11 +760,10 @@ processParms (ast * func, actParm->right = pTree; actParm->etype = defParm->etype; actParm->ftype = defParm->type; + actParm->decorated=0; /* force typechecking */ + decorateType (actParm); } -/* actParm->argSym = resolveFromTable(defParm)->sym ; */ - - actParm->argSym = defParm->sym; /* make a copy and change the regparm type to the defined parm */ actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype)); SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype); @@ -776,6 +793,7 @@ ast * createIvalStruct (ast * sym, sym_link * type, initList * ilist) { ast *rast = NULL; + ast *lAst; symbol *sflds; initList *iloop; @@ -790,8 +808,6 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist) for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) { - ast *lAst; - /* if we have come to end */ if (!iloop) break; @@ -813,6 +829,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist) ast *rast = NULL; initList *iloop; int lcnt = 0, size = 0; + literalList *literalL; /* take care of the special case */ /* array of characters can be init */ @@ -824,43 +841,77 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist) return decorateType (resolveSymbols (rast)); - /* not the special case */ - if (ilist->type != INIT_DEEP) + /* not the special case */ + if (ilist->type != INIT_DEEP) { - werror (E_INIT_STRUCT, ""); - return NULL; + werror (E_INIT_STRUCT, ""); + return NULL; } - iloop = ilist->init.deep; - lcnt = DCL_ELEM (type); + iloop = ilist->init.deep; + lcnt = DCL_ELEM (type); - for (;;) + if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL)) { - ast *aSym; - size++; - - aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size - 1)))); - aSym = decorateType (resolveSymbols (aSym)); - rast = createIval (aSym, type->next, iloop, rast); - iloop = (iloop ? iloop->next : NULL); - if (!iloop) - break; - /* if not array limits given & we */ - /* are out of initialisers then */ - if (!DCL_ELEM (type) && !iloop) - break; - - /* no of elements given and we */ - /* have generated for all of them */ - if (!--lcnt) - break; + ast *aSym; + + aSym = decorateType (resolveSymbols(sym)); + + rast = newNode(ARRAYINIT, aSym, NULL); + rast->values.constlist = literalL; + + // Make sure size is set to length of initializer list. + while (iloop) + { + size++; + iloop = iloop->next; + } + + if (lcnt && size > lcnt) + { + // Array size was specified, and we have more initializers than needed. + char *name=sym->opval.val->sym->name; + int lineno=sym->opval.val->sym->lineDef; + + werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno); + } + } + else + { + for (;;) + { + ast *aSym; + + aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++)))); + aSym = decorateType (resolveSymbols (aSym)); + rast = createIval (aSym, type->next, iloop, rast); + iloop = (iloop ? iloop->next : NULL); + if (!iloop) + { + break; + } + + /* no of elements given and we */ + /* have generated for all of them */ + if (!--lcnt) + { + // there has to be a better way + char *name=sym->opval.val->sym->name; + int lineno=sym->opval.val->sym->lineDef; + werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno); + + break; + } + } } - /* if we have not been given a size */ - if (!DCL_ELEM (type)) - DCL_ELEM (type) = size; + /* if we have not been given a size */ + if (!DCL_ELEM (type)) + { + DCL_ELEM (type) = size; + } - return decorateType (resolveSymbols (rast)); + return decorateType (resolveSymbols (rast)); } @@ -885,7 +936,6 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr) SPEC_SCLS (iexpr->etype) == S_CODE) && IS_ARRAY (iexpr->ftype)) { - /* for each character generate an assignment */ /* to the array element */ char *s = SPEC_CVAL (iexpr->etype).v_char; @@ -963,6 +1013,7 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid) /* if type is SPECIFIER */ if (IS_SPEC (type)) rast = createIvalType (sym, type, ilist); + if (wid) return decorateType (resolveSymbols (newNode (NULLOP, wid, rast))); else @@ -972,9 +1023,42 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid) /*-----------------------------------------------------------------*/ /* initAggregates - initialises aggregate variables with initv */ /*-----------------------------------------------------------------*/ -ast * -initAggregates (symbol * sym, initList * ival, ast * wid) -{ + +/* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *); + +ast * initAggregates (symbol * sym, initList * ival, ast * wid) { + ast *ast; + symbol *newSym; + + if (getenv("TRY_THE_NEW_INITIALIZER")) { + + if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) { + fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless " + "with -mmcs51 and --model-large\n"); + exit(404); + } + + if (SPEC_OCLS(sym->etype)==xdata && + getSize(sym->type) > 16) { // else it isn't worth it: do it the old way + + // copy this symbol + newSym=copySymbol (sym); + SPEC_OCLS(newSym->etype)=code; + sprintf (newSym->name, "%s_init__", sym->name); + sprintf (newSym->rname,"%s_init__", sym->rname); + addSym (SymbolTab, newSym, newSym->name, 0, 0, 1); + + // emit it in the static segment + addSet(&statsg->syms, newSym); + + // now memcpy() the entire array from cseg + ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE + newAst_VALUE (symbolVal (sym)), + newAst_VALUE (symbolVal (newSym))); + return decorateType(resolveSymbols(ast)); + } + } + return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid); } @@ -1005,11 +1089,16 @@ gatherAutoInit (symbol * autoChain) SPEC_SCLS (sym->etype) != S_CODE) { symbol *newSym; + + // this can only be a constant + if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) { + werror (E_CONST_EXPECTED); + } /* insert the symbol into the symbol table */ /* with level = 0 & name = rname */ newSym = copySymbol (sym); - addSym (SymbolTab, newSym, newSym->name, 0, 0); + addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1); /* now lift the code to main */ if (IS_AGGREGATE (sym->type)) @@ -1105,8 +1194,8 @@ processBlockVars (ast * tree, int *stack, int action) if (action == ALLOCATE) { - autoInit = gatherAutoInit (tree->values.sym); *stack += allocVariables (tree->values.sym); + autoInit = gatherAutoInit (tree->values.sym); /* if there are auto inits then do them */ if (autoInit) @@ -1123,6 +1212,7 @@ processBlockVars (ast * tree, int *stack, int action) /*-----------------------------------------------------------------*/ /* constExprValue - returns the value of a constant expression */ +/* or NULL if it is not a constant expression */ /*-----------------------------------------------------------------*/ value * constExprValue (ast * cexpr, int check) @@ -1359,11 +1449,25 @@ astHasSymbol (ast * tree, symbol * sym) else return FALSE; } - + return astHasSymbol (tree->left, sym) || astHasSymbol (tree->right, sym); } +/*-----------------------------------------------------------------*/ +/* astHasDeref - return true if the ast has an indirect access */ +/*-----------------------------------------------------------------*/ +static bool +astHasDeref (ast * tree) +{ + if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree)) + return FALSE; + + if (tree->opval.op == '*' && tree->right == NULL) return TRUE; + + return astHasDeref (tree->left) || astHasDeref (tree->right); +} + /*-----------------------------------------------------------------*/ /* isConformingBody - the loop body has to conform to a set of rules */ /* for the loop to be considered reversible read on for rules */ @@ -1514,6 +1618,8 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) if (astHasVolatile (pbody->left)) return FALSE; + + if (astHasDeref(pbody->right)) return FALSE; return isConformingBody (pbody->left, sym, body) && isConformingBody (pbody->right, sym, body); @@ -1680,7 +1786,7 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end) } -#define DEMAND_INTEGER_PROMOTION +//#define DEMAND_INTEGER_PROMOTION #ifdef DEMAND_INTEGER_PROMOTION @@ -1691,7 +1797,7 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end) void pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr) { - if (!node) + if (!node || IS_CALLOP(node)) { /* WTF? We should never get here. */ return; @@ -1722,31 +1828,6 @@ pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr) #endif -/*-----------------------------------------------------------------*/ -/* Given an assignment operation in a tree, determine if the LHS */ -/* (the result) has a different (integer) type than the RHS. */ -/* If so, walk the RHS and add a typecast to the type of the LHS */ -/* to all leaf nodes. */ -/*-----------------------------------------------------------------*/ -void -propAsgType (ast * tree) -{ -#ifdef DEMAND_INTEGER_PROMOTION - if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) - { - /* Nothing to do here... */ - return; - } - - if (getSize (LTYPE (tree)) > getSize (RTYPE (tree))) - { - pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right)); - } -#else - (void) tree; -#endif -} - /*-----------------------------------------------------------------*/ /* decorateType - compute type for this tree also does type cheking */ /* this is done bottom up, since type have to flow upwards */ @@ -1802,11 +1883,6 @@ decorateType (ast * tree) /* otherwise just copy the type information */ COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type); - if (funcInChain (tree->opval.val->type)) - { - tree->hasVargs = tree->opval.val->sym->hasVargs; - tree->args = copyValueChain (tree->opval.val->sym->args); - } return tree; } @@ -1837,13 +1913,6 @@ decorateType (ast * tree) /* and mark it as referenced */ tree->opval.val->sym->isref = 1; - /* if this is of type function or function pointer */ - if (funcInChain (tree->opval.val->type)) - { - tree->hasVargs = tree->opval.val->sym->hasVargs; - tree->args = copyValueChain (tree->opval.val->sym->args); - - } } } } @@ -1876,10 +1945,10 @@ decorateType (ast * tree) switch (tree->opval.op) { -/*------------------------------------------------------------------*/ -/*----------------------------*/ - /* array node */ -/*----------------------------*/ + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* array node */ + /*----------------------------*/ case '[': /* determine which is the array & which the index */ @@ -1918,10 +1987,10 @@ decorateType (ast * tree) } return tree; -/*------------------------------------------------------------------*/ -/*----------------------------*/ + /*------------------------------------------------------------------*/ + /*----------------------------*/ /* struct/union */ -/*----------------------------*/ + /*----------------------------*/ case '.': /* if this is not a structure */ if (!IS_STRUCT (LTYPE (tree))) @@ -1931,14 +2000,14 @@ decorateType (ast * tree) } TTYPE (tree) = structElemType (LTYPE (tree), (tree->right->type == EX_VALUE ? - tree->right->opval.val : NULL), &tree->args); + tree->right->opval.val : NULL)); TETYPE (tree) = getSpec (TTYPE (tree)); return tree; -/*------------------------------------------------------------------*/ -/*----------------------------*/ + /*------------------------------------------------------------------*/ + /*----------------------------*/ /* struct/union pointer */ -/*----------------------------*/ + /*----------------------------*/ case PTR_OP: /* if not pointer to a structure */ if (!IS_PTR (LTYPE (tree))) @@ -1955,7 +2024,7 @@ decorateType (ast * tree) TTYPE (tree) = structElemType (LTYPE (tree)->next, (tree->right->type == EX_VALUE ? - tree->right->opval.val : NULL), &tree->args); + tree->right->opval.val : NULL)); TETYPE (tree) = getSpec (TTYPE (tree)); return tree; @@ -1968,7 +2037,7 @@ decorateType (ast * tree) { sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree)); COPYTYPE (TTYPE (tree), TETYPE (tree), ltc); - if (!tree->initMode && IS_CONSTANT (TETYPE (tree))) + if (!tree->initMode && IS_CONSTANT(TETYPE(tree))) werror (E_CODE_WRITE, "++/--"); if (tree->right) @@ -1990,7 +2059,7 @@ decorateType (ast * tree) if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) { werror (E_BITWISE_OP); - werror (E_CONTINUE, "left & right types are "); + werror (W_CONTINUE, "left & right types are "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, ","); printTypeChain (RTYPE (tree), stderr); @@ -2020,6 +2089,9 @@ decorateType (ast * tree) return decorateType (otree); } +#if 0 + // we can't do this because of "(int & 0xff) << 3" + /* if right or left is literal then result of that type */ if (IS_LITERAL (RTYPE (tree))) { @@ -2044,6 +2116,11 @@ decorateType (ast * tree) TETYPE (tree) = getSpec (TTYPE (tree)); } } +#else + TTYPE (tree) = + computeType (LTYPE (tree), RTYPE (tree)); + TETYPE (tree) = getSpec (TTYPE (tree)); +#endif LRVAL (tree) = RRVAL (tree) = 1; return tree; } @@ -2057,7 +2134,7 @@ decorateType (ast * tree) /* if bit field then error */ if (IS_BITVAR (tree->left->etype)) { - werror (E_ILLEGAL_ADDR, "addrress of bit variable"); + werror (E_ILLEGAL_ADDR, "address of bit variable"); goto errorTreeReturn; } @@ -2073,7 +2150,13 @@ decorateType (ast * tree) goto errorTreeReturn; } - if (LRVAL (tree)) + if (IS_LITERAL(LTYPE(tree))) + { + werror (E_ILLEGAL_ADDR, "address of literal"); + goto errorTreeReturn; + } + + if (LRVAL (tree)) { werror (E_LVALUE_REQUIRED, "address of"); goto errorTreeReturn; @@ -2128,7 +2211,7 @@ decorateType (ast * tree) if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) { werror (E_BITWISE_OP); - werror (E_CONTINUE, "left & right types are "); + werror (W_CONTINUE, "left & right types are "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, ","); printTypeChain (RTYPE (tree), stderr); @@ -2190,7 +2273,7 @@ decorateType (ast * tree) if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) { werror (E_BITWISE_OP); - werror (E_CONTINUE, "left & right types are "); + werror (W_CONTINUE, "left & right types are "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, ","); printTypeChain (RTYPE (tree), stderr); @@ -2235,9 +2318,7 @@ decorateType (ast * tree) } TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ? LTYPE (tree)->next : NULL); - TETYPE (tree) = getSpec (TTYPE (tree)); - tree->args = tree->left->args; - tree->hasVargs = tree->left->hasVargs; + TETYPE (tree) = getSpec (TTYPE (tree)); SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree)); return tree; } @@ -2274,19 +2355,17 @@ decorateType (ast * tree) } LRVAL (tree) = RRVAL (tree) = 1; - /* promote result to int if left & right are char / short + /* promote result to int if left & right are char this will facilitate hardware multiplies 8bit x 8bit = 16bit */ - if ((IS_CHAR(LETYPE(tree)) || IS_SHORT(LETYPE(tree))) && - (IS_CHAR(RETYPE(tree)) || IS_SHORT(RETYPE(tree)))) { - TETYPE (tree) = getSpec (TTYPE (tree) = - computeType (LTYPE (tree), - RTYPE (tree))); - SPEC_NOUN(TETYPE(tree)) = V_INT; - SPEC_SHORT(TETYPE(tree))=0; + if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) { + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + RTYPE (tree))); + SPEC_NOUN(TETYPE(tree)) = V_INT; } else { - TETYPE (tree) = getSpec (TTYPE (tree) = - computeType (LTYPE (tree), - RTYPE (tree))); + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + RTYPE (tree))); } return tree; @@ -2551,7 +2630,7 @@ decorateType (ast * tree) if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype)) { werror (E_SHIFT_OP_INVALID); - werror (E_CONTINUE, "left & right types are "); + werror (W_CONTINUE, "left & right types are "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, ","); printTypeChain (RTYPE (tree), stderr); @@ -2597,10 +2676,10 @@ decorateType (ast * tree) } return tree; -/*------------------------------------------------------------------*/ -/*----------------------------*/ + /*------------------------------------------------------------------*/ + /*----------------------------*/ /* casting */ -/*----------------------------*/ + /*----------------------------*/ case CAST: /* change the type */ /* cannot cast to an aggregate type */ if (IS_AGGREGATE (LTYPE (tree))) @@ -2608,25 +2687,61 @@ decorateType (ast * tree) werror (E_CAST_ILLEGAL); goto errorTreeReturn; } + + /* make sure the type is complete and sane */ + checkTypeSanity(LETYPE(tree), "(cast)"); +#if 0 /* if the right is a literal replace the tree */ - if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->opval.val = - valCastLiteral (LTYPE (tree), - floatFromVal (valFromType (RETYPE (tree)))); - tree->left = NULL; - tree->right = NULL; - TTYPE (tree) = tree->opval.val->type; - tree->values.literalFromCast = 1; - } - else - { - TTYPE (tree) = LTYPE (tree); - LRVAL (tree) = 1; - } - + if (IS_LITERAL (RETYPE (tree))) { + if (!IS_PTR (LTYPE (tree))) { + tree->type = EX_VALUE; + tree->opval.val = + valCastLiteral (LTYPE (tree), + floatFromVal (valFromType (RETYPE (tree)))); + tree->left = NULL; + tree->right = NULL; + TTYPE (tree) = tree->opval.val->type; + tree->values.literalFromCast = 1; + } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) && + ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ { + sym_link *rest = LTYPE(tree)->next; + werror(W_LITERAL_GENERIC); + TTYPE(tree) = newLink(); + DCL_TYPE(TTYPE(tree)) = FPOINTER; + TTYPE(tree)->next = rest; + tree->left->opval.lnk = TTYPE(tree); + LRVAL (tree) = 1; + } else { + TTYPE (tree) = LTYPE (tree); + LRVAL (tree) = 1; + } + } else { + TTYPE (tree) = LTYPE (tree); + LRVAL (tree) = 1; + } +#else + /* if pointer to struct then check names */ + if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) && + IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) && + strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) { + werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,SPEC_STRUCT(LETYPE(tree))->tag); + } + /* if the right is a literal replace the tree */ + if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) { + tree->type = EX_VALUE; + tree->opval.val = + valCastLiteral (LTYPE (tree), + floatFromVal (valFromType (RETYPE (tree)))); + tree->left = NULL; + tree->right = NULL; + TTYPE (tree) = tree->opval.val->type; + tree->values.literalFromCast = 1; + } else { + TTYPE (tree) = LTYPE (tree); + LRVAL (tree) = 1; + } +#endif TETYPE (tree) = getSpec (TTYPE (tree)); return tree; @@ -2691,7 +2806,7 @@ decorateType (ast * tree) /* if they are pointers they must be castable */ if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree))) { - if (checkType (LTYPE (tree), RTYPE (tree)) == 0) + if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { werror (E_COMPARE_OP); fprintf (stderr, "comparing type "); @@ -2708,7 +2823,7 @@ decorateType (ast * tree) if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) || (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))))) - if (checkType (LTYPE (tree), RTYPE (tree)) == 0) + if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { werror (E_COMPARE_OP); fprintf (stderr, "comparing type "); @@ -2752,19 +2867,30 @@ decorateType (ast * tree) tree->opval.val->type); return tree; -/*------------------------------------------------------------------*/ -/*----------------------------*/ + /*------------------------------------------------------------------*/ + /*----------------------------*/ /* conditional operator '?' */ -/*----------------------------*/ + /*----------------------------*/ case '?': - /* the type is one on the left */ - TTYPE (tree) = LTYPE (tree); - TETYPE (tree) = getSpec (TTYPE (tree)); + /* the type is value of the colon operator (on the right) */ + assert(IS_COLON_OP(tree->right)); + /* if already known then replace the tree : optimizer will do it + but faster to do it here */ + if (IS_LITERAL (LTYPE(tree))) { + if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) { + return tree->right->left ; + } else { + return tree->right->right ; + } + } else { + TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree). + TETYPE (tree) = getSpec (TTYPE (tree)); + } return tree; case ':': /* if they don't match we have a problem */ - if (checkType (LTYPE (tree), RTYPE (tree)) == 0) + if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { werror (E_TYPE_MISMATCH, "conditional operator", " "); goto errorTreeReturn; @@ -2801,8 +2927,6 @@ decorateType (ast * tree) } LLVAL (tree) = 1; - propAsgType (tree); - return tree; case AND_ASSIGN: @@ -2830,8 +2954,6 @@ decorateType (ast * tree) } LLVAL (tree) = 1; - propAsgType (tree); - return tree; /*------------------------------------------------------------------*/ @@ -2867,8 +2989,6 @@ decorateType (ast * tree) } LLVAL (tree) = 1; - propAsgType (tree); - return tree; /*------------------------------------------------------------------*/ @@ -2912,8 +3032,6 @@ decorateType (ast * tree) tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right)); tree->opval.op = '='; - propAsgType (tree); - return tree; /*------------------------------------------------------------------*/ @@ -2929,7 +3047,7 @@ decorateType (ast * tree) } /* they should either match or be castable */ - if (checkType (LTYPE (tree), RTYPE (tree)) == 0) + if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { werror (E_TYPE_MISMATCH, "assignment", " "); fprintf (stderr, "type --> '"); @@ -2946,20 +3064,7 @@ decorateType (ast * tree) if (IS_VOID (LTYPE (tree))) { werror (E_CAST_ZERO); - fprintf (stderr, "type --> '"); - printTypeChain (RTYPE (tree), stderr); - fprintf (stderr, "' "); - fprintf (stderr, "assigned to type --> '"); - printTypeChain (LTYPE (tree), stderr); - fprintf (stderr, "'\n"); - } - - /* extra checks for pointer types */ - if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) && - !IS_GENPTR (LTYPE (tree))) - { - if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree))) - werror (W_PTR_ASSIGN); + printFromToType(RTYPE(tree), LTYPE(tree)); } TETYPE (tree) = getSpec (TTYPE (tree) = @@ -2967,9 +3072,8 @@ decorateType (ast * tree) RRVAL (tree) = 1; LLVAL (tree) = 1; if (!tree->initMode ) { - if (IS_CONSTANT (LETYPE (tree))) { - werror (E_CODE_WRITE, " "); - } + if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree)))) + werror (E_CODE_WRITE, " "); } if (LRVAL (tree)) { @@ -2977,8 +3081,6 @@ decorateType (ast * tree) goto errorTreeReturn; } - propAsgType (tree); - return tree; /*------------------------------------------------------------------*/ @@ -2997,17 +3099,18 @@ decorateType (ast * tree) parmNumber = 1; if (processParms (tree->left, - tree->left->args, - tree->right, &parmNumber, TRUE)) + FUNC_ARGS(tree->left->ftype), + tree->right, &parmNumber, TRUE)) { goto errorTreeReturn; + } - if (options.stackAuto || IS_RENT (LETYPE (tree))) + if (options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) { - tree->left->args = reverseVal (tree->left->args); + //FUNC_ARGS(tree->left->ftype) = + //reverseVal (FUNC_ARGS(tree->left->ftype)); reverseParms (tree->right); } - tree->args = tree->left->args; TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next); return tree; @@ -3019,9 +3122,10 @@ decorateType (ast * tree) if (!tree->right) goto voidcheck; - if (checkType (currFunc->type->next, RTYPE (tree)) == 0) + if (compareType (currFunc->type->next, RTYPE (tree)) == 0) { - werror (E_RETURN_MISMATCH); + werror (W_RETURN_MISMATCH); + printFromToType (RTYPE(tree), currFunc->type->next); goto errorTreeReturn; } @@ -3034,21 +3138,12 @@ decorateType (ast * tree) } /* if there is going to be a casing required then add it */ - if (checkType (currFunc->type->next, RTYPE (tree)) < 0) + if (compareType (currFunc->type->next, RTYPE (tree)) < 0) { -#if 0 && defined DEMAND_INTEGER_PROMOTION - if (IS_INTEGRAL (currFunc->type->next)) - { - pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right)); - } - else -#endif - { - tree->right = - decorateType (newNode (CAST, - newAst_LINK (copyLinkChain (currFunc->type->next)), - tree->right)); - } + tree->right = + decorateType (newNode (CAST, + newAst_LINK (copyLinkChain (currFunc->type->next)), + tree->right)); } RRVAL (tree) = 1; @@ -3142,6 +3237,9 @@ sizeofOp (sym_link * type) { char buff[10]; + /* make sure the type is complete and sane */ + checkTypeSanity(type, "(sizeof)"); + /* get the size and convert it to character */ sprintf (buff, "%d", getSize (type)); @@ -3303,7 +3401,7 @@ createLabel (symbol * label, ast * stmnt) if ((csym = findSym (LabelTab, NULL, name))) werror (E_DUPLICATE_LABEL, label->name); else - addSym (LabelTab, label, name, label->level, 0); + addSym (LabelTab, label, name, label->level, 0, 0); label->islbl = 1; label->key = labelKey++; @@ -3427,8 +3525,12 @@ createIf (ast * condAst, ast * ifBody, ast * elseBody) symbol *ifTrue, *ifFalse, *ifEnd; /* if neither exists */ - if (!elseBody && !ifBody) - return condAst; + if (!elseBody && !ifBody) { + // if there are no side effects (i++, j() etc) + if (!hasSEFcalls(condAst)) { + return condAst; + } + } /* create the labels */ sprintf (buffer, "_iffalse_%d", Lblnum); @@ -4006,8 +4108,11 @@ createFunction (symbol * name, ast * body) sym_link *fetype; iCode *piCode = NULL; + if (getenv("SDCC_DEBUG_FUNCTION_POINTERS")) + fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name); + /* if check function return 0 then some problem */ - if (checkFunction (name) == 0) + if (checkFunction (name, NULL) == 0) return NULL; /* create a dummy block if none exists */ @@ -4036,27 +4141,30 @@ createFunction (symbol * name, ast * body) } name->lastLine = yylineno; currFunc = name; - processFuncArgs (currFunc, 0); + +#if 0 // jwk: this is now done in addDecl() + processFuncArgs (currFunc); +#endif /* set the stack pointer */ /* PENDING: check this for the mcs51 */ stackPtr = -port->stack.direction * port->stack.call_overhead; - if (IS_ISR (name->etype)) + if (IFFUNC_ISISR (name->type)) stackPtr -= port->stack.direction * port->stack.isr_overhead; - if (IS_RENT (name->etype) || options.stackAuto) + if (IFFUNC_ISREENT (name->type) || options.stackAuto) stackPtr -= port->stack.direction * port->stack.reent_overhead; xstackPtr = -port->stack.direction * port->stack.call_overhead; fetype = getSpec (name->type); /* get the specifier for the function */ /* if this is a reentrant function then */ - if (IS_RENT (fetype)) + if (IFFUNC_ISREENT (name->type)) reentrant++; - allocParms (name->args); /* allocate the parameters */ + allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */ /* do processing for parameters that are passed in registers */ - processRegParms (name->args, body); + processRegParms (FUNC_ARGS(name->type), body); /* set the stack pointer */ stackPtr = 0; @@ -4077,10 +4185,11 @@ createFunction (symbol * name, ast * body) body = resolveSymbols (body); /* resolve the symbols */ body = decorateType (body); /* propagateType & do semantic checks */ - ex = newAst_VALUE (symbolVal (name)); /* create name */ + ex = newAst_VALUE (symbolVal (name)); /* create name */ ex = newNode (FUNCTION, ex, body); - ex->values.args = name->args; - + ex->values.args = FUNC_ARGS(name->type); + ex->decorated=1; + if (options.dump_tree) PA(ex); if (fatalError) { werror (E_FUNC_NO_CODE, name->name); @@ -4114,20 +4223,20 @@ skipall: /* dealloc the block variables */ processBlockVars (body, &stack, DEALLOCATE); /* deallocate paramaters */ - deallocParms (name->args); + deallocParms (FUNC_ARGS(name->type)); - if (IS_RENT (fetype)) + if (IFFUNC_ISREENT (name->type)) reentrant--; /* we are done freeup memory & cleanup */ noLineno--; labelKey = 1; name->key = 0; - name->fbody = 1; + FUNC_HASBODY(name->type) = 1; addSet (&operKeyReset, name); applyToSet (operKeyReset, resetParmKey); - if (options.debug && !options.nodebug) + if (options.debug) cdbStructBlock (1, cdbFile); cleanUpLevel (LabelTab, 0); @@ -4138,3 +4247,675 @@ skipall: istack->syms = NULL; return NULL; } + + +#define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); } +/*-----------------------------------------------------------------*/ +/* ast_print : prints the ast (for debugging purposes) */ +/*-----------------------------------------------------------------*/ + +void ast_print (ast * tree, FILE *outfile, int indent) +{ + + if (!tree) return ; + + /* can print only decorated trees */ + if (!tree->decorated) return; + + /* if any child is an error | this one is an error do nothing */ + if (tree->isError || + (tree->left && tree->left->isError) || + (tree->right && tree->right->isError)) { + fprintf(outfile,"ERROR_NODE(%p)\n",tree); + } + + + /* print the line */ + /* if not block & function */ + if (tree->type == EX_OP && + (tree->opval.op != FUNCTION && + tree->opval.op != BLOCK && + tree->opval.op != NULLOP)) { + } + + if (tree->opval.op == FUNCTION) { + int arg=0; + value *args=FUNC_ARGS(tree->left->opval.val->type); + fprintf(outfile,"FUNCTION (%s=%p) type (", + tree->left->opval.val->name, tree); + printTypeChain (tree->ftype,outfile); + fprintf(outfile,") args ("); + do { + if (arg) { + fprintf (outfile, ", "); + } + printTypeChain (args ? args->type : NULL, outfile); + arg++; + args= args ? args->next : NULL; + } while (args); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent); + ast_print(tree->right,outfile,indent); + return ; + } + if (tree->opval.op == BLOCK) { + symbol *decls = tree->values.sym; + INDENT(indent,outfile); + fprintf(outfile,"{\n"); + while (decls) { + INDENT(indent+4,outfile); + fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (", + decls->name, decls); + printTypeChain(decls->type,outfile); + fprintf(outfile,")\n"); + + decls = decls->next; + } + ast_print(tree->right,outfile,indent+4); + INDENT(indent,outfile); + fprintf(outfile,"}\n"); + return; + } + if (tree->opval.op == NULLOP) { + fprintf(outfile,"\n"); + ast_print(tree->left,outfile,indent); + fprintf(outfile,"\n"); + ast_print(tree->right,outfile,indent); + return ; + } + INDENT(indent,outfile); + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* leaf has been reached */ + /*----------------------------*/ + /* if this is of type value */ + /* just get the type */ + if (tree->type == EX_VALUE) { + + if (IS_LITERAL (tree->opval.val->etype)) { + fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree, + (int) floatFromVal(tree->opval.val), + (int) floatFromVal(tree->opval.val), + floatFromVal(tree->opval.val)); + } else if (tree->opval.val->sym) { + /* if the undefined flag is set then give error message */ + if (tree->opval.val->sym->undefined) { + fprintf(outfile,"UNDEFINED SYMBOL "); + } else { + fprintf(outfile,"SYMBOL "); + } + fprintf(outfile,"(%s=%p)", + tree->opval.val->sym->name,tree); + } + if (tree->ftype) { + fprintf(outfile," type ("); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + } else { + fprintf(outfile,"\n"); + } + return ; + } + + /* if type link for the case of cast */ + if (tree->type == EX_LINK) { + fprintf(outfile,"TYPENODE (%p) type = (",tree); + printTypeChain(tree->opval.lnk,outfile); + fprintf(outfile,")\n"); + return ; + } + + + /* depending on type of operator do */ + + switch (tree->opval.op) { + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* array node */ + /*----------------------------*/ + case '[': + fprintf(outfile,"ARRAY_OP (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* struct/union */ + /*----------------------------*/ + case '.': + fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* struct/union pointer */ + /*----------------------------*/ + case PTR_OP: + fprintf(outfile,"PTR_ACCESS (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* ++/-- operation */ + /*----------------------------*/ + case INC_OP: /* incerement operator unary so left only */ + fprintf(outfile,"INC_OP (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + return ; + + case DEC_OP: + fprintf(outfile,"DEC_OP (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + return ; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* bitwise and */ + /*----------------------------*/ + case '&': + if (tree->right) { + fprintf(outfile,"& (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + } else { + fprintf(outfile,"ADDRESS_OF (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + } + return ; + /*----------------------------*/ + /* bitwise or */ + /*----------------------------*/ + case '|': + fprintf(outfile,"OR (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* bitwise xor */ + /*----------------------------*/ + case '^': + fprintf(outfile,"XOR (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* division */ + /*----------------------------*/ + case '/': + fprintf(outfile,"DIV (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* modulus */ + /*----------------------------*/ + case '%': + fprintf(outfile,"MOD (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* address dereference */ + /*----------------------------*/ + case '*': /* can be unary : if right is null then unary operation */ + if (!tree->right) { + fprintf(outfile,"DEREF (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + return ; + } + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* multiplication */ + /*----------------------------*/ + fprintf(outfile,"MULT (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* unary '+' operator */ + /*----------------------------*/ + case '+': + /* if unary plus */ + if (!tree->right) { + fprintf(outfile,"UPLUS (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + } else { + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* addition */ + /*----------------------------*/ + fprintf(outfile,"ADD (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + } + return; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* unary '-' */ + /*----------------------------*/ + case '-': /* can be unary */ + if (!tree->right) { + fprintf(outfile,"UMINUS (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + } else { + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* subtraction */ + /*----------------------------*/ + fprintf(outfile,"SUB (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + } + return; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* compliment */ + /*----------------------------*/ + case '~': + fprintf(outfile,"COMPL (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* not */ + /*----------------------------*/ + case '!': + fprintf(outfile,"NOT (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* shift */ + /*----------------------------*/ + case RRC: + fprintf(outfile,"RRC (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + return ; + + case RLC: + fprintf(outfile,"RLC (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + return ; + case GETHBIT: + fprintf(outfile,"GETHBIT (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + return ; + case LEFT_OP: + fprintf(outfile,"LEFT_SHIFT (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + case RIGHT_OP: + fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* casting */ + /*----------------------------*/ + case CAST: /* change the type */ + fprintf(outfile,"CAST (%p) from type (",tree); + printTypeChain(tree->right->ftype,outfile); + fprintf(outfile,") to type ("); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->right,outfile,indent+4); + return ; + + case AND_OP: + fprintf(outfile,"ANDAND (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + case OR_OP: + fprintf(outfile,"OROR (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* comparison operators */ + /*----------------------------*/ + case '>': + fprintf(outfile,"GT(>) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + case '<': + fprintf(outfile,"LT(<) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + case LE_OP: + fprintf(outfile,"LE(<=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + case GE_OP: + fprintf(outfile,"GE(>=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + case EQ_OP: + fprintf(outfile,"EQ(==) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + case NE_OP: + fprintf(outfile,"NE(!=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* sizeof */ + /*----------------------------*/ + case SIZEOF: /* evaluate wihout code generation */ + fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype))); + return ; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* conditional operator '?' */ + /*----------------------------*/ + case '?': + fprintf(outfile,"QUEST(?) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return; + + case ':': + fprintf(outfile,"COLON(:) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return ; + + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* assignment operators */ + /*----------------------------*/ + case MUL_ASSIGN: + fprintf(outfile,"MULASS(*=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return; + case DIV_ASSIGN: + fprintf(outfile,"DIVASS(/=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return; + case AND_ASSIGN: + fprintf(outfile,"ANDASS(&=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return; + case OR_ASSIGN: + fprintf(outfile,"ORASS(*=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return; + case XOR_ASSIGN: + fprintf(outfile,"XORASS(*=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return; + case RIGHT_ASSIGN: + fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return; + case LEFT_ASSIGN: + fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* -= operator */ + /*----------------------------*/ + case SUB_ASSIGN: + fprintf(outfile,"SUBASS(-=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* += operator */ + /*----------------------------*/ + case ADD_ASSIGN: + fprintf(outfile,"ADDASS(+=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* straight assignemnt */ + /*----------------------------*/ + case '=': + fprintf(outfile,"ASSIGN(=) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* comma operator */ + /*----------------------------*/ + case ',': + fprintf(outfile,"COMMA(,) (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* function call */ + /*----------------------------*/ + case CALL: + case PCALL: + fprintf(outfile,"CALL (%p) type (",tree); + printTypeChain(tree->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent+4); + return; + case PARAM: + fprintf(outfile,"PARMS\n"); + ast_print(tree->left,outfile,indent+4); + if (tree->right && !IS_AST_PARAM(tree->right)) { + ast_print(tree->right,outfile,indent+4); + } + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* return statement */ + /*----------------------------*/ + case RETURN: + fprintf(outfile,"RETURN (%p) type (",tree); + printTypeChain(tree->right->ftype,outfile); + fprintf(outfile,")\n"); + ast_print(tree->right,outfile,indent+4); + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* label statement */ + /*----------------------------*/ + case LABEL : + fprintf(outfile,"LABEL (%p)",tree); + ast_print(tree->left,outfile,indent+4); + ast_print(tree->right,outfile,indent); + return; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* switch statement */ + /*----------------------------*/ + case SWITCH: + { + value *val; + fprintf(outfile,"SWITCH (%p) ",tree); + ast_print(tree->left,outfile,0); + for (val = tree->values.switchVals.swVals; val ; val = val->next) { + INDENT(indent+4,outfile); + fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n", + (int) floatFromVal(val), + tree->values.switchVals.swNum, + (int) floatFromVal(val)); + } + ast_print(tree->right,outfile,indent); + } + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* ifx Statement */ + /*----------------------------*/ + case IFX: + fprintf(outfile,"IF (%p) \n",tree); + ast_print(tree->left,outfile,indent+4); + if (tree->trueLabel) { + INDENT(indent,outfile); + fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name); + } + if (tree->falseLabel) { + INDENT(indent,outfile); + fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name); + } + ast_print(tree->right,outfile,indent+4); + return ; + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* for Statement */ + /*----------------------------*/ + case FOR: + fprintf(outfile,"FOR (%p) \n",tree); + if (AST_FOR( tree, initExpr)) { + INDENT(indent+4,outfile); + fprintf(outfile,"INIT EXPR "); + ast_print(AST_FOR(tree, initExpr),outfile,indent+4); + } + if (AST_FOR( tree, condExpr)) { + INDENT(indent+4,outfile); + fprintf(outfile,"COND EXPR "); + ast_print(AST_FOR(tree, condExpr),outfile,indent+4); + } + if (AST_FOR( tree, loopExpr)) { + INDENT(indent+4,outfile); + fprintf(outfile,"LOOP EXPR "); + ast_print(AST_FOR(tree, loopExpr),outfile,indent+4); + } + fprintf(outfile,"FOR LOOP BODY \n"); + ast_print(tree->left,outfile,indent+4); + return ; + default: + return ; + } +} + +void PA(ast *t) +{ + ast_print(t,stdout,0); +}