Merge pull request #158 from Movax12/definedmacro

Added .DEFINEDMACRO psuedo function
This commit is contained in:
Oliver Schmidt
2015-07-12 13:32:03 +02:00
6 changed files with 237 additions and 186 deletions

View File

@@ -2316,21 +2316,25 @@ Here's a list of all control commands and a description, what they do:
</verb></tscreen> </verb></tscreen>
<sect1><tt>.ISMNEM, .ISMNEMONIC</tt><label id=".ISMNEMONIC"><p> <sect1><tt>.DEFINEDMACRO</tt><label id=".DEFINEDMACRO"><p>
Builtin function. The function expects an identifier as argument in braces. Builtin function. The function expects an identifier as argument in braces.
The argument is evaluated, and the function yields "true" if the identifier The argument is evaluated, and the function yields "true" if the identifier
is defined as an instruction mnemonic that is recognized by the assembler. has already been defined as the name of a macro. Otherwise the function yields
Example: false. Example:
<tscreen><verb> <tscreen><verb>
.if .not .ismnemonic(ina) .macro add foo
.macro ina clc
clc adc foo
adc #$01 .endmacro
.endmacro
.endif
.if .definedmacro(add)
add #$01
.else
clc
adc #$01
.endif
</verb></tscreen> </verb></tscreen>
@@ -3158,6 +3162,23 @@ Here's a list of all control commands and a description, what they do:
the feature in more detail. the feature in more detail.
<sect1><tt>.ISMNEM, .ISMNEMONIC</tt><label id=".ISMNEMONIC"><p>
Builtin function. The function expects an identifier as argument in braces.
The argument is evaluated, and the function yields "true" if the identifier
is defined as an instruction mnemonic that is recognized by the assembler.
Example:
<tscreen><verb>
.if .not .ismnemonic(ina)
.macro ina
clc
adc #$01
.endmacro
.endif
</verb></tscreen>
<sect1><tt>.LINECONT</tt><label id=".LINECONT"><p> <sect1><tt>.LINECONT</tt><label id=".LINECONT"><p>
Switch on or off line continuations using the backslash character Switch on or off line continuations using the backslash character

View File

