Make CaptureBufs be parser values instead of a single static global

This commit is contained in:
Rangi42
2024-03-23 19:44:54 -04:00
parent e9e8915725
commit d9e5e57e27
3 changed files with 50 additions and 55 deletions

View File

@@ -134,13 +134,16 @@ struct CaptureBody {
uint32_t lineNo; uint32_t lineNo;
char const *body; char const *body;
size_t size; size_t size;
void startCapture();
void endCapture();
}; };
void lexer_CheckRecursionDepth(); void lexer_CheckRecursionDepth();
uint32_t lexer_GetLineNo(); uint32_t lexer_GetLineNo();
uint32_t lexer_GetColNo(); uint32_t lexer_GetColNo();
void lexer_DumpStringExpansions(); void lexer_DumpStringExpansions();
bool lexer_CaptureRept(CaptureBody &capture); CaptureBody lexer_CaptureRept();
bool lexer_CaptureMacroBody(CaptureBody &capture); CaptureBody lexer_CaptureMacroBody();
#endif // RGBDS_ASM_LEXER_H #endif // RGBDS_ASM_LEXER_H

View File

@@ -2193,22 +2193,27 @@ yy::parser::symbol_type yylex() {
} }
} }
static void startCapture(CaptureBody &capture) { void CaptureBody::startCapture() {
// Due to parser internals, it reads the EOL after the expression before calling this.
// Thus, we don't need to keep one in the buffer afterwards.
// The following assertion checks that.
assert(lexerState->atLineStart);
assert(!lexerState->capturing); assert(!lexerState->capturing);
lexerState->capturing = true; lexerState->capturing = true;
lexerState->captureSize = 0; lexerState->captureSize = 0;
lexerState->disableMacroArgs = true; lexerState->disableMacroArgs = true;
lexerState->disableInterpolation = true; lexerState->disableInterpolation = true;
capture.lineNo = lexer_GetLineNo(); lineNo = lexer_GetLineNo();
if (auto *mmap = std::get_if<MmappedLexerState>(&lexerState->content); if (auto *mmap = std::get_if<MmappedLexerState>(&lexerState->content);
mmap && lexerState->expansions.empty()) { mmap && lexerState->expansions.empty()) {
capture.body = &mmap->ptr[mmap->offset]; body = &mmap->ptr[mmap->offset];
} else if (auto *view = std::get_if<ViewedLexerState>(&lexerState->content); } else if (auto *view = std::get_if<ViewedLexerState>(&lexerState->content);
view && lexerState->expansions.empty()) { view && lexerState->expansions.empty()) {
capture.body = &view->ptr[view->offset]; body = &view->ptr[view->offset];
} else { } else {
capture.body = nullptr; // Indicates to retrieve the capture buffer when done capturing body = nullptr; // Indicates to retrieve the capture buffer when done capturing
assert(lexerState->captureBuf == nullptr); assert(lexerState->captureBuf == nullptr);
lexerState->captureBuf = new (std::nothrow) std::vector<char>(); lexerState->captureBuf = new (std::nothrow) std::vector<char>();
if (!lexerState->captureBuf) if (!lexerState->captureBuf)
@@ -2216,12 +2221,15 @@ static void startCapture(CaptureBody &capture) {
} }
} }
static void endCapture(CaptureBody &capture) { void CaptureBody::endCapture() {
// This being `nullptr` means we're capturing from the capture buf, which is reallocated // This being `nullptr` means we're capturing from the capture buffer, which is reallocated
// during the whole capture process, and so MUST be retrieved at the end // during the whole capture process, and so MUST be retrieved at the end
if (!capture.body) if (!body)
capture.body = lexerState->captureBuf->data(); body = lexerState->captureBuf->data();
capture.size = lexerState->captureSize; size = lexerState->captureSize;
// ENDR/ENDM or EOF puts us past the start of the line
lexerState->atLineStart = false;
lexerState->capturing = false; lexerState->capturing = false;
lexerState->captureBuf = nullptr; lexerState->captureBuf = nullptr;
@@ -2229,16 +2237,13 @@ static void endCapture(CaptureBody &capture) {
lexerState->disableInterpolation = false; lexerState->disableInterpolation = false;
} }
bool lexer_CaptureRept(CaptureBody &capture) { CaptureBody lexer_CaptureRept() {
startCapture(capture); CaptureBody capture;
capture.startCapture();
size_t depth = 0; size_t depth = 0;
int c = EOF; int c = EOF;
// Due to parser internals, it reads the EOL after the expression before calling this.
// Thus, we don't need to keep one in the buffer afterwards.
// The following assertion checks that.
assert(lexerState->atLineStart);
for (;;) { for (;;) {
nextLine(); nextLine();
// 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
@@ -2282,16 +2287,17 @@ bool lexer_CaptureRept(CaptureBody &capture) {
} }
finish: finish:
endCapture(capture); capture.endCapture();
// ENDR or EOF puts us past the start of the line
lexerState->atLineStart = false;
// Returns true if an ENDR terminated the block, false if it reached EOF first if (c == EOF)
return c != EOF; capture.body = nullptr; // Indicates that it reached EOF before an ENDR terminated it
return capture;
} }
bool lexer_CaptureMacroBody(CaptureBody &capture) { CaptureBody lexer_CaptureMacroBody() {
startCapture(capture); CaptureBody capture;
capture.startCapture();
// If the file is `mmap`ed, we need not to unmap it to keep access to the macro // If the file is `mmap`ed, we need not to unmap it to keep access to the macro
if (auto *mmap = std::get_if<MmappedLexerState>(&lexerState->content); mmap) if (auto *mmap = std::get_if<MmappedLexerState>(&lexerState->content); mmap)
@@ -2299,10 +2305,6 @@ bool lexer_CaptureMacroBody(CaptureBody &capture) {
int c = EOF; int c = EOF;
// Due to parser internals, it reads the EOL after the expression before calling this.
// Thus, we don't need to keep one in the buffer afterwards.
// The following assertion checks that.
assert(lexerState->atLineStart);
for (;;) { for (;;) {
nextLine(); nextLine();
// We're at line start, so attempt to match an `ENDM` token // We're at line start, so attempt to match an `ENDM` token
@@ -2336,10 +2338,10 @@ bool lexer_CaptureMacroBody(CaptureBody &capture) {
} }
finish: finish:
endCapture(capture); capture.endCapture();
// ENDM or EOF puts us past the start of the line
lexerState->atLineStart = false;
// Returns true if an ENDM terminated the block, false if it reached EOF first if (c == EOF)
return c != EOF; capture.body = nullptr; // Indicates that it reached EOF before an ENDM terminated it
return capture;
} }

View File

@@ -10,6 +10,7 @@
#include <variant> #include <variant>
#include <vector> #include <vector>
#include "asm/lexer.hpp"
#include "asm/macro.hpp" #include "asm/macro.hpp"
#include "asm/rpn.hpp" #include "asm/rpn.hpp"
#include "asm/section.hpp" #include "asm/section.hpp"
@@ -56,7 +57,6 @@
#include "asm/fixpoint.hpp" #include "asm/fixpoint.hpp"
#include "asm/format.hpp" #include "asm/format.hpp"
#include "asm/fstack.hpp" #include "asm/fstack.hpp"
#include "asm/lexer.hpp"
#include "asm/main.hpp" #include "asm/main.hpp"
#include "asm/opt.hpp" #include "asm/opt.hpp"
#include "asm/output.hpp" #include "asm/output.hpp"
@@ -70,8 +70,6 @@
using namespace std::literals; using namespace std::literals;
static CaptureBody captureBody; // Captures a REPT/FOR or MACRO
yy::parser::symbol_type yylex(); // Provided by lexer.cpp yy::parser::symbol_type yylex(); // Provided by lexer.cpp
static uint32_t str2int2(std::vector<uint8_t> const &s); static uint32_t str2int2(std::vector<uint8_t> const &s);
@@ -248,8 +246,8 @@
%token SECT_WRAM0 "WRAM0" SECT_WRAMX "WRAMX" SECT_HRAM "HRAM" %token SECT_WRAM0 "WRAM0" SECT_WRAMX "WRAMX" SECT_HRAM "HRAM"
%token SECT_VRAM "VRAM" SECT_SRAM "SRAM" SECT_OAM "OAM" %token SECT_VRAM "VRAM" SECT_SRAM "SRAM" SECT_OAM "OAM"
%type <bool> capture_rept %type <CaptureBody> capture_rept
%type <bool> capture_macro %type <CaptureBody> capture_macro
%type <SectionModifier> sect_mod %type <SectionModifier> sect_mod
%type <std::shared_ptr<MacroArgs>> macro_args %type <std::shared_ptr<MacroArgs>> macro_args
@@ -869,8 +867,8 @@ load:
rept: rept:
POP_REPT uconst NEWLINE capture_rept endofline { POP_REPT uconst NEWLINE capture_rept endofline {
if ($4) if ($4.body)
fstk_RunRept($2, captureBody.lineNo, captureBody.body, captureBody.size); fstk_RunRept($2, $4.lineNo, $4.body, $4.size);
} }
; ;
@@ -880,22 +878,14 @@ for:
} ID { } ID {
lexer_ToggleStringExpansion(true); lexer_ToggleStringExpansion(true);
} COMMA for_args NEWLINE capture_rept endofline { } COMMA for_args NEWLINE capture_rept endofline {
if ($8) if ($8.body)
fstk_RunFor( fstk_RunFor($3, $6.start, $6.stop, $6.step, $8.lineNo, $8.body, $8.size);
$3,
$6.start,
$6.stop,
$6.step,
captureBody.lineNo,
captureBody.body,
captureBody.size
);
} }
; ;
capture_rept: capture_rept:
%empty { %empty {
$$ = lexer_CaptureRept(captureBody); $$ = lexer_CaptureRept();
} }
; ;
@@ -930,14 +920,14 @@ def_macro:
} ID { } ID {
lexer_ToggleStringExpansion(true); lexer_ToggleStringExpansion(true);
} NEWLINE capture_macro endofline { } NEWLINE capture_macro endofline {
if ($6) if ($6.body)
sym_AddMacro($3, captureBody.lineNo, captureBody.body, captureBody.size); sym_AddMacro($3, $6.lineNo, $6.body, $6.size);
} }
; ;
capture_macro: capture_macro:
%empty { %empty {
$$ = lexer_CaptureMacroBody(captureBody); $$ = lexer_CaptureMacroBody();
} }
; ;