]> git.sur5r.net Git - cc65/commitdiff
Working on initializers
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 30 Oct 2000 20:48:11 +0000 (20:48 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 30 Oct 2000 20:48:11 +0000 (20:48 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@411 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ca65/error.c
src/ca65/pseudo.c
src/ca65/symtab.c
src/ca65/symtab.h
src/common/symdefs.h
src/ld65/dbgsyms.c
src/ld65/exports.c
src/od65/dump.c

index 1c46630053a19b541f10be36aa85c19d2731f353..358be913f6e385dca3503fe093cfa4a340e11961 100644 (file)
@@ -163,8 +163,8 @@ void ErrorMsg (const FilePos* Pos, unsigned ErrNum, va_list ap)
        "Syntax error",
        "Symbol `%s' is already defined",
        "Undefined symbol `%s'",
-       "Symbol `%s' is marked as import",
-        "Symbol `%s' is marked as export",
+       "Symbol `%s' is already marked as import",
+        "Symbol `%s' is already marked as export",
        "Exported symbol `%s' is undefined",
        "Exported values must be constant",
        ".IF nesting too deep",
index d93976101d2c7c8f96d670aa9a32e6708b5a3611..9373ec01b73d22de41be384c99c065afa12b1da9 100644 (file)
@@ -42,6 +42,7 @@
 /* common */
 #include "bitops.h"
 #include "check.h"
+#include "symdefs.h"
 #include "tgttrans.h"
 
 /* ca65 */
@@ -727,9 +728,9 @@ static void DoInclude (void)
     if (Tok != TOK_STRCON) {
        ErrorSkip (ERR_STRCON_EXPECTED);
     } else {
-       strcpy (Name, SVal);
-       NextTok ();
-       NewInputFile (Name);
+       strcpy (Name, SVal);
+       NextTok ();
+       NewInputFile (Name);
     }
 }
 
@@ -738,7 +739,34 @@ static void DoInclude (void)
 static void DoInitializer (void)
 /* Export a symbol as initializer */
 {
-    ExportImport (SymInitializer, 0);
+    char Name [sizeof (SVal)];
+    long Val;
+
+    /* Symbol name follows */
+    if (Tok != TOK_IDENT) {
+       ErrorSkip (ERR_IDENT_EXPECTED);
+       return;
+    }
+    strcpy (Name, SVal);
+    NextTok ();
+
+    /* Optional initializer value */
+    if (Tok == TOK_COMMA) {
+       /* Initializer value follows */
+       NextTok ();
+       Val = ConstExpression ();
+       if (Val < EXP_INIT_MIN || Val > EXP_INIT_MAX) {
+           /* Value out of range */
+           Error (ERR_RANGE);
+           return;
+       }
+    } else {
+       /* Use the default initializer value */
+       Val = EXP_INIT_DEF;
+    }
+
+    /* Define the symbol */
+    SymInitializer (Name, (unsigned) Val);
 }
 
 
index f64260330279429a1b489fb8292ea802819fc109..8261572ac88929d845c7dad8b5e8f49e62246b30 100644 (file)
@@ -97,6 +97,7 @@ struct SymEntry_ {
        long                Val;        /* Value (if CONST set) */
        SymEntry*           Sym;        /* Symbol (if trampoline entry) */
     } V;
+    unsigned char          InitVal;    /* Initializer value */
     char                           Name [1];   /* Dynamic allocation */
 };
 
@@ -158,13 +159,14 @@ static SymEntry* NewSymEntry (const char* Name)
     S = xmalloc (sizeof (SymEntry) + Len);
 
     /* Initialize the entry */
-    S->Left   = 0;
-    S->Right  = 0;
-    S->Locals = 0;
-    S->SymTab = 0;
-    S->Flags  = 0;
-    S->V.Expr = 0;
-    S->Pos    = CurPos;
+    S->Left    = 0;
+    S->Right   = 0;
+    S->Locals  = 0;
+    S->SymTab  = 0;
+    S->Pos     = CurPos;
+    S->Flags   = 0;
+    S->V.Expr  = 0;
+    S->InitVal = 0;
     memcpy (S->Name, Name, Len+1);
 
     /* Insert it into the list of all entries */
