mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Make CaptureBufs be parser values instead of a single static global
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user