X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fca65%2Fstudyexpr.c;h=90d2d6e1826dc22277fac14a21b7344557c7bf29;hb=cd72f816d34efbb415bdb9e97435994e4e57b443;hp=0a2986f2a2cb1eccbd6f5a52e133225d2358961a;hpb=7ecb4c50b1bedcf28f8b4dd936e3d28df238d41a;p=cc65 diff --git a/src/ca65/studyexpr.c b/src/ca65/studyexpr.c index 0a2986f2a..90d2d6e18 100644 --- a/src/ca65/studyexpr.c +++ b/src/ca65/studyexpr.c @@ -37,7 +37,7 @@ /* common */ #include "check.h" -#include "print.h" +#include "debugflag.h" #include "shift.h" #include "xmalloc.h" @@ -61,7 +61,7 @@ ExprDesc* ED_Init (ExprDesc* ED) { ED->Flags = ED_OK; ED->AddrSize = ADDR_SIZE_DEFAULT; - ED->Val = 0; + ED->Val = 0; ED->SymCount = 0; ED->SymLimit = 0; ED->SymRef = 0; @@ -106,11 +106,19 @@ int ED_IsConst (const ExprDesc* D) static int ED_IsValid (const ExprDesc* D) -/* Return true if the expression is valid, that is, the TOO_COMPLEX flag is - * not set - */ +/* Return true if the expression is valid, that is, neither the ERROR nor the +** TOO_COMPLEX flags are set. +*/ { - return ((D->Flags & ED_TOO_COMPLEX) == 0); + return ((D->Flags & (ED_ERROR | ED_TOO_COMPLEX)) == 0); +} + + + +static int ED_HasError (const ExprDesc* D) +/* Return true if the expression has an error. */ +{ + return ((D->Flags & ED_ERROR) != 0); } @@ -123,6 +131,14 @@ static void ED_Invalidate (ExprDesc* D) +static void ED_SetError (ExprDesc* D) +/* Set the TOO_COMPLEX and ERROR flags for D */ +{ + D->Flags |= (ED_ERROR | ED_TOO_COMPLEX); +} + + + static void ED_UpdateAddrSize (ExprDesc* ED, unsigned char AddrSize) /* Update the address size of the expression */ { @@ -148,22 +164,22 @@ static void ED_MergeAddrSize (ExprDesc* ED, const ExprDesc* Right) { if (ED->AddrSize == ADDR_SIZE_DEFAULT) { /* If ED is valid, ADDR_SIZE_DEFAULT gets always overridden, otherwise - * it takes precedence over anything else. - */ + ** it takes precedence over anything else. + */ if (ED_IsValid (ED)) { ED->AddrSize = Right->AddrSize; } } else if (Right->AddrSize == ADDR_SIZE_DEFAULT) { /* If Right is valid, ADDR_SIZE_DEFAULT gets always overridden, - * otherwise it takes precedence over anything else. - */ + ** otherwise it takes precedence over anything else. + */ if (!ED_IsValid (Right)) { ED->AddrSize = Right->AddrSize; } } else { /* Neither ED nor Right has a default address size, use the larger of - * the two. - */ + ** the two. + */ if (Right->AddrSize > ED->AddrSize) { ED->AddrSize = Right->AddrSize; } @@ -174,8 +190,8 @@ static void ED_MergeAddrSize (ExprDesc* ED, const ExprDesc* Right) static ED_SymRef* ED_FindSymRef (ExprDesc* ED, SymEntry* Sym) /* Find a symbol reference and return it. Return NULL if the reference does - * not exist. - */ +** not exist. +*/ { unsigned I; ED_SymRef* SymRef; @@ -191,8 +207,8 @@ static ED_SymRef* ED_FindSymRef (ExprDesc* ED, SymEntry* Sym) static ED_SecRef* ED_FindSecRef (ExprDesc* ED, unsigned Sec) /* Find a section reference and return it. Return NULL if the reference does - * not exist. - */ +** not exist. +*/ { unsigned I; ED_SecRef* SecRef; @@ -208,8 +224,8 @@ static ED_SecRef* ED_FindSecRef (ExprDesc* ED, unsigned Sec) static ED_SymRef* ED_AllocSymRef (ExprDesc* ED, SymEntry* Sym) /* Allocate a new symbol reference and return it. The count of the new - * reference will be set to zero, and the reference itself to Sym. - */ +** reference will be set to zero, and the reference itself to Sym. +*/ { ED_SymRef* SymRef; @@ -235,8 +251,8 @@ static ED_SymRef* ED_AllocSymRef (ExprDesc* ED, SymEntry* Sym) static ED_SecRef* ED_AllocSecRef (ExprDesc* ED, unsigned Sec) /* Allocate a new section reference and return it. The count of the new - * reference will be set to zero, and the reference itself to Sec. - */ +** reference will be set to zero, and the reference itself to Sec. +*/ { ED_SecRef* SecRef; @@ -262,8 +278,8 @@ static ED_SecRef* ED_AllocSecRef (ExprDesc* ED, unsigned Sec) static ED_SymRef* ED_GetSymRef (ExprDesc* ED, SymEntry* Sym) /* Get a symbol reference and return it. If the symbol reference does not - * exist, a new one is created and returned. - */ +** exist, a new one is created and returned. +*/ { ED_SymRef* SymRef = ED_FindSymRef (ED, Sym); if (SymRef == 0) { @@ -276,8 +292,8 @@ static ED_SymRef* ED_GetSymRef (ExprDesc* ED, SymEntry* Sym) static ED_SecRef* ED_GetSecRef (ExprDesc* ED, unsigned Sec) /* Get a section reference and return it. If the section reference does not - * exist, a new one is created and returned. - */ +** exist, a new one is created and returned. +*/ { ED_SecRef* SecRef = ED_FindSecRef (ED, Sec); if (SecRef == 0) { @@ -400,8 +416,8 @@ static void ED_Neg (ExprDesc* D) static void ED_Move (ExprDesc* From, ExprDesc* To) /* Move the data from one ExprDesc to another. Old data is freed, and From - * is prepared to that ED_Done may be called safely. - */ +** is prepared to that ED_Done may be called safely. +*/ { /* Delete old data */ ED_Done (To); @@ -416,7 +432,7 @@ static void ED_Move (ExprDesc* From, ExprDesc* To) /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ @@ -444,12 +460,12 @@ static unsigned char GetConstAddrSize (long Val) static void StudyBinaryExpr (ExprNode* Expr, ExprDesc* D) /* Study a binary expression subtree. This is a helper function for StudyExpr - * used for operations that succeed when both operands are known and constant. - * It evaluates the two subtrees and checks if they are constant. If they - * aren't constant, it will set the TOO_COMPLEX flag, and merge references. - * Otherwise the first value is returned in D->Val, the second one in D->Right, - * so the actual operation can be done by the caller. - */ +** used for operations that succeed when both operands are known and constant. +** It evaluates the two subtrees and checks if they are constant. If they +** aren't constant, it will set the TOO_COMPLEX flag, and merge references. +** Otherwise the first value is returned in D->Val, the second one in D->Right, +** so the actual operation can be done by the caller. +*/ { ExprDesc Right; @@ -500,20 +516,17 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D) SymEntry* Sym = Expr->V.Sym; /* If the symbol is defined somewhere, it has an expression associated. - * In this case, just study the expression associated with the symbol, - * but mark the symbol so if we encounter it twice, we know that we have - * a circular reference. - */ + ** In this case, just study the expression associated with the symbol, + ** but mark the symbol so if we encounter it twice, we know that we have + ** a circular reference. + */ if (SymHasExpr (Sym)) { if (SymHasUserMark (Sym)) { - if (Verbosity > 0) { - DumpExpr (Expr, SymResolve); - } LIError (&Sym->DefLines, - "Circular reference in definition of symbol `%m%p'", + "Circular reference in definition of symbol '%m%p'", GetSymName (Sym)); - ED_Invalidate (D); + ED_SetError (D); } else { unsigned char AddrSize; @@ -523,10 +536,15 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D) StudyExprInternal (GetSymExpr (Sym), D); SymUnmarkUser (Sym); + /* If requested and if the expression is valid, dump it */ + if (Debug > 0 && !ED_HasError (D)) { + DumpExpr (Expr, SymResolve); + } + /* If the symbol has an explicit address size, use it. This may - * lead to range errors later (maybe even in the linker stage), if - * the user lied about the address size, but for now we trust him. - */ + ** lead to range errors later (maybe even in the linker stage), if + ** the user lied about the address size, but for now we trust him. + */ AddrSize = GetSymAddrSize (Sym); if (AddrSize != ADDR_SIZE_DEFAULT) { D->AddrSize = AddrSize; @@ -536,8 +554,8 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D) } else if (SymIsImport (Sym)) { /* The symbol is an import. Track the symbols used and update the - * address size. - */ + ** address size. + */ ED_SymRef* SymRef = ED_GetSymRef (D, Sym); ++SymRef->Count; ED_UpdateAddrSize (D, GetSymAddrSize (Sym)); @@ -548,17 +566,17 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D) SymTable* Parent; /* The symbol is undefined. Track symbol usage but set the "too - * complex" flag, since we cannot evaluate the final result. - */ + ** complex" flag, since we cannot evaluate the final result. + */ ED_SymRef* SymRef = ED_GetSymRef (D, Sym); ++SymRef->Count; ED_Invalidate (D); /* Since the symbol may be a forward, and we may need a statement - * about the address size, check higher lexical levels for a symbol - * with the same name and use its address size if we find such a - * symbol which is defined. - */ + ** about the address size, check higher lexical levels for a symbol + ** with the same name and use its address size if we find such a + ** symbol which is defined. + */ AddrSize = GetSymAddrSize (Sym); Parent = GetSymParentScope (Sym); if (AddrSize == ADDR_SIZE_DEFAULT && Parent != 0) { @@ -594,8 +612,8 @@ static void StudyULabel (ExprNode* Expr, ExprDesc* D) /* Study an unnamed label expression node */ { /* If we can resolve the label, study the expression associated with it, - * otherwise mark the expression as too complex to evaluate. - */ + ** otherwise mark the expression as too complex to evaluate. + */ if (ULabCanResolve ()) { /* We can resolve the label */ StudyExprInternal (ULabResolve (Expr->V.IVal), D); @@ -689,8 +707,8 @@ static void StudyMul (ExprNode* Expr, ExprDesc* D) StudyExprInternal (Expr->Right, &Right); /* We can handle the operation if at least one of both operands is const - * and the other one is valid. - */ + ** and the other one is valid. + */ if (ED_IsConst (D) && ED_IsValid (&Right)) { /* Multiplicate both, result goes into Right */ @@ -733,7 +751,7 @@ static void StudyDiv (ExprNode* Expr, ExprDesc* D) if (ED_IsValid (D)) { if (D->Right == 0) { Error ("Division by zero"); - ED_Invalidate (D); + ED_SetError (D); } else { D->Val /= D->Right; } @@ -752,7 +770,7 @@ static void StudyMod (ExprNode* Expr, ExprDesc* D) if (ED_IsValid (D)) { if (D->Right == 0) { Error ("Modulo operation with zero"); - ED_Invalidate (D); + ED_SetError (D); } else { D->Val %= D->Right; } @@ -1097,21 +1115,6 @@ static void StudyBoolNot (ExprNode* Expr, ExprDesc* D) static void StudyBank (ExprNode* Expr, ExprDesc* D) /* Study an EXPR_BANK expression node */ -{ - /* Get the section reference */ - ED_SecRef* SecRef = ED_GetSecRef (D, Expr->V.SecNum); - - /* Update the data and the address size */ - ++SecRef->Count; - - /* The expression is always linker evaluated, so invalidate it */ - ED_Invalidate (D); -} - - - -static void StudyBankRaw (ExprNode* Expr, ExprDesc* D) -/* Study an EXPR_BANKRAW expression node */ { /* Study the expression extracting section references */ StudyExprInternal (Expr->Left, D); @@ -1280,33 +1283,29 @@ static void StudyExprInternal (ExprNode* Expr, ExprDesc* D) /* Study this expression node */ switch (Expr->Op) { - case EXPR_LITERAL: + case EXPR_LITERAL: StudyLiteral (Expr, D); - break; + break; - case EXPR_SYMBOL: + case EXPR_SYMBOL: StudySymbol (Expr, D); break; - case EXPR_SECTION: + case EXPR_SECTION: StudySection (Expr, D); - break; - - case EXPR_ULABEL: - StudyULabel (Expr, D); break; - case EXPR_BANK: - StudyBank (Expr, D); + case EXPR_ULABEL: + StudyULabel (Expr, D); break; - case EXPR_PLUS: + case EXPR_PLUS: StudyPlus (Expr, D); - break; + break; - case EXPR_MINUS: - StudyMinus (Expr, D); - break; + case EXPR_MINUS: + StudyMinus (Expr, D); + break; case EXPR_MUL: StudyMul (Expr, D); @@ -1400,8 +1399,8 @@ static void StudyExprInternal (ExprNode* Expr, ExprDesc* D) StudyBoolNot (Expr, D); break; - case EXPR_BANKRAW: - StudyBankRaw (Expr, D); + case EXPR_BANK: + StudyBank (Expr, D); break; case EXPR_BYTE0: @@ -1437,8 +1436,8 @@ static void StudyExprInternal (ExprNode* Expr, ExprDesc* D) break; default: - Internal ("Unknown Op type: %u", Expr->Op); - break; + Internal ("Unknown Op type: %u", Expr->Op); + break; } } @@ -1481,24 +1480,24 @@ void StudyExpr (ExprNode* Expr, ExprDesc* D) } /* If we don't have an address size, assign one if the expression is a - * constant. - */ + ** constant. + */ if (D->AddrSize == ADDR_SIZE_DEFAULT && ED_IsConst (D)) { D->AddrSize = GetConstAddrSize (D->Val); } /* If the expression is valid, throw away the address size and recalculate - * it using the data we have. This is more exact than the on-the-fly - * calculation done when evaluating the tree, because symbols may have - * been removed from the expression, and the final numeric value is now - * known. - */ + ** it using the data we have. This is more exact than the on-the-fly + ** calculation done when evaluating the tree, because symbols may have + ** been removed from the expression, and the final numeric value is now + ** known. + */ if (ED_IsValid (D)) { unsigned char AddrSize; /* If there are symbols or sections, use the largest one. If the - * expression resolves to a const, use the address size of the value. - */ + ** expression resolves to a const, use the address size of the value. + */ if (D->SymCount > 0 || D->SecCount > 0) { D->AddrSize = ADDR_SIZE_DEFAULT; @@ -1540,6 +1539,3 @@ void StudyExpr (ExprNode* Expr, ExprDesc* D) printf ("%u sections:\n", D->SecCount); #endif } - - -