Support numeric symbol names in \(parentheses)

For example, \(_NARG) will get the last argument
This commit is contained in:
Rangi
2021-04-18 23:47:10 -04:00
committed by Eldred Habert
parent 637bbbdf43
commit 7a314e7aff
7 changed files with 47 additions and 7 deletions

View File

@@ -724,6 +724,8 @@ static bool isMacroChar(char c)
static int peek(void);
static void shiftChar(void);
static uint32_t readNumber(int radix, uint32_t baseValue);
static bool startsIdentifier(int c);
static bool continuesIdentifier(int c);
static uint32_t readParentheticMacroArgNum(void)
{
@@ -736,15 +738,42 @@ static uint32_t readParentheticMacroArgNum(void)
uint32_t num = 0;
int c = peek();
bool hasDigit = c >= '0' && c <= '9';
bool empty = false;
if (hasDigit)
if (c >= '0' && c <= '9') {
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();
if (c != ')')
fatalerror("Invalid character in parenthetic macro argument %s\n", printChar(c));
else if (!hasDigit)
else if (empty)
fatalerror("Empty parenthetic macro argument\n");
else if (num == 0)
fatalerror("Invalid parenthetic macro argument '\\(0)'\n");

View File

@@ -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.
To use the rest, you need to put the multi-digit argument number in parentheses, like
.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
Other macro arguments and symbol interpolations will be expanded inside the parentheses.
For example, if
@@ -1580,10 +1583,12 @@ then
.Ql \[rs](\[rs]1)
will expand to
.Ql \[rs](13) .
And if
.Ql x = 42 ,
Or if
.Ql v10 = 42
and
.Ql x = 10 ,
then
.Ql \[rs]({d:x})
.Ql \[rs](v{d:x})
will expand to
.Ql \[rs](42) .
.Pp

View File

@@ -0,0 +1 @@
\(foo)

View File

@@ -0,0 +1,2 @@
FATAL: invalid-macro-arg-symbol.asm(1):
Parenthetic symbol "foo" does not exist

View File

View File

@@ -12,6 +12,8 @@ MACRO mac
println \(2__) + \(1_2) + \(\1)
x = 2
println \({d:x}) + \(1_{d:x}) + \(\(\(13)))
y equs "NARG"
println \(x) + \(1_{d:x}_) + \(\(\(_{y})))
ENDM
mac 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 1

View File

@@ -4,3 +4,4 @@ next = C
last = D
$F0
$F0
$F0