mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Fix many lexer bugs
More to come...
This commit is contained in:
2
Makefile
2
Makefile
@@ -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!
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
144
src/asm/lexer.c
144
src/asm/lexer.c
@@ -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 (;;) {
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
ERROR: divzero-instr.asm(2):
|
FATAL: divzero-instr.asm(2):
|
||||||
Division by zero
|
Division by zero
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
ERROR: divzero-section-bank.asm(1):
|
FATAL: divzero-section-bank.asm(1):
|
||||||
Division by zero
|
Division by zero
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
x<EFBFBD>
|
<EFBFBD>
|
||||||
|
|||||||
@@ -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)!
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
if {@}
|
if "{@}"
|
||||||
endc
|
endc
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ m: MACRO
|
|||||||
ENDM
|
ENDM
|
||||||
|
|
||||||
REPT 1
|
REPT 1
|
||||||
m ENDR
|
m
|
||||||
|
ENDR
|
||||||
|
|
||||||
REPT 1
|
REPT 1
|
||||||
m \ ENDR
|
m \
|
||||||
|
ENDR
|
||||||
|
|||||||
@@ -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\
|
||||||
|
|||||||
@@ -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).
|
||||||
|
|||||||
@@ -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)!
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
8
test/asm/macro-line-no.asm
Normal file
8
test/asm/macro-line-no.asm
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
WARN "Line 2"
|
||||||
|
m: macro
|
||||||
|
WARN "Line 4"
|
||||||
|
endm
|
||||||
|
WARN "Line 6"
|
||||||
|
m
|
||||||
|
WARN "Line 8"
|
||||||
8
test/asm/macro-line-no.err
Normal file
8
test/asm/macro-line-no.err
Normal 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
|
||||||
0
test/asm/macro-line-no.out
Normal file
0
test/asm/macro-line-no.out
Normal 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
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
ERROR: nested-brackets.asm(5):
|
ERROR: nested-brackets.asm(5):
|
||||||
Missing }
|
Missing }
|
||||||
|
error: Assembly aborted (1 errors)!
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
OK
|
OK
|
||||||
|
OK
|
||||||
Binary file not shown.
@@ -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)!
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)!
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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'
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user