X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fca65%2Fexpr.c;h=b5beb8e780c2203384c0a810e842274519ba2e74;hb=64c5165a5b2984d15035dd17d1e953502db25d36;hp=f6b4125477107df62223b3e8ddce84bcf1aa6e58;hpb=a5d8a5a94f4750fd3f32d98fb718fab161b83e9d;p=cc65 diff --git a/src/ca65/expr.c b/src/ca65/expr.c index f6b412547..b5beb8e78 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 1998-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -34,24 +34,29 @@ #include +#include /* common */ #include "check.h" +#include "cpu.h" #include "exprdefs.h" +#include "print.h" #include "tgttrans.h" +#include "version.h" #include "xmalloc.h" /* ca65 */ #include "error.h" +#include "expr.h" #include "global.h" #include "instr.h" #include "nexttok.h" -#include "objcode.h" +/* #include "objcode.h" */ #include "objfile.h" +#include "segment.h" #include "symtab.h" #include "toklist.h" #include "ulabel.h" -#include "expr.h" @@ -79,7 +84,7 @@ static unsigned FreeNodeCount = 0; -static ExprNode* NewExprNode (void) +static ExprNode* NewExprNode (unsigned Op) /* Create a new expression node */ { ExprNode* N; @@ -93,7 +98,7 @@ static ExprNode* NewExprNode (void) /* Allocate fresh memory */ N = xmalloc (sizeof (ExprNode)); } - N->Op = EXPR_NULL; + N->Op = Op; N->Left = N->Right = 0; N->Obj = 0; @@ -158,7 +163,7 @@ static int FuncBlank (void) } else { /* Skip any tokens */ int Braces = 0; - while (Tok != TOK_SEP && Tok != TOK_EOF) { + while (!TokIsSep (Tok)) { if (Tok == TOK_LPAREN) { ++Braces; } else if (Tok == TOK_RPAREN) { @@ -198,18 +203,69 @@ static int FuncConst (void) static int FuncDefined (void) /* Handle the .DEFINED builtin function */ { + static const char* Keys[] = { + "ANY", + "GLOBAL", + "LOCAL", + }; + + char Name [sizeof (SVal)]; int Result = 0; + int Scope; + /* First argument is a symbol name */ if (Tok != TOK_IDENT) { Error (ERR_IDENT_EXPECTED); if (Tok != TOK_RPAREN) { NextTok (); } + return 0; + } + + /* Remember the name, then skip it */ + strcpy (Name, SVal); + NextTok (); + + /* Comma and scope spec may follow */ + if (Tok == TOK_COMMA) { + + /* Skip the comma */ + NextTok (); + + /* An identifier must follow */ + if (Tok != TOK_IDENT) { + Error (ERR_IDENT_EXPECTED); + return 0; + } + + /* Get the scope, then skip it */ + Scope = GetSubKey (Keys, sizeof (Keys) / sizeof (Keys [0])); + NextTok (); + + /* Check if we got a valid keyword */ + if (Scope < 0) { + Error (ERR_ILLEGAL_SCOPE); + return 0; + } + + /* Map the scope */ + switch (Scope) { + case 0: Scope = SCOPE_ANY; break; + case 1: Scope = SCOPE_GLOBAL; break; + case 2: Scope = SCOPE_LOCAL; break; + default: Internal ("Invalid scope: %d", Scope); + } + } else { - Result = SymIsDef (SVal); - NextTok (); + + /* Any scope */ + Scope = SCOPE_ANY; + } + /* Search for the symbol */ + Result = SymIsDef (SVal, Scope); + /* Done */ return Result; } @@ -231,7 +287,7 @@ static int DoMatch (enum TC EqualityLevel) while (Tok != TOK_COMMA) { /* We may not end-of-line of end-of-file here */ - if (Tok == TOK_SEP || Tok == TOK_EOF) { + if (TokIsSep (Tok)) { Error (ERR_UNEXPECTED_EOL); return 0; } @@ -262,7 +318,7 @@ static int DoMatch (enum TC EqualityLevel) while (Tok != TOK_RPAREN) { /* We may not end-of-line of end-of-file here */ - if (Tok == TOK_SEP || Tok == TOK_EOF) { + if (TokIsSep (Tok)) { Error (ERR_UNEXPECTED_EOL); return 0; } @@ -324,7 +380,7 @@ static int FuncReferenced (void) NextTok (); } } else { - Result = SymIsRef (SVal); + Result = SymIsRef (SVal, SCOPE_ANY); NextTok (); } @@ -359,7 +415,7 @@ static int FuncStrAt (void) Index = ConstExpression (); /* Must be a valid index */ - if (Index >= strlen (Str)) { + if (Index >= (long) strlen (Str)) { Error (ERR_RANGE); return 0; } @@ -415,7 +471,7 @@ static int FuncTCount (void) * will check for the closing paren, we don't need to print an error * here, just bail out. */ - if (Tok == TOK_SEP || Tok == TOK_EOF) { + if (TokIsSep (Tok)) { break; } @@ -459,7 +515,7 @@ static ExprNode* Function (int (*F) (void)) if (Tok != TOK_LPAREN) { Error (ERR_LPAREN_EXPECTED); SkipUntilSep (); - return LiteralExpr (0); + return GenLiteralExpr (0); } NextTok (); @@ -470,7 +526,7 @@ static ExprNode* Function (int (*F) (void)) ConsumeRParen (); /* Return an expression node with the boolean code */ - return LiteralExpr (Result); + return GenLiteralExpr (Result); } @@ -483,12 +539,12 @@ static ExprNode* Factor (void) switch (Tok) { case TOK_INTCON: - N = LiteralExpr (IVal); + N = GenLiteralExpr (IVal); NextTok (); break; case TOK_CHARCON: - N = LiteralExpr (TgtTranslateChar (IVal)); + N = GenLiteralExpr (TgtTranslateChar (IVal)); NextTok (); break; @@ -496,32 +552,28 @@ static ExprNode* Factor (void) NextTok (); if (Tok != TOK_IDENT) { Error (ERR_IDENT_EXPECTED); - N = LiteralExpr (0); /* Dummy */ + N = GenLiteralExpr (0); /* Dummy */ } else { - S = SymRefGlobal (SVal); + S = SymRef (SVal, SCOPE_GLOBAL); if (SymIsConst (S)) { /* Use the literal value instead */ - N = LiteralExpr (GetSymVal (S)); + N = GenLiteralExpr (GetSymVal (S)); } else { /* Create symbol node */ - N = NewExprNode (); - N->Op = EXPR_SYMBOL; - N->V.Sym = S; + N = GenSymExpr (S); } NextTok (); } break; case TOK_IDENT: - S = SymRef (SVal); + S = SymRef (SVal, SCOPE_LOCAL); if (SymIsConst (S)) { /* Use the literal value instead */ - N = LiteralExpr (GetSymVal (S)); + N = GenLiteralExpr (GetSymVal (S)); } else { /* Create symbol node */ - N = NewExprNode (); - N->Op = EXPR_SYMBOL; - N->V.Sym = S; + N = GenSymExpr (S); } NextTok (); break; @@ -533,36 +585,32 @@ static ExprNode* Factor (void) case TOK_MINUS: NextTok (); - N = NewExprNode (); + N = NewExprNode (EXPR_UNARY_MINUS); N->Left = Factor (); - N->Op = EXPR_UNARY_MINUS; break; case TOK_NOT: NextTok (); - N = NewExprNode (); + N = NewExprNode (EXPR_NOT); N->Left = Factor (); - N->Op = EXPR_NOT; break; case TOK_STAR: case TOK_PC: NextTok (); - N = CurrentPC (); + N = GenCurrentPC (); break; case TOK_LT: NextTok (); - N = NewExprNode (); + N = NewExprNode (EXPR_BYTE0); N->Left = Factor (); - N->Op = EXPR_BYTE0; break; case TOK_GT: NextTok (); - N = NewExprNode (); + N = NewExprNode (EXPR_BYTE1); N->Left = Factor (); - N->Op = EXPR_BYTE1; break; case TOK_LPAREN: @@ -580,7 +628,7 @@ static ExprNode* Factor (void) break; case TOK_CPU: - N = LiteralExpr (GetCPU()); + N = GenLiteralExpr (CPUIsets[CPU]); NextTok (); break; @@ -608,6 +656,17 @@ static ExprNode* Factor (void) N = Function (FuncTCount); break; + case TOK_TIME: + N = GenLiteralExpr (time (0)); + NextTok (); + break; + + case TOK_VERSION: + N = GenLiteralExpr (VERSION); + NextTok (); + break; + + case TOK_XMATCH: N = Function (FuncXMatch); break; @@ -615,9 +674,9 @@ static ExprNode* Factor (void) default: if (LooseCharTerm && Tok == TOK_STRCON && strlen(SVal) == 1) { /* A character constant */ - N = LiteralExpr (TgtTranslateChar (SVal[0])); + N = GenLiteralExpr (TgtTranslateChar (SVal[0])); } else { - N = LiteralExpr (0); /* Dummy */ + N = GenLiteralExpr (0); /* Dummy */ Error (ERR_SYNTAX); } NextTok (); @@ -630,32 +689,29 @@ static ExprNode* Factor (void) static ExprNode* Term (void) { - ExprNode* Root; - /* Read left hand side */ - Root = Factor (); + ExprNode* Root = Factor (); /* Handle multiplicative operations */ while (Tok == TOK_MUL || Tok == TOK_DIV || Tok == TOK_MOD || Tok == TOK_AND || Tok == TOK_XOR || Tok == TOK_SHL || Tok == TOK_SHR) { - /* Create a new node and insert the left expression */ + /* Create the new node */ ExprNode* Left = Root; - Root = NewExprNode (); - Root->Left = Left; - - /* Determine the operator token */ switch (Tok) { - case TOK_MUL: Root->Op = EXPR_MUL; break; - case TOK_DIV: Root->Op = EXPR_DIV; break; - case TOK_MOD: Root->Op = EXPR_MOD; break; - case TOK_AND: Root->Op = EXPR_AND; break; - case TOK_XOR: Root->Op = EXPR_XOR; break; - case TOK_SHL: Root->Op = EXPR_SHL; break; - case TOK_SHR: Root->Op = EXPR_SHR; break; + case TOK_MUL: Root = NewExprNode (EXPR_MUL); break; + case TOK_DIV: Root = NewExprNode (EXPR_DIV); break; + case TOK_MOD: Root = NewExprNode (EXPR_MOD); break; + case TOK_AND: Root = NewExprNode (EXPR_AND); break; + case TOK_XOR: Root = NewExprNode (EXPR_XOR); break; + case TOK_SHL: Root = NewExprNode (EXPR_SHL); break; + case TOK_SHR: Root = NewExprNode (EXPR_SHR); break; default: Internal ("Invalid token"); } + Root->Left = Left; + + /* Skip the operator token */ NextTok (); /* Parse the right hand side */ @@ -671,26 +727,23 @@ static ExprNode* Term (void) static ExprNode* SimpleExpr (void) { - ExprNode* Root; - /* Read left hand side */ - Root = Term (); + ExprNode* Root = Term (); /* Handle additive operations */ while (Tok == TOK_PLUS || Tok == TOK_MINUS || Tok == TOK_OR) { - /* Create a new node and insert the left expression */ + /* Create the new node */ ExprNode* Left = Root; - Root = NewExprNode (); - Root->Left = Left; - - /* Determine the operator token */ switch (Tok) { - case TOK_PLUS: Root->Op = EXPR_PLUS; break; - case TOK_MINUS: Root->Op = EXPR_MINUS; break; - case TOK_OR: Root->Op = EXPR_OR; break; + case TOK_PLUS: Root = NewExprNode (EXPR_PLUS); break; + case TOK_MINUS: Root = NewExprNode (EXPR_MINUS); break; + case TOK_OR: Root = NewExprNode (EXPR_OR); break; default: Internal ("Invalid token"); } + Root->Left = Left; + + /* Skip the operator token */ NextTok (); /* Parse the right hand side */ @@ -714,21 +767,20 @@ static ExprNode* BoolExpr (void) while (Tok == TOK_EQ || Tok == TOK_NE || Tok == TOK_LT || Tok == TOK_GT || Tok == TOK_LE || Tok == TOK_GE) { - /* Create a new node and insert the left expression */ + /* Create the new node */ ExprNode* Left = Root; - Root = NewExprNode (); - Root->Left = Left; - - /* Determine the operator token */ switch (Tok) { - case TOK_EQ: Root->Op = EXPR_EQ; break; - case TOK_NE: Root->Op = EXPR_NE; break; - case TOK_LT: Root->Op = EXPR_LT; break; - case TOK_GT: Root->Op = EXPR_GT; break; - case TOK_LE: Root->Op = EXPR_LE; break; - case TOK_GE: Root->Op = EXPR_GE; break; + case TOK_EQ: Root = NewExprNode (EXPR_EQ); break; + case TOK_NE: Root = NewExprNode (EXPR_NE); break; + case TOK_LT: Root = NewExprNode (EXPR_LT); break; + case TOK_GT: Root = NewExprNode (EXPR_GT); break; + case TOK_LE: Root = NewExprNode (EXPR_LE); break; + case TOK_GE: Root = NewExprNode (EXPR_GE); break; default: Internal ("Invalid token"); } + Root->Left = Left; + + /* Skip the operator token */ NextTok (); /* Parse the right hand side */ @@ -751,17 +803,16 @@ static ExprNode* Expr2 (void) /* Handle booleans */ while (Tok == TOK_BAND || Tok == TOK_BXOR) { - /* Create a new node and insert the left expression */ + /* Create the new node */ ExprNode* Left = Root; - Root = NewExprNode (); - Root->Left = Left; - - /* Determine the operator token */ switch (Tok) { - case TOK_BAND: Root->Op = EXPR_BAND; break; - case TOK_BXOR: Root->Op = EXPR_BXOR; break; + case TOK_BAND: Root = NewExprNode (EXPR_BAND); break; + case TOK_BXOR: Root = NewExprNode (EXPR_BXOR); break; default: Internal ("Invalid token"); } + Root->Left = Left; + + /* Skip the operator token */ NextTok (); /* Parse the right hand side */ @@ -784,16 +835,15 @@ static ExprNode* Expr1 (void) /* Handle booleans */ while (Tok == TOK_BOR) { - /* Create a new node and insert the left expression */ + /* Create the new node */ ExprNode* Left = Root; - Root = NewExprNode (); - Root->Left = Left; - - /* Determine the operator token */ switch (Tok) { - case TOK_BOR: Root->Op = EXPR_BOR; break; + case TOK_BOR: Root = NewExprNode (EXPR_BOR); break; default: Internal ("Invalid token"); } + Root->Left = Left; + + /* Skip the operator token */ NextTok (); /* Parse the right hand side */ @@ -815,14 +865,10 @@ static ExprNode* Expr0 (void) /* Handle booleans */ if (Tok == TOK_BNOT) { - /* Create a new node */ - Root = NewExprNode (); + /* Create the new node */ + Root = NewExprNode (EXPR_BNOT); - /* Determine the operator token */ - switch (Tok) { - case TOK_BNOT: Root->Op = EXPR_BNOT; break; - default: Internal ("Invalid token"); - } + /* Skip the operator token */ NextTok (); /* Parse the left hand side, allow more BNOTs */ @@ -845,8 +891,8 @@ static ExprNode* SimplifyExpr (ExprNode* Root) /* Try to simplify the given expression tree */ { if (Root) { - SimplifyExpr (Root->Left); - SimplifyExpr (Root->Right); + Root->Left = SimplifyExpr (Root->Left); + Root->Right = SimplifyExpr (Root->Right); if (IsConstExpr (Root)) { /* The complete expression is constant */ Root->V.Val = GetExprVal (Root); @@ -877,52 +923,88 @@ long ConstExpression (void) * not constant. */ { + long Val; + /* Read the expression, and call finalize (exception here, since we * expect a const). */ ExprNode* Expr = FinalizeExpr (Expression ()); - /* Return the value */ + /* Get the value */ if (IsConstExpr (Expr)) { - return GetExprVal (Expr); + Val = GetExprVal (Expr); } else { Error (ERR_CONSTEXPR_EXPECTED); - return 0; + Val = 0; + } + + /* Free the expression tree and return the value */ + FreeExpr (Expr); + return Val; +} + + + +void FreeExpr (ExprNode* Root) +/* Free the expression, Root is pointing to. */ +{ + if (Root) { + FreeExpr (Root->Left); + FreeExpr (Root->Right); + if (Root->Op == EXPR_SYMBOL) { + /* Remove the symbol reference */ + SymDelRef (Root->V.Sym, Root); + } + FreeExprNode (Root); } } -ExprNode* LiteralExpr (long Val) +ExprNode* GenLiteralExpr (long Val) /* Return an expression tree that encodes the given literal value */ { - ExprNode* Expr = NewExprNode (); - Expr->Op = EXPR_LITERAL; + ExprNode* Expr = NewExprNode (EXPR_LITERAL); Expr->V.Val = Val; return Expr; } -ExprNode* CurrentPC (void) +ExprNode* GenSymExpr (SymEntry* Sym) +/* Return an expression node that encodes the given symbol */ +{ + ExprNode* Expr = NewExprNode (EXPR_SYMBOL); + Expr->V.Sym = Sym; + SymAddRef (Sym, Expr); + return Expr; +} + + + +static ExprNode* GenSectionExpr (unsigned SegNum) +/* Return an expression node for the given section */ +{ + ExprNode* Expr = NewExprNode (EXPR_SECTION); + Expr->V.SegNum = SegNum; + return Expr; +} + + + +ExprNode* GenCurrentPC (void) /* Return the current program counter as expression */ { - ExprNode* Left; ExprNode* Root; if (RelocMode) { /* Create SegmentBase + Offset */ - Left = NewExprNode (); - Left->Op = EXPR_SEGMENT; - Left->V.SegNum = GetSegNum (); - - Root = NewExprNode (); - Root->Left = Left; - Root->Right = LiteralExpr (GetPC ()); - Root->Op = EXPR_PLUS; + Root = NewExprNode (EXPR_PLUS); + Root->Left = GenSectionExpr (GetSegNum ()); + Root->Right = GenLiteralExpr (GetPC ()); } else { - /* Absolute mode, just return PC value */ - Root = LiteralExpr (GetPC ()); + /* Absolute mode, just return PC value */ + Root = GenLiteralExpr (GetPC ()); } return Root; @@ -930,45 +1012,37 @@ ExprNode* CurrentPC (void) -ExprNode* SwapExpr (ExprNode* Expr) +ExprNode* GenSwapExpr (ExprNode* Expr) /* Return an extended expression with lo and hi bytes swapped */ { - ExprNode* N = NewExprNode (); - N->Op = EXPR_SWAP; + ExprNode* N = NewExprNode (EXPR_SWAP); N->Left = Expr; return N; } -ExprNode* BranchExpr (unsigned Offs) +ExprNode* GenBranchExpr (unsigned Offs) /* Return an expression that encodes the difference between current PC plus * offset and the target expression (that is, Expression() - (*+Offs) ). */ { ExprNode* N; ExprNode* Root; - ExprNode* Left; /* Create *+Offs */ if (RelocMode) { - Left = NewExprNode (); - Left->Op = EXPR_SEGMENT; - Left->V.SegNum = GetSegNum (); - - N = NewExprNode (); - N->Left = Left; - N->Right = LiteralExpr (GetPC () + Offs); - N->Op = EXPR_PLUS; + N = NewExprNode (EXPR_PLUS); + N->Left = GenSectionExpr (GetSegNum ()); + N->Right = GenLiteralExpr (GetPC () + Offs); } else { - N = LiteralExpr (GetPC () + Offs); + N = GenLiteralExpr (GetPC () + Offs); } /* Create the root node */ - Root = NewExprNode (); + Root = NewExprNode (EXPR_MINUS); Root->Left = Expression (); Root->Right = N; - Root->Op = EXPR_MINUS; /* Return the result */ return SimplifyExpr (Root); @@ -976,14 +1050,10 @@ ExprNode* BranchExpr (unsigned Offs) -ExprNode* ULabelExpr (unsigned Num) +ExprNode* GenULabelExpr (unsigned Num) /* Return an expression for an unnamed label with the given index */ { - /* Get an expression node */ - ExprNode* Node = NewExprNode (); - - /* Set the values */ - Node->Op = EXPR_ULABEL; + ExprNode* Node = NewExprNode (EXPR_ULABEL); Node->V.Val = Num; /* Return the new node */ @@ -992,26 +1062,40 @@ ExprNode* ULabelExpr (unsigned Num) -void FreeExpr (ExprNode* Root) -/* Free the expression, Root is pointing to. */ +ExprNode* GenByteExpr (ExprNode* Expr) +/* Force the given expression into a byte and return the result */ { - if (Root) { - FreeExpr (Root->Left); - FreeExpr (Root->Right); - FreeExprNode (Root); - } + /* Use the low byte operator to force the expression into byte size */ + ExprNode* Root = NewExprNode (EXPR_BYTE0); + Root->Left = Expr; + + /* Return the result */ + return Root; } -ExprNode* ForceWordExpr (ExprNode* Expr) +ExprNode* GenWordExpr (ExprNode* Expr) /* Force the given expression into a word and return the result. */ { - /* And the expression by $FFFF to force it into word size */ - ExprNode* Root = NewExprNode (); + /* AND the expression by $FFFF to force it into word size */ + ExprNode* Root = NewExprNode (EXPR_AND); + Root->Left = Expr; + Root->Right = GenLiteralExpr (0xFFFF); + + /* Return the result */ + return Root; +} + + + +ExprNode* GenNE (ExprNode* Expr, long Val) +/* Generate an expression that compares Expr and Val for inequality */ +{ + /* Generate a compare node */ + ExprNode* Root = NewExprNode (EXPR_NE); Root->Left = Expr; - Root->Op = EXPR_AND; - Root->Right = LiteralExpr (0xFFFF); + Root->Right = GenLiteralExpr (Val); /* Return the result */ return Root; @@ -1036,7 +1120,7 @@ int IsConstExpr (ExprNode* Root) case EXPR_SYMBOL: Sym = Root->V.Sym; if (SymHasUserMark (Sym)) { - if (Verbose) { + if (Verbosity > 0) { DumpExpr (Root); } PError (GetSymPos (Sym), ERR_CIRCULAR_REFERENCE); @@ -1069,7 +1153,7 @@ int IsConstExpr (ExprNode* Root) } else { return IsConstExpr (Root->Right); } - } else { + } else { /* lhs not const --> tree not const */ return 0; } @@ -1112,13 +1196,13 @@ static void CheckByteExpr (const ExprNode* N, int* IsByte) case EXPR_SYMBOL: if (SymIsZP (N->V.Sym)) { *IsByte = 1; - } else if (SymHasExpr (N->V.Sym)) { + } else if (SymHasExpr (N->V.Sym)) { /* Check if this expression is a byte expression */ *IsByte = IsByteExpr (GetSymExpr (N->V.Sym)); } break; - case EXPR_SEGMENT: + case EXPR_SECTION: if (GetSegType (N->V.SegNum) == SEGTYPE_ZP) { *IsByte = 1; } @@ -1307,31 +1391,31 @@ static ExprNode* RemoveSyms (ExprNode* Expr, int MustClone) case EXPR_SYMBOL: if (SymHasExpr (Expr->V.Sym)) { - /* The symbol has an expression tree */ - SymEntry* Sym = Expr->V.Sym; - if (SymHasUserMark (Sym)) { - /* Circular definition */ - if (Verbose) { - DumpExpr (Expr); - } - PError (GetSymPos (Sym), ERR_CIRCULAR_REFERENCE); - return LiteralExpr (0); /* Return a dummy value */ - } - SymMarkUser (Sym); - Expr = RemoveSyms (GetSymExpr (Sym), 1); - SymUnmarkUser (Sym); - return Expr; + /* The symbol has an expression tree */ + SymEntry* Sym = Expr->V.Sym; + if (SymHasUserMark (Sym)) { + /* Circular definition */ + if (Verbosity) { + DumpExpr (Expr); + } + PError (GetSymPos (Sym), ERR_CIRCULAR_REFERENCE); + return GenLiteralExpr (0); /* Return a dummy value */ + } + SymMarkUser (Sym); + Expr = RemoveSyms (GetSymExpr (Sym), 1); + SymUnmarkUser (Sym); + return Expr; } else if (SymIsConst (Expr->V.Sym)) { - /* The symbol is a constant */ - return LiteralExpr (GetSymVal (Expr->V.Sym)); + /* The symbol is a constant */ + return GenLiteralExpr (GetSymVal (Expr->V.Sym)); } break; case EXPR_ULABEL: if (ULabCanResolve ()) { - ExprNode* NewExpr = ULabResolve (Expr->V.Val); - FreeExpr (Expr); - Expr = NewExpr; + ExprNode* NewExpr = ULabResolve (Expr->V.Val); + FreeExpr (Expr); + Expr = NewExpr; } break; @@ -1340,33 +1424,34 @@ static ExprNode* RemoveSyms (ExprNode* Expr, int MustClone) /* Clone the current node if needed */ if (MustClone) { - /* Create a new node */ - ExprNode* Clone = NewExprNode (); - - /* Clone the operation */ - Clone->Op = Expr->Op; + ExprNode* Clone; - /* Clone the attribute if needed */ + /* Clone the expression tree */ switch (Expr->Op) { case EXPR_LITERAL: + Clone = GenLiteralExpr (Expr->V.Val); + break; + case EXPR_ULABEL: - Clone->V.Val = Expr->V.Val; - break; + Clone = GenULabelExpr (Expr->V.Val); + break; case EXPR_SYMBOL: - Clone->V.Sym = Expr->V.Sym; - break; + Clone = GenSymExpr (Expr->V.Sym); + break; - case EXPR_SEGMENT: - Clone->V.SegNum = Expr->V.SegNum; - break; + case EXPR_SECTION: + Clone = GenSectionExpr (Expr->V.SegNum); + break; - } + default: + Clone = NewExprNode (Expr->Op); + Clone->Left = RemoveSyms (Expr->Left, 1); + Clone->Right = RemoveSyms (Expr->Right, 1); + break; - /* Clone the tree nodes */ - Clone->Left = RemoveSyms (Expr->Left, MustClone); - Clone->Right = RemoveSyms (Expr->Right, MustClone); + } /* Done */ return Clone; @@ -1374,12 +1459,11 @@ static ExprNode* RemoveSyms (ExprNode* Expr, int MustClone) } else { /* Nothing to clone */ - Expr->Left = RemoveSyms (Expr->Left, MustClone); - Expr->Right = RemoveSyms (Expr->Right, MustClone); + Expr->Left = RemoveSyms (Expr->Left, 0); + Expr->Right = RemoveSyms (Expr->Right, 0); /* Done */ return Expr; - } } @@ -1419,7 +1503,7 @@ static ExprNode* ConstExtract (ExprNode* Expr, long* Val, int Sign) return Left; } else { /* Check for SEG - SEG which is now possible */ - if (Left->Op == EXPR_SEGMENT && Right->Op == EXPR_SEGMENT && + if (Left->Op == EXPR_SECTION && Right->Op == EXPR_SECTION && Left->V.SegNum == Right->V.SegNum) { /* SEG - SEG, remove it completely */ FreeExprNode (Left); @@ -1461,13 +1545,12 @@ ExprNode* FinalizeExpr (ExprNode* Expr) Expr = ConstExtract (Expr, &Val, 1); if (Expr == 0) { /* Reduced to a literal value */ - Expr = LiteralExpr (Val); + Expr = GenLiteralExpr (Val); } else if (Val) { /* Extracted a value */ - N = NewExprNode (); - N->Op = EXPR_PLUS; + N = NewExprNode (EXPR_PLUS); N->Left = Expr; - N->Right = LiteralExpr (Val); + N->Right = GenLiteralExpr (Val); Expr = N; } return Expr; @@ -1487,34 +1570,34 @@ ExprNode* CloneExpr (ExprNode* Expr) return 0; } - /* Get a new node */ - Clone = NewExprNode (); - - /* Clone the operation */ - Clone->Op = Expr->Op; - - /* Clone the attribute if needed */ + /* Clone the node */ switch (Expr->Op) { case EXPR_LITERAL: + Clone = GenLiteralExpr (Expr->V.Val); + break; + case EXPR_ULABEL: - Clone->V.Val = Expr->V.Val; + Clone = GenULabelExpr (Expr->V.Val); break; case EXPR_SYMBOL: - Clone->V.Sym = Expr->V.Sym; + Clone = GenSymExpr (Expr->V.Sym); break; - case EXPR_SEGMENT: - Clone->V.SegNum = Expr->V.SegNum; + case EXPR_SECTION: + Clone = GenSectionExpr (Expr->V.SegNum); break; + default: + /* Generate a new node */ + Clone = NewExprNode (Expr->Op); + /* Clone the tree nodes */ + Clone->Left = CloneExpr (Expr->Left); + Clone->Right = CloneExpr (Expr->Right); + break; } - /* Clone the tree nodes */ - Clone->Left = CloneExpr (Expr->Left); - Clone->Right = CloneExpr (Expr->Right); - /* Done */ return Clone; } @@ -1545,10 +1628,10 @@ void WriteExpr (ExprNode* Expr) case EXPR_SYMBOL: /* Maybe we should use a code here? */ CHECK (SymIsImport (Expr->V.Sym)); /* Safety */ - ObjWrite16 (GetSymIndex (Expr->V.Sym)); + ObjWriteVar (GetSymIndex (Expr->V.Sym)); break; - case EXPR_SEGMENT: + case EXPR_SECTION: ObjWrite8 (Expr->V.SegNum); break; @@ -1567,3 +1650,4 @@ void WriteExpr (ExprNode* Expr) +