@@ -482,7 +484,7 @@ void SymImport (const char* Name, int ZP)
     }
     if (S->Flags & SF_EXPORT) {
        /* The symbol is already marked as exported symbol */
-       Error (ERR_SYM_ALREADY_EXPORT);
+       Error (ERR_SYM_ALREADY_EXPORT, Name);
        return;
     }
 
@@ -520,7 +522,7 @@ void SymExport (const char* Name, int ZP)
     S = SymFind (SymTab, Name, SF_ALLOC_NEW);
     if (S->Flags & SF_IMPORT) {
        /* The symbol is already marked as imported external symbol */
-       Error (ERR_SYM_ALREADY_IMPORT);
+       Error (ERR_SYM_ALREADY_IMPORT, Name);
        return;
     }
 
@@ -577,18 +579,15 @@ void SymGlobal (const char* Name, int ZP)
 
 
 
-void SymInitializer (const char* Name, int ZP)
+void SymInitializer (const char* Name, unsigned InitVal)
 /* Mark the given symbol as an initializer. This will also mark the symbol as
- * an export. Initializers may never be zero page symbols, the ZP parameter
- * is supplied to make the prototype the same as the other functions (this
- * is used in pseudo.c). Passing something else but zero as ZP argument will
- * trigger an internal error.
+ * an export. Initializers may never be zero page symbols.
  */
 {
     SymEntry* S;
 
-    /* Check the ZP parameter */
-    CHECK (ZP == 0);
+    /* Check the InitVal parameter */
+    CHECK (InitVal >= EXP_INIT_MIN && InitVal <= EXP_INIT_MAX);
 
     /* Don't accept local symbols */
     if (IsLocal (Name)) {
@@ -600,20 +599,30 @@ void SymInitializer (const char* Name, int ZP)
     S = SymFind (SymTab, Name, SF_ALLOC_NEW);
     if (S->Flags & SF_IMPORT) {
        /* The symbol is already marked as imported external symbol */
-       Error (ERR_SYM_ALREADY_IMPORT);
+       Error (ERR_SYM_ALREADY_IMPORT, Name);
        return;
     }
 
-    /* If the symbol is marked as global, check the symbol size, then do
-     * silently remove the global flag
-     */
+    /* If the symbol is marked as global, silently remove the global flag */
     if (S->Flags & SF_GLOBAL) {
-               if ((S->Flags & SF_ZP) != 0) {
-           Error (ERR_SYM_REDECL_MISMATCH);
-       }
         S->Flags &= ~SF_GLOBAL;
     }
 
+    /* Check if the symbol was not already defined as ZP symbol */
+    if ((S->Flags & SF_ZP) != 0) {
+       Error (ERR_SYM_REDECL_MISMATCH);
+    }
+
+    /* If the symbol was already declared as an initializer, check if the new
+     * initializer value is the same as the old one.
+     */
+    if (S->Flags & SF_INITIALIZER) {
+       if (S->InitVal != InitVal) {
+           Error (ERR_SYM_REDECL_MISMATCH);
+       }
+    }
+    S->InitVal = InitVal;
+
     /* Set the symbol data */
     S->Flags |= SF_EXPORT | SF_INITIALIZER | SF_REFERENCED;
 }
@@ -634,7 +643,7 @@ int SymIsRef (const char* Name)
 {
     SymEntry* S = SymFindAny (SymTab, Name);
     return S != 0 && (S->Flags & SF_REFERENCED) != 0;
-}
+}                                         
 
 
 
@@ -1079,7 +1088,7 @@ void WriteExports (void)
 
            /* Add the initializer bits */
            if (S->Flags & SF_INITIALIZER) {
-               ExprMask |= EXP_INIT;
+               ExprMask |= S->InitVal;
            }
 
            /* Write the type */
@@ -1151,7 +1160,7 @@ void WriteDbgSyms (void)
 
                /* Add the initializer bits */
                if (S->Flags & SF_INITIALIZER) {
-                   ExprMask |= EXP_INIT;
+                   ExprMask |= S->InitVal;
                }
 
                /* Write the type */
