]> git.sur5r.net Git - cc65/commitdiff
Add initializer
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 30 Oct 2000 19:30:26 +0000 (19:30 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 30 Oct 2000 19:30:26 +0000 (19:30 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@406 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ca65/pseudo.c
src/ca65/scanner.c
src/ca65/scanner.h
src/ca65/symtab.c
src/ca65/symtab.h
src/od65/dump.c

index 7deb39c1bdcc660b01d9bb80fdfd78071d83f731..d93976101d2c7c8f96d670aa9a32e6708b5a3611 100644 (file)
@@ -735,6 +735,14 @@ static void DoInclude (void)
 
 
 
+static void DoInitializer (void)
+/* Export a symbol as initializer */
+{
+    ExportImport (SymInitializer, 0);
+}
+
+
+
 static void DoInvalid (void)
 /* Handle a token that is invalid here, since it should have been handled on
  * a much lower level of the expression hierarchy. Getting this sort of token
@@ -1179,6 +1187,7 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,          DoImportZP      },
     { ccNone,          DoIncBin        },
     { ccNone,          DoInclude       },
+    { ccNone,          DoInitializer   },
     { ccNone,          DoInvalid       },      /* .LEFT */
     { ccNone,          DoLineCont      },
     { ccNone,          DoList          },
index fb5212a3c2cedeaccd16897250fb0496ec968598..b14a974d6f4b8a9a407430246a1fecd1145fb963 100644 (file)
@@ -182,6 +182,7 @@ struct DotKeyword {
     { "IMPORTZP",      TOK_IMPORTZP    },
     { "INCBIN",                TOK_INCBIN      },
     { "INCLUDE",       TOK_INCLUDE     },
+    { "INITIALIZER",   TOK_INITIALIZER },
     { "LEFT",          TOK_LEFT        },
     { "LINECONT",      TOK_LINECONT    },
     { "LIST",          TOK_LIST        },
index 91ca49a2751386b1728eb22bc10debd74e22df15..0849eb52903b25542e955f8c69c8c24bc5156d37 100644 (file)
@@ -165,6 +165,7 @@ enum Token {
     TOK_IMPORTZP,
     TOK_INCBIN,
     TOK_INCLUDE,
+    TOK_INITIALIZER,
     TOK_LEFT,
     TOK_LINECONT,
     TOK_LIST,
index 12d9a4745739a072e68934ee845a6a0bc0c0cc10..f43b4c7b1178b2d790834564a1044e3908ace7f8 100644 (file)
@@ -63,8 +63,9 @@
 #define SF_EXPORT              0x0004          /* Export this symbol */
 #define SF_IMPORT      0x0008          /* Import this symbol */
 #define SF_GLOBAL      0x0010          /* Global symbol */
-#define SF_ZP                  0x0020          /* Declared as zeropage symbol */
-#define SF_ABS         0x0040          /* Declared as absolute symbol */
+#define SF_INITIALIZER 0x0020          /* Exported initializer */
+#define SF_ZP                  0x0040          /* Declared as zeropage symbol */
+#define SF_ABS         0x0080          /* Declared as absolute symbol */
 #define SF_INDEXED     0x0800          /* Index is valid */
 #define SF_CONST       0x1000          /* The symbol has a constant value */
 #define SF_MULTDEF             0x2000          /* Multiply defined symbol */
@@ -81,8 +82,6 @@
 #define SF_DBGINFOMASK (SF_TRAMPOLINE | SF_DEFINED | SF_EXPORT | SF_IMPORT)
 #define SF_DBGINFOVAL  (SF_DEFINED)
 
-
-
 /* Structure of a symbol table entry */
 struct SymEntry_ {
     SymEntry*                      Left;       /* Lexically smaller entry */
@@ -116,6 +115,12 @@ struct SymTable_ {
 
 
 
+/* Arguments for SymFind */
+#define SF_FIND_EXISTING       0
+#define SF_ALLOC_NEW           1
+
+
+
 /* Symbol table variables */
 static SymEntry*               SymList = 0;    /* List of all symbol table entries */
 static SymEntry*       SymLast = 0;    /* Pointer to last defined symbol */
@@ -354,10 +359,8 @@ static SymEntry* SymFindAny (SymTable* Tab, const char* Name)
 static SymEntry* SymRefInternal (SymTable* Table, const char* Name)
 /* Search for the symbol in the given table and return it */
 {
-    SymEntry* S;
-
     /* Try to find the symbol, create a new one if the symbol does not exist */
-    S = SymFind (Table, Name, 1);
+    SymEntry* S = SymFind (Table, Name, SF_ALLOC_NEW);
 
     /* Mark the symbol as referenced */
     S->Flags |= SF_REFERENCED;
@@ -396,10 +399,8 @@ void SymLeaveLevel (void)
 void SymDef (const char* Name, ExprNode* Expr, int ZP)
 /* Define a new symbol */
 {
-    SymEntry* S;
-
     /* Do we have such a symbol? */
-    S = SymFind (SymTab, Name, 1);
+    SymEntry* S = SymFind (SymTab, Name, SF_ALLOC_NEW);
     if (S->Flags & SF_IMPORT) {
                /* Defined symbol is marked as imported external symbol */
                Error (ERR_SYM_ALREADY_IMPORT);
@@ -473,7 +474,7 @@ void SymImport (const char* Name, int ZP)
     }
 
     /* Do we have such a symbol? */
-    S = SymFind (SymTab, Name, 1);
+    S = SymFind (SymTab, Name, SF_ALLOC_NEW);
     if (S->Flags & SF_DEFINED) {
        Error (ERR_SYM_ALREADY_DEFINED, Name);
        S->Flags |= SF_MULTDEF;
@@ -516,7 +517,7 @@ void SymExport (const char* Name, int ZP)
     }
 
     /* Do we have such a symbol? */
-    S = SymFind (SymTab, Name, 1);
+    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);
@@ -556,7 +557,7 @@ void SymGlobal (const char* Name, int ZP)
     }
 
     /* Search for this symbol, create a new entry if needed */
-    S = SymFind (SymTab, Name, 1);
+    S = SymFind (SymTab, Name, SF_ALLOC_NEW);
 
     /* If the symbol is already marked as import or export, check the
      * size of the definition, then bail out. */
@@ -576,6 +577,49 @@ void SymGlobal (const char* Name, int ZP)
 
 
 
+void SymInitializer (const char* Name, int ZP)
+/* 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.
+ */
+{
+    SymEntry* S;
+
+    /* Check the ZP parameter */
+    CHECK (ZP == 0);
+
+    /* Don't accept local symbols */
+    if (IsLocal (Name)) {
+       Error (ERR_ILLEGAL_LOCAL_USE);
+       return;
+    }
+
+    /* Do we have such a symbol? */
+    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);
+       return;
+    }
+
+    /* If the symbol is marked as global, check the symbol size, then do
+     * 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;
+    }
+
+    /* Set the symbol data */
+    S->Flags |= SF_EXPORT | SF_INITIALIZER | SF_REFERENCED;
+}
+
+
+
 int SymIsDef (const char* Name)
 /* Return true if the given symbol is already defined */
 {
@@ -1030,20 +1074,30 @@ void WriteExports (void)
            /* Check if the symbol is const */
            ExprMask = (SymIsConst (S))? EXP_CONST : EXP_EXPR;
 
-           /* Write the type */
-           if (S->Flags & SF_ZP) {
-               ObjWrite8 (EXP_ZP | ExprMask);
-           } else {
-               ObjWrite8 (EXP_ABS | ExprMask);
+           /* Add zeropage/abs bits */
+           ExprMask |= (S->Flags & SF_ZP)? EXP_ZP : EXP_ABS;
+
+           /* Add the initializer bits */
+           if (S->Flags & SF_INITIALIZER) {
+               ExprMask |= EXP_INITIALIZER;
            }
+
+           /* Write the type */
+           ObjWrite8 (ExprMask);
+
+           /* Write the name */
                    ObjWriteStr (S->Name);
-           if (ExprMask == EXP_CONST) {
+
+           /* Write the value */
+           if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) {
                /* Constant value */
                ObjWrite32 (S->V.Val);
            } else {
                /* Expression involved */
                WriteExpr (S->V.Expr);
             }
+
+           /* Write the source file position */
            ObjWritePos (&S->Pos);
        }
        S = S->List;
index 9176bc7022bb2372b0530b283980c8742f74ff62..6c5642b27e759be7006a6deb6b1bf4cda948be3a 100644 (file)
@@ -42,7 +42,7 @@
 
 /* common */
 #include "exprdefs.h"
-         
+
 /* ca65 */
 #include "symentry.h"
 
@@ -86,6 +86,14 @@ void SymGlobal (const char* Name, int ZP);
  * either imported or exported.
  */
 
+void SymInitializer (const char* Name, int ZP);
+/* 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.
+ */
+
 int SymIsConst (SymEntry* Sym);
 /* Return true if the given symbol has a constant value */
 
@@ -145,4 +153,4 @@ void WriteDbgSyms (void);
 
 
 
-         
+
index b9bf7f1224b3b647b662255b5b4be0ca9e6abfad..a4413df96af4e1c8c3225d039b2097258a79b57d 100644 (file)
@@ -33,6 +33,7 @@
 
 
 
+#include <string.h>
 #include <time.h>
 
 /* common */
@@ -536,7 +537,7 @@ void DumpObjExports (FILE* F, unsigned long Offset)
 
        unsigned long   Value = 0;
        int             HaveValue;
-       const char*     TypeDesc;
+       char            TypeDesc[128];
 
                /* Read the data for one export */
                unsigned char Type  = Read8 (F);
@@ -552,12 +553,17 @@ void DumpObjExports (FILE* F, unsigned long Offset)
        ReadFilePos (F, &Pos);
 
        /* Get a description for the type */
-       switch (Type) {
-           case EXP_ABS|EXP_CONST:     TypeDesc = "EXP_ABS,EXP_CONST"; break;
-           case EXP_ZP|EXP_CONST:      TypeDesc = "EXP_ZP,EXP_CONST";  break;
-           case EXP_ABS|EXP_EXPR:      TypeDesc = "EXP_ABS,EXP_EXPR";  break;
-                   case EXP_ZP|EXP_EXPR:       TypeDesc = "EXP_ZP,EXP_EXPR";   break;
-           default:                    TypeDesc = "EXP_UNKNOWN";       break;
+       TypeDesc[0] = '\0';
+       switch (Type & EXP_MASK_SIZE) {
+           case EXP_ABS:       strcat (TypeDesc, "EXP_ABS");           break;
+           case EXP_ZP:        strcat (TypeDesc, "EXP_ZP");            break;
+       }
+       switch (Type & EXP_MASK_VAL) {
+           case EXP_CONST:     strcat (TypeDesc, ",EXP_CONST");        break;
+           case EXP_EXPR:      strcat (TypeDesc, ",EXP_EXPR");         break;
+       }
+       if (Type & EXP_INITIALIZER) {
+           strcat (TypeDesc, ",EXP_INITIALIZER");
        }
 
        /* Print the header */