mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Make failed macro arg expansions non-fatal
Expanding empty strings is valid but pointless;
macro args already skipped doing so, now other
`beginExpansion` calls do too.
This also fixes failed interpolations (which were
already non-fatal) to continue reading characters,
not evaluate to their initial '{' character.
This commit is contained in:
@@ -739,6 +739,7 @@ static uint32_t readBracketedMacroArgNum(void)
|
|||||||
uint32_t num = 0;
|
uint32_t num = 0;
|
||||||
int c = peek();
|
int c = peek();
|
||||||
bool empty = false;
|
bool empty = false;
|
||||||
|
bool symbolError = false;
|
||||||
|
|
||||||
if (c >= '0' && c <= '9') {
|
if (c >= '0' && c <= '9') {
|
||||||
num = readNumber(10, 0);
|
num = readNumber(10, 0);
|
||||||
@@ -760,25 +761,33 @@ static uint32_t readBracketedMacroArgNum(void)
|
|||||||
|
|
||||||
struct Symbol const *sym = sym_FindScopedSymbol(symName);
|
struct Symbol const *sym = sym_FindScopedSymbol(symName);
|
||||||
|
|
||||||
if (!sym)
|
if (!sym) {
|
||||||
fatalerror("Bracketed symbol \"%s\" does not exist\n", symName);
|
error("Bracketed symbol \"%s\" does not exist\n", symName);
|
||||||
else if (!sym_IsNumeric(sym))
|
num = 0;
|
||||||
fatalerror("Bracketed symbol \"%s\" is not numeric\n", symName);
|
symbolError = true;
|
||||||
|
} else if (!sym_IsNumeric(sym)) {
|
||||||
num = sym_GetConstantSymValue(sym);
|
error("Bracketed symbol \"%s\" is not numeric\n", symName);
|
||||||
|
num = 0;
|
||||||
|
symbolError = true;
|
||||||
|
} else {
|
||||||
|
num = sym_GetConstantSymValue(sym);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
empty = true;
|
empty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
c = peek();
|
c = peek();
|
||||||
if (c != '>')
|
|
||||||
fatalerror("Invalid character in bracketed macro argument %s\n", printChar(c));
|
|
||||||
else if (empty)
|
|
||||||
fatalerror("Empty bracketed macro argument\n");
|
|
||||||
else if (num == 0)
|
|
||||||
fatalerror("Invalid bracketed macro argument '\\<0>'\n");
|
|
||||||
|
|
||||||
shiftChar();
|
shiftChar();
|
||||||
|
if (c != '>') {
|
||||||
|
error("Invalid character in bracketed macro argument %s\n", printChar(c));
|
||||||
|
return 0;
|
||||||
|
} else if (empty) {
|
||||||
|
error("Empty bracketed macro argument\n");
|
||||||
|
return 0;
|
||||||
|
} else if (num == 0 && !symbolError) {
|
||||||
|
error("Invalid bracketed macro argument '\\<0>'\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
lexerState->disableMacroArgs = disableMacroArgs;
|
lexerState->disableMacroArgs = disableMacroArgs;
|
||||||
lexerState->disableInterpolation = disableInterpolation;
|
lexerState->disableInterpolation = disableInterpolation;
|
||||||
@@ -787,7 +796,7 @@ static uint32_t readBracketedMacroArgNum(void)
|
|||||||
|
|
||||||
static char const *readMacroArg(char name)
|
static char const *readMacroArg(char name)
|
||||||
{
|
{
|
||||||
char const *str;
|
char const *str = NULL;
|
||||||
|
|
||||||
if (name == '@') {
|
if (name == '@') {
|
||||||
str = macro_GetUniqueIDStr();
|
str = macro_GetUniqueIDStr();
|
||||||
@@ -796,18 +805,22 @@ static char const *readMacroArg(char name)
|
|||||||
} else if (name == '<') {
|
} else if (name == '<') {
|
||||||
uint32_t num = readBracketedMacroArgNum();
|
uint32_t num = readBracketedMacroArgNum();
|
||||||
|
|
||||||
|
if (num == 0)
|
||||||
|
return NULL;
|
||||||
str = macro_GetArg(num);
|
str = macro_GetArg(num);
|
||||||
if (!str)
|
if (!str)
|
||||||
fatalerror("Macro argument '\\<%" PRIu32 ">' not defined\n", num);
|
error("Macro argument '\\<%" PRIu32 ">' not defined\n", num);
|
||||||
|
return str;
|
||||||
} else if (name == '0') {
|
} else if (name == '0') {
|
||||||
fatalerror("Invalid macro argument '\\0'\n");
|
error("Invalid macro argument '\\0'\n");
|
||||||
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
|
assert(name > '0' && name <= '9');
|
||||||
str = macro_GetArg(name - '0');
|
str = macro_GetArg(name - '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!str)
|
if (!str)
|
||||||
fatalerror("Macro argument '\\%c' not defined\n", name);
|
error("Macro argument '\\%c' not defined\n", name);
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -907,10 +920,10 @@ restart:
|
|||||||
char const *str = readMacroArg(c);
|
char const *str = readMacroArg(c);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the macro arg is an empty string, it cannot be
|
* If the macro arg is invalid or an empty string, it cannot be
|
||||||
* expanded, so skip it and keep peeking.
|
* expanded, so skip it and keep peeking.
|
||||||
*/
|
*/
|
||||||
if (!str[0])
|
if (!str || !str[0])
|
||||||
goto restart;
|
goto restart;
|
||||||
|
|
||||||
beginExpansion(str, c == '#', NULL);
|
beginExpansion(str, c == '#', NULL);
|
||||||
@@ -930,10 +943,9 @@ restart:
|
|||||||
shiftChar();
|
shiftChar();
|
||||||
char const *ptr = readInterpolation(0);
|
char const *ptr = readInterpolation(0);
|
||||||
|
|
||||||
if (ptr) {
|
if (ptr && ptr[0])
|
||||||
beginExpansion(ptr, false, ptr);
|
beginExpansion(ptr, false, ptr);
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
@@ -1369,10 +1381,9 @@ static char const *readInterpolation(unsigned int depth)
|
|||||||
shiftChar();
|
shiftChar();
|
||||||
char const *ptr = readInterpolation(depth + 1);
|
char const *ptr = readInterpolation(depth + 1);
|
||||||
|
|
||||||
if (ptr) {
|
if (ptr && ptr[0])
|
||||||
beginExpansion(ptr, false, ptr);
|
beginExpansion(ptr, false, ptr);
|
||||||
continue; /* Restart, reading from the new buffer */
|
continue; /* Restart, reading from the new buffer */
|
||||||
}
|
|
||||||
} else if (c == EOF || c == '\r' || c == '\n' || c == '"') {
|
} else if (c == EOF || c == '\r' || c == '\n' || c == '"') {
|
||||||
error("Missing }\n");
|
error("Missing }\n");
|
||||||
break;
|
break;
|
||||||
@@ -1573,8 +1584,10 @@ static void readString(void)
|
|||||||
shiftChar();
|
shiftChar();
|
||||||
char const *str = readMacroArg(c);
|
char const *str = readMacroArg(c);
|
||||||
|
|
||||||
while (*str)
|
if (str) {
|
||||||
append_yylval_string(*str++);
|
while (*str)
|
||||||
|
append_yylval_string(*str++);
|
||||||
|
}
|
||||||
continue; // Do not copy an additional character
|
continue; // Do not copy an additional character
|
||||||
|
|
||||||
case EOF: // Can't really print that one
|
case EOF: // Can't really print that one
|
||||||
@@ -1595,9 +1608,10 @@ static void readString(void)
|
|||||||
lexerState->disableMacroArgs = false;
|
lexerState->disableMacroArgs = false;
|
||||||
char const *ptr = readInterpolation(0);
|
char const *ptr = readInterpolation(0);
|
||||||
|
|
||||||
if (ptr)
|
if (ptr) {
|
||||||
while (*ptr)
|
while (*ptr)
|
||||||
append_yylval_string(*ptr++);
|
append_yylval_string(*ptr++);
|
||||||
|
}
|
||||||
lexerState->disableMacroArgs = true;
|
lexerState->disableMacroArgs = true;
|
||||||
continue; // Do not copy an additional character
|
continue; // Do not copy an additional character
|
||||||
|
|
||||||
@@ -1719,7 +1733,8 @@ static size_t appendStringLiteral(size_t i)
|
|||||||
shiftChar();
|
shiftChar();
|
||||||
char const *str = readMacroArg(c);
|
char const *str = readMacroArg(c);
|
||||||
|
|
||||||
i = appendEscapedSubstring(str, i);
|
if (str)
|
||||||
|
i = appendEscapedSubstring(str, i);
|
||||||
continue; // Do not copy an additional character
|
continue; // Do not copy an additional character
|
||||||
|
|
||||||
case EOF: // Can't really print that one
|
case EOF: // Can't really print that one
|
||||||
@@ -1746,7 +1761,7 @@ static size_t appendStringLiteral(size_t i)
|
|||||||
lexerState->disableMacroArgs = false;
|
lexerState->disableMacroArgs = false;
|
||||||
char const *ptr = readInterpolation(0);
|
char const *ptr = readInterpolation(0);
|
||||||
|
|
||||||
if (ptr)
|
if (ptr && ptr[0])
|
||||||
i = appendEscapedSubstring(ptr, i);
|
i = appendEscapedSubstring(ptr, i);
|
||||||
lexerState->disableMacroArgs = true;
|
lexerState->disableMacroArgs = true;
|
||||||
continue; // Do not copy an additional character
|
continue; // Do not copy an additional character
|
||||||
@@ -2012,7 +2027,9 @@ static int yylex_NORMAL(void)
|
|||||||
if (sym && sym->type == SYM_EQUS) {
|
if (sym && sym->type == SYM_EQUS) {
|
||||||
char const *s = sym_GetStringValue(sym);
|
char const *s = sym_GetStringValue(sym);
|
||||||
|
|
||||||
beginExpansion(s, false, sym->name);
|
assert(s);
|
||||||
|
if (s[0])
|
||||||
|
beginExpansion(s, false, sym->name);
|
||||||
continue; /* Restart, reading from the new buffer */
|
continue; /* Restart, reading from the new buffer */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,8 @@ ERROR: interpolation-overflow.asm(4):
|
|||||||
warning: interpolation-overflow.asm(4): [-Wlarge-constant]
|
warning: interpolation-overflow.asm(4): [-Wlarge-constant]
|
||||||
Precision of fixed-point constant is too large
|
Precision of fixed-point constant is too large
|
||||||
while expanding symbol "0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
while expanding symbol "0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||||
FATAL: interpolation-overflow.asm(4):
|
ERROR: interpolation-overflow.asm(4):
|
||||||
Macro argument '\1' not defined
|
Macro argument '\1' not defined
|
||||||
|
ERROR: interpolation-overflow.asm(4):
|
||||||
|
syntax error, unexpected number
|
||||||
|
error: Assembly aborted (4 errors)!
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
FATAL: invalid-empty-macro-arg.asm(1):
|
ERROR: invalid-empty-macro-arg.asm(1):
|
||||||
Empty bracketed macro argument
|
Empty bracketed macro argument
|
||||||
|
error: Assembly aborted (1 error)!
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
FATAL: invalid-macro-arg-character.asm(1):
|
ERROR: invalid-macro-arg-character.asm(1):
|
||||||
Invalid character in bracketed macro argument '!'
|
Invalid character in bracketed macro argument '!'
|
||||||
|
ERROR: invalid-macro-arg-character.asm(1):
|
||||||
|
syntax error, unexpected >
|
||||||
|
error: Assembly aborted (2 errors)!
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
FATAL: invalid-macro-arg-symbol.asm(1):
|
ERROR: invalid-macro-arg-symbol.asm(1):
|
||||||
Bracketed symbol "foo" does not exist
|
Bracketed symbol "foo" does not exist
|
||||||
|
error: Assembly aborted (1 error)!
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ m: macro
|
|||||||
SHIFT
|
SHIFT
|
||||||
SHIFT
|
SHIFT
|
||||||
SHIFT 256
|
SHIFT 256
|
||||||
PRINTLN "\1"
|
PRINTLN "\1?"
|
||||||
endm
|
endm
|
||||||
|
|
||||||
m This, used, not, to, work
|
m This, used, not, to, work
|
||||||
|
|||||||
@@ -2,5 +2,6 @@ warning: rept-shift.asm(15) -> rept-shift.asm::m(10): [-Wmacro-shift]
|
|||||||
Cannot shift macro arguments past their end
|
Cannot shift macro arguments past their end
|
||||||
warning: rept-shift.asm(15) -> rept-shift.asm::m(11): [-Wmacro-shift]
|
warning: rept-shift.asm(15) -> rept-shift.asm::m(11): [-Wmacro-shift]
|
||||||
Cannot shift macro arguments past their end
|
Cannot shift macro arguments past their end
|
||||||
FATAL: rept-shift.asm(15) -> rept-shift.asm::m(12):
|
ERROR: rept-shift.asm(15) -> rept-shift.asm::m(12):
|
||||||
Macro argument '\1' not defined
|
Macro argument '\1' not defined
|
||||||
|
error: Assembly aborted (1 error)!
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
This works!
|
This works!
|
||||||
|
?
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
x\0
|
x\0 = 10
|
||||||
|
println x
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
FATAL: symbol-invalid-macro-arg.asm(1):
|
ERROR: symbol-invalid-macro-arg.asm(1):
|
||||||
Invalid macro argument '\0'
|
Invalid macro argument '\0'
|
||||||
|
error: Assembly aborted (1 error)!
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
$A
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
warn_unique EQUS "WARN \"\\@\""
|
warn_unique EQUS "WARN \"\\@!\""
|
||||||
|
|
||||||
m: macro
|
m: macro
|
||||||
warn_unique
|
warn_unique
|
||||||
|
|||||||
@@ -1,27 +1,31 @@
|
|||||||
warning: unique-id.asm(12) -> unique-id.asm::m(4): [-Wuser]
|
warning: unique-id.asm(12) -> unique-id.asm::m(4): [-Wuser]
|
||||||
_u1
|
_u1!
|
||||||
while expanding symbol "warn_unique"
|
while expanding symbol "warn_unique"
|
||||||
warning: unique-id.asm(12) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~1(6): [-Wuser]
|
warning: unique-id.asm(12) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~1(6): [-Wuser]
|
||||||
_u2
|
_u2!
|
||||||
while expanding symbol "warn_unique"
|
while expanding symbol "warn_unique"
|
||||||
warning: unique-id.asm(12) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~2(6): [-Wuser]
|
warning: unique-id.asm(12) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~2(6): [-Wuser]
|
||||||
_u3
|
_u3!
|
||||||
while expanding symbol "warn_unique"
|
while expanding symbol "warn_unique"
|
||||||
warning: unique-id.asm(12) -> unique-id.asm::m(8): [-Wuser]
|
warning: unique-id.asm(12) -> unique-id.asm::m(8): [-Wuser]
|
||||||
_u1
|
_u1!
|
||||||
while expanding symbol "warn_unique"
|
while expanding symbol "warn_unique"
|
||||||
warning: unique-id.asm(14) -> unique-id.asm::m(4): [-Wuser]
|
warning: unique-id.asm(14) -> unique-id.asm::m(4): [-Wuser]
|
||||||
_u4
|
_u4!
|
||||||
while expanding symbol "warn_unique"
|
while expanding symbol "warn_unique"
|
||||||
warning: unique-id.asm(14) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~1(6): [-Wuser]
|
warning: unique-id.asm(14) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~1(6): [-Wuser]
|
||||||
_u5
|
_u5!
|
||||||
while expanding symbol "warn_unique"
|
while expanding symbol "warn_unique"
|
||||||
warning: unique-id.asm(14) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~2(6): [-Wuser]
|
warning: unique-id.asm(14) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~2(6): [-Wuser]
|
||||||
_u6
|
_u6!
|
||||||
while expanding symbol "warn_unique"
|
while expanding symbol "warn_unique"
|
||||||
warning: unique-id.asm(14) -> unique-id.asm::m(8): [-Wuser]
|
warning: unique-id.asm(14) -> unique-id.asm::m(8): [-Wuser]
|
||||||
_u4
|
_u4!
|
||||||
while expanding symbol "warn_unique"
|
while expanding symbol "warn_unique"
|
||||||
FATAL: unique-id.asm(15):
|
ERROR: unique-id.asm(15):
|
||||||
Macro argument '\@' not defined
|
Macro argument '\@' not defined
|
||||||
while expanding symbol "warn_unique"
|
while expanding symbol "warn_unique"
|
||||||
|
warning: unique-id.asm(15): [-Wuser]
|
||||||
|
!
|
||||||
|
while expanding symbol "warn_unique"
|
||||||
|
error: Assembly aborted (1 error)!
|
||||||
|
|||||||
Reference in New Issue
Block a user