mirror of
https://github.com/cc65/cc65.git
synced 2024-12-23 19:29:37 +00:00
Add initializer
git-svn-id: svn://svn.cc65.org/cc65/trunk@406 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
3485519242
commit
9977ddd973
@ -735,6 +735,14 @@ static void DoInclude (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void DoInitializer (void)
|
||||||
|
/* Export a symbol as initializer */
|
||||||
|
{
|
||||||
|
ExportImport (SymInitializer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void DoInvalid (void)
|
static void DoInvalid (void)
|
||||||
/* Handle a token that is invalid here, since it should have been handled on
|
/* 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
|
* a much lower level of the expression hierarchy. Getting this sort of token
|
||||||
@ -1179,6 +1187,7 @@ static CtrlDesc CtrlCmdTab [] = {
|
|||||||
{ ccNone, DoImportZP },
|
{ ccNone, DoImportZP },
|
||||||
{ ccNone, DoIncBin },
|
{ ccNone, DoIncBin },
|
||||||
{ ccNone, DoInclude },
|
{ ccNone, DoInclude },
|
||||||
|
{ ccNone, DoInitializer },
|
||||||
{ ccNone, DoInvalid }, /* .LEFT */
|
{ ccNone, DoInvalid }, /* .LEFT */
|
||||||
{ ccNone, DoLineCont },
|
{ ccNone, DoLineCont },
|
||||||
{ ccNone, DoList },
|
{ ccNone, DoList },
|
||||||
|
@ -182,6 +182,7 @@ struct DotKeyword {
|
|||||||
{ "IMPORTZP", TOK_IMPORTZP },
|
{ "IMPORTZP", TOK_IMPORTZP },
|
||||||
{ "INCBIN", TOK_INCBIN },
|
{ "INCBIN", TOK_INCBIN },
|
||||||
{ "INCLUDE", TOK_INCLUDE },
|
{ "INCLUDE", TOK_INCLUDE },
|
||||||
|
{ "INITIALIZER", TOK_INITIALIZER },
|
||||||
{ "LEFT", TOK_LEFT },
|
{ "LEFT", TOK_LEFT },
|
||||||
{ "LINECONT", TOK_LINECONT },
|
{ "LINECONT", TOK_LINECONT },
|
||||||
{ "LIST", TOK_LIST },
|
{ "LIST", TOK_LIST },
|
||||||
|
@ -165,6 +165,7 @@ enum Token {
|
|||||||
TOK_IMPORTZP,
|
TOK_IMPORTZP,
|
||||||
TOK_INCBIN,
|
TOK_INCBIN,
|
||||||
TOK_INCLUDE,
|
TOK_INCLUDE,
|
||||||
|
TOK_INITIALIZER,
|
||||||
TOK_LEFT,
|
TOK_LEFT,
|
||||||
TOK_LINECONT,
|
TOK_LINECONT,
|
||||||
TOK_LIST,
|
TOK_LIST,
|
||||||
|
@ -63,8 +63,9 @@
|
|||||||
#define SF_EXPORT 0x0004 /* Export this symbol */
|
#define SF_EXPORT 0x0004 /* Export this symbol */
|
||||||
#define SF_IMPORT 0x0008 /* Import this symbol */
|
#define SF_IMPORT 0x0008 /* Import this symbol */
|
||||||
#define SF_GLOBAL 0x0010 /* Global symbol */
|
#define SF_GLOBAL 0x0010 /* Global symbol */
|
||||||
#define SF_ZP 0x0020 /* Declared as zeropage symbol */
|
#define SF_INITIALIZER 0x0020 /* Exported initializer */
|
||||||
#define SF_ABS 0x0040 /* Declared as absolute symbol */
|
#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_INDEXED 0x0800 /* Index is valid */
|
||||||
#define SF_CONST 0x1000 /* The symbol has a constant value */
|
#define SF_CONST 0x1000 /* The symbol has a constant value */
|
||||||
#define SF_MULTDEF 0x2000 /* Multiply defined symbol */
|
#define SF_MULTDEF 0x2000 /* Multiply defined symbol */
|
||||||
@ -81,8 +82,6 @@
|
|||||||
#define SF_DBGINFOMASK (SF_TRAMPOLINE | SF_DEFINED | SF_EXPORT | SF_IMPORT)
|
#define SF_DBGINFOMASK (SF_TRAMPOLINE | SF_DEFINED | SF_EXPORT | SF_IMPORT)
|
||||||
#define SF_DBGINFOVAL (SF_DEFINED)
|
#define SF_DBGINFOVAL (SF_DEFINED)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Structure of a symbol table entry */
|
/* Structure of a symbol table entry */
|
||||||
struct SymEntry_ {
|
struct SymEntry_ {
|
||||||
SymEntry* Left; /* Lexically smaller entry */
|
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 */
|
/* Symbol table variables */
|
||||||
static SymEntry* SymList = 0; /* List of all symbol table entries */
|
static SymEntry* SymList = 0; /* List of all symbol table entries */
|
||||||
static SymEntry* SymLast = 0; /* Pointer to last defined symbol */
|
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)
|
static SymEntry* SymRefInternal (SymTable* Table, const char* Name)
|
||||||
/* Search for the symbol in the given table and return it */
|
/* 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 */
|
/* 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 */
|
/* Mark the symbol as referenced */
|
||||||
S->Flags |= SF_REFERENCED;
|
S->Flags |= SF_REFERENCED;
|
||||||
@ -396,10 +399,8 @@ void SymLeaveLevel (void)
|
|||||||
void SymDef (const char* Name, ExprNode* Expr, int ZP)
|
void SymDef (const char* Name, ExprNode* Expr, int ZP)
|
||||||
/* Define a new symbol */
|
/* Define a new symbol */
|
||||||
{
|
{
|
||||||
SymEntry* S;
|
|
||||||
|
|
||||||
/* Do we have such a symbol? */
|
/* Do we have such a symbol? */
|
||||||
S = SymFind (SymTab, Name, 1);
|
SymEntry* S = SymFind (SymTab, Name, SF_ALLOC_NEW);
|
||||||
if (S->Flags & SF_IMPORT) {
|
if (S->Flags & SF_IMPORT) {
|
||||||
/* Defined symbol is marked as imported external symbol */
|
/* Defined symbol is marked as imported external symbol */
|
||||||
Error (ERR_SYM_ALREADY_IMPORT);
|
Error (ERR_SYM_ALREADY_IMPORT);
|
||||||
@ -473,7 +474,7 @@ void SymImport (const char* Name, int ZP)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Do we have such a symbol? */
|
/* Do we have such a symbol? */
|
||||||
S = SymFind (SymTab, Name, 1);
|
S = SymFind (SymTab, Name, SF_ALLOC_NEW);
|
||||||
if (S->Flags & SF_DEFINED) {
|
if (S->Flags & SF_DEFINED) {
|
||||||
Error (ERR_SYM_ALREADY_DEFINED, Name);
|
Error (ERR_SYM_ALREADY_DEFINED, Name);
|
||||||
S->Flags |= SF_MULTDEF;
|
S->Flags |= SF_MULTDEF;
|
||||||
@ -516,7 +517,7 @@ void SymExport (const char* Name, int ZP)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Do we have such a symbol? */
|
/* Do we have such a symbol? */
|
||||||
S = SymFind (SymTab, Name, 1);
|
S = SymFind (SymTab, Name, SF_ALLOC_NEW);
|
||||||
if (S->Flags & SF_IMPORT) {
|
if (S->Flags & SF_IMPORT) {
|
||||||
/* The symbol is already marked as imported external symbol */
|
/* The symbol is already marked as imported external symbol */
|
||||||
Error (ERR_SYM_ALREADY_IMPORT);
|
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 */
|
/* 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
|
/* If the symbol is already marked as import or export, check the
|
||||||
* size of the definition, then bail out. */
|
* 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)
|
int SymIsDef (const char* Name)
|
||||||
/* Return true if the given symbol is already defined */
|
/* Return true if the given symbol is already defined */
|
||||||
{
|
{
|
||||||
@ -1030,20 +1074,30 @@ void WriteExports (void)
|
|||||||
/* Check if the symbol is const */
|
/* Check if the symbol is const */
|
||||||
ExprMask = (SymIsConst (S))? EXP_CONST : EXP_EXPR;
|
ExprMask = (SymIsConst (S))? EXP_CONST : EXP_EXPR;
|
||||||
|
|
||||||
/* Write the type */
|
/* Add zeropage/abs bits */
|
||||||
if (S->Flags & SF_ZP) {
|
ExprMask |= (S->Flags & SF_ZP)? EXP_ZP : EXP_ABS;
|
||||||
ObjWrite8 (EXP_ZP | ExprMask);
|
|
||||||
} else {
|
/* Add the initializer bits */
|
||||||
ObjWrite8 (EXP_ABS | ExprMask);
|
if (S->Flags & SF_INITIALIZER) {
|
||||||
|
ExprMask |= EXP_INITIALIZER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write the type */
|
||||||
|
ObjWrite8 (ExprMask);
|
||||||
|
|
||||||
|
/* Write the name */
|
||||||
ObjWriteStr (S->Name);
|
ObjWriteStr (S->Name);
|
||||||
if (ExprMask == EXP_CONST) {
|
|
||||||
|
/* Write the value */
|
||||||
|
if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) {
|
||||||
/* Constant value */
|
/* Constant value */
|
||||||
ObjWrite32 (S->V.Val);
|
ObjWrite32 (S->V.Val);
|
||||||
} else {
|
} else {
|
||||||
/* Expression involved */
|
/* Expression involved */
|
||||||
WriteExpr (S->V.Expr);
|
WriteExpr (S->V.Expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write the source file position */
|
||||||
ObjWritePos (&S->Pos);
|
ObjWritePos (&S->Pos);
|
||||||
}
|
}
|
||||||
S = S->List;
|
S = S->List;
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
#include "exprdefs.h"
|
#include "exprdefs.h"
|
||||||
|
|
||||||
/* ca65 */
|
/* ca65 */
|
||||||
#include "symentry.h"
|
#include "symentry.h"
|
||||||
|
|
||||||
@ -86,6 +86,14 @@ void SymGlobal (const char* Name, int ZP);
|
|||||||
* either imported or exported.
|
* 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);
|
int SymIsConst (SymEntry* Sym);
|
||||||
/* Return true if the given symbol has a constant value */
|
/* Return true if the given symbol has a constant value */
|
||||||
|
|
||||||
@ -145,4 +153,4 @@ void WriteDbgSyms (void);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
@ -536,7 +537,7 @@ void DumpObjExports (FILE* F, unsigned long Offset)
|
|||||||
|
|
||||||
unsigned long Value = 0;
|
unsigned long Value = 0;
|
||||||
int HaveValue;
|
int HaveValue;
|
||||||
const char* TypeDesc;
|
char TypeDesc[128];
|
||||||
|
|
||||||
/* Read the data for one export */
|
/* Read the data for one export */
|
||||||
unsigned char Type = Read8 (F);
|
unsigned char Type = Read8 (F);
|
||||||
@ -552,12 +553,17 @@ void DumpObjExports (FILE* F, unsigned long Offset)
|
|||||||
ReadFilePos (F, &Pos);
|
ReadFilePos (F, &Pos);
|
||||||
|
|
||||||
/* Get a description for the type */
|
/* Get a description for the type */
|
||||||
switch (Type) {
|
TypeDesc[0] = '\0';
|
||||||
case EXP_ABS|EXP_CONST: TypeDesc = "EXP_ABS,EXP_CONST"; break;
|
switch (Type & EXP_MASK_SIZE) {
|
||||||
case EXP_ZP|EXP_CONST: TypeDesc = "EXP_ZP,EXP_CONST"; break;
|
case EXP_ABS: strcat (TypeDesc, "EXP_ABS"); break;
|
||||||
case EXP_ABS|EXP_EXPR: TypeDesc = "EXP_ABS,EXP_EXPR"; break;
|
case EXP_ZP: strcat (TypeDesc, "EXP_ZP"); break;
|
||||||
case EXP_ZP|EXP_EXPR: TypeDesc = "EXP_ZP,EXP_EXPR"; break;
|
}
|
||||||
default: TypeDesc = "EXP_UNKNOWN"; 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 */
|
/* Print the header */
|
||||||
|
Loading…
Reference in New Issue
Block a user