]> git.sur5r.net Git - cc65/commitdiff
Rewrote expression evaluation. More smaller changes.
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 11 Nov 2003 13:57:30 +0000 (13:57 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 11 Nov 2003 13:57:30 +0000 (13:57 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@2638 b7a2c559-68d2-44c3-8de9-860c34a00d81

14 files changed:
src/ca65/asserts.c
src/ca65/condasm.c
src/ca65/error.c
src/ca65/expr.c
src/ca65/expr.h
src/ca65/instr.c
src/ca65/objcode.c
src/ca65/scanner.c
src/ca65/scanner.h
src/ca65/segment.c
src/ca65/symentry.c
src/ca65/symentry.h
src/ca65/symtab.c
src/ca65/symtab.h

index 25f5178fcc4808ce816172f181a59b55411f3ce6..a5f8af5936ddff6a15719a771cca66beb64bd00c 100644 (file)
@@ -7,7 +7,7 @@
 /*                                                                           */
 /*                                                                           */
 /* (C) 2003      Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
+/*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -118,9 +118,6 @@ void WriteAssertions (void)
         /* Get the next assertion */
         Assertion* A = CollAtUnchecked (&Assertions, I);
 
-        /* Finalize the expression */
-        A->Expr = FinalizeExpr (A->Expr);
-
         /* Write it to the file */
         WriteExpr (A->Expr);
         ObjWriteVar (A->Action);
@@ -134,4 +131,4 @@ void WriteAssertions (void)
 
 
 
-                 
+
index 0aef3b364ed11e89fe27f94cfa97a49f42c0a657..88d7716f70bc3ffebec45c5c22fc8416a0c5be37 100644 (file)
@@ -295,7 +295,7 @@ void DoConditionals (void)
                NextTok ();
                if (IfCond) {
                    ExprNode* Expr = Expression();
-                   SetIfCond (D, IsConstExpr (Expr));
+                   SetIfCond (D, IsConstExpr (Expr, 0));
                    FreeExpr (Expr);
                }
                IfCond = GetCurrentIfCond ();
@@ -330,7 +330,7 @@ void DoConditionals (void)
                NextTok ();
                if (IfCond) {
                    ExprNode* Expr = Expression();
-                   SetIfCond (D, !IsConstExpr (Expr));
+                   SetIfCond (D, !IsConstExpr (Expr, 0));
                    FreeExpr (Expr);
                }
                IfCond = GetCurrentIfCond ();
index f4cda093dba2ece816a7c61cd54c8e3a19805e99..06bbf26153bf48b3d3f84e68b8acbbffa21733b4 100644 (file)
@@ -181,8 +181,8 @@ void Internal (const char* Format, ...)
 /* Print a message about an internal compiler error and die. */
 {
     va_list ap;
-    va_start (ap, Format);  
-    fprintf (stderr, "Internal assembler error\n");
+    va_start (ap, Format);
+    fprintf (stderr, "Internal assembler error:\n");
     vfprintf (stderr, Format, ap);
     va_end (ap);
     fprintf (stderr, "\n");
index 3c73fd19b1ab5d06ef111ee3095c098ab9b93b12..cf5f5e5377a81ca9e322f6981a7c51e6ba34f6dd 100644 (file)
@@ -7,7 +7,7 @@
 /*                                                                           */
 /*                                                                           */
 /* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
+/*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -41,6 +41,7 @@
 #include "cpu.h"
 #include "exprdefs.h"
 #include "print.h"
+#include "shift.h"
 #include "tgttrans.h"
 #include "version.h"
 #include "xmalloc.h"
  * using the Left link.
  */
 #define        MAX_FREE_NODES  64
-static ExprNode*       FreeExprNodes = 0;
-static unsigned                FreeNodeCount = 0;
+static ExprNode*       FreeExprNodes = 0;
+static unsigned                FreeNodeCount = 0;
+
+/* Structure for parsing expression trees */
+typedef struct ExprDesc ExprDesc;
+struct ExprDesc {
+    long        Val;           /* The offset value */
+    long        Left;           /* Left value for StudyBinaryExpr */
+    int                TooComplex;     /* Expression is too complex to evaluate */
+    long        SymCount;       /* Symbol reference count */
+    long        SecCount;       /* Section reference count */
+    SymEntry*   SymRef;         /* Symbol reference if any */
+    unsigned    SecRef;                /* Section reference if any */
+};
+
 
 
 
@@ -84,6 +98,26 @@ static unsigned              FreeNodeCount = 0;
 
 
 
+static ExprDesc* InitExprDesc (ExprDesc* ED)
+/* Initialize an ExprDesc structure for use with StudyExpr */
+{
+    ED->Val       = 0;
+    ED->TooComplex = 0;
+    ED->SymCount   = 0;
+    ED->SecCount   = 0;
+    return ED;
+}
+
+
+
+static int ExprDescIsConst (const ExprDesc* ED)
+/* Return true if the expression is constant */
+{
+    return (ED->TooComplex == 0 && ED->SymCount == 0 && ED->SecCount == 0);
+}
+
+
+
 static ExprNode* NewExprNode (unsigned Op)
 /* Create a new expression node */
 {
@@ -194,7 +228,7 @@ static int FuncConst (void)
     ExprNode* Expr = Expression ();
 
     /* Check the constness of the expression */
-    int Result = IsConstExpr (Expr);
+    int Result = IsConstExpr (Expr, 0);
 
     /* Free the expression */
     FreeExpr (Expr);
@@ -534,6 +568,12 @@ static ExprNode* Factor (void)
            N->Left = Factor ();
            break;
 
+        case TOK_BANK:
+            NextTok ();
+            N = NewExprNode (EXPR_BYTE2);
+            N->Left = Factor ();
+            break;
+
        case TOK_LPAREN:
            NextTok ();
            N = Expr0 ();
@@ -722,13 +762,13 @@ static ExprNode* Expr2 (void)
     ExprNode* Root = BoolExpr ();
 
     /* Handle booleans */
-    while (Tok == TOK_BAND || Tok == TOK_BXOR) {
+    while (Tok == TOK_BOOLAND || Tok == TOK_BOOLXOR) {
 
        /* Create the new node */
        ExprNode* Left = Root;
        switch (Tok) {
-                   case TOK_BAND:      Root = NewExprNode (EXPR_BAND); break;
-                   case TOK_BXOR:      Root = NewExprNode (EXPR_BXOR); break;
+                   case TOK_BOOLAND:   Root = NewExprNode (EXPR_BOOLAND); break;
+                   case TOK_BOOLXOR:   Root = NewExprNode (EXPR_BOOLXOR); break;
            default:            Internal ("Invalid token");
        }
        Root->Left = Left;
@@ -754,12 +794,12 @@ static ExprNode* Expr1 (void)
     ExprNode* Root = Expr2 ();
 
     /* Handle booleans */
-    while (Tok == TOK_BOR) {
+    while (Tok == TOK_BOOLOR) {
 
        /* Create the new node */
        ExprNode* Left = Root;
        switch (Tok) {
-                   case TOK_BOR:       Root = NewExprNode (EXPR_BOR);  break;
+                   case TOK_BOOLOR:    Root = NewExprNode (EXPR_BOOLOR);  break;
            default:            Internal ("Invalid token");
        }
        Root->Left = Left;
@@ -784,10 +824,10 @@ static ExprNode* Expr0 (void)
     ExprNode* Root;
 
     /* Handle booleans */
-    if (Tok == TOK_BNOT) {
+    if (Tok == TOK_BOOLNOT) {
 
        /* Create the new node */
-        Root = NewExprNode (EXPR_BNOT);
+        Root = NewExprNode (EXPR_BOOLNOT);
 
         /* Skip the operator token */
        NextTok ();
@@ -808,22 +848,440 @@ static ExprNode* Expr0 (void)
 
 
 
-static ExprNode* SimplifyExpr (ExprNode* Root)
+static void StudyExpr (ExprNode* Expr, ExprDesc* D, int Sign);
+static void StudyBinaryExpr (ExprNode* Expr, ExprDesc* D)
+/* Study a binary expression subtree */
+{
+    StudyExpr (Expr->Left, D, 1);
+    if (ExprDescIsConst (D)) {
+        D->Left = D->Val;
+        D->Val = 0;
+        StudyExpr (Expr->Right, D, 1);
+        if (!ExprDescIsConst (D)) {
+            D->TooComplex = 1;
+        }
+    } else {
+        D->TooComplex = 1;
+    }
+}
+
+
+
+static void StudyExpr (ExprNode* Expr, ExprDesc* D, int Sign)
+/* Study an expression tree and place the contents into D */
+{
+    SymEntry* Sym;
+    unsigned  Sec;
+    ExprDesc  SD;
+    ExprDesc  SD1;
+
+    /* Initialize SD. This is not needed in all cases, but it's rather cheap
+     * and simplifies the code below.
+     */
+    InitExprDesc (&SD);
+
+    /* Study this expression node */
+    switch (Expr->Op) {
+
+       case EXPR_LITERAL:
+            D->Val += (Sign * Expr->V.Val);
+           break;
+
+       case EXPR_SYMBOL:
+            Sym = Expr->V.Sym;
+            if (SymIsImport (Sym)) {
+                if (D->SymCount == 0) {
+                    D->SymCount += Sign;
+                    D->SymRef = Sym;
+                } else if (D->SymRef == Sym) {
+                    /* Same symbol */
+                    D->SymCount += Sign;
+                } else {
+                    /* More than one import */
+                    D->TooComplex = 1;
+                }
+            } else if (SymHasExpr (Sym)) {
+                if (SymHasUserMark (Sym)) {
+                    if (Verbosity > 0) {
+                        DumpExpr (Expr, SymResolve);
+                    }
+                    PError (GetSymPos (Sym),
+                            "Circular reference in definition of symbol `%s'",
+                            GetSymName (Sym));
+                    D->TooComplex = 1;
+                } else {
+                    SymMarkUser (Sym);
+                    StudyExpr (GetSymExpr (Sym), D, Sign);
+                    SymUnmarkUser (Sym);
+                }
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+       case EXPR_SECTION:
+            Sec = Expr->V.SegNum;
+            if (D->SecCount == 0) {
+                D->SecCount += Sign;
+                D->SecRef = Sec;
+            } else if (D->SecRef == Sec) {
+                /* Same section */
+                D->SecCount += Sign;
+            } else {
+                /* More than one section */
+                D->TooComplex = 1;
+            }
+           break;
+
+       case EXPR_ULABEL:
+            if (ULabCanResolve ()) {
+                /* We can resolve the label */
+                StudyExpr (ULabResolve (Expr->V.Val), D, Sign);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+       case EXPR_PLUS:
+                   StudyExpr (Expr->Left, D, Sign);
+                   StudyExpr (Expr->Right, D, Sign);
+           break;
+
+       case EXPR_MINUS:
+           StudyExpr (Expr->Left, D, Sign);
+           StudyExpr (Expr->Right, D, -Sign);
+           break;
+
+        case EXPR_MUL:
+            InitExprDesc (&SD1);
+            StudyExpr (Expr->Left, &SD, 1);
+            StudyExpr (Expr->Right, &SD1, 1);
+            if (SD.TooComplex == 0 && SD1.TooComplex == 0) {
+                /* First calculate SD = SD*SD1 if possible */
+                if (ExprDescIsConst (&SD)) {
+                    /* Left is a constant */
+                    SD1.Val      *= SD.Val;
+                    SD1.SymCount *= SD.Val;
+                    SD1.SecCount *= SD.Val;
+                    SD = SD1;
+                } else if (ExprDescIsConst (&SD1)) {
+                    /* Right is constant */
+                    SD.Val      *= SD1.Val;
+                    SD.SymCount *= SD1.Val;
+                    SD.SecCount *= SD1.Val;
+                } else {
+                    D->TooComplex = 1;
+                }
+                /* Now calculate D * Sign * SD */
+                if (!D->TooComplex) {
+                    if ((D->SymCount == 0 || SD.SymCount == 0 || D->SymRef == SD.SymRef) &&
+                        (D->SecCount == 0 || SD.SecCount == 0 || D->SecRef == SD.SecRef)) {
+                        D->Val      += (Sign * SD.Val);
+                        if (D->SymCount == 0) {
+                            D->SymRef = SD.SymRef;
+                        }
+                        D->SymCount += (Sign * SD.SymCount);
+                        if (D->SecCount == 0) {
+                            D->SecRef = SD.SecRef;
+                        }
+                        D->SecCount += (Sign * SD.SecCount);
+                    }
+                } else {
+                    D->TooComplex = 1;
+                }
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_DIV:
+            StudyBinaryExpr (Expr, &SD);
+            if (!SD.TooComplex) {
+                if (SD.Val == 0) {
+                    Error ("Division by zero");
+                    D->TooComplex = 1;
+                } else {
+                    D->Val += Sign * (SD.Left / SD.Val);
+                }
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_MOD:
+            StudyBinaryExpr (Expr, &SD);
+            if (!SD.TooComplex) {
+                if (SD.Val == 0) {
+                    Error ("Modulo operation with zero");
+                    D->TooComplex = 1;
+                } else {
+                    D->Val += Sign * (SD.Left % SD.Val);
+                }
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_OR:
+            StudyBinaryExpr (Expr, &SD);
+            if (!SD.TooComplex) {
+                D->Val += Sign * (SD.Left | SD.Val);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_XOR:
+            StudyBinaryExpr (Expr, &SD);
+            if (!SD.TooComplex) {
+                D->Val += Sign * (SD.Left ^ SD.Val);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_AND:
+            StudyBinaryExpr (Expr, &SD);
+            if (!SD.TooComplex) {
+                D->Val += Sign * (SD.Left & SD.Val);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_SHL:
+            StudyBinaryExpr (Expr, &SD);
+            if (!SD.TooComplex) {
+                D->Val += (Sign * shl_l (SD.Left, (unsigned) SD.Val));
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_SHR:
+            StudyBinaryExpr (Expr, &SD);
+            if (!SD.TooComplex) {
+                D->Val += (Sign * shr_l (SD.Left, (unsigned) SD.Val));
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_EQ:
+            StudyBinaryExpr (Expr, &SD);
+            if (!SD.TooComplex) {
+                D->Val += Sign * (SD.Left == SD.Val);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_NE:
+            StudyBinaryExpr (Expr, &SD);
+            if (!SD.TooComplex) {
+                D->Val += Sign * (SD.Left != SD.Val);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_LT:
+            StudyBinaryExpr (Expr, &SD);
+            if (!SD.TooComplex) {
+                D->Val += Sign * (SD.Left < SD.Val);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_GT:
+            StudyBinaryExpr (Expr, &SD);
+            if (!SD.TooComplex) {
+                D->Val += Sign * (SD.Left > SD.Val);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_LE:
+            StudyBinaryExpr (Expr, &SD);
+            if (!SD.TooComplex) {
+                D->Val += Sign * (SD.Left <= SD.Val);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_GE:
+            StudyBinaryExpr (Expr, &SD);
+            if (!SD.TooComplex) {
+                D->Val += Sign * (SD.Left >= SD.Val);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_BOOLAND:
+            StudyExpr (Expr->Left, &SD, 1);
+            if (ExprDescIsConst (&SD)) {
+                if (SD.Val != 0) {   /* Shortcut op */
+                    SD.Val = 0;
+                    StudyExpr (Expr->Right, &SD, 1);
+                    if (ExprDescIsConst (&SD)) {
+                        D->Val += Sign * (SD.Val != 0);
+                    } else {
+                        D->TooComplex = 1;
+                    }
+                }
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_BOOLOR:
+            StudyExpr (Expr->Left, &SD, 1);
+            if (ExprDescIsConst (&SD)) {
+                if (SD.Val == 0) {   /* Shortcut op */
+                    StudyExpr (Expr->Right, &SD, 1);
+                    if (ExprDescIsConst (&SD)) {
+                        D->Val += Sign * (SD.Val != 0);
+                    } else {
+                        D->TooComplex = 1;
+                    }
+                } else {
+                    D->Val += Sign;
+                }
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_BOOLXOR:
+            StudyBinaryExpr (Expr, &SD);
+            if (!SD.TooComplex) {
+                D->Val += Sign * ((SD.Left != 0) ^ (SD.Val != 0));
+            }
+            break;
+
+        case EXPR_UNARY_MINUS:
+            StudyExpr (Expr->Left, D, -Sign);
+            break;
+
+        case EXPR_NOT:
+            StudyExpr (Expr->Left, &SD, 1);
+            if (ExprDescIsConst (&SD)) {
+                D->Val += (Sign * ~SD.Val);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_SWAP:
+            StudyExpr (Expr->Left, &SD, 1);
+            if (ExprDescIsConst (&SD)) {
+                D->Val += Sign * (((SD.Val >> 8) & 0x00FF) | ((SD.Val << 8) & 0xFF00));
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_BOOLNOT:
+            StudyExpr (Expr->Left, &SD, 1);
+            if (ExprDescIsConst (&SD)) {
+                D->Val += Sign * (SD.Val != 0);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_FORCEWORD:
+        case EXPR_FORCEFAR:
+            /* Ignore */
+            StudyExpr (Expr->Left, D, Sign);
+            break;
+
+        case EXPR_BYTE0:
+            StudyExpr (Expr->Left, &SD, 1);
+            if (ExprDescIsConst (&SD)) {
+                D->Val += Sign * (SD.Val & 0xFF);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_BYTE1:
+            StudyExpr (Expr->Left, &SD, 1);
+            if (ExprDescIsConst (&SD)) {
+                D->Val += Sign * ((SD.Val >> 8) & 0xFF);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_BYTE2:
+            StudyExpr (Expr->Left, &SD, 1);
+            if (ExprDescIsConst (&SD)) {
+                D->Val += Sign * ((SD.Val >> 16) & 0xFF);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_BYTE3:
+            StudyExpr (Expr->Left, &SD, 1);
+            if (ExprDescIsConst (&SD)) {
+                D->Val += Sign * ((SD.Val >> 24) & 0xFF);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_WORD0:
+            StudyExpr (Expr->Left, &SD, 1);
+            if (ExprDescIsConst (&SD)) {
+                D->Val += Sign * (SD.Val & 0xFFFF);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        case EXPR_WORD1:
+            StudyExpr (Expr->Left, &SD, 1);
+            if (ExprDescIsConst (&SD)) {
+                D->Val += Sign * ((SD.Val >> 16) & 0xFFFF);
+            } else {
+                D->TooComplex = 1;
+            }
+            break;
+
+        default:
+           Internal ("Unknown Op type: %u", Expr->Op);
+           break;
+    }
+}
+
+
+
+static ExprNode* SimplifyExpr (ExprNode* Expr)
 /* Try to simplify the given expression tree */
 {
-    if (Root) {
-               Root->Left  = SimplifyExpr (Root->Left);
-       Root->Right = SimplifyExpr (Root->Right);
-       if (IsConstExpr (Root)) {
-           /* The complete expression is constant */
-           Root->V.Val = GetExprVal (Root);
-           Root->Op = EXPR_LITERAL;
-           FreeExpr (Root->Left);
-           FreeExpr (Root->Right);
-           Root->Left = Root->Right = 0;
-               }
+    if (Expr && Expr->Op != EXPR_LITERAL) {
+
+        /* Create an expression description and initialize it */
+        ExprDesc D;
+        InitExprDesc (&D);
+
+        /* Study the expression */
+        StudyExpr (Expr, &D, 1);
+
+        /* Now check if we can generate a literal value */
+        if (ExprDescIsConst (&D)) {
+            /* No external references */
+            FreeExpr (Expr);
+            Expr = GenLiteralExpr (D.Val);
+        }
     }
-    return Root;
+    return Expr;
 }
 
 
@@ -833,7 +1291,16 @@ ExprNode* Expression (void)
  * a pointer to the root of the tree.
  */
 {
+#if 1
     return SimplifyExpr (Expr0 ());
+#else
+    /* Test code */
+    ExprNode* Expr = Expr0 ();
+    printf ("Before: "); DumpExpr (Expr, SymResolve);
+    Expr = SimplifyExpr (Expr);
+    printf ("After:  "); DumpExpr (Expr, SymResolve);
+    return Expr;
+#endif
 }
 
 
@@ -844,24 +1311,28 @@ long ConstExpression (void)
  * not constant.
  */
 {
-    long Val;
+#if 1
+    /* Read the expression */
+    ExprNode* Expr = Expr0 ();
+#else
+    /* Test code */
+    ExprNode* Expr = Expression ();
+#endif
 
-    /* Read the expression, and call finalize (exception here, since we
-     * expect a const).
-     */
-    ExprNode* Expr = FinalizeExpr (Expression ());
+    /* Study the expression */
+    ExprDesc D;
+    InitExprDesc (&D);
+    StudyExpr (Expr, &D, 1);
 
-    /* Get the value */
-    if (IsConstExpr (Expr)) {
-       Val = GetExprVal (Expr);
-    } else {
+    /* Check if the expression is constant */
+    if (!ExprDescIsConst (&D)) {
        Error ("Constant expression expected");
-       Val = 0;
+       D.Val = 0;
     }
 
     /* Free the expression tree and return the value */
     FreeExpr (Expr);
-    return Val;
+    return D.Val;
 }
 
 
@@ -951,7 +1422,7 @@ ExprNode* GenBranchExpr (unsigned Offs)
     if (RelocMode) {
        N = NewExprNode (EXPR_PLUS);
        N->Left  = GenSectionExpr (GetCurrentSegNum ());
-       N->Right = GenLiteralExpr (GetPC () + Offs);
+       N->Right = GenLiteralExpr (GetPC () + Offs);
     } else {
        N = GenLiteralExpr (GetPC () + Offs);
     }
@@ -1020,80 +1491,25 @@ ExprNode* GenNE (ExprNode* Expr, long Val)
 
 
 
-int IsConstExpr (ExprNode* Root)
+int IsConstExpr (ExprNode* Expr, long* Val)
 /* Return true if the given expression is a constant expression, that is, one
- * with no references to external symbols.
+ * with no references to external symbols. If Val is not NULL and the
+ * expression is constant, the constant value is stored here.
  */
 {
-    int Const;
-    SymEntry* Sym;
-
-    if (EXPR_IS_LEAF (Root->Op)) {
-       switch (Root->Op) {
-
-           case EXPR_LITERAL:
-               return 1;
-
-           case EXPR_SYMBOL:
-               Sym = Root->V.Sym;
-               if (SymHasUserMark (Sym)) {
-                   if (Verbosity > 0) {
-                       DumpExpr (Root);
-                   }
-                   PError (GetSymPos (Sym), "Circular reference in symbol definition");
-                   Const = 0;                
-               } else {
-                   SymMarkUser (Sym);
-                   Const = SymIsConst (Sym);
-                   SymUnmarkUser (Sym);
-               }
-               return Const;
-
-           default:
-               return 0;
-
-       }
-    } else if (EXPR_IS_UNARY (Root->Op)) {
-
-       return IsConstExpr (Root->Left);
-
+    /* Study the expression */
+    ExprDesc D;
+    InitExprDesc (&D);
+    StudyExpr (Expr, &D, 1);
+
+    /* Check if the expression is constant */
+    if (ExprDescIsConst (&D)) {
+        if (Val) {
+            *Val = D.Val;
+        }
+        return 1;
     } else {
-
-       /* We must handle shortcut boolean expressions here */
-       switch (Root->Op) {
-
-           case EXPR_BAND:
-               if (IsConstExpr (Root->Left)) {
-                   /* lhs is const, if it is zero, don't eval right */
-                   if (GetExprVal (Root->Left) == 0) {
-                       return 1;
-                   } else {
-                       return IsConstExpr (Root->Right);
-                   }
-               } else {
-                   /* lhs not const --> tree not const */
-                   return 0;
-               }
-               break;
-
-           case EXPR_BOR:
-               if (IsConstExpr (Root->Left)) {
-                   /* lhs is const, if it is not zero, don't eval right */
-                   if (GetExprVal (Root->Left) != 0) {
-                       return 1;
-                   } else {
-                       return IsConstExpr (Root->Right);
-                   }
-               } else {
-                   /* lhs not const --> tree not const */
-                   return 0;
-               }
-               break;
-
-           default:
-               /* All others are handled normal */
-               return IsConstExpr (Root->Left) && IsConstExpr (Root->Right);
-       }
+        return 0;
     }
 }
 
@@ -1105,7 +1521,7 @@ static void CheckByteExpr (const ExprNode* N, int* IsByte)
  */
 {
     if (N) {
-       switch (N->Op & EXPR_TYPEMASK) {
+       switch (N->Op & EXPR_TYPEMASK) {
 
            case EXPR_LEAFNODE:
                switch (N->Op) {
@@ -1149,12 +1565,10 @@ int IsByteExpr (ExprNode* Root)
 /* Return true if this is a byte expression */
 {
     int IsByte;
+    long Val;
 
-    if (IsConstExpr (Root)) {
-       if (Root->Op != EXPR_LITERAL) {
-           SimplifyExpr (Root);
-       }
-               return IsByteRange (GetExprVal (Root));
+    if (IsConstExpr (Root, &Val)) {
+               IsByte = IsByteRange (Val);
     } else if (Root->Op == EXPR_BYTE0 || Root->Op == EXPR_BYTE1 ||
               Root->Op == EXPR_BYTE2 || Root->Op == EXPR_BYTE3) {
        /* Symbol forced to have byte range */
@@ -1174,307 +1588,6 @@ int IsByteExpr (ExprNode* Root)
 
 
 
-long GetExprVal (ExprNode* Expr)
-/* Get the value of a constant expression */
-{
-    long Right, Left;
-
-    switch (Expr->Op) {
-
-               case EXPR_LITERAL:
-           return Expr->V.Val;
-
-               case EXPR_SYMBOL:
-           return GetSymVal (Expr->V.Sym);
-
-               case EXPR_PLUS:
-           return GetExprVal (Expr->Left) + GetExprVal (Expr->Right);
-
-               case EXPR_MINUS:
-           return GetExprVal (Expr->Left) - GetExprVal (Expr->Right);
-
-               case EXPR_MUL:
-           return GetExprVal (Expr->Left) * GetExprVal (Expr->Right);
-
-               case EXPR_DIV:
-           Left  = GetExprVal (Expr->Left);
-           Right = GetExprVal (Expr->Right);
-           if (Right == 0) {
-               Error ("Division by zero");
-               return 0;
-           }
-           return Left / Right;
-
-               case EXPR_MOD:
-           Left  = GetExprVal (Expr->Left);
-           Right = GetExprVal (Expr->Right);
-           if (Right == 0) {
-               Error ("Modulo operation with zero");
-               return 0;
-           }
-           return Left % Right;
-
-               case EXPR_OR:
-                   return GetExprVal (Expr->Left) | GetExprVal (Expr->Right);
-
-               case EXPR_XOR:
-                   return GetExprVal (Expr->Left) ^ GetExprVal (Expr->Right);
-
-               case EXPR_AND:
-                   return GetExprVal (Expr->Left) & GetExprVal (Expr->Right);
-
-               case EXPR_SHL:
-                   return GetExprVal (Expr->Left) << GetExprVal (Expr->Right);
-
-               case EXPR_SHR:
-                   return GetExprVal (Expr->Left) >> GetExprVal (Expr->Right);
-
-               case EXPR_EQ:
-                   return (GetExprVal (Expr->Left) == GetExprVal (Expr->Right));
-
-               case EXPR_NE:
-                   return (GetExprVal (Expr->Left) != GetExprVal (Expr->Right));
-
-               case EXPR_LT:
-           return (GetExprVal (Expr->Left) < GetExprVal (Expr->Right));
-
-               case EXPR_GT:
-           return (GetExprVal (Expr->Left) > GetExprVal (Expr->Right));
-
-               case EXPR_LE:
-           return (GetExprVal (Expr->Left) <= GetExprVal (Expr->Right));
-
-               case EXPR_GE:
-           return (GetExprVal (Expr->Left) >= GetExprVal (Expr->Right));
-
-               case EXPR_UNARY_MINUS:
-           return -GetExprVal (Expr->Left);
-
-               case EXPR_NOT:
-           return ~GetExprVal (Expr->Left);
-
-               case EXPR_BYTE0:
-           return GetExprVal (Expr->Left) & 0xFF;
-
-               case EXPR_BYTE1:
-           return (GetExprVal (Expr->Left) >> 8) & 0xFF;
-
-               case EXPR_BYTE2:
-           return (GetExprVal (Expr->Left) >> 16) & 0xFF;
-
-               case EXPR_BYTE3:
-           return (GetExprVal (Expr->Left) >> 24) & 0xFF;
-
-        case EXPR_SWAP:
-           Left = GetExprVal (Expr->Left);
-           return ((Left >> 8) & 0x00FF) | ((Left << 8) & 0xFF00);
-
-       case EXPR_BAND:
-           return GetExprVal (Expr->Left) && GetExprVal (Expr->Right);
-
-       case EXPR_BOR:
-           return GetExprVal (Expr->Left) || GetExprVal (Expr->Right);
-
-       case EXPR_BXOR:
-           return (GetExprVal (Expr->Left) != 0) ^ (GetExprVal (Expr->Right) != 0);
-
-       case EXPR_BNOT:
-                   return !GetExprVal (Expr->Left);
-
-       case EXPR_ULABEL:
-           Internal ("GetExprVal called for EXPR_ULABEL");
-           /* NOTREACHED */
-           return 0;
-
-        default:
-           Internal ("Unknown Op type: %u", Expr->Op);
-           /* NOTREACHED */
-           return 0;
-    }
-}
-
-
-
-static ExprNode* RemoveSyms (ExprNode* Expr, int MustClone)
-/* Remove resolved symbols from the tree by cloning symbol expressions */
-{
-    /* Accept NULL pointers */
-    if (Expr == 0) {
-       return 0;
-    }
-
-    /* Special node handling */
-    switch (Expr->Op) {
-
-       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 (Verbosity) {
-                       DumpExpr (Expr);
-                   }
-                   PError (GetSymPos (Sym), "Circular reference in symbol definition");
-                   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 GenLiteralExpr (GetSymVal (Expr->V.Sym));
-           }
-           break;
-
-       case EXPR_ULABEL:
-           if (ULabCanResolve ()) {
-               ExprNode* NewExpr = ULabResolve (Expr->V.Val);
-               FreeExpr (Expr);
-               Expr = NewExpr;
-           }
-           break;
-
-    }
-
-    /* Clone the current node if needed */
-    if (MustClone) {
-
-               ExprNode* Clone;
-
-       /* Clone the expression tree */
-       switch (Expr->Op) {
-
-           case EXPR_LITERAL:
-                Clone = GenLiteralExpr (Expr->V.Val);
-                break;
-
-           case EXPR_ULABEL:
-                Clone = GenULabelExpr (Expr->V.Val);
-                break;
-
-           case EXPR_SYMBOL:
-                Clone = GenSymExpr (Expr->V.Sym);
-                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;
-
-       }
-
-       /* Done */
-       return Clone;
-
-    } else {
-
-       /* Nothing to clone */
-               Expr->Left  = RemoveSyms (Expr->Left, 0);
-       Expr->Right = RemoveSyms (Expr->Right, 0);
-
-       /* Done */
-       return Expr;
-    }
-}
-
-
-
-static ExprNode* ConstExtract (ExprNode* Expr, long* Val, int Sign)
-/* Extract and evaluate all constant factors in an subtree that has only
- * additions and subtractions.
- */
-{
-    if (Expr->Op == EXPR_LITERAL) {
-       if (Sign < 0) {
-           *Val -= Expr->V.Val;
-       } else {
-           *Val += Expr->V.Val;
-       }
-               FreeExprNode (Expr);
-       return 0;
-    }
-
-    if (Expr->Op == EXPR_PLUS || Expr->Op == EXPR_MINUS) {
-       ExprNode* Left;
-       ExprNode* Right;
-       Left = ConstExtract (Expr->Left, Val, Sign);
-       if (Expr->Op == EXPR_MINUS) {
-           Sign = -Sign;
-       }
-       Right = ConstExtract (Expr->Right, Val, Sign);
-       if (Left == 0 && Right == 0) {
-           FreeExprNode (Expr);
-           return 0;
-       } else if (Left == 0) {
-           FreeExprNode (Expr);
-           return Right;
-       } else if (Right == 0) {
-           FreeExprNode (Expr);
-           return Left;
-       } else {
-           /* Check for SEG - SEG which is now possible */
-           if (Left->Op == EXPR_SECTION && Right->Op == EXPR_SECTION &&
-               Left->V.SegNum == Right->V.SegNum) {
-               /* SEG - SEG, remove it completely */
-               FreeExprNode (Left);
-               FreeExprNode (Right);
-               FreeExprNode (Expr);
-               return 0;
-           } else {
-               Expr->Left  = Left;
-               Expr->Right = Right;
-               return Expr;
-           }
-       }
-    }
-
-    /* Some other sort of node, finalize the terms */
-    if (Expr->Left) {
-       Expr->Left = FinalizeExpr (Expr->Left);
-    }
-    if (Expr->Right) {
-       Expr->Right = FinalizeExpr (Expr->Right);
-    }
-
-    return Expr;
-}
-
-
-
-ExprNode* FinalizeExpr (ExprNode* Expr)
-/* Resolve any symbols by cloning the symbol expression tree instead of the
- * symbol reference, then try to simplify the expression as much as possible.
- * This function must only be called if all symbols are resolved (no undefined
- * symbol errors).
- */
-{
-    long Val = 0;
-    ExprNode* N;
-
-    Expr = RemoveSyms (Expr, 0);
-    Expr = ConstExtract (Expr, &Val, 1);
-    if (Expr == 0) {
-       /* Reduced to a literal value */
-       Expr = GenLiteralExpr (Val);
-    } else if (Val) {
-       /* Extracted a value */
-       N = NewExprNode (EXPR_PLUS);
-       N->Left = Expr;
-       N->Right = GenLiteralExpr (Val);
-       Expr = N;
-    }
-    return Expr;
-}
-
-
-
 ExprNode* CloneExpr (ExprNode* Expr)
 /* Clone the given expression tree. The function will simply clone symbol
  * nodes, it will not resolve them.
@@ -1526,38 +1639,41 @@ void WriteExpr (ExprNode* Expr)
 {
     /* Null expressions are encoded by a type byte of zero */
     if (Expr == 0) {
-       ObjWrite8 (0);
+       ObjWrite8 (EXPR_NULL);
        return;
     }
 
-    /* Write the expression code */
-    ObjWrite8 (Expr->Op);
-
     /* If the is a leafnode, write the expression attribute, otherwise
      * write the expression operands.
      */
     switch (Expr->Op) {
 
         case EXPR_LITERAL:
+            ObjWrite8 (EXPR_LITERAL);
            ObjWrite32 (Expr->V.Val);
            break;
 
         case EXPR_SYMBOL:
-           /* Maybe we should use a code here? */
-           CHECK (SymIsImport (Expr->V.Sym));  /* Safety */
-           ObjWriteVar (GetSymIndex (Expr->V.Sym));
+           if (SymIsImport (Expr->V.Sym)) {
+                ObjWrite8 (EXPR_SYMBOL);
+                ObjWriteVar (GetSymIndex (Expr->V.Sym));
+            } else {
+                WriteExpr (GetSymExpr (Expr->V.Sym));
+            }
            break;
 
         case EXPR_SECTION:
+            ObjWrite8 (EXPR_SECTION);
            ObjWrite8 (Expr->V.SegNum);
            break;
 
        case EXPR_ULABEL:
-           Internal ("WriteExpr: Cannot write EXPR_ULABEL nodes");
+            WriteExpr (ULabResolve (Expr->V.Val));
            break;
 
         default:
            /* Not a leaf node */
+            ObjWrite8 (Expr->Op);
            WriteExpr (Expr->Left);
            WriteExpr (Expr->Right);
            break;
index b08dd39ed9a6805be06f9eedcae405d64226c8c7..2edff0e1d117a4b1a1f24ee497e11bea53b7ab53 100644 (file)
@@ -7,7 +7,7 @@
 /*                                                                           */
 /*                                                                           */
 /* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
+/*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -92,30 +92,21 @@ ExprNode* GenWordExpr (ExprNode* Expr);
 ExprNode* GenNE (ExprNode* Expr, long Val);
 /* Generate an expression that compares Expr and Val for inequality */
 
-int IsConstExpr (ExprNode* Root);
+int IsConstExpr (ExprNode* Expr, long* Val);
 /* Return true if the given expression is a constant expression, that is, one
- * with no references to external symbols.
+ * with no references to external symbols. If Val is not NULL and the
+ * expression is constant, the constant value is stored here.
  */
 
 int IsByteExpr (ExprNode* Root);
 /* Return true if this is a byte expression */
 
-long GetExprVal (ExprNode* Expr);
-/* Get the value of a constant expression */
-
 int IsByteRange (long Val);
 /* Return true if this is a byte value */
 
 int IsWordRange (long Val);
 /* Return true if this is a word value */
 
-ExprNode* FinalizeExpr (ExprNode* Expr);
-/* Resolve any symbols by cloning the symbol expression tree instead of the
- * symbol reference, then try to simplify the expression as much as possible.
- * This function must only be called if all symbols are resolved (no undefined
- * symbol errors).
- */
-
 ExprNode* CloneExpr (ExprNode* Expr);
 /* Clone the given expression tree. The function will simply clone symbol
  * nodes, it will not resolve them.
index 784c523113d349cea750822927d9ce93ca903541..f5dfff89b79b2672e2affe161736fe7b6ae0477f 100644 (file)
@@ -673,8 +673,8 @@ static long PutImmed8 (const InsDesc* Ins)
     }
 
     /* If we have an expression and it's const, get it's value */
-    if (A.Expr && IsConstExpr (A.Expr)) {
-       Val = GetExprVal (A.Expr);
+    if (A.Expr) {
+        (void) IsConstExpr (A.Expr, &Val);
     }
 
     /* Check how many extension bytes are needed and output the instruction */
index 9a2225b6914e73adf662e588947e9053e6b9bbab..890b52ceede625370fc0cd0a1e162df72ec24c8c 100644 (file)
@@ -144,10 +144,10 @@ void EmitData (const unsigned char* Data, unsigned Size)
 
 void EmitByte (ExprNode* Expr)
 /* Emit one byte */
-{
-    if (IsConstExpr (Expr)) {
+{                  
+    long Val;
+    if (IsConstExpr (Expr, &Val)) {
        /* Constant expression, emit literal byte */
-       long Val = GetExprVal (Expr);
        FreeExpr (Expr);
        if ((Val & ~0xFF) != 0) {
            Error ("Range error");
@@ -167,9 +167,9 @@ void EmitByte (ExprNode* Expr)
 void EmitWord (ExprNode* Expr)
 /* Emit one word */
 {
-    if (IsConstExpr (Expr)) {
+    long Val;
+    if (IsConstExpr (Expr, &Val)) {
        /* Constant expression, emit literal byte */
-       long Val = GetExprVal (Expr);
        FreeExpr (Expr);
                if ((Val & ~0xFFFF) != 0) {
            Error ("Range error");
@@ -190,9 +190,9 @@ void EmitWord (ExprNode* Expr)
 void EmitFarAddr (ExprNode* Expr)
 /* Emit a 24 bit expression */
 {
-    if (IsConstExpr (Expr)) {
+    long Val;
+    if (IsConstExpr (Expr, &Val)) {
        /* Constant expression, emit literal byte */
-       long Val = GetExprVal (Expr);
        FreeExpr (Expr);
                if ((Val & ~0xFFFFFF) != 0) {
            Error ("Range error");
@@ -214,9 +214,9 @@ void EmitFarAddr (ExprNode* Expr)
 void EmitDWord (ExprNode* Expr)
 /* Emit one dword */
 {
-    if (IsConstExpr (Expr)) {
+    long Val;
+    if (IsConstExpr (Expr, &Val)) {
        /* Constant expression, emit literal byte */
-       long Val = GetExprVal (Expr);
        FreeExpr (Expr);
        Emit0 (Val & 0xFF);
        Emit0 ((Val >> 8) & 0xFF);
index 8bc847decd741dc39ed165f7fa72b1d3cc7acf75..b1a3b522d2fe2952df45dcf125b951bbccbff3a2 100644 (file)
@@ -122,7 +122,7 @@ struct DotKeyword {
     { ".A8",                   TOK_A8          },
     { ".ADDR",                 TOK_ADDR        },
     { ".ALIGN",                TOK_ALIGN       },
-    { ".AND",          TOK_BAND        },
+    { ".AND",          TOK_BOOLAND     },
     { ".ASCIIZ",               TOK_ASCIIZ      },
     { ".ASSERT",        TOK_ASSERT      },
     { ".AUTOIMPORT",   TOK_AUTOIMPORT  },
@@ -206,9 +206,9 @@ struct DotKeyword {
     { ".MATCH",                TOK_MATCH       },
     { ".MID",          TOK_MID         },
     { ".MOD",          TOK_MOD         },
-    { ".NOT",          TOK_BNOT        },
+    { ".NOT",          TOK_BOOLNOT     },
     { ".NULL",         TOK_NULL        },
-    { ".OR",           TOK_BOR         },
+    { ".OR",           TOK_BOOLOR      },
     { ".ORG",                  TOK_ORG         },
     { ".OUT",                  TOK_OUT         },
     { ".P02",                  TOK_P02         },
@@ -247,7 +247,7 @@ struct DotKeyword {
     { ".WARNING",      TOK_WARNING     },
     { ".WORD",                 TOK_WORD        },
     { ".XMATCH",       TOK_XMATCH      },
-    { ".XOR",                  TOK_BXOR        },
+    { ".XOR",                  TOK_BOOLXOR     },
     { ".ZEROPAGE",     TOK_ZEROPAGE    },
 };
 
@@ -875,7 +875,7 @@ CharAgain:
            NextChar ();
            if (C == '&') {
                NextChar ();
-               Tok = TOK_BAND;
+               Tok = TOK_BOOLAND;
            } else {
                Tok = TOK_AND;
            }
@@ -885,7 +885,7 @@ CharAgain:
            NextChar ();
            if (C == '|') {
                NextChar ();
-               Tok = TOK_BOR;
+               Tok = TOK_BOOLOR;
            } else {
                Tok = TOK_OR;
            }
@@ -989,7 +989,7 @@ CharAgain:
 
        case '!':
            NextChar ();
-           Tok = TOK_BNOT;
+           Tok = TOK_BOOLNOT;
            return;
 
        case '>':
index ecaf01e10aa663fbc3a680d43fd9355bdb6742e6..38a2b2d95c50a2ff6935658c0a42e681e28010b5 100644 (file)
@@ -77,10 +77,10 @@ enum Token {
     TOK_LE,            /* <= */
     TOK_GE,            /* >= */
 
-    TOK_BAND,                  /* .and */
-    TOK_BOR,           /* .or */
-    TOK_BXOR,                  /* .xor */
-    TOK_BNOT,          /* .not */
+    TOK_BOOLAND,               /* .and */
+    TOK_BOOLOR,                /* .or */
+    TOK_BOOLXOR,       /* .xor */
+    TOK_BOOLNOT,       /* .not */
 
     TOK_PLUS,          /* + */
     TOK_MINUS,         /* - */
@@ -90,6 +90,7 @@ enum Token {
     TOK_MOD,           /* ! */
     TOK_OR,            /* | */
     TOK_XOR,           /* ^ */
+    TOK_BANK = TOK_XOR, /* Alias */
     TOK_AND,           /* & */
     TOK_SHL,           /* << */
     TOK_SHR,           /* >> */
@@ -192,7 +193,7 @@ enum Token {
     TOK_MID,
     TOK_NULL,
     TOK_ORG,
-    TOK_OUT,     
+    TOK_OUT,
     TOK_P02,
     TOK_P816,
     TOK_PAGELENGTH,
index 6642eb5bf55e4ca260e807b63115077cd0829a8f..b1ea4da56c2fa7b9a3143a7b31034e333a6dae98 100644 (file)
@@ -290,13 +290,12 @@ void SegCheck (void)
        Fragment* F = S->Root;
        while (F) {
                    if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
-                       F->V.Expr = FinalizeExpr (F->V.Expr);
-                       if (IsConstExpr (F->V.Expr)) {
-                   /* We are able to evaluate the expression. Get the value
-                    * and check for range errors.
+                long Val;
+                       if (IsConstExpr (F->V.Expr, &Val)) {
+                   /* We are able to evaluate the expression. Check for
+                    * range errors.
                     */
                    unsigned I;
-                   long Val = GetExprVal (F->V.Expr);
                    int Abs = (F->Type != FRAG_SEXPR);
 
                    if (F->Len == 1) {
@@ -317,36 +316,36 @@ void SegCheck (void)
                            if (Val > 65535) {
                                PError (&F->Pos, "Range error");
                            }
-                       } else {
-                           /* PC relative value */
-                           if (Val < -32768 || Val > 32767) {
-                               PError (&F->Pos, "Range error");
-                           }
-                       }
-                   }
+                       } else {
+                           /* PC relative value */
+                           if (Val < -32768 || Val > 32767) {
+                               PError (&F->Pos, "Range error");
+                           }
+                       }
+                   }
 
                     /* We don't need the expression tree any longer */
                     FreeExpr (F->V.Expr);
 
-                   /* Convert the fragment into a literal fragment */
-                   for (I = 0; I < F->Len; ++I) {
-                       F->V.Data [I] = Val & 0xFF;
-                       Val >>= 8;
+                   /* Convert the fragment into a literal fragment */
+                   for (I = 0; I < F->Len; ++I) {
+                       F->V.Data [I] = Val & 0xFF;
+                       Val >>= 8;
                    }
-                   F->Type = FRAG_LITERAL;
-               } else {
-                   /* We cannot evaluate the expression now, leave the job for
-                    * the linker. However, we are able to check for explicit
-                    * byte expressions and we will do so.
-                    */
-                   if (F->Type == FRAG_EXPR && F->Len == 1 && !IsByteExpr (F->V.Expr)) {
-                       PError (&F->Pos, "Range error");
-                   }
-               }
-           }
-           F = F->Next;
-       }
-       S = S->List;
+                   F->Type = FRAG_LITERAL;
+               } else {
+                   /* We cannot evaluate the expression now, leave the job for
+                    * the linker. However, we are able to check for explicit
+                    * byte expressions and we will do so.
+                    */
+                   if (F->Type == FRAG_EXPR && F->Len == 1 && !IsByteExpr (F->V.Expr)) {
+                       PError (&F->Pos, "Range error");
+                   }
+               }
+           }
+           F = F->Next;
+       }
+       S = S->List;
     }
 }
 
@@ -378,7 +377,7 @@ void SegDump (void)
            } else if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
                        State = 1;
                printf ("\n  Expression (%u): ", F->Len);
-               DumpExpr (F->V.Expr);
+               DumpExpr (F->V.Expr, SymResolve);
            } else if (F->Type == FRAG_FILL) {
                State = 1;
                printf ("\n  Fill bytes (%u)", F->Len);
index 9fe7f154fcd59c82930f389c74191cebba4b278e..2c1600760c16fbec4b9bf5d94d53639680fbae16 100644 (file)
@@ -7,7 +7,7 @@
 /*                                                                           */
 /*                                                                           */
 /* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
+/*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -160,15 +160,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned AddrSize, unsigned Flags)
     }
 
     /* Set the symbol value */
-    if (IsConstExpr (Expr)) {
-               /* Expression is const, store the value */
-               S->Flags |= SF_CONST;
-               S->V.Val = GetExprVal (Expr);
-               FreeExpr (Expr);
-    } else {
-               /* Not const, store the expression */
-        S->V.Expr  = Expr;
-    }
+    S->V.Expr  = Expr;
 
     /* If the symbol is marked as global, export it */
     if (S->Flags & SF_GLOBAL) {
@@ -182,7 +174,10 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned AddrSize, unsigned Flags)
 
     /* If the symbol is exported, check the address sizes */
     if (S->Flags & SF_EXPORT) {
-        if (S->AddrSize > S->ExportSize) {
+        if (S->ExportSize == ADDR_SIZE_DEFAULT) {
+            /* Use the real size of the symbol */
+            S->ExportSize = S->AddrSize;
+        } else if (S->AddrSize > S->ExportSize) {
             Warning (1, "Address size mismatch for symbol `%s'", GetSymName (S));
         }
     }
@@ -262,11 +257,6 @@ void SymExport (SymEntry* S, unsigned AddrSize, unsigned Flags)
        return;
     }
 
-    /* Map a default address size to a real value */
-    if (AddrSize == ADDR_SIZE_DEFAULT) {
-        AddrSize = SymAddrSize (S);
-    }
-
     /* If the symbol was already marked as an export or global, check if
      * this was done specifiying the same address size. In case of a global
      * declaration, silently remove the global flag.
@@ -283,7 +273,10 @@ void SymExport (SymEntry* S, unsigned AddrSize, unsigned Flags)
      * exported size.
      */
     if (S->Flags & SF_DEFINED) {
-        if (S->AddrSize > S->ExportSize) {
+        if (S->ExportSize == ADDR_SIZE_DEFAULT) {
+            /* Use the real size of the symbol */
+            S->ExportSize = S->AddrSize;
+        } else if (S->AddrSize > S->ExportSize) {
             Warning (1, "Address size mismatch for symbol `%s'", GetSymName (S));
         }
     }
@@ -374,35 +367,32 @@ int SymIsImport (const SymEntry* S)
 
 
 
-int SymHasExpr (const SymEntry* S)
-/* Return true if the given symbol has an associated expression */
+int SymIsConst (SymEntry* S, long* Val)
+/* Return true if the given symbol has a constant value. If Val is not NULL
+ * and the symbol has a constant value, store it's value there.
+ */
 {
     /* Resolve trampoline entries */
     if (S->Flags & SF_TRAMPOLINE) {
-       S = S->V.Sym;
+       S = S->V.Sym;
     }
 
-    /* Check the expression */
-    return ((S->Flags & SF_DEFINED) != 0 &&
-                   (S->Flags & SF_IMPORT)  == 0 &&
-                   (S->Flags & SF_CONST)   == 0);
+    /* Check for constness */
+    return (SymHasExpr (S) && IsConstExpr (S->V.Expr, Val));
 }
 
 
 
-void SymFinalize (SymEntry* S)
-/* Finalize a symbol expression if there is one */
+int SymHasExpr (const SymEntry* S)
+/* Return true if the given symbol has an associated expression */
 {
     /* Resolve trampoline entries */
     if (S->Flags & SF_TRAMPOLINE) {
-               S = S->V.Sym;
+       S = S->V.Sym;
     }
 
-    /* Check if we have an expression */
-    if ((S->Flags & SF_FINALIZED) == 0 && SymHasExpr (S)) {
-               S->V.Expr = FinalizeExpr (S->V.Expr);
-        S->Flags |= SF_FINALIZED;
-    }
+    /* Check the expression */
+    return ((S->Flags & (SF_DEFINED|SF_IMPORT)) == SF_DEFINED);
 }
 
 
@@ -449,30 +439,31 @@ int SymHasUserMark (SymEntry* S)
 
 
 
-long GetSymVal (SymEntry* S)
-/* Return the symbol value */
+struct ExprNode* GetSymExpr (SymEntry* S)
+/* Get the expression for a non-const symbol */
 {
     /* Resolve trampoline entries */
     if (S->Flags & SF_TRAMPOLINE) {
        S = S->V.Sym;
     }
 
-    PRECONDITION ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_CONST) != 0);
-    return S->V.Val;
+    PRECONDITION (S != 0 && SymHasExpr (S));
+    return S->V.Expr;
 }
 
 
 
-struct ExprNode* GetSymExpr (SymEntry* S)
-/* Get the expression for a non-const symbol */
+const struct ExprNode* SymResolve (const SymEntry* S)
+/* Helper function for DumpExpr. Resolves a symbol into an expression or return
+ * NULL. Do not call in other contexts!
+ */
 {
     /* Resolve trampoline entries */
     if (S->Flags & SF_TRAMPOLINE) {
        S = S->V.Sym;
     }
 
-    PRECONDITION (S != 0 && (S->Flags & SF_CONST) == 0);
-    return S->V.Expr;
+    return SymHasExpr (S)? S->V.Expr : 0;
 }
 
 
@@ -496,7 +487,7 @@ unsigned GetSymIndex (SymEntry* S)
     if (S->Flags & SF_TRAMPOLINE) {
        S = S->V.Sym;
     }
-    PRECONDITION (S != 0 && (S->Flags & SF_INDEXED));
+    PRECONDITION (S != 0 && (S->Flags & SF_INDEXED) != 0);
     return S->Index;
 }
 
index 80289058ad137be86c8ed89c02556e60dd160e2a..11584a881634de1f7185521a4bee7e8381f7a50d 100644 (file)
@@ -7,7 +7,7 @@
 /*                                                                           */
 /*                                                                           */
 /* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
+/*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -60,9 +60,7 @@
 #define SF_GLOBAL      0x0010          /* Global symbol */
 #define SF_LABEL        0x0080          /* Used as a label */
 #define SF_FORCED       0x0100          /* Forced import, SF_IMPORT also set */
-#define SF_FINALIZED    0x0200          /* Symbol is finalized */
 #define SF_INDEXED     0x0800          /* Index is valid */
-#define SF_CONST       0x1000          /* The symbol has a constant value */
 #define SF_MULTDEF             0x2000          /* Multiply defined symbol */
 #define        SF_DEFINED      0x4000          /* Defined */
 #define SF_REFERENCED  0x8000          /* Referenced */
@@ -164,12 +162,14 @@ int SymIsRef (const SymEntry* Sym);
 int SymIsImport (const SymEntry* Sym);
 /* Return true if the given symbol is marked as import */
 
+int SymIsConst (SymEntry* Sym, long* Val);
+/* Return true if the given symbol has a constant value. If Val is not NULL
+ * and the symbol has a constant value, store it's value there.
+ */
+
 int SymHasExpr (const SymEntry* Sym);
 /* Return true if the given symbol has an associated expression */
 
-void SymFinalize (SymEntry* S);
-/* Finalize a symbol expression if there is one */
-
 void SymMarkUser (SymEntry* Sym);
 /* Set a user mark on the specified symbol */
 
@@ -179,12 +179,14 @@ void SymUnmarkUser (SymEntry* Sym);
 int SymHasUserMark (SymEntry* Sym);
 /* Return the state of the user mark for the specified symbol */
 
-long GetSymVal (SymEntry* Sym);
-/* Return the symbol value */
-
 struct ExprNode* GetSymExpr (SymEntry* Sym);
 /* Get the expression for a non-const symbol */
 
+const struct ExprNode* SymResolve (const SymEntry* Sym);
+/* Helper function for DumpExpr. Resolves a symbol into an expression or return
+ * NULL. Do not call in other contexts!
+ */
+
 const char* GetSymName (SymEntry* Sym);
 /* Return the name of the symbol */
 
index f6055591e40ba683f41789f489f61a99f67e8c5a..6af89a97eece65ed8f8c97ed7d79ebdb09d50d67 100644 (file)
@@ -434,30 +434,6 @@ void SymConDes (const char* Name, unsigned Type, unsigned Prio)
 
 
 
-int SymIsConst (SymEntry* S)
-/* Return true if the given symbol has a constant value */
-{
-    /* Resolve trampoline entries */
-    if (S->Flags & SF_TRAMPOLINE) {
-       S = S->V.Sym;
-    }
-
-    /* Check for constness */
-    if (S->Flags & SF_CONST) {
-       return 1;
-    } else if ((S->Flags & SF_DEFINED) && IsConstExpr (S->V.Expr)) {
-       /* Constant expression, remember the value */
-       ExprNode* Expr = S->V.Expr;
-               S->Flags |= SF_CONST;
-       S->V.Val = GetExprVal (Expr);
-       FreeExpr (Expr);
-       return 1;
-    }
-    return 0;
-}
-
-
-
 int SymIsZP (SymEntry* S)
 /* Return true if the symbol is explicitly marked as zeropage symbol */
 {
@@ -705,26 +681,6 @@ void WriteImports (void)
 
 
 
-static unsigned char GetExportExprMask (SymEntry* S)
-/* Return the expression bits for the given symbol table entry */
-{
-    unsigned char ExprMask;
-
-    /* Check if the symbol is const */
-    ExprMask = (SymIsConst (S))? EXP_CONST : EXP_EXPR;
-
-    /* Add zeropage/abs bits */
-    ExprMask |= (S->ExportSize == ADDR_SIZE_ZP)? EXP_ZP : EXP_ABS;
-
-    /* Add the label/equate bits */
-    ExprMask |= (S->Flags & SF_LABEL)? EXP_LABEL : EXP_EQUATE;
-
-    /* Return the mask */
-    return ExprMask;
-}
-
-
-
 void WriteExports (void)
 /* Write the exports list to the object file */
 {
@@ -741,13 +697,13 @@ void WriteExports (void)
     S = SymList;
     while (S) {
                if ((S->Flags & SF_EXPMASK) == SF_EXPVAL) {
-                   unsigned char ExprMask;
 
-           /* Finalize an associated expression if we have one */
-           SymFinalize (S);
+            long ConstVal;
 
            /* Get the expression bits */
-           ExprMask = GetExportExprMask (S);
+            unsigned char ExprMask = SymIsConst (S, &ConstVal)? EXP_CONST : EXP_EXPR;
+            ExprMask |= (S->ExportSize == ADDR_SIZE_ZP)? EXP_ZP : EXP_ABS;
+            ExprMask |= (S->Flags & SF_LABEL)? EXP_LABEL : EXP_EQUATE;
 
            /* Count the number of ConDes types */
            for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
@@ -775,7 +731,7 @@ void WriteExports (void)
            /* Write the value */
            if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) {
                /* Constant value */
-               ObjWrite32 (S->V.Val);
+               ObjWrite32 (ConstVal);
            } else {
                /* Expression involved */
                WriteExpr (S->V.Expr);
@@ -793,26 +749,6 @@ void WriteExports (void)
 
 
 
-static unsigned char GetDbgExprMask (SymEntry* S)
-/* Return the expression bits for the given symbol table entry */
-{
-    unsigned char ExprMask;
-
-    /* Check if the symbol is const */
-    ExprMask = (SymIsConst (S))? EXP_CONST : EXP_EXPR;
-
-    /* Add zeropage/abs bits */
-    ExprMask |= (S->AddrSize == ADDR_SIZE_ZP)? EXP_ZP : EXP_ABS;
-
-    /* Add the label/equate bits */
-    ExprMask |= (S->Flags & SF_LABEL)? EXP_LABEL : EXP_EQUATE;
-
-    /* Return the mask */
-    return ExprMask;
-}
-
-
-
 void WriteDbgSyms (void)
 /* Write a list of all symbols to the object file */
 {
@@ -842,13 +778,13 @@ void WriteDbgSyms (void)
        S = SymList;
        while (S) {
            if ((S->Flags & SF_DBGINFOMASK) == SF_DBGINFOVAL) {
-               unsigned char ExprMask;
 
-               /* Finalize an associated expression if we have one */
-               SymFinalize (S);
+                long ConstVal;
 
                /* Get the expression bits */
-                       ExprMask = GetDbgExprMask (S);
+                unsigned char ExprMask = (SymIsConst (S, &ConstVal))? EXP_CONST : EXP_EXPR;
+                ExprMask |= (S->AddrSize == ADDR_SIZE_ZP)? EXP_ZP : EXP_ABS;
+                ExprMask |= (S->Flags & SF_LABEL)? EXP_LABEL : EXP_EQUATE;
 
                /* Write the type */
                ObjWrite8 (ExprMask);
@@ -859,7 +795,7 @@ void WriteDbgSyms (void)
                /* Write the value */
                if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) {
                    /* Constant value */
-                   ObjWrite32 (S->V.Val);
+                   ObjWrite32 (ConstVal);
                } else {
                    /* Expression involved */
                    WriteExpr (S->V.Expr);
@@ -885,3 +821,4 @@ void WriteDbgSyms (void)
 
 
 
+                                 
index 7debe5be005b87e3af2572d3fe0c6eff0da879ea..fc28def444fb176b7737d7efbe67adb7831addd8 100644 (file)
@@ -7,7 +7,7 @@
 /*                                                                           */
 /*                                                                           */
 /* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
+/*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -54,7 +54,7 @@
 
 
 
-/* Symbol table flags */                                        
+/* Symbol table flags */
 #define ST_NONE         0x00            /* No flags */
 #define ST_DEFINED      0x01            /* Scope has been defined */
 
@@ -107,9 +107,6 @@ void SymConDes (const char* Name, unsigned Type, unsigned Prio);
  * mark the symbol as an export. Initializers may never be zero page symbols.
  */
 
-int SymIsConst (SymEntry* Sym);
-/* Return true if the given symbol has a constant value */
-
 int SymIsZP (SymEntry* Sym);
 /* Return true if the symbol is explicitly marked as zeropage symbol */