index 6c5642b27e759be7006a6deb6b1bf4cda948be3a..959bc3a0c692742ef574a1f04098148ec827f1b0 100644 (file)
@@ -86,12 +86,9 @@ void SymGlobal (const char* Name, int ZP);
  * either imported or exported.
  */
 
-void SymInitializer (const char* Name, int ZP);
+void SymInitializer (const char* Name, unsigned InitVal);
 /* Mark the given symbol as an initializer. This will also mark the symbol as
- * an export. Initializers may never be zero page symbols, the ZP parameter
- * is supplied to make the prototype the same as the other functions (this
- * is used in pseudo.c). Passing something else but zero as ZP argument will
- * trigger an internal error.
+ * an export. Initializers may never be zero page symbols.
  */
 
 int SymIsConst (SymEntry* Sym);
index 69a42f0241cc52126b0482439fec52ff04348207..f4e192bf5f79144120d5de84db357357d97d2dbc 100644 (file)
 
 
 /* Import size */
-#define IMP_ABS        0x00            /* Import as normal value */
-#define IMP_ZP                 0x01            /* Import as zero page symbol */
-#define IMP_MASK_SIZE  0x01            /* Size mask */
+#define IMP_ABS        0x00            /* Import as normal value */
+#define IMP_ZP                 0x01            /* Import as zero page symbol */
+#define IMP_MASK_SIZE  0x01            /* Size mask */
 
-#define IS_IMP_ABS(x)  (((x) & IMP_MASK_SIZE) == IMP_ABS)
-#define IS_IMP_ZP(x)   (((x) & IMP_MASK_SIZE) == IMP_ZP)
+#define IS_IMP_ABS(x)  (((x) & IMP_MASK_SIZE) == IMP_ABS)
+#define IS_IMP_ZP(x)   (((x) & IMP_MASK_SIZE) == IMP_ZP)
 
 /* Export size */
-#define EXP_ABS                0x00            /* Export as normal value */
-#define EXP_ZP                 0x01            /* Export as zero page value */
-#define EXP_MASK_SIZE  0x01            /* Size mask */
+#define EXP_ABS                0x00            /* Export as normal value */
+#define EXP_ZP                 0x20            /* Export as zero page value */
+#define EXP_MASK_SIZE  0x20            /* Size mask */
 
 #define IS_EXP_ABS(x)          (((x) & EXP_MASK_SIZE) == EXP_ABS)
-#define IS_EXP_ZP(x)   (((x) & EXP_MASK_SIZE) == EXP_ZP)
+#define IS_EXP_ZP(x)   (((x) & EXP_MASK_SIZE) == EXP_ZP)
 
 /* Export value type */
-#define EXP_CONST      0x00            /* Mask bit for const values */
-#define EXP_EXPR       0x02            /* Mask bit for expr values */
-#define EXP_MASK_VAL   0x02            /* Value mask */
+#define EXP_CONST      0x00            /* Mask bit for const values */
+#define EXP_EXPR       0x40            /* Mask bit for expr values */
+#define EXP_MASK_VAL   0x40            /* Value mask */
 
 #define IS_EXP_CONST(x)        (((x) & EXP_MASK_VAL) == EXP_CONST)
 #define IS_EXP_EXPR(x)         (((x) & EXP_MASK_VAL) == EXP_EXPR)
 
 /* Export initializer flag */
-#define EXP_INIT       0x04            /* Mask bit for initializer export */
-#define EXP_MASK_INIT  0x04            /* Value mask */
+#define EXP_INIT_MIN   0x01            /* Minimum value */
+#define EXP_INIT_MAX   0x1F            /* Maximum value */
+#define EXP_INIT_DEF   0x18            /* Default value */
+#define EXP_MASK_INIT  0x1F            /* Initializer value mask */
 
-#define IS_EXP_INIT(x) (((x) & EXP_MASK_INIT) == EXP_INIT)
+#define IS_EXP_INIT(x)         (((x) & EXP_MASK_INIT) != 0)
+#define GET_EXP_INIT_VAL(x)    ((x) & EXP_MASK_INIT)
 
 
 
