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 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");

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. 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

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) 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

View File

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