mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Parentheses in macro args prevent commas from starting new arguments
This is similar to C's behavior, and convenient for passing
function calls as single values, like `MUL(3.0, 4.0)` or
`STRSUB("str", 2, 1)`.
Fixes #704
This commit is contained in:
@@ -2056,6 +2056,7 @@ static int yylex_RAW(void)
|
||||
lexer_GetLineNo(), lexer_GetColNo());
|
||||
|
||||
/* This is essentially a modified `appendStringLiteral` */
|
||||
unsigned int parenDepth = 0;
|
||||
size_t i = 0;
|
||||
int c;
|
||||
|
||||
@@ -2076,8 +2077,7 @@ static int yylex_RAW(void)
|
||||
discardComment();
|
||||
c = peek();
|
||||
/* fallthrough */
|
||||
case ',': /* End of macro arg */
|
||||
case '\r':
|
||||
case '\r': /* End of line */
|
||||
case '\n':
|
||||
case EOF:
|
||||
goto finish;
|
||||
@@ -2092,12 +2092,29 @@ static int yylex_RAW(void)
|
||||
append_yylval_string(c); /* Append the slash */
|
||||
break;
|
||||
|
||||
case ',': /* End of macro arg */
|
||||
if (parenDepth == 0)
|
||||
goto finish;
|
||||
goto append;
|
||||
|
||||
case '(': /* Open parentheses inside macro args */
|
||||
if (parenDepth < UINT_MAX)
|
||||
parenDepth++;
|
||||
goto append;
|
||||
|
||||
case ')': /* Close parentheses inside macro args */
|
||||
if (parenDepth > 0)
|
||||
parenDepth--;
|
||||
goto append;
|
||||
|
||||
case '\\': /* Character escape */
|
||||
shiftChar();
|
||||
c = peek();
|
||||
|
||||
switch (c) {
|
||||
case ',': /* Escape `\,` only inside a macro arg */
|
||||
case ',': /* Escapes only valid inside a macro arg */
|
||||
case '(':
|
||||
case ')':
|
||||
case '\\': /* Escapes shared with string literals */
|
||||
case '"':
|
||||
case '{':
|
||||
@@ -2137,6 +2154,7 @@ static int yylex_RAW(void)
|
||||
/* fallthrough */
|
||||
|
||||
default: /* Regular characters will just get copied */
|
||||
append:
|
||||
append_yylval_string(c);
|
||||
shiftChar();
|
||||
break;
|
||||
|
||||
@@ -1184,7 +1184,11 @@ ENDM
|
||||
.Pp
|
||||
Macro arguments support all the escape sequences of strings, as well as
|
||||
.Ql \[rs],
|
||||
to escape commas, since those otherwise separate arguments.
|
||||
to escape commas, as well as
|
||||
.Ql \[rs](
|
||||
and
|
||||
.Ql \[rs])
|
||||
to escape parentheses, since those otherwise separate and enclose arguments, respectively.
|
||||
.Ss Exporting and importing symbols
|
||||
Importing and exporting of symbols is a feature that is very useful when your project spans many source files and, for example, you need to jump to a routine defined in another file.
|
||||
.Pp
|
||||
@@ -1553,18 +1557,27 @@ which will print 5 and not 6 as you might have expected.
|
||||
Line continuations work as usual inside macros or lists of macro arguments.
|
||||
However, some characters need to be escaped, as in the following example:
|
||||
.Bd -literal -offset indent
|
||||
MACRO PrintMacro
|
||||
MACRO PrintMacro1
|
||||
PRINTLN STRCAT(\[rs]1)
|
||||
ENDM
|
||||
PrintMacro1 "Hello "\[rs], \[rs]
|
||||
"world"
|
||||
MACRO PrintMacro2
|
||||
PRINT \[rs]1
|
||||
ENDM
|
||||
|
||||
PrintMacro STRCAT("Hello "\[rs], \[rs]
|
||||
PrintMacro2 STRCAT("Hello ", \[rs]
|
||||
"world\[rs]n")
|
||||
.Ed
|
||||
.Pp
|
||||
The comma needs to be escaped to avoid it being treated as separating the macro's arguments.
|
||||
The comma in
|
||||
.Ql PrintMacro1
|
||||
needs to be escaped to prevent it from starting another macro argument.
|
||||
The comma in
|
||||
.Ql PrintMacro2
|
||||
does not need escaping because it is inside parentheses, similar to macro arguments in C.
|
||||
The backslash in
|
||||
.Ql \[rs]n
|
||||
does not need to be escaped because string literals also work as usual inside macro arguments.
|
||||
also does not need escaping because string literals work as usual inside macro arguments.
|
||||
.Pp
|
||||
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 angle brackets, like
|
||||
|
||||
19
test/asm/macro-arg-parentheses.asm
Normal file
19
test/asm/macro-arg-parentheses.asm
Normal file
@@ -0,0 +1,19 @@
|
||||
MACRO printargs
|
||||
REPT _NARG
|
||||
PRINTLN \1
|
||||
SHIFT
|
||||
ENDR
|
||||
ENDM
|
||||
|
||||
printargs mul(3.0, 4.0)
|
||||
|
||||
MACRO printlit
|
||||
REPT _NARG
|
||||
PRINTLN "\1"
|
||||
SHIFT
|
||||
ENDR
|
||||
ENDM
|
||||
|
||||
printlit a(b,c\,d), ((e,f),g), ))h, i\,j,
|
||||
printlit \(k, l), (m:\)n,o(p)q), (r,s)t
|
||||
printlit "))u,v(", ("w,x","y,z"),
|
||||
0
test/asm/macro-arg-parentheses.err
Normal file
0
test/asm/macro-arg-parentheses.err
Normal file
11
test/asm/macro-arg-parentheses.out
Normal file
11
test/asm/macro-arg-parentheses.out
Normal file
@@ -0,0 +1,11 @@
|
||||
$C0000
|
||||
a(b,c,d)
|
||||
((e,f),g)
|
||||
))h
|
||||
i,j
|
||||
(k
|
||||
l)
|
||||
(m:)n,o(p)q)
|
||||
(r,s)t
|
||||
"))u,v("
|
||||
("w,x","y,z")
|
||||
@@ -22,7 +22,7 @@ STR EQUS "str\"ing"
|
||||
printargs "literal \"\\\"", \ ; comment 2
|
||||
"""multi-"line"
|
||||
""string"" arg"""
|
||||
printargs MUL(2.0\, 3.0)
|
||||
printargs MUL(2.0, 3.0)
|
||||
printargs "unclosed
|
||||
|
||||
printlit NUM
|
||||
@@ -32,7 +32,7 @@ STR EQUS "str\"ing"
|
||||
printlit "literal \"\\\"", \ ; comment 4
|
||||
"""multi-"line"
|
||||
""string"" arg"""
|
||||
printlit MUL(2.0\, 3.0)
|
||||
printlit MUL(2.0, 3.0)
|
||||
printlit this\n is\, \{not\} a\\n syntax\" error
|
||||
printlit "unclosed
|
||||
printlit """EOF
|
||||
Reference in New Issue
Block a user