1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-23 04:30:10 +00:00

Add initializer

git-svn-id: svn://svn.cc65.org/cc65/trunk@406 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2000-10-30 19:30:26 +00:00
parent 3485519242
commit 9977ddd973
6 changed files with 107 additions and 28 deletions

View 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 },

View 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 },

View File

@ -165,6 +165,7 @@ enum Token {
TOK_IMPORTZP,
TOK_INCBIN,
TOK_INCLUDE,
TOK_INITIALIZER,
TOK_LEFT,
TOK_LINECONT,
TOK_LIST,

View 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;

View 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);

View 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 */