From 78801e324c297d8fecdeaad2ab6b479a3a3deba9 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Tue, 26 Mar 2024 23:47:33 -0400 Subject: [PATCH] Group pointer and size as a `ContentSpan` struct --- include/asm/fstack.hpp | 9 ++++----- include/asm/lexer.hpp | 22 +++++++++++----------- include/asm/symbol.hpp | 16 +++++++--------- src/asm/fstack.cpp | 20 +++++++------------- src/asm/lexer.cpp | 40 +++++++++++++++++++--------------------- src/asm/parser.y | 12 ++++++------ src/asm/symbol.cpp | 12 +++++------- 7 files changed, 59 insertions(+), 72 deletions(-) diff --git a/include/asm/fstack.hpp b/include/asm/fstack.hpp index 283f5513..ab51f3a6 100644 --- a/include/asm/fstack.hpp +++ b/include/asm/fstack.hpp @@ -15,6 +15,8 @@ #include "linkdefs.hpp" +#include "asm/lexer.hpp" + struct FileStackNode { FileStackNodeType type; std::variant< @@ -64,17 +66,14 @@ std::optional fstk_FindFile(std::string const &path); bool yywrap(); void fstk_RunInclude(std::string const &path, bool updateStateNow); void fstk_RunMacro(std::string const ¯oName, std::shared_ptr macroArgs); -void fstk_RunRept( - uint32_t count, int32_t reptLineNo, std::shared_ptr body, size_t size -); +void fstk_RunRept(uint32_t count, int32_t reptLineNo, ContentSpan const &span); void fstk_RunFor( std::string const &symName, int32_t start, int32_t stop, int32_t step, int32_t reptLineNo, - std::shared_ptr body, - size_t size + ContentSpan const &span ); void fstk_StopRept(); bool fstk_Break(); diff --git a/include/asm/lexer.hpp b/include/asm/lexer.hpp index c786e566..cb42ae09 100644 --- a/include/asm/lexer.hpp +++ b/include/asm/lexer.hpp @@ -41,6 +41,11 @@ struct IfStackEntry { bool reachedElseBlock; // Whether an ELSE block ran already }; +struct ContentSpan { + std::shared_ptr ptr; + size_t size; +}; + struct BufferedContent { int fd; size_t index = 0; // Read index into the buffer @@ -52,19 +57,17 @@ struct BufferedContent { }; struct MmappedContent { - std::shared_ptr ptr; - size_t size; + ContentSpan span; size_t offset = 0; - MmappedContent(std::shared_ptr ptr_, size_t size_) : ptr(ptr_), size(size_) {} + MmappedContent(std::shared_ptr ptr, size_t size) : span({.ptr = ptr, .size = size}) {} }; struct ViewedContent { - std::shared_ptr ptr; - size_t size; + ContentSpan span; size_t offset = 0; - ViewedContent(std::shared_ptr ptr_, size_t size_) : ptr(ptr_), size(size_) {} + ViewedContent(ContentSpan const &span_) : span(span_) {} }; struct LexerState { @@ -95,9 +98,7 @@ struct LexerState { void setAsCurrentState(); bool setFileAsNextState(std::string const &filePath, bool updateStateNow); - void setViewAsNextState( - char const *name, std::shared_ptr ptr, size_t size, uint32_t lineNo_ - ); + void setViewAsNextState(char const *name, ContentSpan const &span, uint32_t lineNo_); void clear(uint32_t lineNo_); }; @@ -137,8 +138,7 @@ void lexer_DumpStringExpansions(); struct Capture { uint32_t lineNo; - std::shared_ptr body; - size_t size; + ContentSpan span; }; Capture lexer_CaptureRept(); diff --git a/include/asm/symbol.hpp b/include/asm/symbol.hpp index ab5ed9de..d531f8f6 100644 --- a/include/asm/symbol.hpp +++ b/include/asm/symbol.hpp @@ -10,9 +10,9 @@ #include #include #include -#include #include +#include "asm/lexer.hpp" #include "asm/section.hpp" enum SymbolType { @@ -37,10 +37,10 @@ struct Symbol { uint32_t fileLine; // Line where the symbol was defined std::variant< - int32_t, // If isNumeric() - int32_t (*)(), // If isNumeric() and has a callback - std::pair, size_t>, // For SYM_MACRO - std::shared_ptr // For SYM_EQUS + int32_t, // If isNumeric() + int32_t (*)(), // If isNumeric() and has a callback + ContentSpan, // For SYM_MACRO + std::shared_ptr // For SYM_EQUS > data; @@ -62,7 +62,7 @@ struct Symbol { int32_t getValue() const; int32_t getOutputValue() const; - std::pair, size_t> getMacro() const; + ContentSpan const &getMacro() const; std::shared_ptr getEqus() 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 Symbol *sym_FindScopedValidSymbol(std::string const &symName); Symbol const *sym_GetPC(); -Symbol *sym_AddMacro( - std::string const &symName, int32_t defLineNo, std::shared_ptr body, size_t size -); +Symbol *sym_AddMacro(std::string const &symName, int32_t defLineNo, ContentSpan const &span); Symbol *sym_Ref(std::string const &symName); Symbol *sym_AddString(std::string const &symName, std::shared_ptr value); Symbol *sym_RedefString(std::string const &symName, std::shared_ptr value); diff --git a/src/asm/fstack.cpp b/src/asm/fstack.cpp index 8043f4fb..a7e4c391 100644 --- a/src/asm/fstack.cpp +++ b/src/asm/fstack.cpp @@ -281,13 +281,10 @@ static void newMacroContext(Symbol const ¯o, std::shared_ptr macr .macroArgs = macroArgs, }); - auto [body, size] = macro.getMacro(); - context.lexerState.setViewAsNextState("MACRO", body, size, macro.fileLine); + context.lexerState.setViewAsNextState("MACRO", macro.getMacro(), macro.fileLine); } -static Context &newReptContext( - int32_t reptLineNo, std::shared_ptr body, size_t size, uint32_t count -) { +static Context &newReptContext(int32_t reptLineNo, ContentSpan const &span, uint32_t count) { checkRecursionDepth(); Context &oldContext = contextStack.top(); @@ -309,7 +306,7 @@ static Context &newReptContext( .macroArgs = oldContext.macroArgs, }); - context.lexerState.setViewAsNextState("REPT", body, size, reptLineNo); + context.lexerState.setViewAsNextState("REPT", span, reptLineNo); context.nbReptIters = count; @@ -349,13 +346,11 @@ void fstk_RunMacro(std::string const ¯oName, std::shared_ptr macr newMacroContext(*macro, macroArgs); } -void fstk_RunRept( - uint32_t count, int32_t reptLineNo, std::shared_ptr body, size_t size -) { +void fstk_RunRept(uint32_t count, int32_t reptLineNo, ContentSpan const &span) { if (count == 0) return; - newReptContext(reptLineNo, body, size, count); + newReptContext(reptLineNo, span, count); } void fstk_RunFor( @@ -364,8 +359,7 @@ void fstk_RunFor( int32_t stop, int32_t step, int32_t reptLineNo, - std::shared_ptr body, - size_t size + ContentSpan const &span ) { if (Symbol *sym = sym_AddVar(symName, start); sym->type != SYM_VAR) return; @@ -386,7 +380,7 @@ void fstk_RunFor( if (count == 0) return; - Context &context = newReptContext(reptLineNo, body, size, count); + Context &context = newReptContext(reptLineNo, span, count); context.isForLoop = true; context.forValue = start; context.forStep = step; diff --git a/src/asm/lexer.cpp b/src/asm/lexer.cpp index a4ffbf62..4ed97fce 100644 --- a/src/asm/lexer.cpp +++ b/src/asm/lexer.cpp @@ -460,11 +460,9 @@ bool LexerState::setFileAsNextState(std::string const &filePath, bool updateStat return true; } -void LexerState::setViewAsNextState( - char const *name, std::shared_ptr ptr, size_t size, uint32_t lineNo_ -) { +void LexerState::setViewAsNextState(char const *name, ContentSpan const &span, uint32_t lineNo_) { path = name; // Used to report read errors in `peekInternal` - content.emplace(ptr, size); + content.emplace(span); clear(lineNo_); lexerStateEOL = this; } @@ -675,12 +673,12 @@ static int peekInternal(uint8_t distance) { ); if (auto *mmap = std::get_if(&lexerState->content); mmap) { - if (size_t idx = mmap->offset + distance; idx < mmap->size) - return (uint8_t)mmap->ptr[idx]; + if (size_t idx = mmap->offset + distance; idx < mmap->span.size) + return (uint8_t)mmap->span.ptr[idx]; return EOF; } else if (auto *view = std::get_if(&lexerState->content); view) { - if (size_t idx = view->offset + distance; idx < view->size) - return (uint8_t)view->ptr[idx]; + if (size_t idx = view->offset + distance; idx < view->span.size) + return (uint8_t)view->span.ptr[idx]; return EOF; } else { assert(std::holds_alternative(lexerState->content)); @@ -2180,28 +2178,28 @@ static Capture startCapture() { lexerState->capturing = true; lexerState->captureSize = 0; - Capture capture = {.lineNo = lexer_GetLineNo(), .body = nullptr, .size = 0}; + uint32_t lineNo = lexer_GetLineNo(); if (auto *mmap = std::get_if(&lexerState->content); mmap && lexerState->expansions.empty()) { - capture.body = std::shared_ptr(mmap->ptr, &mmap->ptr[mmap->offset]); + return {.lineNo = lineNo, .span = {.ptr = std::shared_ptr(mmap->span.ptr, &mmap->span.ptr[mmap->offset]), .size = 0}}; } else if (auto *view = std::get_if(&lexerState->content); view && lexerState->expansions.empty()) { - capture.body = std::shared_ptr(view->ptr, &view->ptr[view->offset]); + return {.lineNo = lineNo, .span = {.ptr = std::shared_ptr(view->span.ptr, &view->span.ptr[view->offset]), .size = 0}}; } else { - // `capture.body == nullptr`; indicates to retrieve the capture buffer when done capturing assert(lexerState->captureBuf == nullptr); lexerState->captureBuf = std::make_shared>(); + // `.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) { // 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 - if (!capture.body) - capture.body = - std::shared_ptr(lexerState->captureBuf, lexerState->captureBuf->data()); - capture.size = lexerState->captureSize; + if (!capture.span.ptr) + capture.span.ptr = + std::shared_ptr(lexerState->captureBuf, lexerState->captureBuf->data()); + capture.span.size = lexerState->captureSize; // ENDR/ENDM or EOF puts us past the start of the line lexerState->atLineStart = false; @@ -2238,7 +2236,7 @@ Capture lexer_CaptureRept() { endCapture(capture); // The final ENDR has been captured, but we don't want it! // We know we have read exactly "ENDR", not e.g. an EQUS - capture.size -= strlen("ENDR"); + capture.span.size -= strlen("ENDR"); return capture; } depth--; @@ -2254,7 +2252,7 @@ Capture lexer_CaptureRept() { if (c == EOF) { error("Unterminated REPT/FOR block\n"); 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; } else if (c == '\n' || c == '\r') { handleCRLF(c); @@ -2284,7 +2282,7 @@ Capture lexer_CaptureMacro() { endCapture(capture); // The ENDM has been captured, but we don't want it! // We know we have read exactly "ENDM", not e.g. an EQUS - capture.size -= strlen("ENDM"); + capture.span.size -= strlen("ENDM"); return capture; default: @@ -2297,7 +2295,7 @@ Capture lexer_CaptureMacro() { if (c == EOF) { error("Unterminated macro definition\n"); 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; } else if (c == '\n' || c == '\r') { handleCRLF(c); diff --git a/src/asm/parser.y b/src/asm/parser.y index a07b9236..9b062ce3 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -866,8 +866,8 @@ load: rept: POP_REPT uconst NEWLINE capture_rept endofline { - if ($4.body) - fstk_RunRept($2, $4.lineNo, $4.body, $4.size); + if ($4.span.ptr) + fstk_RunRept($2, $4.lineNo, $4.span); } ; @@ -877,8 +877,8 @@ for: } ID { lexer_ToggleStringExpansion(true); } COMMA for_args NEWLINE capture_rept endofline { - if ($8.body) - fstk_RunFor($3, $6.start, $6.stop, $6.step, $8.lineNo, $8.body, $8.size); + if ($8.span.ptr) + fstk_RunFor($3, $6.start, $6.stop, $6.step, $8.lineNo, $8.span); } ; @@ -919,8 +919,8 @@ def_macro: } ID { lexer_ToggleStringExpansion(true); } NEWLINE capture_macro endofline { - if ($6.body) - sym_AddMacro($3, $6.lineNo, $6.body, $6.size); + if ($6.span.ptr) + sym_AddMacro($3, $6.lineNo, $6.span); } ; diff --git a/src/asm/symbol.cpp b/src/asm/symbol.cpp index 88ab5cee..d7325eba 100644 --- a/src/asm/symbol.cpp +++ b/src/asm/symbol.cpp @@ -74,9 +74,9 @@ int32_t Symbol::getOutputValue() const { } } -std::pair, size_t> Symbol::getMacro() const { - assert((std::holds_alternative, size_t>>(data))); - return std::get, size_t>>(data); +ContentSpan const &Symbol::getMacro() const { + assert((std::holds_alternative(data))); + return std::get(data); } std::shared_ptr Symbol::getEqus() const { @@ -489,16 +489,14 @@ void sym_Export(std::string const &symName) { } // Add a macro definition -Symbol *sym_AddMacro( - std::string const &symName, int32_t defLineNo, std::shared_ptr body, size_t size -) { +Symbol *sym_AddMacro(std::string const &symName, int32_t defLineNo, ContentSpan const &span) { Symbol *sym = createNonrelocSymbol(symName, false); if (!sym) return nullptr; sym->type = SYM_MACRO; - sym->data = std::make_pair(body, size); + sym->data = span; sym->src = fstk_GetFileStack(); // The symbol is created at the line after the `ENDM`,