ref: 61b2fd98160f3aa9f7f66f00273090412623002b
parent: 5ad7a9375076f1d352a9825379e0abee43c2fdfc
author: ISSOtm <[email protected]>
date: Tue Jul 28 20:39:18 EDT 2020
Add string expansion reporting And fix line counting with expansion-made newlines. This has the same bug as the old lexer (equs-newline's output does not print the second warning as being part of the expansion). Additionally, we regress equs-recursion, as we are no longer able to catch this specific EQUS recursion. Simply enough, the new expansion begins **after** the old one ends! I have found no way to handle that.
--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -25,6 +25,7 @@
#include "asm/asm.h"
#include "asm/lexer.h"
+#include "asm/fstack.h"
#include "asm/macro.h"
#include "asm/main.h"
#include "asm/rpn.h"
@@ -230,6 +231,7 @@
struct Expansion {
struct Expansion *firstChild;
struct Expansion *next;
+ char *name;
char const *contents;
size_t len;
uint8_t distance; /* Distance between the beginning of this expansion and of its parent */
@@ -461,6 +463,7 @@
{
struct Expansion *expansion = lexerState->expansions;
struct Expansion *prevLevel = NULL; /* Top level has no "previous" level */
+ unsigned int depth = 0;
for (;;) {
/* Find the closest expansion whose end is after the target */
@@ -481,10 +484,14 @@
/* Otherwise, register this expansion and repeat the process */
prevLevel = expansion;
expansion = expansion->firstChild;
+
+ if (depth++ > nMaxRecursionDepth)
+ fatalerror("Recursion limit (%u) exceeded", nMaxRecursionDepth);
}
}
-static void beginExpansion(size_t distance, uint8_t skip, char const *str, size_t size)
+static void beginExpansion(size_t distance, uint8_t skip,
+ char const *str, size_t size, char const *name)
{
struct Expansion *parent = getExpansionAtDistance(&distance);
struct Expansion **insertPoint = parent ? &parent->firstChild : &lexerState->expansions;
@@ -498,6 +505,7 @@
fatalerror("Unable to allocate new expansion: %s", strerror(errno));
(*insertPoint)->firstChild = NULL;
(*insertPoint)->next = NULL; /* Expansions are always performed left to right */
+ (*insertPoint)->name = strdup(name);
(*insertPoint)->contents = str;
(*insertPoint)->len = size;
(*insertPoint)->distance = distance;
@@ -513,6 +521,7 @@
do {
struct Expansion *next = expansion->next;
+ free(expansion->name);
free(expansion);
expansion = next;
} while (expansion);
@@ -654,6 +663,8 @@
}
}
+ /* FIXME: this may not be too great, as only the top level is considered... */
+
/*
* The logic is as follows:
* - Any characters up to the expansion need to be consumed in the file
@@ -732,7 +743,37 @@
void lexer_DumpStringExpansions(void)
{
- /* TODO */
+ if (!lexerState)
+ return;
+ /* This is essentially a modified copy-paste of `getExpansionAtDistance(0)` */
+ struct Expansion *stack[nMaxRecursionDepth];
+
+ struct Expansion *expansion = lexerState->expansions;
+ unsigned int depth = 0;
+ size_t distance = lexerState->expansionOfs;
+
+ for (;;) {
+ /* Find the closest expansion whose end is after the target */
+ while (expansion && expansion->len - expansion->distance <= distance) {
+ distance -= expansion->skip;
+ expansion = expansion->next;
+ }
+
+ /* If there is none, or it begins after the target, return the previous level */
+ if (!expansion || expansion->distance > distance)
+ break;
+
+ /* We know we are inside of that expansion */
+ distance -= expansion->distance; /* Distances are relative to their parent */
+
+ stack[depth++] = expansion;
+ if (!expansion->firstChild)
+ break;
+ expansion = expansion->firstChild;
+ }
+
+ while (depth--)
+ fprintf(stderr, "while expanding symbol \"%s\"\n", stack[depth]->name);
}
/* Function to discard all of a line's comments */
@@ -1379,7 +1420,7 @@
if (sym && sym->type == SYM_EQUS) {
char const *s = sym_GetStringValue(sym);
- beginExpansion(0, 0, s, strlen(s));
+ beginExpansion(0, 0, s, strlen(s), sym->name);
continue; /* Restart, reading from the new buffer */
}
}
@@ -1457,7 +1498,9 @@
int yylex(void)
{
- if (lexerState->atLineStart) {
+ if (lexerState->atLineStart
+ /* Newlines read within an expansion should not increase the line count */
+ && (!lexerState->expansions || lexerState->expansions->distance)) {
lexerState->lineNo++;
lexerState->colNo = 0;
}
--- /dev/null
+++ b/test/asm/equs-newline.asm
@@ -1,0 +1,4 @@
+
+ACT equs "WARN \"First\"\nWARN \"Second\""
+ ACT
+ WARN "Third"
--- /dev/null
+++ b/test/asm/equs-newline.err
@@ -1,0 +1,8 @@
+warning: test/asm/equs-newline.asm(2): [-Wuser]
+ First
+while expanding symbol "ACT"
+warning: test/asm/equs-newline.asm(3): [-Wuser]
+ Second
+while expanding symbol "ACT"
+warning: test/asm/equs-newline.asm(4): [-Wuser]
+ Third
--- /dev/null
+++ b/test/asm/equs-purge.asm
@@ -1,0 +1,2 @@
+BYE equs "PURGE BYE\nWARN \"Crash?\"\n \n"
+BYE
--- /dev/null
+++ b/test/asm/equs-purge.err
@@ -1,0 +1,3 @@
+warning: test/asm/equs-purge.asm(0): [-Wuser]
+ Crash?
+while expanding symbol "BYE"