index 5c649ce766577189c6e509fdda19760ca843a9ee..413f6cfa853210bbbc127a6b6c234be274e8a20e 100644 (file)
@@ -151,7 +151,7 @@ DbgSym* ReadDbgSym (FILE* F, ObjData* O)
     D->Name = ReadStr (F);
 
     /* Read the value */
-    if (Type & EXP_EXPR) {
+    if (IS_EXP_EXPR (Type)) {
                D->Expr = ReadExpr (F, O);
     } else {
        D->Expr = LiteralExpr (Read32 (F), O);
index 8f0427a6d145232b3320845ebe18273df8a416d7..971db1558cd778d5bfccd2b997e1a25e2e17bf76 100644 (file)
@@ -39,6 +39,7 @@
 
 /* common */
 #include "check.h"
+#include "coll.h"
 #include "hashstr.h"
 #include "symdefs.h"
 #include "xmalloc.h"
 
 
 /*****************************************************************************/
-/*                                          Data                                    */
+/*                                          Data                                    */
 /*****************************************************************************/
 
 
 
 /* Hash table */
-#define HASHTAB_SIZE   4081
-static Export*                 HashTab [HASHTAB_SIZE];
+#define HASHTAB_SIZE           4081
+static Export*                 HashTab [HASHTAB_SIZE];
 
 /* Import management variables */
-static unsigned                ImpCount = 0;           /* Import count */
-static unsigned                ImpOpen  = 0;           /* Count of open imports */
+static unsigned                ImpCount = 0;           /* Import count */
+static unsigned                ImpOpen  = 0;           /* Count of open imports */
 
 /* Export management variables */
-static unsigned                ExpCount = 0;           /* Export count */
-static Export**                ExpPool  = 0;           /* Exports array */
+static unsigned                ExpCount = 0;           /* Export count */
+static Export**                ExpPool  = 0;           /* Exports array */
 
 /* Defines for the flags in Export */
-#define EXP_USERMARK   0x0001
+#define EXP_USERMARK           0x0001
+
+/* List of all exports that are also initializers */
+static Collection      Initializers = STATIC_COLLECTION_INITIALIZER;
 
 
 
@@ -227,6 +231,11 @@ void InsertExport (Export* E)
     Import* Imp;
     unsigned HashVal;
 
+    /* If this is an initializer, insert it into the initializer list */
+    if (IS_EXP_INIT (E->Type)) {
+       CollAppend (&Initializers, E);
+    }
+
     /* Create a hash value for the given name */
     HashVal = HashStr (E->Name) % HASHTAB_SIZE;
 
@@ -242,7 +251,7 @@ void InsertExport (Export* E)
        do {
            if (strcmp (L->Name, E->Name) == 0) {
                /* This may be an unresolved external */
-               if (L->Expr == 0) {
+               if (L->Expr == 0) {
 
                    /* This *is* an unresolved external */
                    E->Next     = L->Next;
@@ -298,7 +307,7 @@ Export* ReadExport (FILE* F, ObjData* O)
     E->Name = ReadStr (F);
 
     /* Read the value */
-    if (Type & EXP_EXPR) {
+    if (IS_EXP_EXPR (Type)) {
                E->Expr = ReadExpr (F, O);
     } else {
        E->Expr = LiteralExpr (Read32 (F), O);
@@ -408,18 +417,18 @@ long GetExportVal (const Export* E)
 
 
 
-static void CheckSymType (Export* E)
+static void CheckSymType (const Export* E)
 /* Check the types for one export */
 {
     /* External with matching imports */
     Import* Imp = E->ImpList;
-    int ZP = (E->Type & EXP_ZP) != 0;
+    int ZP = IS_EXP_ZP (E->Type);
     while (Imp) {
-       if (ZP != ((Imp->Type & IMP_ZP) != 0)) {
+       if (ZP != IS_IMP_ZP (Imp->Type)) {
            /* Export is ZP, import is abs or the other way round */
            if (E->Obj) {
-               /* User defined export */
-               Warning ("Type mismatch for `%s', export in "
+               /* User defined export */
+               Warning ("Type mismatch for `%s', export in "
                         "%s(%lu), import in %s(%lu)",
                         E->Name, E->Obj->Files [Imp->Pos.Name],
                         E->Pos.Line, Imp->Obj->Files [Imp->Pos.Name],
@@ -444,7 +453,7 @@ static void CheckSymTypes (void)
 
     /* Print all open imports */
     for (I = 0; I < ExpCount; ++I) {
-       Export* E = ExpPool [I];
+       const Export* E = ExpPool [I];
        if (E->Expr != 0 && E->ImpCount > 0) {
            /* External with matching imports */
            CheckSymType (E);
@@ -545,19 +554,20 @@ void PrintExportMap (FILE* F)
     /* Print all exports */
     Count = 0;
     for (I = 0; I < ExpCount; ++I) {
-       Export* E = ExpPool [I];
+       const Export* E = ExpPool [I];
 
        /* Print unreferenced symbols only if explictly requested */
        if (VerboseMap || E->ImpCount > 0) {
            fprintf (F,
-                    "%-25s %06lX %c%c    ",
-                    E->Name,
-                    GetExportVal (E),
-                    E->ImpCount? 'R' : ' ',
-                    (E->Type & EXP_ZP)? 'Z' : ' ');
+                    "%-25s %06lX %c%c%c   ",
+                    E->Name,
+                    GetExportVal (E),
+                    E->ImpCount? 'R' : ' ',
+                    IS_EXP_ZP (E->Type)? 'Z' : ' ',
+                    IS_EXP_INIT (E->Type)? 'I' : ' ');
            if (++Count == 2) {
-               Count = 0;
-               fprintf (F, "\n");
+               Count = 0;
+               fprintf (F, "\n");
            }
        }
     }
@@ -570,13 +580,13 @@ void PrintImportMap (FILE* F)
 /* Print an import map to the given file */
 {
     unsigned I;
-    Import* Imp;
+    const Import* Imp;
 
     /* Loop over all exports */
     for (I = 0; I < ExpCount; ++I) {
 
        /* Get the export */
-       Export* Exp = ExpPool [I];
+       const Export* Exp = ExpPool [I];
 
        /* Print the symbol only if there are imports, or if a verbose map
         * file is requested.
@@ -591,23 +601,23 @@ void PrintImportMap (FILE* F)
 
            /* Print the export */
            fprintf (F,
-                    "%s (%s):\n",
-                    Exp->Name,
-                    ObjName);
+                    "%s (%s):\n",
+                    Exp->Name,
+                    ObjName);
 
            /* Print all imports for this symbol */
            Imp = Exp->ImpList;
            while (Imp) {
 
-               /* Print the import */
-               fprintf (F,
-                        "    %-25s %s(%lu)\n",
-                        Imp->Obj->Name,
-                        Imp->Obj->Files [Imp->Pos.Name],
-                        Imp->Pos.Line);
+               /* Print the import */
+               fprintf (F,
+                        "    %-25s %s(%lu)\n",
+                        Imp->Obj->Name,
+                        Imp->Obj->Files [Imp->Pos.Name],
+                        Imp->Pos.Line);
 
-               /* Next import */
-               Imp = Imp->Next;
+               /* Next import */
+               Imp = Imp->Next;
            }
        }
     }
@@ -623,7 +633,7 @@ void PrintExportLabels (FILE* F)
 
     /* Print all exports */
     for (I = 0; I < ExpCount; ++I) {
-       Export* E = ExpPool [I];
+       const Export* E = ExpPool [I];
                fprintf (F, "al %06lX .%s\n", GetExportVal (E), E->Name);
     }
 }
index 19016fa4146d694aea89cf30209b0d6fb7d31c31..f5b880bdad90d708cf97e886df25e51b4af82f09 100644 (file)
@@ -213,7 +213,7 @@ static const char* GetExportFlags (unsigned Flags)
        case EXP_EXPR:  strcat (TypeDesc, ",EXP_EXPR");         break;
     }
     if (IS_EXP_INIT (Flags)) {
-       strcat (TypeDesc, ",EXP_INIT");
+       sprintf (TypeDesc+strlen(TypeDesc), ",EXP_INIT=%u", GET_EXP_INIT_VAL(Flags));
     }
 
     /* Return the result */