Group pointer and size as a ContentSpan struct

This commit is contained in:
Rangi42
2024-03-26 23:47:33 -04:00
committed by Sylvie
parent bf0cabb3ea
commit 78801e324c
7 changed files with 59 additions and 72 deletions

View File

@@ -15,6 +15,8 @@
#include "linkdefs.hpp" #include "linkdefs.hpp"
#include "asm/lexer.hpp"
struct FileStackNode { struct FileStackNode {
FileStackNodeType type; FileStackNodeType type;
std::variant< std::variant<
@@ -64,17 +66,14 @@ std::optional<std::string> fstk_FindFile(std::string const &path);
bool yywrap(); bool yywrap();
void fstk_RunInclude(std::string const &path, bool updateStateNow); void fstk_RunInclude(std::string const &path, bool updateStateNow);
void fstk_RunMacro(std::string const &macroName, std::shared_ptr<MacroArgs> macroArgs); void fstk_RunMacro(std::string const &macroName, std::shared_ptr<MacroArgs> macroArgs);
void fstk_RunRept( void fstk_RunRept(uint32_t count, int32_t reptLineNo, ContentSpan const &span);
uint32_t count, int32_t reptLineNo, std::shared_ptr<char const[]> body, size_t size
);
void fstk_RunFor( void fstk_RunFor(
std::string const &symName, std::string const &symName,
int32_t start, int32_t start,
int32_t stop, int32_t stop,
int32_t step, int32_t step,
int32_t reptLineNo, int32_t reptLineNo,
std::shared_ptr<char const[]> body, ContentSpan const &span
size_t size
); );
void fstk_StopRept(); void fstk_StopRept();
bool fstk_Break(); bool fstk_Break();

View File

@@ -41,6 +41,11 @@ struct IfStackEntry {
bool reachedElseBlock; // Whether an ELSE block ran already bool reachedElseBlock; // Whether an ELSE block ran already
}; };
struct ContentSpan {
std::shared_ptr<char[]> ptr;
size_t size;
};
struct BufferedContent { struct BufferedContent {
int fd; int fd;
size_t index = 0; // Read index into the buffer size_t index = 0; // Read index into the buffer
@@ -52,19 +57,17 @@ struct BufferedContent {
}; };
struct MmappedContent { struct MmappedContent {
std::shared_ptr<char[]> ptr; ContentSpan span;
size_t size;
size_t offset = 0; size_t offset = 0;
MmappedContent(std::shared_ptr<char[]> ptr_, size_t size_) : ptr(ptr_), size(size_) {} MmappedContent(std::shared_ptr<char[]> ptr, size_t size) : span({.ptr = ptr, .size = size}) {}
}; };
struct ViewedContent { struct ViewedContent {
std::shared_ptr<char const[]> ptr; ContentSpan span;
size_t size;
size_t offset = 0; size_t offset = 0;
ViewedContent(std::shared_ptr<char const[]> ptr_, size_t size_) : ptr(ptr_), size(size_) {} ViewedContent(ContentSpan const &span_) : span(span_) {}
}; };
struct LexerState { struct LexerState {
@@ -95,9 +98,7 @@ struct LexerState {
void setAsCurrentState(); void setAsCurrentState();
bool setFileAsNextState(std::string const &filePath, bool updateStateNow); bool setFileAsNextState(std::string const &filePath, bool updateStateNow);
void setViewAsNextState( void setViewAsNextState(char const *name, ContentSpan const &span, uint32_t lineNo_);
char const *name, std::shared_ptr<char const[]> ptr, size_t size, uint32_t lineNo_
);
void clear(uint32_t lineNo_); void clear(uint32_t lineNo_);
}; };
@@ -137,8 +138,7 @@ void lexer_DumpStringExpansions();
struct Capture { struct Capture {
uint32_t lineNo; uint32_t lineNo;
std::shared_ptr<char const[]> body; ContentSpan span;
size_t size;
}; };
Capture lexer_CaptureRept(); Capture lexer_CaptureRept();

View File

@@ -10,9 +10,9 @@
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <time.h> #include <time.h>
#include <utility>
#include <variant> #include <variant>
#include "asm/lexer.hpp"
#include "asm/section.hpp" #include "asm/section.hpp"
enum SymbolType { enum SymbolType {
@@ -37,10 +37,10 @@ struct Symbol {
uint32_t fileLine; // Line where the symbol was defined uint32_t fileLine; // Line where the symbol was defined
std::variant< std::variant<
int32_t, // If isNumeric() int32_t, // If isNumeric()
int32_t (*)(), // If isNumeric() and has a callback int32_t (*)(), // If isNumeric() and has a callback
std::pair<std::shared_ptr<char const[]>, size_t>, // For SYM_MACRO ContentSpan, // For SYM_MACRO
std::shared_ptr<std::string> // For SYM_EQUS std::shared_ptr<std::string> // For SYM_EQUS
> >
data; data;
@@ -62,7 +62,7 @@ struct Symbol {
int32_t getValue() const; int32_t getValue() const;
int32_t getOutputValue() const; int32_t getOutputValue() const;
std::pair<std::shared_ptr<char const[]>, size_t> getMacro() const; ContentSpan const &getMacro() const;
std::shared_ptr<std::string> getEqus() const; std::shared_ptr<std::string> getEqus() const;
uint32_t getConstantValue() const; uint32_t getConstantValue() const;
}; };
@@ -89,9 +89,7 @@ Symbol *sym_FindScopedSymbol(std::string const &symName);
// Find a scoped symbol by name; do not return `@` or `_NARG` when they have no value // Find a scoped symbol by name; do not return `@` or `_NARG` when they have no value
Symbol *sym_FindScopedValidSymbol(std::string const &symName); Symbol *sym_FindScopedValidSymbol(std::string const &symName);
Symbol const *sym_GetPC(); Symbol const *sym_GetPC();
Symbol *sym_AddMacro( Symbol *sym_AddMacro(std::string const &symName, int32_t defLineNo, ContentSpan const &span);
std::string const &symName, int32_t defLineNo, std::shared_ptr<char const[]> body, size_t size
);
Symbol *sym_Ref(std::string const &symName); Symbol *sym_Ref(std::string const &symName);
Symbol *sym_AddString(std::string const &symName, std::shared_ptr<std::string> value); Symbol *sym_AddString(std::string const &symName, std::shared_ptr<std::string> value);
Symbol *sym_RedefString(std::string const &symName, std::shared_ptr<std::string> value); Symbol *sym_RedefString(std::string const &symName, std::shared_ptr<std::string> value);

View File

@@ -281,13 +281,10 @@ static void newMacroContext(Symbol const &macro, std::shared_ptr<MacroArgs> macr
.macroArgs = macroArgs, .macroArgs = macroArgs,
}); });
auto [body, size] = macro.getMacro(); context.lexerState.setViewAsNextState("MACRO", macro.getMacro(), macro.fileLine);
context.lexerState.setViewAsNextState("MACRO", body, size, macro.fileLine);
} }
static Context &newReptContext( static Context &newReptContext(int32_t reptLineNo, ContentSpan const &span, uint32_t count) {
int32_t reptLineNo, std::shared_ptr<char const[]> body, size_t size, uint32_t count
) {
checkRecursionDepth(); checkRecursionDepth();
Context &oldContext = contextStack.top(); Context &oldContext = contextStack.top();
@@ -309,7 +306,7 @@ static Context &newReptContext(
.macroArgs = oldContext.macroArgs, .macroArgs = oldContext.macroArgs,
}); });
context.lexerState.setViewAsNextState("REPT", body, size, reptLineNo); context.lexerState.setViewAsNextState("REPT", span, reptLineNo);
context.nbReptIters = count; context.nbReptIters = count;
@@ -349,13 +346,11 @@ void fstk_RunMacro(std::string const &macroName, std::shared_ptr<MacroArgs> macr
newMacroContext(*macro, macroArgs); newMacroContext(*macro, macroArgs);
} }
void fstk_RunRept( void fstk_RunRept(uint32_t count, int32_t reptLineNo, ContentSpan const &span) {
uint32_t count, int32_t reptLineNo, std::shared_ptr<char const[]> body, size_t size
) {
if (count == 0) if (count == 0)
return; return;
newReptContext(reptLineNo, body, size, count); newReptContext(reptLineNo, span, count);
} }
void fstk_RunFor( void fstk_RunFor(
@@ -364,8 +359,7 @@ void fstk_RunFor(
int32_t stop, int32_t stop,
int32_t step, int32_t step,
int32_t reptLineNo, int32_t reptLineNo,
std::shared_ptr<char const[]> body, ContentSpan const &span
size_t size
) { ) {
if (Symbol *sym = sym_AddVar(symName, start); sym->type != SYM_VAR) if (Symbol *sym = sym_AddVar(symName, start); sym->type != SYM_VAR)
return; return;
@@ -386,7 +380,7 @@ void fstk_RunFor(
if (count == 0) if (count == 0)
return; return;
Context &context = newReptContext(reptLineNo, body, size, count); Context &context = newReptContext(reptLineNo, span, count);
context.isForLoop = true; context.isForLoop = true;
context.forValue = start; context.forValue = start;
context.forStep = step; context.forStep = step;

View File

@@ -460,11 +460,9 @@ bool LexerState::setFileAsNextState(std::string const &filePath, bool updateStat
return true; return true;
} }
void LexerState::setViewAsNextState( void LexerState::setViewAsNextState(char const *name, ContentSpan const &span, uint32_t lineNo_) {
char const *name, std::shared_ptr<char const[]> ptr, size_t size, uint32_t lineNo_
) {
path = name; // Used to report read errors in `peekInternal` path = name; // Used to report read errors in `peekInternal`
content.emplace<ViewedContent>(ptr, size); content.emplace<ViewedContent>(span);
clear(lineNo_); clear(lineNo_);
lexerStateEOL = this; lexerStateEOL = this;
} }
@@ -675,12 +673,12 @@ static int peekInternal(uint8_t distance) {
); );
if (auto *mmap = std::get_if<MmappedContent>(&lexerState->content); mmap) { if (auto *mmap = std::get_if<MmappedContent>(&lexerState->content); mmap) {
if (size_t idx = mmap->offset + distance; idx < mmap->size) if (size_t idx = mmap->offset + distance; idx < mmap->span.size)
return (uint8_t)mmap->ptr[idx]; return (uint8_t)mmap->span.ptr[idx];
return EOF; return EOF;
} else if (auto *view = std::get_if<ViewedContent>(&lexerState->content); view) { } else if (auto *view = std::get_if<ViewedContent>(&lexerState->content); view) {
if (size_t idx = view->offset + distance; idx < view->size) if (size_t idx = view->offset + distance; idx < view->span.size)
return (uint8_t)view->ptr[idx]; return (uint8_t)view->span.ptr[idx];
return EOF; return EOF;
} else { } else {
assert(std::holds_alternative<BufferedContent>(lexerState->content)); assert(std::holds_alternative<BufferedContent>(lexerState->content));
@@ -2180,28 +2178,28 @@ static Capture startCapture() {
lexerState->capturing = true; lexerState->capturing = true;
lexerState->captureSize = 0; lexerState->captureSize = 0;
Capture capture = {.lineNo = lexer_GetLineNo(), .body = nullptr, .size = 0}; uint32_t lineNo = lexer_GetLineNo();
if (auto *mmap = std::get_if<MmappedContent>(&lexerState->content); if (auto *mmap = std::get_if<MmappedContent>(&lexerState->content);
mmap && lexerState->expansions.empty()) { mmap && lexerState->expansions.empty()) {
capture.body = std::shared_ptr<char const[]>(mmap->ptr, &mmap->ptr[mmap->offset]); return {.lineNo = lineNo, .span = {.ptr = std::shared_ptr<char[]>(mmap->span.ptr, &mmap->span.ptr[mmap->offset]), .size = 0}};
} else if (auto *view = std::get_if<ViewedContent>(&lexerState->content); } else if (auto *view = std::get_if<ViewedContent>(&lexerState->content);
view && lexerState->expansions.empty()) { view && lexerState->expansions.empty()) {
capture.body = std::shared_ptr<char const[]>(view->ptr, &view->ptr[view->offset]); return {.lineNo = lineNo, .span = {.ptr = std::shared_ptr<char[]>(view->span.ptr, &view->span.ptr[view->offset]), .size = 0}};
} else { } else {
// `capture.body == nullptr`; indicates to retrieve the capture buffer when done capturing
assert(lexerState->captureBuf == nullptr); assert(lexerState->captureBuf == nullptr);
lexerState->captureBuf = std::make_shared<std::vector<char>>(); lexerState->captureBuf = std::make_shared<std::vector<char>>();
// `.span.ptr == nullptr`; indicates to retrieve the capture buffer when done capturing
return {.lineNo = lineNo, .span = {.ptr = nullptr, .size = 0}};
} }
return capture;
} }
static void endCapture(Capture &capture) { static void endCapture(Capture &capture) {
// This being `nullptr` means we're capturing from the capture buffer, 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 (!capture.span.ptr)
capture.body = capture.span.ptr =
std::shared_ptr<char const[]>(lexerState->captureBuf, lexerState->captureBuf->data()); std::shared_ptr<char[]>(lexerState->captureBuf, lexerState->captureBuf->data());
capture.size = lexerState->captureSize; capture.span.size = lexerState->captureSize;
// ENDR/ENDM or EOF puts us past the start of the line // ENDR/ENDM or EOF puts us past the start of the line
lexerState->atLineStart = false; lexerState->atLineStart = false;
@@ -2238,7 +2236,7 @@ Capture lexer_CaptureRept() {
endCapture(capture); endCapture(capture);
// The final ENDR has been captured, but we don't want it! // The final ENDR has been captured, but we don't want it!
// We know we have read exactly "ENDR", not e.g. an EQUS // We know we have read exactly "ENDR", not e.g. an EQUS
capture.size -= strlen("ENDR"); capture.span.size -= strlen("ENDR");
return capture; return capture;
} }
depth--; depth--;
@@ -2254,7 +2252,7 @@ Capture lexer_CaptureRept() {
if (c == EOF) { if (c == EOF) {
error("Unterminated REPT/FOR block\n"); error("Unterminated REPT/FOR block\n");
endCapture(capture); endCapture(capture);
capture.body = nullptr; // Indicates that it reached EOF before an ENDR capture.span.ptr = nullptr; // Indicates that it reached EOF before an ENDR
return capture; return capture;
} else if (c == '\n' || c == '\r') { } else if (c == '\n' || c == '\r') {
handleCRLF(c); handleCRLF(c);
@@ -2284,7 +2282,7 @@ Capture lexer_CaptureMacro() {
endCapture(capture); endCapture(capture);
// The ENDM has been captured, but we don't want it! // The ENDM has been captured, but we don't want it!
// We know we have read exactly "ENDM", not e.g. an EQUS // We know we have read exactly "ENDM", not e.g. an EQUS
capture.size -= strlen("ENDM"); capture.span.size -= strlen("ENDM");
return capture; return capture;
default: default:
@@ -2297,7 +2295,7 @@ Capture lexer_CaptureMacro() {
if (c == EOF) { if (c == EOF) {
error("Unterminated macro definition\n"); error("Unterminated macro definition\n");
endCapture(capture); endCapture(capture);
capture.body = nullptr; // Indicates that it reached EOF before an ENDM capture.span.ptr = nullptr; // Indicates that it reached EOF before an ENDM
return capture; return capture;
} else if (c == '\n' || c == '\r') { } else if (c == '\n' || c == '\r') {
handleCRLF(c); handleCRLF(c);

View File

@@ -866,8 +866,8 @@ load:
rept: rept:
POP_REPT uconst NEWLINE capture_rept endofline { POP_REPT uconst NEWLINE capture_rept endofline {
if ($4.body) if ($4.span.ptr)
fstk_RunRept($2, $4.lineNo, $4.body, $4.size); fstk_RunRept($2, $4.lineNo, $4.span);
} }
; ;
@@ -877,8 +877,8 @@ 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.body) if ($8.span.ptr)
fstk_RunFor($3, $6.start, $6.stop, $6.step, $8.lineNo, $8.body, $8.size); fstk_RunFor($3, $6.start, $6.stop, $6.step, $8.lineNo, $8.span);
} }
; ;
@@ -919,8 +919,8 @@ def_macro:
} ID { } ID {
lexer_ToggleStringExpansion(true); lexer_ToggleStringExpansion(true);
} NEWLINE capture_macro endofline { } NEWLINE capture_macro endofline {
if ($6.body) if ($6.span.ptr)
sym_AddMacro($3, $6.lineNo, $6.body, $6.size); sym_AddMacro($3, $6.lineNo, $6.span);
} }
; ;

View File

@@ -74,9 +74,9 @@ int32_t Symbol::getOutputValue() const {
} }
} }
std::pair<std::shared_ptr<char const []>, size_t> Symbol::getMacro() const { ContentSpan const &Symbol::getMacro() const {
assert((std::holds_alternative<std::pair<std::shared_ptr<char const[]>, size_t>>(data))); assert((std::holds_alternative<ContentSpan>(data)));
return std::get<std::pair<std::shared_ptr<char const[]>, size_t>>(data); return std::get<ContentSpan>(data);
} }
std::shared_ptr<std::string> Symbol::getEqus() const { std::shared_ptr<std::string> Symbol::getEqus() const {
@@ -489,16 +489,14 @@ void sym_Export(std::string const &symName) {
} }
// Add a macro definition // Add a macro definition
Symbol *sym_AddMacro( Symbol *sym_AddMacro(std::string const &symName, int32_t defLineNo, ContentSpan const &span) {
std::string const &symName, int32_t defLineNo, std::shared_ptr<char const[]> body, size_t size
) {
Symbol *sym = createNonrelocSymbol(symName, false); Symbol *sym = createNonrelocSymbol(symName, false);
if (!sym) if (!sym)
return nullptr; return nullptr;
sym->type = SYM_MACRO; sym->type = SYM_MACRO;
sym->data = std::make_pair(body, size); sym->data = span;
sym->src = fstk_GetFileStack(); sym->src = fstk_GetFileStack();
// The symbol is created at the line after the `ENDM`, // The symbol is created at the line after the `ENDM`,