mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Refactor peekInternal to be a LexerState method
This commit is contained in:
@@ -14,7 +14,7 @@
|
|||||||
#include "platform.hpp" // SSIZE_MAX
|
#include "platform.hpp" // SSIZE_MAX
|
||||||
|
|
||||||
#define LEXER_BUF_SIZE 128
|
#define LEXER_BUF_SIZE 128
|
||||||
// The buffer needs to be large enough for the maximum `peekInternal` lookahead distance
|
// The buffer needs to be large enough for the maximum `lexerState->peek()` lookahead distance
|
||||||
static_assert(LEXER_BUF_SIZE > 1, "Lexer buffer size is too small");
|
static_assert(LEXER_BUF_SIZE > 1, "Lexer buffer size is too small");
|
||||||
// This caps the size of buffer reads, and according to POSIX, passing more than SSIZE_MAX is UB
|
// This caps the size of buffer reads, and according to POSIX, passing more than SSIZE_MAX is UB
|
||||||
static_assert(LEXER_BUF_SIZE <= SSIZE_MAX, "Lexer buffer size is too large");
|
static_assert(LEXER_BUF_SIZE <= SSIZE_MAX, "Lexer buffer size is too large");
|
||||||
@@ -53,6 +53,7 @@ struct ViewedContent {
|
|||||||
|
|
||||||
bool canPeek(uint8_t distance) const { return offset + distance < span.size; }
|
bool canPeek(uint8_t distance) const { return offset + distance < span.size; }
|
||||||
uint8_t peek(uint8_t distance) const { return span.ptr[offset + distance]; }
|
uint8_t peek(uint8_t distance) const { return span.ptr[offset + distance]; }
|
||||||
|
|
||||||
std::shared_ptr<char[]> makeSharedContentPtr() const {
|
std::shared_ptr<char[]> makeSharedContentPtr() const {
|
||||||
return std::shared_ptr<char[]>(span.ptr, &span.ptr[offset]);
|
return std::shared_ptr<char[]>(span.ptr, &span.ptr[offset]);
|
||||||
}
|
}
|
||||||
@@ -106,6 +107,8 @@ struct LexerState {
|
|||||||
|
|
||||||
~LexerState();
|
~LexerState();
|
||||||
|
|
||||||
|
int peek(uint8_t distance);
|
||||||
|
|
||||||
std::shared_ptr<char[]> makeSharedCaptureBufPtr() const {
|
std::shared_ptr<char[]> makeSharedCaptureBufPtr() const {
|
||||||
return std::shared_ptr<char[]>(captureBuf, captureBuf->data());
|
return std::shared_ptr<char[]>(captureBuf, captureBuf->data());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -455,7 +455,7 @@ bool LexerState::setFileAsNextState(std::string const &filePath, bool updateStat
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LexerState::setViewAsNextState(char const *name, ContentSpan const &span, uint32_t lineNo_) {
|
void LexerState::setViewAsNextState(char const *name, ContentSpan const &span, uint32_t lineNo_) {
|
||||||
path = name; // Used to report read errors in `peekInternal`
|
path = name; // Used to report read errors in `.peek()`
|
||||||
content.emplace<ViewedContent>(span);
|
content.emplace<ViewedContent>(span);
|
||||||
clear(lineNo_);
|
clear(lineNo_);
|
||||||
lexerStateEOL = this;
|
lexerStateEOL = this;
|
||||||
@@ -687,35 +687,33 @@ static std::shared_ptr<std::string> readMacroArg(char name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We only need one character of lookahead, for macro arguments
|
int LexerState::peek(uint8_t distance) {
|
||||||
static int peekInternal(uint8_t distance) {
|
// We only need one character of lookahead, for macro arguments
|
||||||
for (Expansion &exp : lexerState->expansions) {
|
assert(distance == 0 || distance == 1);
|
||||||
|
|
||||||
|
for (Expansion &exp : expansions) {
|
||||||
// An expansion that has reached its end will have `exp->offset` == `exp->size()`,
|
// An expansion that has reached its end will have `exp->offset` == `exp->size()`,
|
||||||
// and `peekInternal` will continue with its parent
|
// and `.peek()` will continue with its parent
|
||||||
assert(exp.offset <= exp.size());
|
assert(exp.offset <= exp.size());
|
||||||
if (exp.canPeek(distance))
|
if (exp.canPeek(distance))
|
||||||
return exp.peek(distance);
|
return exp.peek(distance);
|
||||||
distance -= exp.size() - exp.offset;
|
distance -= exp.size() - exp.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto *view = std::get_if<ViewedContent>(&lexerState->content); view) {
|
if (auto *view = std::get_if<ViewedContent>(&content); view) {
|
||||||
if (view->canPeek(distance))
|
if (view->canPeek(distance))
|
||||||
return view->peek(distance);
|
return view->peek(distance);
|
||||||
return EOF;
|
|
||||||
} else {
|
} else {
|
||||||
assert(std::holds_alternative<BufferedContent>(lexerState->content));
|
assert(std::holds_alternative<BufferedContent>(content));
|
||||||
auto &cbuf = std::get<BufferedContent>(lexerState->content);
|
auto &cbuf = std::get<BufferedContent>(content);
|
||||||
|
|
||||||
assert(distance < LEXER_BUF_SIZE);
|
assert(distance < LEXER_BUF_SIZE);
|
||||||
|
if (!cbuf.canPeek(distance))
|
||||||
|
cbuf.refill(); // Buffer isn't full enough, read some chars in
|
||||||
if (cbuf.canPeek(distance))
|
if (cbuf.canPeek(distance))
|
||||||
return cbuf.peek(distance);
|
return cbuf.peek(distance);
|
||||||
// Buffer isn't full enough, read some chars in
|
|
||||||
cbuf.refill();
|
|
||||||
if (cbuf.canPeek(distance))
|
|
||||||
return cbuf.peek(distance);
|
|
||||||
// If there aren't enough chars even after refilling, give up
|
|
||||||
return EOF;
|
|
||||||
}
|
}
|
||||||
|
// If there aren't enough chars, give up
|
||||||
|
return EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
// forward declarations for peek
|
// forward declarations for peek
|
||||||
@@ -723,7 +721,7 @@ static void shiftChar();
|
|||||||
static std::shared_ptr<std::string> readInterpolation(size_t depth);
|
static std::shared_ptr<std::string> readInterpolation(size_t depth);
|
||||||
|
|
||||||
static int peek() {
|
static int peek() {
|
||||||
int c = peekInternal(0);
|
int c = lexerState->peek(0);
|
||||||
|
|
||||||
if (lexerState->macroArgScanDistance > 0)
|
if (lexerState->macroArgScanDistance > 0)
|
||||||
return c;
|
return c;
|
||||||
@@ -733,7 +731,7 @@ static int peek() {
|
|||||||
if (c == '\\' && !lexerState->disableMacroArgs) {
|
if (c == '\\' && !lexerState->disableMacroArgs) {
|
||||||
// If character is a backslash, check for a macro arg
|
// If character is a backslash, check for a macro arg
|
||||||
lexerState->macroArgScanDistance++;
|
lexerState->macroArgScanDistance++;
|
||||||
c = peekInternal(1);
|
c = lexerState->peek(1);
|
||||||
if (isMacroChar(c)) {
|
if (isMacroChar(c)) {
|
||||||
shiftChar();
|
shiftChar();
|
||||||
shiftChar();
|
shiftChar();
|
||||||
|
|||||||
Reference in New Issue
Block a user