Fix many lexer bugs

More to come...
This commit is contained in:
ISSOtm
2020-08-14 21:11:44 +02:00
parent df75fd2ec2
commit cd747d8175
38 changed files with 188 additions and 107 deletions

View File

@@ -198,7 +198,7 @@ develop:
-fsanitize=unreachable -fsanitize=vla-bound \ -fsanitize=unreachable -fsanitize=vla-bound \
-fsanitize=signed-integer-overflow -fsanitize=bounds \ -fsanitize=signed-integer-overflow -fsanitize=bounds \
-fsanitize=object-size -fsanitize=bool -fsanitize=enum \ -fsanitize=object-size -fsanitize=bool -fsanitize=enum \
-fsanitize=alignment -fsanitize=null -DDEVELOP" CFLAGS="-g -O0" -fsanitize=alignment -fsanitize=null -DDEVELOP" CFLAGS="-ggdb3 -O0"
# Targets for the project maintainer to easily create Windows exes. # Targets for the project maintainer to easily create Windows exes.
# This is not for Windows users! # This is not for Windows users!

View File

@@ -12,7 +12,7 @@
#include <stdint.h> #include <stdint.h>
uint32_t calchash(const char *s); uint32_t calchash(const char *s);
char const *print(char c); char const *print(int c);
size_t readUTF8Char(uint8_t *dest, char const *src); size_t readUTF8Char(uint8_t *dest, char const *src);
#endif /* RGBDS_UTIL_H */ #endif /* RGBDS_UTIL_H */

View File

@@ -26,7 +26,7 @@ struct Context {
struct Context *child; struct Context *child;
struct LexerState *lexerState; struct LexerState *lexerState;
uint32_t uniqueID; uint32_t uniqueID;
char *fileName; char const *fileName;
uint32_t lineNo; /* Line number at which the context was EXITED */ uint32_t lineNo; /* Line number at which the context was EXITED */
struct Symbol const *macro; struct Symbol const *macro;
uint32_t nbReptIters; /* If zero, this isn't a REPT block */ uint32_t nbReptIters; /* If zero, this isn't a REPT block */
@@ -149,14 +149,12 @@ bool yywrap(void)
contextDepth--; contextDepth--;
lexer_DeleteState(contextStack->child->lexerState); lexer_DeleteState(contextStack->child->lexerState);
/* If at top level (= not in macro or in REPT), free the file name */
if (!contextStack->macro && contextStack->reptIters == 0)
free(contextStack->child->fileName);
/* Free the entry and make its parent the current entry */ /* Free the entry and make its parent the current entry */
free(contextStack->child); free(contextStack->child);
contextStack->child = NULL; contextStack->child = NULL;
lexer_SetState(contextStack->lexerState); lexer_SetState(contextStack->lexerState);
macro_SetUniqueID(contextStack->uniqueID);
return false; return false;
} }
@@ -197,7 +195,7 @@ void fstk_RunInclude(char const *path)
/* We're back at top-level, so most things are reset */ /* We're back at top-level, so most things are reset */
contextStack->uniqueID = 0; contextStack->uniqueID = 0;
macro_SetUniqueID(0); macro_SetUniqueID(0);
contextStack->fileName = fullPath; contextStack->fileName = lexer_GetFileName();
contextStack->macro = NULL; contextStack->macro = NULL;
contextStack->nbReptIters = 0; contextStack->nbReptIters = 0;
} }
@@ -217,8 +215,9 @@ void fstk_RunMacro(char *macroName, struct MacroArgs *args)
macro_UseNewArgs(args); macro_UseNewArgs(args);
newContext(0); newContext(0);
/* Line minus 1 because buffer begins with a newline */
contextStack->lexerState = lexer_OpenFileView(macro->macro, contextStack->lexerState = lexer_OpenFileView(macro->macro,
macro->macroSize, macro->fileLine); macro->macroSize, macro->fileLine - 1);
if (!contextStack->lexerState) if (!contextStack->lexerState)
fatalerror("Failed to set up lexer for macro invocation\n"); fatalerror("Failed to set up lexer for macro invocation\n");
lexer_SetStateAtEOL(contextStack->lexerState); lexer_SetStateAtEOL(contextStack->lexerState);
@@ -311,7 +310,7 @@ void fstk_Init(char *mainPath, uint32_t maxRecursionDepth)
lexer_SetState(topLevelContext->lexerState); lexer_SetState(topLevelContext->lexerState);
topLevelContext->uniqueID = 0; topLevelContext->uniqueID = 0;
macro_SetUniqueID(0); macro_SetUniqueID(0);
topLevelContext->fileName = mainPath; topLevelContext->fileName = lexer_GetFileName();
topLevelContext->macro = NULL; topLevelContext->macro = NULL;
topLevelContext->nbReptIters = 0; topLevelContext->nbReptIters = 0;
topLevelContext->reptDepth = 0; topLevelContext->reptDepth = 0;

