Added function .ADDRSIZE to ca65
This commit is contained in:
parent
ae4f9336b3
commit
c6f45a338c
8 changed files with 116 additions and 1 deletions
|
@ -629,6 +629,92 @@ static ExprNode* FuncReferenced (void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static ExprNode* FuncAddrSize(void)
|
||||||
|
/* Handle the .ADDRSIZE function */
|
||||||
|
{
|
||||||
|
StrBuf ScopeName = STATIC_STRBUF_INITIALIZER;
|
||||||
|
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
||||||
|
SymEntry* Sym;
|
||||||
|
int AddrSize;
|
||||||
|
int NoScope;
|
||||||
|
|
||||||
|
|
||||||
|
/* Assume we don't know the size */
|
||||||
|
AddrSize = 0;
|
||||||
|
|
||||||
|
/* Check for a cheap local which needs special handling */
|
||||||
|
if (CurTok.Tok == TOK_LOCAL_IDENT) {
|
||||||
|
|
||||||
|
/* Cheap local symbol */
|
||||||
|
Sym = SymFindLocal(SymLast, &CurTok.SVal, SYM_FIND_EXISTING);
|
||||||
|
if (Sym == 0) {
|
||||||
|
Error("Unknown symbol or scope: `%m%p'", &CurTok.SVal);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AddrSize = Sym->AddrSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remember and skip SVal, terminate ScopeName so it is empty */
|
||||||
|
SB_Copy(&Name, &CurTok.SVal);
|
||||||
|
NextTok();
|
||||||
|
SB_Terminate(&ScopeName);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
/* Parse the scope and the name */
|
||||||
|
SymTable* ParentScope = ParseScopedIdent(&Name, &ScopeName);
|
||||||
|
|
||||||
|
/* Check if the parent scope is valid */
|
||||||
|
if (ParentScope == 0) {
|
||||||
|
/* No such scope */
|
||||||
|
SB_Done(&ScopeName);
|
||||||
|
SB_Done(&Name);
|
||||||
|
return GenLiteral0();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If ScopeName is empty, no explicit scope was specified. We have to
|
||||||
|
* search upper scope levels in this case.
|
||||||
|
*/
|
||||||
|
NoScope = SB_IsEmpty(&ScopeName);
|
||||||
|
|
||||||
|
/* If we did find a scope with the name, read the symbol defining the
|
||||||
|
* size, otherwise search for a symbol entry with the name and scope.
|
||||||
|
*/
|
||||||
|
if (NoScope) {
|
||||||
|
Sym = SymFindAny(ParentScope, &Name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Sym = SymFind(ParentScope, &Name, SYM_FIND_EXISTING);
|
||||||
|
}
|
||||||
|
/* If we found the symbol retrieve the size, otherwise complain */
|
||||||
|
if (Sym) {
|
||||||
|
AddrSize = Sym->AddrSize;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Error("Unknown symbol or scope: `%m%p%m%p'",
|
||||||
|
&ScopeName, &Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we have a size */
|
||||||
|
/* if we don't know, return it anyway, zero can mean unknown, or uncomment this code for an error
|
||||||
|
if (AddrSize == 0 ) {
|
||||||
|
Error ("Address size of `%m%p%m%p' is unknown", &ScopeName, &Name);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Free the string buffers */
|
||||||
|
SB_Done(&ScopeName);
|
||||||
|
SB_Done(&Name);
|
||||||
|
|
||||||
|
/* Return the size */
|
||||||
|
return GenLiteralExpr(AddrSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static ExprNode* FuncSizeOf (void)
|
static ExprNode* FuncSizeOf (void)
|
||||||
/* Handle the .SIZEOF function */
|
/* Handle the .SIZEOF function */
|
||||||
{
|
{
|
||||||
|
@ -965,6 +1051,10 @@ static ExprNode* Factor (void)
|
||||||
N = Function (FuncBankByte);
|
N = Function (FuncBankByte);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TOK_ADDRSIZE:
|
||||||
|
N = Function(FuncAddrSize);
|
||||||
|
break;
|
||||||
|
|
||||||
case TOK_BLANK:
|
case TOK_BLANK:
|
||||||
N = Function (FuncBlank);
|
N = Function (FuncBlank);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -63,6 +63,7 @@ static const char* FeatureKeys[FEAT_COUNT] = {
|
||||||
"c_comments",
|
"c_comments",
|
||||||
"force_range",
|
"force_range",
|
||||||
"underline_in_numbers",
|
"underline_in_numbers",
|
||||||
|
"addrsize",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,6 +120,7 @@ feature_t SetFeature (const StrBuf* Key)
|
||||||
case FEAT_C_COMMENTS: CComments = 1; break;
|
case FEAT_C_COMMENTS: CComments = 1; break;
|
||||||
case FEAT_FORCE_RANGE: ForceRange = 1; break;
|
case FEAT_FORCE_RANGE: ForceRange = 1; break;
|
||||||
case FEAT_UNDERLINE_IN_NUMBERS: UnderlineInNumbers= 1; break;
|
case FEAT_UNDERLINE_IN_NUMBERS: UnderlineInNumbers= 1; break;
|
||||||
|
case FEAT_ADDRSIZE: AddrSize = 1; break;
|
||||||
default: /* Keep gcc silent */ break;
|
default: /* Keep gcc silent */ break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ typedef enum {
|
||||||
FEAT_C_COMMENTS,
|
FEAT_C_COMMENTS,
|
||||||
FEAT_FORCE_RANGE,
|
FEAT_FORCE_RANGE,
|
||||||
FEAT_UNDERLINE_IN_NUMBERS,
|
FEAT_UNDERLINE_IN_NUMBERS,
|
||||||
|
FEAT_ADDRSIZE,
|
||||||
|
|
||||||
/* Special value: Number of features available */
|
/* Special value: Number of features available */
|
||||||
FEAT_COUNT
|
FEAT_COUNT
|
||||||
|
|
|
@ -82,3 +82,4 @@ unsigned char OrgPerSeg = 0; /* Make .org local to current seg */
|
||||||
unsigned char CComments = 0; /* Allow C like comments */
|
unsigned char CComments = 0; /* Allow C like comments */
|
||||||
unsigned char ForceRange = 0; /* Force values into expected range */
|
unsigned char ForceRange = 0; /* Force values into expected range */
|
||||||
unsigned char UnderlineInNumbers = 0; /* Allow underlines in numbers */
|
unsigned char UnderlineInNumbers = 0; /* Allow underlines in numbers */
|
||||||
|
unsigned char AddrSize = 0; /* Allow .ADDRSIZE function */
|
||||||
|
|
|
@ -84,6 +84,8 @@ extern unsigned char OrgPerSeg; /* Make .org local to current seg */
|
||||||
extern unsigned char CComments; /* Allow C like comments */
|
extern unsigned char CComments; /* Allow C like comments */
|
||||||
extern unsigned char ForceRange; /* Force values into expected range */
|
extern unsigned char ForceRange; /* Force values into expected range */
|
||||||
extern unsigned char UnderlineInNumbers; /* Allow underlines in numbers */
|
extern unsigned char UnderlineInNumbers; /* Allow underlines in numbers */
|
||||||
|
extern unsigned char AddrSize; /* Allow .ADDRSIZE function */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1964,6 +1964,7 @@ static CtrlDesc CtrlCmdTab [] = {
|
||||||
{ ccNone, DoA16 },
|
{ ccNone, DoA16 },
|
||||||
{ ccNone, DoA8 },
|
{ ccNone, DoA8 },
|
||||||
{ ccNone, DoAddr }, /* .ADDR */
|
{ ccNone, DoAddr }, /* .ADDR */
|
||||||
|
{ ccNone, DoUnexpected }, /* .ADDRSIZE */
|
||||||
{ ccNone, DoAlign },
|
{ ccNone, DoAlign },
|
||||||
{ ccNone, DoASCIIZ },
|
{ ccNone, DoASCIIZ },
|
||||||
{ ccNone, DoAssert },
|
{ ccNone, DoAssert },
|
||||||
|
|
|
@ -135,6 +135,7 @@ struct DotKeyword {
|
||||||
{ ".A16", TOK_A16 },
|
{ ".A16", TOK_A16 },
|
||||||
{ ".A8", TOK_A8 },
|
{ ".A8", TOK_A8 },
|
||||||
{ ".ADDR", TOK_ADDR },
|
{ ".ADDR", TOK_ADDR },
|
||||||
|
{ ".ADDRSIZE", TOK_ADDRSIZE },
|
||||||
{ ".ALIGN", TOK_ALIGN },
|
{ ".ALIGN", TOK_ALIGN },
|
||||||
{ ".AND", TOK_BOOLAND },
|
{ ".AND", TOK_BOOLAND },
|
||||||
{ ".ASCIIZ", TOK_ASCIIZ },
|
{ ".ASCIIZ", TOK_ASCIIZ },
|
||||||
|
@ -723,8 +724,24 @@ static token_t FindDotKeyword (void)
|
||||||
R = bsearch (&K, DotKeywords, sizeof (DotKeywords) / sizeof (DotKeywords [0]),
|
R = bsearch (&K, DotKeywords, sizeof (DotKeywords) / sizeof (DotKeywords [0]),
|
||||||
sizeof (DotKeywords [0]), CmpDotKeyword);
|
sizeof (DotKeywords [0]), CmpDotKeyword);
|
||||||
if (R != 0) {
|
if (R != 0) {
|
||||||
|
|
||||||
|
/* By default, disable any somewhat experiemental DotKeyword. */
|
||||||
|
|
||||||
|
switch (R->Tok) {
|
||||||
|
|
||||||
|
case TOK_ADDRSIZE:
|
||||||
|
/* Disallow .ADDRSIZE function by default */
|
||||||
|
if (AddrSize == 0) {
|
||||||
|
return TOK_NONE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
return R->Tok;
|
return R->Tok;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return TOK_NONE;
|
return TOK_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,6 +123,7 @@ typedef enum token_t {
|
||||||
TOK_A16 = TOK_FIRSTPSEUDO,
|
TOK_A16 = TOK_FIRSTPSEUDO,
|
||||||
TOK_A8,
|
TOK_A8,
|
||||||
TOK_ADDR,
|
TOK_ADDR,
|
||||||
|
TOK_ADDRSIZE,
|
||||||
TOK_ALIGN,
|
TOK_ALIGN,
|
||||||
TOK_ASCIIZ,
|
TOK_ASCIIZ,
|
||||||
TOK_ASSERT,
|
TOK_ASSERT,
|
||||||
|
|
Loading…
Add table
Reference in a new issue