mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Support numeric symbol names in \(parentheses)
For example, \(_NARG) will get the last argument
This commit is contained in:
@@ -724,6 +724,8 @@ static bool isMacroChar(char c)
|
|||||||
static int peek(void);
|
static int peek(void);
|
||||||
static void shiftChar(void);
|
static void shiftChar(void);
|
||||||
static uint32_t readNumber(int radix, uint32_t baseValue);
|
static uint32_t readNumber(int radix, uint32_t baseValue);
|
||||||
|
static bool startsIdentifier(int c);
|
||||||
|
static bool continuesIdentifier(int c);
|
||||||
|
|
||||||
static uint32_t readParentheticMacroArgNum(void)
|
static uint32_t readParentheticMacroArgNum(void)
|
||||||
{
|
{
|
||||||
@@ -736,15 +738,42 @@ static uint32_t readParentheticMacroArgNum(void)
|
|||||||
|
|
||||||
uint32_t num = 0;
|
uint32_t num = 0;
|
||||||
int c = peek();
|
int c = peek();
|
||||||
bool hasDigit = c >= '0' && c <= '9';
|
bool empty = false;
|
||||||
|
|
||||||
if (hasDigit)
|
if (c >= '0' && c <= '9') {
|
||||||
num = readNumber(10, 0);
|
num = readNumber(10, 0);
|
||||||
|
} else if (startsIdentifier(c)) {
|
||||||
|
char symName[MAXSYMLEN + 1];
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
for (; continuesIdentifier(c); c = peek()) {
|
||||||
|
if (i < sizeof(symName))
|
||||||
|
symName[i++] = c;
|
||||||
|
shiftChar();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == sizeof(symName)) {
|
||||||
|
warning(WARNING_LONG_STR, "Symbol name too long\n");
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
symName[i] = '\0';
|
||||||
|
|
||||||
|
struct Symbol const *sym = sym_FindScopedSymbol(symName);
|
||||||
|
|
||||||
|
if (!sym)
|
||||||
|
fatalerror("Parenthetic symbol \"%s\" does not exist\n", symName);
|
||||||
|
else if (!sym_IsNumeric(sym))
|
||||||
|
fatalerror("Parenthetic symbol \"%s\" is not numeric\n", symName);
|
||||||
|
|
||||||
|
num = sym_GetConstantSymValue(sym);
|
||||||
|
} else {
|
||||||
|
empty = true;
|
||||||
|
}
|
||||||
|
|
||||||
c = peek();
|
c = peek();
|
||||||
if (c != ')')
|
if (c != ')')
|
||||||
fatalerror("Invalid character in parenthetic macro argument %s\n", printChar(c));
|
fatalerror("Invalid character in parenthetic macro argument %s\n", printChar(c));
|
||||||
else if (!hasDigit)
|
else if (empty)
|
||||||
fatalerror("Empty parenthetic macro argument\n");
|
fatalerror("Empty parenthetic macro argument\n");
|
||||||
else if (num == 0)
|
else if (num == 0)
|
||||||
fatalerror("Invalid parenthetic macro argument '\\(0)'\n");
|
fatalerror("Invalid parenthetic macro argument '\\(0)'\n");
|
||||||
|
|||||||
@@ -1569,7 +1569,10 @@ does not need to be escaped because string literals also work as usual inside ma
|
|||||||
Since there are only nine digits, you can only access the first nine macro arguments like this.
|
Since there are only nine digits, you can only access the first nine macro arguments like this.
|
||||||
To use the rest, you need to put the multi-digit argument number in parentheses, like
|
To use the rest, you need to put the multi-digit argument number in parentheses, like
|
||||||
.Ql \[rs](10) .
|
.Ql \[rs](10) .
|
||||||
This parenthetic syntax only supports decimal numbers.
|
This parenthetic syntax supports decimal numbers and numeric symbol names.
|
||||||
|
For example,
|
||||||
|
.Ql \[rs](_NARG)
|
||||||
|
will get the last argument.
|
||||||
.Pp
|
.Pp
|
||||||
Other macro arguments and symbol interpolations will be expanded inside the parentheses.
|
Other macro arguments and symbol interpolations will be expanded inside the parentheses.
|
||||||
For example, if
|
For example, if
|
||||||
@@ -1580,10 +1583,12 @@ then
|
|||||||
.Ql \[rs](\[rs]1)
|
.Ql \[rs](\[rs]1)
|
||||||
will expand to
|
will expand to
|
||||||
.Ql \[rs](13) .
|
.Ql \[rs](13) .
|
||||||
And if
|
Or if
|
||||||
.Ql x = 42 ,
|
.Ql v10 = 42
|
||||||
|
and
|
||||||
|
.Ql x = 10 ,
|
||||||
then
|
then
|
||||||
.Ql \[rs]({d:x})
|
.Ql \[rs](v{d:x})
|
||||||
will expand to
|
will expand to
|
||||||
.Ql \[rs](42) .
|
.Ql \[rs](42) .
|
||||||
.Pp
|
.Pp
|
||||||
|
|||||||
1
test/asm/invalid-macro-arg-symbol.asm
Normal file
1
test/asm/invalid-macro-arg-symbol.asm
Normal file
@@ -0,0 +1 @@
|
|||||||
|
\(foo)
|
||||||
2
test/asm/invalid-macro-arg-symbol.err
Normal file
2
test/asm/invalid-macro-arg-symbol.err
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
FATAL: invalid-macro-arg-symbol.asm(1):
|
||||||
|
Parenthetic symbol "foo" does not exist
|
||||||
0
test/asm/invalid-macro-arg-symbol.out
Normal file
0
test/asm/invalid-macro-arg-symbol.out
Normal file
@@ -12,6 +12,8 @@ MACRO mac
|
|||||||
println \(2__) + \(1_2) + \(\1)
|
println \(2__) + \(1_2) + \(\1)
|
||||||
x = 2
|
x = 2
|
||||||
println \({d:x}) + \(1_{d:x}) + \(\(\(13)))
|
println \({d:x}) + \(1_{d:x}) + \(\(\(13)))
|
||||||
|
y equs "NARG"
|
||||||
|
println \(x) + \(1_{d:x}_) + \(\(\(_{y})))
|
||||||
ENDM
|
ENDM
|
||||||
|
|
||||||
mac 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 1
|
mac 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 1
|
||||||
|
|||||||
@@ -4,3 +4,4 @@ next = C
|
|||||||
last = D
|
last = D
|
||||||
$F0
|
$F0
|
||||||
$F0
|
$F0
|
||||||
|
$F0
|
||||||
|
|||||||
Reference in New Issue
Block a user