@@ -418,30 +418,22 @@ static ExprNode* FuncDefined (void)
static ExprNode* FuncIsMnemonic (void) static ExprNode* FuncDefinedMacro (void)
/* Handle the .ISMNEMONIC, .ISMNEM builtin function */ /* Handle the .DEFINEDMACRO builtin function */
{ {
int Instr = -1; Macro* Mac = 0;
/* Check for a macro or an instruction depending on UbiquitousIdents */ /* Check if the identifier is a macro */
if (CurTok.Tok == TOK_IDENT) { if (CurTok.Tok == TOK_IDENT) {
if (UbiquitousIdents) { Mac = FindMacro (&CurTok.SVal);
/* 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 { } else {
Error ("Identifier expected."); Error ("Identifier expected.");
} }
/* Skip the name */ /* Skip the name */
NextTok (); NextTok ();
return GenLiteralExpr (Instr > 0); return GenLiteralExpr (Mac != 0);
} }
@@ -462,6 +454,36 @@ static ExprNode* FuncHiWord (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* FuncLoByte (void) ExprNode* FuncLoByte (void)
/* Handle the .LOBYTE builtin function */ /* Handle the .LOBYTE builtin function */
{ {
@@ -1094,8 +1116,8 @@ static ExprNode* Factor (void)
N = Function (FuncDefined); N = Function (FuncDefined);
break; break;
case TOK_ISMNEMONIC: case TOK_DEFINEDMACRO:
N = Function (FuncIsMnemonic); N = Function (FuncDefinedMacro);
break; break;
case TOK_HIBYTE: case TOK_HIBYTE:
@@ -1106,6 +1128,10 @@ static ExprNode* Factor (void)
N = Function (FuncHiWord); N = Function (FuncHiWord);
break; break;
case TOK_ISMNEMONIC:
N = Function (FuncIsMnemonic);
break;
case TOK_LOBYTE: case TOK_LOBYTE:
N = Function (FuncLoByte); N = Function (FuncLoByte);
break; break;

View File

@@ -83,3 +83,4 @@ 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 */ unsigned char AddrSize = 0; /* Allow .ADDRSIZE function */

View File

@@ -1989,6 +1989,7 @@ static CtrlDesc CtrlCmdTab [] = {
{ ccNone, DoDebugInfo }, { ccNone, DoDebugInfo },
{ ccNone, DoDefine }, { ccNone, DoDefine },
{ ccNone, DoUnexpected }, /* .DEFINED */ { ccNone, DoUnexpected }, /* .DEFINED */
{ ccNone, DoUnexpected }, /* .DEFINEDMACRO */
{ ccNone, DoDelMac }, { ccNone, DoDelMac },
{ ccNone, DoDestructor }, { ccNone, DoDestructor },
{ ccNone, DoDWord }, { ccNone, DoDWord },

View File

@@ -132,165 +132,166 @@ struct DotKeyword {
const char* Key; /* MUST be first field */ const char* Key; /* MUST be first field */
token_t Tok; token_t Tok;
} DotKeywords [] = { } DotKeywords [] = {
{ ".A16", TOK_A16 }, { ".A16", TOK_A16 },
{ ".A8", TOK_A8 }, { ".A8", TOK_A8 },
{ ".ADDR", TOK_ADDR }, { ".ADDR", TOK_ADDR },
{ ".ADDRSIZE", TOK_ADDRSIZE }, { ".ADDRSIZE", TOK_ADDRSIZE },
{ ".ALIGN", TOK_ALIGN }, { ".ALIGN", TOK_ALIGN },
{ ".AND", TOK_BOOLAND }, { ".AND", TOK_BOOLAND },
{ ".ASCIIZ", TOK_ASCIIZ }, { ".ASCIIZ", TOK_ASCIIZ },
{ ".ASSERT", TOK_ASSERT }, { ".ASSERT", TOK_ASSERT },
{ ".AUTOIMPORT", TOK_AUTOIMPORT }, { ".AUTOIMPORT", TOK_AUTOIMPORT },
{ ".BANK", TOK_BANK }, { ".BANK", TOK_BANK },
{ ".BANKBYTE", TOK_BANKBYTE }, { ".BANKBYTE", TOK_BANKBYTE },
{ ".BANKBYTES", TOK_BANKBYTES }, { ".BANKBYTES", TOK_BANKBYTES },
{ ".BITAND", TOK_AND }, { ".BITAND", TOK_AND },
{ ".BITNOT", TOK_NOT }, { ".BITNOT", TOK_NOT },
{ ".BITOR", TOK_OR }, { ".BITOR", TOK_OR },
{ ".BITXOR", TOK_XOR }, { ".BITXOR", TOK_XOR },
{ ".BLANK", TOK_BLANK }, { ".BLANK", TOK_BLANK },
{ ".BSS", TOK_BSS }, { ".BSS", TOK_BSS },
{ ".BYT", TOK_BYTE }, { ".BYT", TOK_BYTE },
{ ".BYTE", TOK_BYTE }, { ".BYTE", TOK_BYTE },
{ ".CASE", TOK_CASE }, { ".CASE", TOK_CASE },
{ ".CHARMAP", TOK_CHARMAP }, { ".CHARMAP", TOK_CHARMAP },
{ ".CODE", TOK_CODE }, { ".CODE", TOK_CODE },
{ ".CONCAT", TOK_CONCAT }, { ".CONCAT", TOK_CONCAT },
{ ".CONDES", TOK_CONDES }, { ".CONDES", TOK_CONDES },
{ ".CONST", TOK_CONST }, { ".CONST", TOK_CONST },
{ ".CONSTRUCTOR", TOK_CONSTRUCTOR }, { ".CONSTRUCTOR", TOK_CONSTRUCTOR },
{ ".CPU", TOK_CPU }, { ".CPU", TOK_CPU },
{ ".DATA", TOK_DATA }, { ".DATA", TOK_DATA },
{ ".DBG", TOK_DBG }, { ".DBG", TOK_DBG },
{ ".DBYT", TOK_DBYT }, { ".DBYT", TOK_DBYT },
{ ".DEBUGINFO", TOK_DEBUGINFO }, { ".DEBUGINFO", TOK_DEBUGINFO },
{ ".DEF", TOK_DEFINED }, { ".DEF", TOK_DEFINED },
{ ".DEFINE", TOK_DEFINE }, { ".DEFINE", TOK_DEFINE },
{ ".DEFINED", TOK_DEFINED }, { ".DEFINED", TOK_DEFINED },
{ ".DELMAC", TOK_DELMAC }, { ".DEFINEDMACRO", TOK_DEFINEDMACRO },
{ ".DELMACRO", TOK_DELMAC }, { ".DELMAC", TOK_DELMAC },
{ ".DESTRUCTOR", TOK_DESTRUCTOR }, { ".DELMACRO", TOK_DELMAC },
{ ".DWORD", TOK_DWORD }, { ".DESTRUCTOR", TOK_DESTRUCTOR },
{ ".ELSE", TOK_ELSE }, { ".DWORD", TOK_DWORD },
{ ".ELSEIF", TOK_ELSEIF }, { ".ELSE", TOK_ELSE },
{ ".END", TOK_END }, { ".ELSEIF", TOK_ELSEIF },
{ ".ENDENUM", TOK_ENDENUM }, { ".END", TOK_END },
{ ".ENDIF", TOK_ENDIF }, { ".ENDENUM", TOK_ENDENUM },
{ ".ENDMAC", TOK_ENDMACRO }, { ".ENDIF", TOK_ENDIF },
{ ".ENDMACRO", TOK_ENDMACRO }, { ".ENDMAC", TOK_ENDMACRO },
{ ".ENDPROC", TOK_ENDPROC }, { ".ENDMACRO", TOK_ENDMACRO },
{ ".ENDREP", TOK_ENDREP }, { ".ENDPROC", TOK_ENDPROC },
{ ".ENDREPEAT", TOK_ENDREP }, { ".ENDREP", TOK_ENDREP },
{ ".ENDSCOPE", TOK_ENDSCOPE }, { ".ENDREPEAT", TOK_ENDREP },
{ ".ENDSTRUCT", TOK_ENDSTRUCT }, { ".ENDSCOPE", TOK_ENDSCOPE },
{ ".ENDUNION", TOK_ENDUNION }, { ".ENDSTRUCT", TOK_ENDSTRUCT },
{ ".ENUM", TOK_ENUM }, { ".ENDUNION", TOK_ENDUNION },
{ ".ERROR", TOK_ERROR }, { ".ENUM", TOK_ENUM },
{ ".EXITMAC", TOK_EXITMACRO }, { ".ERROR", TOK_ERROR },
{ ".EXITMACRO", TOK_EXITMACRO }, { ".EXITMAC", TOK_EXITMACRO },
{ ".EXPORT", TOK_EXPORT }, { ".EXITMACRO", TOK_EXITMACRO },
{ ".EXPORTZP", TOK_EXPORTZP }, { ".EXPORT", TOK_EXPORT },
{ ".FARADDR", TOK_FARADDR }, { ".EXPORTZP", TOK_EXPORTZP },
{ ".FATAL", TOK_FATAL }, { ".FARADDR", TOK_FARADDR },
{ ".FEATURE", TOK_FEATURE }, { ".FATAL", TOK_FATAL },
{ ".FILEOPT", TOK_FILEOPT }, { ".FEATURE", TOK_FEATURE },
{ ".FOPT", TOK_FILEOPT }, { ".FILEOPT", TOK_FILEOPT },
{ ".FORCEIMPORT", TOK_FORCEIMPORT }, { ".FOPT", TOK_FILEOPT },
{ ".FORCEWORD", TOK_FORCEWORD }, { ".FORCEIMPORT", TOK_FORCEIMPORT },
{ ".GLOBAL", TOK_GLOBAL }, { ".FORCEWORD", TOK_FORCEWORD },
{ ".GLOBALZP", TOK_GLOBALZP }, { ".GLOBAL", TOK_GLOBAL },
{ ".HIBYTE", TOK_HIBYTE }, { ".GLOBALZP", TOK_GLOBALZP },
{ ".HIBYTES", TOK_HIBYTES }, { ".HIBYTE", TOK_HIBYTE },
{ ".HIWORD", TOK_HIWORD }, { ".HIBYTES", TOK_HIBYTES },
{ ".I16", TOK_I16 }, { ".HIWORD", TOK_HIWORD },
{ ".I8", TOK_I8 }, { ".I16", TOK_I16 },
{ ".IDENT", TOK_MAKEIDENT }, { ".I8", TOK_I8 },
{ ".IF", TOK_IF }, { ".IDENT", TOK_MAKEIDENT },
{ ".IFBLANK", TOK_IFBLANK }, { ".IF", TOK_IF },
{ ".IFCONST", TOK_IFCONST }, { ".IFBLANK", TOK_IFBLANK },
{ ".IFDEF", TOK_IFDEF }, { ".IFCONST", TOK_IFCONST },
{ ".IFNBLANK", TOK_IFNBLANK }, { ".IFDEF", TOK_IFDEF },
{ ".IFNCONST", TOK_IFNCONST }, { ".IFNBLANK", TOK_IFNBLANK },
{ ".IFNDEF", TOK_IFNDEF }, { ".IFNCONST", TOK_IFNCONST },
{ ".IFNREF", TOK_IFNREF }, { ".IFNDEF", TOK_IFNDEF },
{ ".IFP02", TOK_IFP02 }, { ".IFNREF", TOK_IFNREF },
{ ".IFP816", TOK_IFP816 }, { ".IFP02", TOK_IFP02 },
{ ".IFPC02", TOK_IFPC02 }, { ".IFP816", TOK_IFP816 },
{ ".IFPSC02", TOK_IFPSC02 }, { ".IFPC02", TOK_IFPC02 },
{ ".IFREF", TOK_IFREF }, { ".IFPSC02", TOK_IFPSC02 },
{ ".IMPORT", TOK_IMPORT }, { ".IFREF", TOK_IFREF },
{ ".IMPORTZP", TOK_IMPORTZP }, { ".IMPORT", TOK_IMPORT },
{ ".INCBIN", TOK_INCBIN }, { ".IMPORTZP", TOK_IMPORTZP },
{ ".INCLUDE", TOK_INCLUDE }, { ".INCBIN", TOK_INCBIN },
{ ".INTERRUPTOR", TOK_INTERRUPTOR }, { ".INCLUDE", TOK_INCLUDE },
{ ".ISMNEM", TOK_ISMNEMONIC }, { ".INTERRUPTOR", TOK_INTERRUPTOR },
{ ".ISMNEMONIC", TOK_ISMNEMONIC }, { ".ISMNEM", TOK_ISMNEMONIC },
{ ".LEFT", TOK_LEFT }, { ".ISMNEMONIC", TOK_ISMNEMONIC },
{ ".LINECONT", TOK_LINECONT }, { ".LEFT", TOK_LEFT },
{ ".LIST", TOK_LIST }, { ".LINECONT", TOK_LINECONT },
{ ".LISTBYTES", TOK_LISTBYTES }, { ".LIST", TOK_LIST },
{ ".LOBYTE", TOK_LOBYTE }, { ".LISTBYTES", TOK_LISTBYTES },
{ ".LOBYTES", TOK_LOBYTES }, { ".LOBYTE", TOK_LOBYTE },
{ ".LOCAL", TOK_LOCAL }, { ".LOBYTES", TOK_LOBYTES },
{ ".LOCALCHAR", TOK_LOCALCHAR }, { ".LOCAL", TOK_LOCAL },
{ ".LOWORD", TOK_LOWORD }, { ".LOCALCHAR", TOK_LOCALCHAR },
{ ".MAC", TOK_MACRO }, { ".LOWORD", TOK_LOWORD },
{ ".MACPACK", TOK_MACPACK }, { ".MAC", TOK_MACRO },
{ ".MACRO", TOK_MACRO }, { ".MACPACK", TOK_MACPACK },
{ ".MATCH", TOK_MATCH }, { ".MACRO", TOK_MACRO },
{ ".MAX", TOK_MAX }, { ".MATCH", TOK_MATCH },
{ ".MID", TOK_MID }, { ".MAX", TOK_MAX },
{ ".MIN", TOK_MIN }, { ".MID", TOK_MID },
{ ".MOD", TOK_MOD }, { ".MIN", TOK_MIN },
{ ".NOT", TOK_BOOLNOT }, { ".MOD", TOK_MOD },
{ ".NULL", TOK_NULL }, { ".NOT", TOK_BOOLNOT },
{ ".OR", TOK_BOOLOR }, { ".NULL", TOK_NULL },
{ ".ORG", TOK_ORG }, { ".OR", TOK_BOOLOR },
{ ".OUT", TOK_OUT }, { ".ORG", TOK_ORG },
{ ".P02", TOK_P02 }, { ".OUT", TOK_OUT },
{ ".P816", TOK_P816 }, { ".P02", TOK_P02 },
{ ".PAGELEN", TOK_PAGELENGTH }, { ".P816", TOK_P816 },
{ ".PAGELENGTH", TOK_PAGELENGTH }, { ".PAGELEN", TOK_PAGELENGTH },
{ ".PARAMCOUNT", TOK_PARAMCOUNT }, { ".PAGELENGTH", TOK_PAGELENGTH },
{ ".PC02", TOK_PC02 }, { ".PARAMCOUNT", TOK_PARAMCOUNT },
{ ".POPCPU", TOK_POPCPU }, { ".PC02", TOK_PC02 },
{ ".POPSEG", TOK_POPSEG }, { ".POPCPU", TOK_POPCPU },
{ ".PROC", TOK_PROC }, { ".POPSEG", TOK_POPSEG },
{ ".PSC02", TOK_PSC02 }, { ".PROC", TOK_PROC },
{ ".PUSHCPU", TOK_PUSHCPU }, { ".PSC02", TOK_PSC02 },
{ ".PUSHSEG", TOK_PUSHSEG }, { ".PUSHCPU", TOK_PUSHCPU },
{ ".REF", TOK_REFERENCED }, { ".PUSHSEG", TOK_PUSHSEG },
{ ".REFERENCED", TOK_REFERENCED }, { ".REF", TOK_REFERENCED },
{ ".RELOC", TOK_RELOC }, { ".REFERENCED", TOK_REFERENCED },
{ ".REPEAT", TOK_REPEAT }, { ".RELOC", TOK_RELOC },
{ ".RES", TOK_RES }, { ".REPEAT", TOK_REPEAT },
{ ".RIGHT", TOK_RIGHT }, { ".RES", TOK_RES },
{ ".RODATA", TOK_RODATA }, { ".RIGHT", TOK_RIGHT },
{ ".SCOPE", TOK_SCOPE }, { ".RODATA", TOK_RODATA },
{ ".SEGMENT", TOK_SEGMENT }, { ".SCOPE", TOK_SCOPE },
{ ".SET", TOK_SET }, { ".SEGMENT", TOK_SEGMENT },
{ ".SETCPU", TOK_SETCPU }, { ".SET", TOK_SET },
{ ".SHL", TOK_SHL }, { ".SETCPU", TOK_SETCPU },
{ ".SHR", TOK_SHR }, { ".SHL", TOK_SHL },
{ ".SIZEOF", TOK_SIZEOF }, { ".SHR", TOK_SHR },
{ ".SMART", TOK_SMART }, { ".SIZEOF", TOK_SIZEOF },
{ ".SPRINTF", TOK_SPRINTF }, { ".SMART", TOK_SMART },
{ ".STRAT", TOK_STRAT }, { ".SPRINTF", TOK_SPRINTF },
{ ".STRING", TOK_STRING }, { ".STRAT", TOK_STRAT },
{ ".STRLEN", TOK_STRLEN }, { ".STRING", TOK_STRING },
{ ".STRUCT", TOK_STRUCT }, { ".STRLEN", TOK_STRLEN },
{ ".TAG", TOK_TAG }, { ".STRUCT", TOK_STRUCT },
{ ".TCOUNT", TOK_TCOUNT }, { ".TAG", TOK_TAG },
{ ".TIME", TOK_TIME }, { ".TCOUNT", TOK_TCOUNT },
{ ".UNDEF", TOK_UNDEF }, { ".TIME", TOK_TIME },
{ ".UNDEFINE", TOK_UNDEF }, { ".UNDEF", TOK_UNDEF },
{ ".UNION", TOK_UNION }, { ".UNDEFINE", TOK_UNDEF },
{ ".VERSION", TOK_VERSION }, { ".UNION", TOK_UNION },
{ ".WARNING", TOK_WARNING }, { ".VERSION", TOK_VERSION },
{ ".WORD", TOK_WORD }, { ".WARNING", TOK_WARNING },
{ ".XMATCH", TOK_XMATCH }, { ".WORD", TOK_WORD },
{ ".XOR", TOK_BOOLXOR }, { ".XMATCH", TOK_XMATCH },
{ ".ZEROPAGE", TOK_ZEROPAGE }, { ".XOR", TOK_BOOLXOR },
{ ".ZEROPAGE", TOK_ZEROPAGE },
}; };

View File

@@ -148,6 +148,7 @@ typedef enum token_t {
TOK_DEBUGINFO, TOK_DEBUGINFO,
TOK_DEFINE, TOK_DEFINE,
TOK_DEFINED, TOK_DEFINED,
TOK_DEFINEDMACRO,
TOK_DELMAC, TOK_DELMAC,
TOK_DESTRUCTOR, TOK_DESTRUCTOR,
TOK_DWORD, TOK_DWORD,