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:
cuz
2000-11-20 15:22:57 +00:00
parent 9c35f5278a
commit b9970cb7da
35 changed files with 1029 additions and 388 deletions

View File

@@ -33,6 +33,8 @@
#include <string.h>
/* ca65 */
#include "error.h"
#include "expr.h"

View File

@@ -33,6 +33,8 @@
#include <string.h>
/* common */
#include "check.h"
#include "exprdefs.h"

View File

@@ -33,6 +33,8 @@
#include <string.h>
/* common */
#include "check.h"
#include "hashstr.h"

View File

@@ -34,10 +34,11 @@
#include <stdio.h>
#include <string.h>
/* common */
#include "check.h"
/* ca65 */
#include "error.h"
#include "expr.h"

View File

@@ -33,6 +33,8 @@
#include <string.h>
/* common */
#include "optdefs.h"
#include "xmalloc.h"

View File

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

View File

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

View File

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

View File

@@ -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,

View File

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

View File

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