ref: 6e805cd3182390d756dc973dd61f2d31a476cdb1
parent: e11f25024e619c9c1fdd6d3a2cf577f937fa13f9
author: ISSOtm <eldredhabert0@gmail.com>
date: Fri Jul 31 20:52:10 EDT 2020
Implement macro args This finally allows running 90% of the test suite, debugging time!
--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -373,7 +373,7 @@
struct LexerState *state = malloc(sizeof(*state));
if (!state) {
- error("Failed to allocate memory for lexer state: %s", strerror(errno));
+ error("Failed to allocate memory for lexer state: %s\n", strerror(errno));
return NULL;
}
// TODO: init `path`
@@ -1088,7 +1088,7 @@
}
}
} else if (c == EOF || c == '\r' || c == '\n' || c == '"') {
- error("Unterminated interpolation\n");
+ error("Missing }\n");
break;
} else if (c == '}') {
shiftChars(1);
@@ -1441,10 +1441,6 @@
shiftChars(1); /* Shift that EOL */
/* fallthrough */
case '\n':
- if (lexerStateEOL) {
- lexer_SetState(lexerStateEOL);
- lexerStateEOL = NULL;
- }
return '\n';
case EOF:
@@ -1490,9 +1486,95 @@
}
}
+static bool isWhitespace(int c)
+{
+ return c == ' ' || c == '\t';
+}
+
static int yylex_RAW(void)
{
- fatalerror("LEXER_RAW not yet implemented\n");
+ /* This is essentially a modified `readString` */
+ size_t i = 0;
+
+ /* Trim left of string... */
+ while (isWhitespace(peek(0)))
+ shiftChars(1);
+
+ for (;;) {
+ int c = peek(0);
+
+ switch (c) {
+ case ',':
+ shiftChars(1);
+ /* fallthrough */
+ case '\r':
+ case '\n': /* Do not shift these! */
+ case EOF:
+ if (c != ',')
+ lexer_SetMode(LEXER_NORMAL);
+ if (i == sizeof(yylval.tzString)) {
+ i--;
+ warning(WARNING_LONG_STR, "Macro argument too long\n");
+ }
+ /* Trim whitespace */
+ while (i && isWhitespace(yylval.tzString[i - 1]))
+ i--;
+ yylval.tzString[i] = '\0';
+ return T_STRING;
+
+ case '\\': /* Character escape */
+ c = peek(1);
+ switch (c) {
+ 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);
+ break;
+
+ case EOF: /* Can't really print that one */
+ error("Illegal character escape at end of input\n");
+ c = '\\';
+ break;
+ default:
+ error("Illegal character escape '%s'\n", print(c));
+ c = '\\';
+ break;
+ }
+ break;
+
+ case '{': /* Symbol interpolation */
+ shiftChars(1);
+ char const *ptr = readInterpolation();
+
+ if (ptr) {
+ while (*ptr) {
+ if (i == sizeof(yylval.tzString))
+ break;
+ yylval.tzString[i++] = *ptr++;
+ }
+ }
+ continue; /* Do not copy an additional character */
+
+ /* Regular characters will just get copied */
+ }
+ if (i < sizeof(yylval.tzString)) /* Copy one extra to flag overflow */
+ yylval.tzString[i++] = c;
+ shiftChars(1);
+ }
}
/*
@@ -1548,11 +1630,16 @@
int yylex(void)
{
restart:
- if (lexerState->atLineStart
- /* Newlines read within an expansion should not increase the line count */
- && (!lexerState->expansions || lexerState->expansions->distance)) {
- lexerState->lineNo++;
- lexerState->colNo = 0;
+ if (lexerState->atLineStart) {
+ /* Newlines read within an expansion should not increase the line count */
+ if (!lexerState->expansions || lexerState->expansions->distance) {
+ lexerState->lineNo++;
+ lexerState->colNo = 0;
+ }
+ if (lexerStateEOL) {
+ lexer_SetState(lexerStateEOL);
+ lexerStateEOL = NULL;
+ }
}
static int (* const lexerModeFuncs[])(void) = {
@@ -1572,6 +1659,7 @@
if (!lexerState->capturing) {
if (!yywrap())
goto restart;
+ return 0;
}
}
}