Working on the condes feature
git-svn-id: svn://svn.cc65.org/cc65/trunk@451 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -33,6 +33,8 @@
|
||||
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* ca65 */
|
||||
#include "error.h"
|
||||
#include "expr.h"
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* common */
|
||||
#include "check.h"
|
||||
#include "exprdefs.h"
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* common */
|
||||
#include "check.h"
|
||||
#include "hashstr.h"
|
||||
|
||||
@@ -34,10 +34,11 @@
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* common */
|
||||
#include "check.h"
|
||||
|
||||
|
||||
/* ca65 */
|
||||
#include "error.h"
|
||||
#include "expr.h"
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* common */
|
||||
#include "optdefs.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
/* common */
|
||||
#include "bitops.h"
|
||||
#include "cddefs.h"
|
||||
#include "check.h"
|
||||
#include "symdefs.h"
|
||||
#include "tgttrans.h"
|
||||
@@ -173,6 +174,32 @@ static long IntArg (long Min, long Max)
|
||||
|
||||
|
||||
|
||||
static void ConDes (const char* Name, unsigned Type)
|
||||
/* Parse remaining line for constructor/destructor of the remaining type */
|
||||
{
|
||||
long Prio;
|
||||
|
||||
/* Optional constructor priority */
|
||||
if (Tok == TOK_COMMA) {
|
||||
/* Priority value follows */
|
||||
NextTok ();
|
||||
Prio = ConstExpression ();
|
||||
if (Prio < CD_PRIO_MIN || Prio > CD_PRIO_MAX) {
|
||||
/* Value out of range */
|
||||
Error (ERR_RANGE);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* Use the default priority value */
|
||||
Prio = CD_PRIO_DEF;
|
||||
}
|
||||
|
||||
/* Define the symbol */
|
||||
SymConDes (Name, Type, (unsigned) Prio);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Handler functions */
|
||||
/*****************************************************************************/
|
||||
@@ -320,7 +347,7 @@ static void DoByte (void)
|
||||
NextTok ();
|
||||
/* Do smart handling of dangling comma */
|
||||
if (Tok == TOK_SEP) {
|
||||
Error (ERR_UNEXPECTED_EOL);
|
||||
Error (ERR_UNEXPECTED_EOL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -346,6 +373,76 @@ static void DoCode (void)
|
||||
|
||||
|
||||
|
||||
static void DoConDes (void)
|
||||
/* Export a symbol as constructor/destructor */
|
||||
{
|
||||
static const char* Keys[] = {
|
||||
"CONSTRUCTOR",
|
||||
"DESTRUCTOR",
|
||||
};
|
||||
char Name [sizeof (SVal)];
|
||||
long Type;
|
||||
|
||||
/* Symbol name follows */
|
||||
if (Tok != TOK_IDENT) {
|
||||
ErrorSkip (ERR_IDENT_EXPECTED);
|
||||
return;
|
||||
}
|
||||
strcpy (Name, SVal);
|
||||
NextTok ();
|
||||
|
||||
/* Type follows. May be encoded as identifier or numerical */
|
||||
ConsumeComma ();
|
||||
if (Tok == TOK_IDENT) {
|
||||
|
||||
/* Map the following keyword to a number, then skip it */
|
||||
Type = GetSubKey (Keys, sizeof (Keys) / sizeof (Keys [0]));
|
||||
NextTok ();
|
||||
|
||||
/* Check if we got a valid keyword */
|
||||
if (Type < 0) {
|
||||
Error (ERR_SYNTAX);
|
||||
SkipUntilSep ();
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* Read the type as numerical value */
|
||||
Type = ConstExpression ();
|
||||
if (Type < CD_TYPE_MIN || Type > CD_TYPE_MAX) {
|
||||
/* Value out of range */
|
||||
Error (ERR_RANGE);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Parse the remainder of the line and export the symbol */
|
||||
ConDes (Name, (unsigned) Type);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void DoConstructor (void)
|
||||
/* Export a symbol as constructor */
|
||||
{
|
||||
char Name [sizeof (SVal)];
|
||||
|
||||
/* Symbol name follows */
|
||||
if (Tok != TOK_IDENT) {
|
||||
ErrorSkip (ERR_IDENT_EXPECTED);
|
||||
return;
|
||||
}
|
||||
strcpy (Name, SVal);
|
||||
NextTok ();
|
||||
|
||||
/* Parse the remainder of the line and export the symbol */
|
||||
ConDes (Name, CD_TYPE_CON);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void DoData (void)
|
||||
/* Switch to the data segment */
|
||||
{
|
||||
@@ -422,6 +519,25 @@ static void DoDefine (void)
|
||||
|
||||
|
||||
|
||||
static void DoDestructor (void)
|
||||
/* Export a symbol as destructor */
|
||||
{
|
||||
char Name [sizeof (SVal)];
|
||||
|
||||
/* Symbol name follows */
|
||||
if (Tok != TOK_IDENT) {
|
||||
ErrorSkip (ERR_IDENT_EXPECTED);
|
||||
return;
|
||||
}
|
||||
strcpy (Name, SVal);
|
||||
NextTok ();
|
||||
|
||||
/* Parse the remainder of the line and export the symbol */
|
||||
ConDes (Name, CD_TYPE_DES);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void DoDWord (void)
|
||||
/* Define dwords */
|
||||
{
|
||||
@@ -736,41 +852,6 @@ static void DoInclude (void)
|
||||
|
||||
|
||||
|
||||
static void DoInitializer (void)
|
||||
/* Export a symbol as initializer */
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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
|
||||
@@ -1171,7 +1252,9 @@ static CtrlDesc CtrlCmdTab [] = {
|
||||
{ ccNone, DoCase },
|
||||
{ ccNone, DoCode },
|
||||
{ ccNone, DoUnexpected, }, /* .CONCAT */
|
||||
{ ccNone, DoConDes },
|
||||
{ ccNone, DoUnexpected }, /* .CONST */
|
||||
{ ccNone, DoConstructor },
|
||||
{ ccNone, DoUnexpected }, /* .CPU */
|
||||
{ ccNone, DoData },
|
||||
{ ccNone, DoDbg, },
|
||||
@@ -1179,6 +1262,7 @@ static CtrlDesc CtrlCmdTab [] = {
|
||||
{ ccNone, DoDebugInfo },
|
||||
{ ccNone, DoDefine },
|
||||
{ ccNone, DoUnexpected }, /* .DEFINED */
|
||||
{ ccNone, DoDestructor },
|
||||
{ ccNone, DoDWord },
|
||||
{ ccKeepToken, DoConditionals }, /* .ELSE */
|
||||
{ ccKeepToken, DoConditionals }, /* .ELSEIF */
|
||||
@@ -1215,7 +1299,6 @@ static CtrlDesc CtrlCmdTab [] = {
|
||||
{ ccNone, DoImportZP },
|
||||
{ ccNone, DoIncBin },
|
||||
{ ccNone, DoInclude },
|
||||
{ ccNone, DoInitializer },
|
||||
{ ccNone, DoInvalid }, /* .LEFT */
|
||||
{ ccNone, DoLineCont },
|
||||
{ ccNone, DoList },
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* common */
|
||||
#include "xmalloc.h"
|
||||
|
||||
@@ -106,7 +108,7 @@ static void RepeatTokenCheck (TokList* L)
|
||||
/* Called each time a token from a repeat token list is set. Is used to check
|
||||
* for and replace identifiers that are the repeat counter.
|
||||
*/
|
||||
{
|
||||
{
|
||||
if (Tok == TOK_IDENT && L->Data != 0 && strcmp (SVal, L->Data) == 0) {
|
||||
/* Must replace by the repeat counter */
|
||||
Tok = TOK_INTCON;
|
||||
|
||||
@@ -133,7 +133,9 @@ struct DotKeyword {
|
||||
{ "CASE", TOK_CASE },
|
||||
{ "CODE", TOK_CODE },
|
||||
{ "CONCAT", TOK_CONCAT },
|
||||
{ "CONDES", TOK_CONDES },
|
||||
{ "CONST", TOK_CONST },
|
||||
{ "CONSTRUCTOR", TOK_CONSTRUCTOR },
|
||||
{ "CPU", TOK_CPU },
|
||||
{ "DATA", TOK_DATA },
|
||||
{ "DBG", TOK_DBG },
|
||||
@@ -142,6 +144,7 @@ struct DotKeyword {
|
||||
{ "DEF", TOK_DEFINED },
|
||||
{ "DEFINE", TOK_DEFINE },
|
||||
{ "DEFINED", TOK_DEFINED },
|
||||
{ "DESTRUCTOR", TOK_DESTRUCTOR },
|
||||
{ "DWORD", TOK_DWORD },
|
||||
{ "ELSE", TOK_ELSE },
|
||||
{ "ELSEIF", TOK_ELSEIF },
|
||||
@@ -182,7 +185,6 @@ struct DotKeyword {
|
||||
{ "IMPORTZP", TOK_IMPORTZP },
|
||||
{ "INCBIN", TOK_INCBIN },
|
||||
{ "INCLUDE", TOK_INCLUDE },
|
||||
{ "INITIALIZER", TOK_INITIALIZER },
|
||||
{ "LEFT", TOK_LEFT },
|
||||
{ "LINECONT", TOK_LINECONT },
|
||||
{ "LIST", TOK_LIST },
|
||||
|
||||
@@ -120,8 +120,10 @@ enum Token {
|
||||
TOK_BYTE,
|
||||
TOK_CASE,
|
||||
TOK_CODE,
|
||||
TOK_CONCAT,
|
||||
TOK_CONCAT,
|
||||
TOK_CONDES,
|
||||
TOK_CONST,
|
||||
TOK_CONSTRUCTOR,
|
||||
TOK_CPU,
|
||||
TOK_DATA,
|
||||
TOK_DBG,
|
||||
@@ -129,6 +131,7 @@ enum Token {
|
||||
TOK_DEBUGINFO,
|
||||
TOK_DEFINE,
|
||||
TOK_DEFINED,
|
||||
TOK_DESTRUCTOR,
|
||||
TOK_DWORD,
|
||||
TOK_ELSE,
|
||||
TOK_ELSEIF,
|
||||
@@ -165,7 +168,6 @@ enum Token {
|
||||
TOK_IMPORTZP,
|
||||
TOK_INCBIN,
|
||||
TOK_INCLUDE,
|
||||
TOK_INITIALIZER,
|
||||
TOK_LEFT,
|
||||
TOK_LINECONT,
|
||||
TOK_LIST,
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <string.h>
|
||||
|
||||
/* common */
|
||||
#include "cddefs.h"
|
||||
#include "check.h"
|
||||
#include "hashstr.h"
|
||||
#include "symdefs.h"
|
||||
@@ -63,9 +64,8 @@
|
||||
#define SF_EXPORT 0x0004 /* Export this symbol */
|
||||
#define SF_IMPORT 0x0008 /* Import this symbol */
|
||||
#define SF_GLOBAL 0x0010 /* Global 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_ZP 0x0020 /* Declared as zeropage symbol */
|
||||
#define SF_ABS 0x0040 /* 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 */
|
||||
@@ -97,15 +97,16 @@ struct SymEntry {
|
||||
long Val; /* Value (if CONST set) */
|
||||
SymEntry* Sym; /* Symbol (if trampoline entry) */
|
||||
} V;
|
||||
unsigned char InitVal; /* Initializer value */
|
||||
unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */
|
||||
/* ...actually value+1 (used as flag) */
|
||||
char Name [1]; /* Dynamic allocation */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Definitions for the hash table */
|
||||
#define MAIN_HASHTAB_SIZE 213
|
||||
#define SUB_HASHTAB_SIZE 53
|
||||
#define MAIN_HASHTAB_SIZE 213
|
||||
#define SUB_HASHTAB_SIZE 53
|
||||
typedef struct SymTable SymTable;
|
||||
struct SymTable {
|
||||
unsigned TableSlots; /* Number of hash table slots */
|
||||
@@ -140,7 +141,7 @@ static unsigned ExportCount = 0;/* Counter for export symbols */
|
||||
|
||||
static int IsLocal (const char* Name)
|
||||
/* Return true if Name is the name of a local symbol */
|
||||
{
|
||||
{
|
||||
return (*Name == LocalStart);
|
||||
}
|
||||
|
||||
@@ -166,7 +167,7 @@ static SymEntry* NewSymEntry (const char* Name)
|
||||
S->Pos = CurPos;
|
||||
S->Flags = 0;
|
||||
S->V.Expr = 0;
|
||||
S->InitVal = 0;
|
||||
memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio));
|
||||
memcpy (S->Name, Name, Len+1);
|
||||
|
||||
/* Insert it into the list of all entries */
|
||||
@@ -579,15 +580,16 @@ void SymGlobal (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.
|
||||
void SymConDes (const char* Name, unsigned Type, unsigned Prio)
|
||||
/* Mark the given symbol as a module constructor/destructor. This will also
|
||||
* mark the symbol as an export. Initializers may never be zero page symbols.
|
||||
*/
|
||||
{
|
||||
SymEntry* S;
|
||||
|
||||
/* Check the InitVal parameter */
|
||||
CHECK (InitVal >= EXP_INIT_MIN && InitVal <= EXP_INIT_MAX);
|
||||
/* Check the parameters */
|
||||
CHECK (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX);
|
||||
CHECK (Prio >= CD_PRIO_MIN && Prio <= CD_PRIO_MAX);
|
||||
|
||||
/* Don't accept local symbols */
|
||||
if (IsLocal (Name)) {
|
||||
@@ -613,18 +615,18 @@ void SymInitializer (const char* Name, unsigned InitVal)
|
||||
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 the symbol was already declared as a condes, check if the new
|
||||
* priority value is the same as the old one.
|
||||
*/
|
||||
if (S->Flags & SF_INITIALIZER) {
|
||||
if (S->InitVal != InitVal) {
|
||||
if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
|
||||
if (S->ConDesPrio[Type] != Prio) {
|
||||
Error (ERR_SYM_REDECL_MISMATCH);
|
||||
}
|
||||
}
|
||||
S->InitVal = InitVal;
|
||||
S->ConDesPrio[Type] = Prio;
|
||||
|
||||
/* Set the symbol data */
|
||||
S->Flags |= SF_EXPORT | SF_INITIALIZER | SF_REFERENCED;
|
||||
S->Flags |= SF_EXPORT | SF_REFERENCED;
|
||||
}
|
||||
|
||||
|
||||
@@ -1064,6 +1066,7 @@ void WriteExports (void)
|
||||
/* Write the exports list to the object file */
|
||||
{
|
||||
SymEntry* S;
|
||||
unsigned Type;
|
||||
|
||||
/* Tell the object file module that we're about to start the exports */
|
||||
ObjStartExports ();
|
||||
@@ -1086,14 +1089,26 @@ void WriteExports (void)
|
||||
/* Add zeropage/abs bits */
|
||||
ExprMask |= (S->Flags & SF_ZP)? EXP_ZP : EXP_ABS;
|
||||
|
||||
/* Add the initializer bits */
|
||||
if (S->Flags & SF_INITIALIZER) {
|
||||
ExprMask |= S->InitVal;
|
||||
/* Count the number of ConDes types */
|
||||
for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
|
||||
if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
|
||||
INC_EXP_CONDES_COUNT (ExprMask);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the type */
|
||||
ObjWrite8 (ExprMask);
|
||||
|
||||
/* Write any ConDes declarations */
|
||||
if (GET_EXP_CONDES_COUNT (ExprMask) > 0) {
|
||||
for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
|
||||
unsigned char Prio = S->ConDesPrio[Type];
|
||||
if (Prio != CD_PRIO_NONE) {
|
||||
ObjWrite8 (CD_BUILD (Type, Prio));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the name */
|
||||
ObjWriteStr (S->Name);
|
||||
|
||||
@@ -1158,11 +1173,6 @@ void WriteDbgSyms (void)
|
||||
/* Add zeropage/abs bits */
|
||||
ExprMask |= (S->Flags & SF_ZP)? EXP_ZP : EXP_ABS;
|
||||
|
||||
/* Add the initializer bits */
|
||||
if (S->Flags & SF_INITIALIZER) {
|
||||
ExprMask |= S->InitVal;
|
||||
}
|
||||
|
||||
/* Write the type */
|
||||
ObjWrite8 (ExprMask);
|
||||
|
||||
|
||||
@@ -86,9 +86,9 @@ void SymGlobal (const char* Name, int ZP);
|
||||
* either imported or exported.
|
||||
*/
|
||||
|
||||
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.
|
||||
void SymConDes (const char* Name, unsigned Type, unsigned Prio);
|
||||
/* Mark the given symbol as a module constructor/destructor. This will also
|
||||
* mark the symbol as an export. Initializers may never be zero page symbols.
|
||||
*/
|
||||
|
||||
int SymIsConst (SymEntry* Sym);
|
||||
|
||||
Reference in New Issue
Block a user