Merge remote-tracking branch 'upstream/master' into pcenginetarget
This commit is contained in:
116
src/ca65/expr.c
116
src/ca65/expr.c
@@ -62,6 +62,7 @@
|
||||
#include "symtab.h"
|
||||
#include "toklist.h"
|
||||
#include "ulabel.h"
|
||||
#include "macro.h"
|
||||
|
||||
|
||||
|
||||
@@ -417,6 +418,34 @@ static ExprNode* FuncDefined (void)
|
||||
|
||||
|
||||
|
||||
static ExprNode* FuncIsMnemonic (void)
|
||||
/* Handle the .ISMNEMONIC, .ISMNEM builtin function */
|
||||
{
|
||||
int Instr = -1;
|
||||
|
||||
/* Check for a macro or an instruction depending on UbiquitousIdents */
|
||||
|
||||
if (CurTok.Tok == TOK_IDENT) {
|
||||
if (UbiquitousIdents) {
|
||||
/* Macros CAN be instructions, so check for them first */
|
||||
if (FindMacro (&CurTok.SVal) == 0) {
|
||||
Instr = FindInstruction (&CurTok.SVal);
|
||||
}
|
||||
} else {
|
||||
/* Macros and symbols may NOT use the names of instructions, so just check for the instruction */
|
||||
Instr = FindInstruction (&CurTok.SVal);
|
||||
}
|
||||
} else {
|
||||
Error ("Identifier expected.");
|
||||
}
|
||||
/* Skip the name */
|
||||
NextTok ();
|
||||
|
||||
return GenLiteralExpr (Instr > 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ExprNode* FuncHiByte (void)
|
||||
/* Handle the .HIBYTE builtin function */
|
||||
{
|
||||
@@ -629,6 +658,85 @@ 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (AddrSize == 0) {
|
||||
Warning (1, "Unknown address size: `%m%p%m%p'", &ScopeName, &Name);
|
||||
}
|
||||
|
||||
/* Free the string buffers */
|
||||
SB_Done (&ScopeName);
|
||||
SB_Done (&Name);
|
||||
|
||||
/* Return the size. */
|
||||
|
||||
return GenLiteralExpr (AddrSize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ExprNode* FuncSizeOf (void)
|
||||
/* Handle the .SIZEOF function */
|
||||
{
|
||||
@@ -965,6 +1073,10 @@ static ExprNode* Factor (void)
|
||||
N = Function (FuncBankByte);
|
||||
break;
|
||||
|
||||
case TOK_ADDRSIZE:
|
||||
N = Function (FuncAddrSize);
|
||||
break;
|
||||
|
||||
case TOK_BLANK:
|
||||
N = Function (FuncBlank);
|
||||
break;
|
||||
@@ -982,6 +1094,10 @@ static ExprNode* Factor (void)
|
||||
N = Function (FuncDefined);
|
||||
break;
|
||||
|
||||
case TOK_ISMNEMONIC:
|
||||
N = Function (FuncIsMnemonic);
|
||||
break;
|
||||
|
||||
case TOK_HIBYTE:
|
||||
N = Function (FuncHiByte);
|
||||
break;
|
||||
|
||||
@@ -63,6 +63,7 @@ static const char* FeatureKeys[FEAT_COUNT] = {
|
||||
"c_comments",
|
||||
"force_range",
|
||||
"underline_in_numbers",
|
||||
"addrsize",
|
||||
};
|
||||
|
||||
|
||||
@@ -119,6 +120,7 @@ feature_t SetFeature (const StrBuf* Key)
|
||||
case FEAT_C_COMMENTS: CComments = 1; break;
|
||||
case FEAT_FORCE_RANGE: ForceRange = 1; break;
|
||||
case FEAT_UNDERLINE_IN_NUMBERS: UnderlineInNumbers= 1; break;
|
||||
case FEAT_ADDRSIZE: AddrSize = 1; break;
|
||||
default: /* Keep gcc silent */ break;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ typedef enum {
|
||||
FEAT_C_COMMENTS,
|
||||
FEAT_FORCE_RANGE,
|
||||
FEAT_UNDERLINE_IN_NUMBERS,
|
||||
FEAT_ADDRSIZE,
|
||||
|
||||
/* Special value: Number of features available */
|
||||
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 ForceRange = 0; /* Force values into expected range */
|
||||
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 ForceRange; /* Force values into expected range */
|
||||
extern unsigned char UnderlineInNumbers; /* Allow underlines in numbers */
|
||||
extern unsigned char AddrSize; /* Allow .ADDRSIZE function */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -713,9 +713,9 @@ static const struct {
|
||||
{ "ROR", 0x000006F, 0x62, 1, PutAll },
|
||||
{ "RTI", 0x0000001, 0x40, 0, PutAll },
|
||||
{ "RTS", 0x0000001, 0x60, 0, PutAll },
|
||||
{ "SBC", 0x080A66C, 0xe0, 0, PutAll },
|
||||
{ "SAX", 0x0000001, 0x22, 0, PutAll },
|
||||
{ "SAY", 0x0000001, 0x42, 0, PutAll },
|
||||
{ "SBC", 0x080A66C, 0xe0, 0, PutAll },
|
||||
{ "SEC", 0x0000001, 0x38, 0, PutAll },
|
||||
{ "SED", 0x0000001, 0xf8, 0, PutAll },
|
||||
{ "SEI", 0x0000001, 0x78, 0, PutAll },
|
||||
|
||||
@@ -303,6 +303,10 @@ static void SetSys (const char* Sys)
|
||||
NewSymbol ("__SIM65C02__", 1);
|
||||
break;
|
||||
|
||||
case TGT_OSIC1P:
|
||||
NewSymbol ("__OSIC1P__", 1);
|
||||
break;
|
||||
|
||||
case TGT_PCENGINE:
|
||||
NewSymbol ("__PCE__", 1);
|
||||
break;
|
||||
|
||||
@@ -1964,6 +1964,7 @@ static CtrlDesc CtrlCmdTab [] = {
|
||||
{ ccNone, DoA16 },
|
||||
{ ccNone, DoA8 },
|
||||
{ ccNone, DoAddr }, /* .ADDR */
|
||||
{ ccNone, DoUnexpected }, /* .ADDRSIZE */
|
||||
{ ccNone, DoAlign },
|
||||
{ ccNone, DoASCIIZ },
|
||||
{ ccNone, DoAssert },
|
||||
@@ -2039,6 +2040,7 @@ static CtrlDesc CtrlCmdTab [] = {
|
||||
{ ccNone, DoIncBin },
|
||||
{ ccNone, DoInclude },
|
||||
{ ccNone, DoInterruptor },
|
||||
{ ccNone, DoUnexpected }, /* .ISMNEMONIC */
|
||||
{ ccNone, DoInvalid }, /* .LEFT */
|
||||
{ ccNone, DoLineCont },
|
||||
{ ccNone, DoList },
|
||||
|
||||
@@ -135,6 +135,7 @@ struct DotKeyword {
|
||||
{ ".A16", TOK_A16 },
|
||||
{ ".A8", TOK_A8 },
|
||||
{ ".ADDR", TOK_ADDR },
|
||||
{ ".ADDRSIZE", TOK_ADDRSIZE },
|
||||
{ ".ALIGN", TOK_ALIGN },
|
||||
{ ".AND", TOK_BOOLAND },
|
||||
{ ".ASCIIZ", TOK_ASCIIZ },
|
||||
@@ -222,6 +223,8 @@ struct DotKeyword {
|
||||
{ ".INCBIN", TOK_INCBIN },
|
||||
{ ".INCLUDE", TOK_INCLUDE },
|
||||
{ ".INTERRUPTOR", TOK_INTERRUPTOR },
|
||||
{ ".ISMNEM", TOK_ISMNEMONIC },
|
||||
{ ".ISMNEMONIC", TOK_ISMNEMONIC },
|
||||
{ ".LEFT", TOK_LEFT },
|
||||
{ ".LINECONT", TOK_LINECONT },
|
||||
{ ".LIST", TOK_LIST },
|
||||
@@ -723,7 +726,24 @@ static token_t FindDotKeyword (void)
|
||||
R = bsearch (&K, DotKeywords, sizeof (DotKeywords) / sizeof (DotKeywords [0]),
|
||||
sizeof (DotKeywords [0]), CmpDotKeyword);
|
||||
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;
|
||||
|
||||
} else {
|
||||
return TOK_NONE;
|
||||
}
|
||||
|
||||
@@ -696,10 +696,10 @@ void SymDump (FILE* F)
|
||||
|
||||
while (S) {
|
||||
/* Ignore unused symbols */
|
||||
if ((S->Flags & SF_UNUSED) != 0) {
|
||||
if ((S->Flags & SF_UNUSED) == 0) {
|
||||
fprintf (F,
|
||||
"%m%-24p %s %s %s %s %s\n",
|
||||
GetSymName (S),
|
||||
"%-24s %s %s %s %s %s\n",
|
||||
SB_GetConstBuf (GetSymName (S)),
|
||||
(S->Flags & SF_DEFINED)? "DEF" : "---",
|
||||
(S->Flags & SF_REFERENCED)? "REF" : "---",
|
||||
(S->Flags & SF_IMPORT)? "IMP" : "---",
|
||||
|
||||
@@ -123,6 +123,7 @@ typedef enum token_t {
|
||||
TOK_A16 = TOK_FIRSTPSEUDO,
|
||||
TOK_A8,
|
||||
TOK_ADDR,
|
||||
TOK_ADDRSIZE,
|
||||
TOK_ALIGN,
|
||||
TOK_ASCIIZ,
|
||||
TOK_ASSERT,
|
||||
@@ -198,6 +199,7 @@ typedef enum token_t {
|
||||
TOK_INCBIN,
|
||||
TOK_INCLUDE,
|
||||
TOK_INTERRUPTOR,
|
||||
TOK_ISMNEMONIC,
|
||||
TOK_LEFT,
|
||||
TOK_LINECONT,
|
||||
TOK_LIST,
|
||||
|
||||
Reference in New Issue
Block a user