View File

@@ -272,7 +272,6 @@ struct LexerState {
char *captureBuf; /* Buffer to send the captured text to if non-NULL */ char *captureBuf; /* Buffer to send the captured text to if non-NULL */
size_t captureCapacity; /* Size of the buffer above */ size_t captureCapacity; /* Size of the buffer above */
size_t expansionDistance; /* Distance already considered for expansions */
bool expandStrings; bool expandStrings;
struct Expansion *expansions; struct Expansion *expansions;
size_t expansionOfs; /* Offset into the current top-level expansion (negative = before) */ size_t expansionOfs; /* Offset into the current top-level expansion (negative = before) */
@@ -290,7 +289,6 @@ static void initState(struct LexerState *state)
state->capturing = false; state->capturing = false;
state->captureBuf = NULL; state->captureBuf = NULL;
state->expansionDistance = 0;
state->expandStrings = true; state->expandStrings = true;
state->expansions = NULL; state->expansions = NULL;
state->expansionOfs = 0; state->expansionOfs = 0;
@@ -538,7 +536,31 @@ static struct Expansion *getExpansionAtDistance(size_t *distance)
#define LOOKUP_PRE_NEST(exp) #define LOOKUP_PRE_NEST(exp)
#define LOOKUP_POST_NEST(exp) #define LOOKUP_POST_NEST(exp)
lookupExpansion(expansion, *distance); struct Expansion *exp = lexerState->expansions;
for (;;) {
/* Find the closest expansion whose end is after the target */
while (exp && exp->totalLen + exp->distance <= *distance) {
*distance -= exp->totalLen - exp->skip;
exp = exp->next;
}
/* If there is none, or it begins after the target, return the previous level */
if (!exp || exp->distance > *distance)
break;
/* We know we are inside of that expansion */
*distance -= exp->distance; /* Distances are relative to their parent */
/* Otherwise, register this expansion and repeat the process */
LOOKUP_PRE_NEST(exp);
expansion = exp;
if (!exp->firstChild) /* If there are no children, this is it */
break;
exp = exp->firstChild;
LOOKUP_POST_NEST(exp);
}
#undef LOOKUP_PRE_NEST #undef LOOKUP_PRE_NEST
#undef LOOKUP_POST_NEST #undef LOOKUP_POST_NEST
@@ -553,7 +575,7 @@ static void beginExpansion(size_t distance, uint8_t skip,
struct Expansion *parent = NULL; struct Expansion *parent = NULL;
unsigned int depth = 0; unsigned int depth = 0;
#define LOOKUP_PRE_NEST(exp) (exp)->totalLen += size #define LOOKUP_PRE_NEST(exp) (exp)->totalLen += size - skip
#define LOOKUP_POST_NEST(exp) do { \ #define LOOKUP_POST_NEST(exp) do { \
if (name && ++depth >= nMaxRecursionDepth) \ if (name && ++depth >= nMaxRecursionDepth) \
fatalerror("Recursion limit (%u) exceeded\n", nMaxRecursionDepth); \ fatalerror("Recursion limit (%u) exceeded\n", nMaxRecursionDepth); \
@@ -604,6 +626,8 @@ static char const *expandMacroArg(char name, size_t distance)
if (name == '@') if (name == '@')
str = macro_GetUniqueIDStr(); str = macro_GetUniqueIDStr();
else if (name == '0')
fatalerror("Invalid macro argument '\\0'\n");
else else
str = macro_GetArg(name - '0'); str = macro_GetArg(name - '0');
if (!str) if (!str)
@@ -624,11 +648,11 @@ static int peekInternal(uint8_t distance)
struct Expansion const *expansion = getExpansionAtDistance(&ofs); struct Expansion const *expansion = getExpansionAtDistance(&ofs);
if (expansion) { if (expansion) {
assert(distance < expansion->len); assert(ofs < expansion->len);
return expansion->contents[ofs]; return expansion->contents[ofs];
} }
distance = ofs - lexerState->expansionOfs; distance = ofs;
if (lexerState->isMmapped) { if (lexerState->isMmapped) {
if (lexerState->offset + distance >= lexerState->size) if (lexerState->offset + distance >= lexerState->size)
@@ -681,12 +705,11 @@ static int peek(uint8_t distance)
{ {
int c = peekInternal(distance); int c = peekInternal(distance);
if (distance >= lexerState->expansionDistance) {
/* If not capturing and character is a backslash, check for a macro arg */ /* If not capturing and character is a backslash, check for a macro arg */
if (!lexerState->capturing && c == '\\') { if (!lexerState->capturing && c == '\\') {
distance++; distance++;
c = peekInternal(distance); c = peekInternal(distance);
if (c == '@' || (c >= '1' && c <= '9')) { if (c == '@' || (c >= '0' && c <= '9')) {
/* Expand the argument and return its first character */ /* Expand the argument and return its first character */
c = expandMacroArg(c, distance - 1)[0]; c = expandMacroArg(c, distance - 1)[0];
/* WARNING: this assumes macro args can't be empty!! */ /* WARNING: this assumes macro args can't be empty!! */
@@ -694,8 +717,6 @@ static int peek(uint8_t distance)
c = '\\'; c = '\\';
} }
} }
lexerState->expansionDistance = distance + 1; /* Do not consider again */
}
return c; return c;
} }
@@ -713,8 +734,6 @@ static void shiftChars(uint8_t distance)
} }
} }
lexerState->expansionDistance -= distance;
/* FIXME: this may not be too great, as only the top level is considered... */ /* FIXME: this may not be too great, as only the top level is considered... */
/* /*
@@ -830,6 +849,35 @@ static void discardComment(void)
} }
} }
/* Function to read a line continuation */
static bool isWhitespace(int c)
{
return c == ' ' || c == '\t';
}
static void readLineContinuation(void)
{
for (;;) {
int c = peek(0);
if (isWhitespace(c)) {
shiftChars(1);
} else if (c == '\r' || c == '\n') {
shiftChars(1);
if (!lexerState->expansions
|| lexerState->expansions->distance) {
lexerState->lineNo++;
}
return;
} else {
error("Begun line continuation, but encountered character %s\n",
print(c));
return;
}
}
}
/* Functions to lex numbers of various radixes */ /* Functions to lex numbers of various radixes */
static void readNumber(int radix, int32_t baseValue) static void readNumber(int radix, int32_t baseValue)
@@ -1190,6 +1238,13 @@ static void readString(void)
shiftChars(1); shiftChars(1);
break; break;
case ' ':
case '\r':
case '\n':
shiftChars(1); /* Shift the backslash */
readLineContinuation();
continue;
case EOF: /* Can't really print that one */ case EOF: /* Can't really print that one */
error("Illegal character escape at end of input\n"); error("Illegal character escape at end of input\n");
c = '\\'; c = '\\';
@@ -1477,15 +1532,11 @@ static int yylex_NORMAL(void)
} }
} }
static bool isWhitespace(int c)
{
return c == ' ' || c == '\t';
}
static int yylex_RAW(void) static int yylex_RAW(void)
{ {
/* This is essentially a modified `readString` */ /* This is essentially a modified `readString` */
size_t i = 0; size_t i = 0;
bool insideString = false;
/* Trim left of string... */ /* Trim left of string... */
while (isWhitespace(peek(0))) while (isWhitespace(peek(0)))
@@ -1495,15 +1546,23 @@ static int yylex_RAW(void)
int c = peek(0); int c = peek(0);
switch (c) { switch (c) {
case ',': case '"':
insideString = !insideString;
/* Other than that, just process quotes normally */
break;
case ';': /* Comments inside macro args */
if (insideString)
break;
do {
shiftChars(1); shiftChars(1);
c = peek(0);
} while (c != EOF && c != '\r' && c != '\n');
/* fallthrough */ /* fallthrough */
case ',':
case '\r': case '\r':
case '\n': /* Do not shift these! */ case '\n':
case EOF: case EOF:
/* Empty macro args break their expansion, so prevent that */
if (i == 0)
return c;
if (i == sizeof(yylval.tzString)) { if (i == sizeof(yylval.tzString)) {
i--; i--;
warning(WARNING_LONG_STR, "Macro argument too long\n"); warning(WARNING_LONG_STR, "Macro argument too long\n");
@@ -1511,6 +1570,11 @@ static int yylex_RAW(void)
/* Trim whitespace */ /* Trim whitespace */
while (i && isWhitespace(yylval.tzString[i - 1])) while (i && isWhitespace(yylval.tzString[i - 1]))
i--; i--;
/* Empty macro args break their expansion, so prevent that */
if (i == 0) {
shiftChars(1);
return c == EOF ? 0 : c;
}
yylval.tzString[i] = '\0'; yylval.tzString[i] = '\0';
return T_STRING; return T_STRING;
@@ -1518,31 +1582,21 @@ static int yylex_RAW(void)
c = peek(1); c = peek(1);
switch (c) { switch (c) {
case ',': case ',':
case '\\': /* Return that character unchanged */
case '"':
case '{':
case '}':
shiftChars(1);
break;
case 'n':
c = '\n';
shiftChars(1);
break;
case 'r':
c = '\r';
shiftChars(1);
break;
case 't':
c = '\t';
shiftChars(1); shiftChars(1);
break; break;
case ' ':
case '\r':
case '\n':
shiftChars(1); /* Shift the backslash */
readLineContinuation();
continue;
case EOF: /* Can't really print that one */ case EOF: /* Can't really print that one */
error("Illegal character escape at end of input\n"); error("Illegal character escape at end of input\n");
c = '\\'; c = '\\';
break; break;
default: default: /* Pass the rest as-is */
error("Illegal character escape '%s'\n", print(c));
c = '\\'; c = '\\';
break; break;
} }
@@ -1622,16 +1676,16 @@ static int yylex_SKIP_TO_ENDC(void)
int yylex(void) int yylex(void)
{ {
restart: restart:
if (lexerState->atLineStart && lexerStateEOL) {
lexer_SetState(lexerStateEOL);
lexerStateEOL = NULL;
}
if (lexerState->atLineStart) { if (lexerState->atLineStart) {
/* Newlines read within an expansion should not increase the line count */ /* Newlines read within an expansion should not increase the line count */
if (!lexerState->expansions || lexerState->expansions->distance) { if (!lexerState->expansions || lexerState->expansions->distance) {
lexerState->lineNo++; lexerState->lineNo++;
lexerState->colNo = 0; lexerState->colNo = 0;
} }
if (lexerStateEOL) {
lexer_SetState(lexerStateEOL);
lexerStateEOL = NULL;
}
} }
static int (* const lexerModeFuncs[])(void) = { static int (* const lexerModeFuncs[])(void) = {
@@ -1693,6 +1747,7 @@ void lexer_CaptureRept(char **capture, size_t *size)
*/ */
assert(lexerState->atLineStart); assert(lexerState->atLineStart);
for (;;) { for (;;) {
lexerState->lineNo++;
/* We're at line start, so attempt to match a `REPT` or `ENDR` token */ /* We're at line start, so attempt to match a `REPT` or `ENDR` token */
do { /* Discard initial whitespace */ do { /* Discard initial whitespace */
c = nextChar(); c = nextChar();
@@ -1720,7 +1775,6 @@ void lexer_CaptureRept(char **capture, size_t *size)
level--; level--;
} }
} }
lexerState->lineNo++;
/* Just consume characters until EOL or EOF */ /* Just consume characters until EOL or EOF */
for (;;) { for (;;) {

View File

@@ -28,10 +28,13 @@ uint32_t calchash(const char *s)
return hash; return hash;
} }
char const *print(char c) char const *print(int c)
{ {
static char buf[5]; /* '\xNN' + '\0' */ static char buf[5]; /* '\xNN' + '\0' */
if (c == EOF)
return "EOF";
if (isprint(c)) { if (isprint(c)) {
buf[0] = c; buf[0] = c;
buf[1] = '\0'; buf[1] = '\0';

View File

@@ -6,5 +6,5 @@ ERROR: assert.asm(18):
Expected constant expression: 'FloatingBase' is not constant at assembly time Expected constant expression: 'FloatingBase' is not constant at assembly time
ERROR: assert.asm(18): ERROR: assert.asm(18):
Assertion failed Assertion failed
ERROR: assert.asm(21): FATAL: assert.asm(21):
Assertion failed Assertion failed

View File

@@ -1,2 +1,2 @@
ERROR: divzero-instr.asm(2): FATAL: divzero-instr.asm(2):
Division by zero Division by zero

View File

@@ -1,2 +1,2 @@
ERROR: divzero-section-bank.asm(1): FATAL: divzero-section-bank.asm(1):
Division by zero Division by zero

View File

@@ -1,8 +1,7 @@
warning: test/asm/equs-newline.asm(2): [-Wuser] warning: equs-newline.asm(3): [-Wuser]
First First
while expanding symbol "ACT" while expanding symbol "ACT"
warning: test/asm/equs-newline.asm(3): [-Wuser] warning: equs-newline.asm(3): [-Wuser]
Second Second
while expanding symbol "ACT" warning: equs-newline.asm(4): [-Wuser]
warning: test/asm/equs-newline.asm(4): [-Wuser]
Third Third

View File

@@ -1,3 +1,3 @@
warning: test/asm/equs-purge.asm(0): [-Wuser] warning: equs-purge.asm(2): [-Wuser]
Crash? Crash?
while expanding symbol "BYE" while expanding symbol "BYE"

View File

@@ -1,4 +1,4 @@
ERROR: equs-recursion.asm(2): FATAL: equs-recursion.asm(2):
Recursion limit (64) exceeded Recursion limit (64) exceeded
while expanding symbol "recurse" while expanding symbol "recurse"
while expanding symbol "recurse" while expanding symbol "recurse"
@@ -64,3 +64,4 @@ while expanding symbol "recurse"
while expanding symbol "recurse" while expanding symbol "recurse"
while expanding symbol "recurse" while expanding symbol "recurse"
while expanding symbol "recurse" while expanding symbol "recurse"
while expanding symbol "recurse"

View File

@@ -1 +1 @@
x<EFBFBD> <EFBFBD>

View File

@@ -1,2 +1,3 @@
ERROR: garbage_char.asm(1): ERROR: garbage_char.asm(1):
Found garbage character: 0xFF Unknown character 0xFF
error: Assembly aborted (1 errors)!

View File

@@ -1,2 +1,2 @@
if {@} if "{@}"
endc endc

View File

@@ -1,2 +1,2 @@
ERROR: include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1): FATAL: include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1) -> include-recursion.asm(1):
Recursion limit (64) exceeded Recursion limit (64) exceeded

View File

@@ -2,7 +2,9 @@ m: MACRO
ENDM ENDM
REPT 1 REPT 1
m ENDR m
ENDR
REPT 1 REPT 1
m \ ENDR m \
ENDR

View File

@@ -2,6 +2,7 @@
; file doesn't cause a segfault. ; file doesn't cause a segfault.
bar: MACRO bar: MACRO
WARN ""
ENDM ENDM
foo: bar baz\ foo: bar baz\

View File

@@ -1,2 +1,2 @@
ERROR: load-overflow.asm(4): FATAL: load-overflow.asm(4):
Section 'Overflow' grew too big (max size = 0x8000 bytes, reached 0x8001). Section 'Overflow' grew too big (max size = 0x8000 bytes, reached 0x8001).

View File

@@ -1,3 +1,3 @@
ERROR: local-purge.asm(8): ERROR: local-purge.asm(8):
'.loc' not defined Interpolated symbol ".loc" does not exist
error: Assembly aborted (1 errors)! error: Assembly aborted (1 errors)!

View File

@@ -1,2 +1,2 @@
ERROR: local-ref-without-parent.asm(3): FATAL: local-ref-without-parent.asm(3):
Local label reference '.test' in main scope Local label reference '.test' in main scope

View File

@@ -0,0 +1,8 @@
WARN "Line 2"
m: macro
WARN "Line 4"
endm
WARN "Line 6"
m
WARN "Line 8"

View File

@@ -0,0 +1,8 @@
warning: macro-line-no.asm(2): [-Wuser]
Line 2
warning: macro-line-no.asm(6): [-Wuser]
Line 6
warning: macro-line-no.asm(7) -> macro-line-no.asm::m(4): [-Wuser]
Line 4
warning: macro-line-no.asm(8): [-Wuser]
Line 8

View File

View File

@@ -1,2 +1,2 @@
ERROR: macro-recursion.asm(4) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2): FATAL: macro-recursion.asm(4) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2):
Recursion limit (64) exceeded Recursion limit (64) exceeded

View File

@@ -1,2 +1,3 @@
ERROR: nested-brackets.asm(5): ERROR: nested-brackets.asm(5):
Missing } Missing }
error: Assembly aborted (1 errors)!

View File

@@ -1 +1,2 @@
OK OK
OK

Binary file not shown.

View File

@@ -1,2 +1,3 @@
ERROR: null-in-macro.asm(2): ERROR: null-in-macro.asm(4) -> null-in-macro.asm::foo(2):
Found null character Unknown character 0x00
error: Assembly aborted (1 errors)!

View File

@@ -1,2 +1,2 @@
ERROR: pops-no-pushed-sections.asm(1): FATAL: pops-no-pushed-sections.asm(1):
No entries in the section stack No entries in the section stack

View File

@@ -1,4 +1,4 @@
ERROR: pops-restore-no-section.asm(9): ERROR: pops-restore-no-section.asm(9):
Label "DisallowedContent" created outside of a SECTION Label "DisallowedContent" created outside of a SECTION
ERROR: pops-restore-no-section.asm(10): FATAL: pops-restore-no-section.asm(10):
Code generation before SECTION directive Code generation before SECTION directive

View File

@@ -1,2 +1,2 @@
ERROR: remote-local-noexist.asm(7): FATAL: remote-local-noexist.asm(7):
'Parent.child.fail' is a nonsensical reference to a nested local symbol 'Parent.child.fail' is a nonsensical reference to a nested local symbol

View File

@@ -1,2 +1,2 @@
ERROR: rept-shift.asm(17) -> rept-shift.asm::m(14): FATAL: rept-shift.asm(17) -> rept-shift.asm::m(14):
Macro argument '\1' not defined Macro argument '\1' not defined

View File

@@ -6,5 +6,5 @@ ERROR: section-union.asm(37):
Section "test" already declared as fixed at $c000 Section "test" already declared as fixed at $c000
ERROR: section-union.asm(37): ERROR: section-union.asm(37):
Section "test" already declared as aligned to 256 bytes Section "test" already declared as aligned to 256 bytes
ERROR: section-union.asm(37): FATAL: section-union.asm(37):
Cannot create section "test" (3 errors) Cannot create section "test" (3 errors)

View File

@@ -1,3 +1,3 @@
ERROR: sym-collision.asm(26): ERROR: sym-collision.asm(26):
'dork' not defined Interpolated symbol "dork" does not exist
error: Assembly aborted (1 errors)! error: Assembly aborted (1 errors)!

View File

@@ -1,7 +1,7 @@
aqfj: $FE00 aqfj: $FE00
cxje: $FE01 cxje: $FE01
dgsd: $FE02 dgsd: $FE02
dork: $0 dork:
lxok: $FE04 lxok: $FE04
psgp: $FE05 psgp: $FE05
sfly: $FE06 sfly: $FE06

View File

@@ -1,2 +1,2 @@
ERROR: symbol-invalid-macro-arg.asm(1): FATAL: symbol-invalid-macro-arg.asm(1):
Invalid macro argument '\0' in symbol Invalid macro argument '\0'

View File

@@ -12,6 +12,7 @@ rc=0
bold=$(tput bold) bold=$(tput bold)
resbold=$(tput sgr0) resbold=$(tput sgr0)
red=$(tput setaf 1) red=$(tput setaf 1)
green=$(tput setaf 2)
rescolors=$(tput op) rescolors=$(tput op)
tryDiff () { tryDiff () {
diff -u --strip-trailing-cr $1 $2 || (echo "${bold}${red}${i%.asm}${variant}.$3 mismatch!${rescolors}${resbold}"; false) diff -u --strip-trailing-cr $1 $2 || (echo "${bold}${red}${i%.asm}${variant}.$3 mismatch!${rescolors}${resbold}"; false)
@@ -36,6 +37,7 @@ fi
for i in *.asm; do for i in *.asm; do
for variant in '' '.pipe'; do for variant in '' '.pipe'; do
echo -e "${bold}${green}${i%.asm}${variant}...${rescolors}${resbold}"
if [ -z "$variant" ]; then if [ -z "$variant" ]; then
../../rgbasm -Weverything -o $o $i > $output 2> $errput ../../rgbasm -Weverything -o $o $i > $output 2> $errput
desired_output=${i%.asm}.out desired_output=${i%.asm}.out
@@ -59,8 +61,8 @@ for i in *.asm; do
# Escape regex metacharacters # Escape regex metacharacters
subst="$(printf '%s\n' "$i" | sed 's:[][\/.^$*]:\\&:g')" subst="$(printf '%s\n' "$i" | sed 's:[][\/.^$*]:\\&:g')"
# Replace the file name with a dash to match changed output # Replace the file name with a dash to match changed output
sed "s/$subst/-/g" ${i%.asm}.out > $desired_output sed "s/$subst/<stdin>/g" ${i%.asm}.out > $desired_output
sed "s/$subst/-/g" ${i%.asm}.err > $desired_errput sed "s/$subst/<stdin>/g" ${i%.asm}.err > $desired_errput
fi fi
tryDiff $desired_output $output out tryDiff $desired_output $output out

View File

@@ -1,19 +1,19 @@
warning: unique-id.asm(12) -> unique-id.asm::m(4): [-Wuser] warning: unique-id.asm(12) -> unique-id.asm::m(4): [-Wuser]
_0
warning: unique-id.asm(12) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~1(6): [-Wuser]
_1 _1
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~1(6): [-Wuser]
_2 _2
warning: unique-id.asm(12) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~2(6): [-Wuser]
_3
warning: unique-id.asm(12) -> unique-id.asm::m(8): [-Wuser] warning: unique-id.asm(12) -> unique-id.asm::m(8): [-Wuser]
_0 _1
warning: unique-id.asm(14) -> unique-id.asm::m(4): [-Wuser] warning: unique-id.asm(14) -> unique-id.asm::m(4): [-Wuser]
_3
warning: unique-id.asm(14) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~1(6): [-Wuser]
_4 _4
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~1(6): [-Wuser]
_5 _5
warning: unique-id.asm(14) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~2(6): [-Wuser]
_6
warning: unique-id.asm(14) -> unique-id.asm::m(8): [-Wuser] warning: unique-id.asm(14) -> unique-id.asm::m(8): [-Wuser]
_3 _4
ERROR: unique-id.asm(15): FATAL: unique-id.asm(15):
Macro argument '\@' not defined Macro argument '\@' not defined
while expanding symbol "print" while expanding symbol "print"