mirror of
https://github.com/gbdev/rgbds.git
synced 2026-06-10 02:32:34 +00:00
Intern strings used as identifiers (for labels, constants, macros, charmaps, etc) (#1980)
This commit is contained in:
@@ -13,7 +13,8 @@
|
||||
|
||||
#include "linkdefs.hpp" // AssertionType, RPNCommand
|
||||
|
||||
#include "asm/rpn.hpp" // Expression
|
||||
#include "asm/intern.hpp" // InternedStr
|
||||
#include "asm/rpn.hpp" // Expression
|
||||
|
||||
struct AlignmentSpec {
|
||||
uint8_t alignment;
|
||||
@@ -54,8 +55,8 @@ std::string act_StringFormat(
|
||||
std::string const &spec, std::vector<std::variant<uint32_t, std::string>> const &args
|
||||
);
|
||||
|
||||
std::string act_SectionName(std::string const &symName);
|
||||
std::string act_SectionName(InternedStr symName);
|
||||
|
||||
void act_CompoundAssignment(std::string const &symName, RPNCommand op, int32_t constValue);
|
||||
void act_CompoundAssignment(InternedStr symName, RPNCommand op, int32_t constValue);
|
||||
|
||||
#endif // RGBDS_ASM_ACTIONS_HPP
|
||||
|
||||
@@ -10,13 +10,14 @@
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "asm/intern.hpp"
|
||||
|
||||
void charmap_Init();
|
||||
bool charmap_ForEach(
|
||||
void (*mapFunc)(std::string const &),
|
||||
void (*charFunc)(std::string const &, std::vector<int32_t>)
|
||||
void (*mapFunc)(InternedStr), void (*charFunc)(std::string const &, std::vector<int32_t>)
|
||||
);
|
||||
void charmap_New(std::string const &name, std::string const *baseName);
|
||||
void charmap_Set(std::string const &name);
|
||||
void charmap_New(InternedStr name, InternedStr const *baseName);
|
||||
void charmap_Set(InternedStr name);
|
||||
void charmap_Push();
|
||||
void charmap_Pop();
|
||||
void charmap_CheckStack();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "linkdefs.hpp"
|
||||
|
||||
#include "asm/intern.hpp"
|
||||
#include "asm/lexer.hpp"
|
||||
|
||||
struct FileStackNode {
|
||||
@@ -68,12 +69,10 @@ bool fstk_FailedOnMissingInclude();
|
||||
|
||||
bool yywrap();
|
||||
bool fstk_RunInclude(std::string const &path, bool isQuiet);
|
||||
void fstk_RunMacro(
|
||||
std::string const ¯oName, std::shared_ptr<MacroArgs> macroArgs, bool isQuiet
|
||||
);
|
||||
void fstk_RunMacro(InternedStr macroName, std::shared_ptr<MacroArgs> macroArgs, bool isQuiet);
|
||||
void fstk_RunRept(uint32_t count, int32_t reptLineNo, ContentSpan const &span, bool isQuiet);
|
||||
void fstk_RunFor(
|
||||
std::string const &symName,
|
||||
InternedStr symName,
|
||||
int32_t start,
|
||||
int32_t stop,
|
||||
int32_t step,
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#ifndef RGBDS_ASM_INTERN_HPP
|
||||
#define RGBDS_ASM_INTERN_HPP
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility> // hash
|
||||
|
||||
class InternedStr {
|
||||
size_t index;
|
||||
|
||||
public:
|
||||
constexpr InternedStr() : index(static_cast<size_t>(-1)) {}
|
||||
explicit constexpr InternedStr(size_t index_) : index(index_) {}
|
||||
|
||||
std::string const &str() const;
|
||||
char const *c_str() const { return str().c_str(); }
|
||||
|
||||
bool operator==(InternedStr const &rhs) const { return index == rhs.index; }
|
||||
|
||||
template<typename T>
|
||||
friend struct std::hash;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct std::hash<InternedStr> {
|
||||
size_t operator()(InternedStr const &str) const { return std::hash<size_t>{}(str.index); }
|
||||
};
|
||||
|
||||
InternedStr intern(std::string_view str);
|
||||
|
||||
#endif // RGBDS_ASM_INTERN_HPP
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "platform.hpp" // SSIZE_MAX
|
||||
|
||||
#include "asm/intern.hpp"
|
||||
|
||||
// This value is a compromise between `LexerState` allocation performance when reading the entire
|
||||
// file works, and buffering performance when it doesn't (e.g. when piping a file into RGBASM).
|
||||
static constexpr size_t LEXER_BUF_SIZE = 64;
|
||||
@@ -32,7 +34,7 @@ enum LexerMode {
|
||||
};
|
||||
|
||||
struct Expansion {
|
||||
std::optional<std::string> name;
|
||||
std::optional<InternedStr> name;
|
||||
std::shared_ptr<std::string> contents;
|
||||
size_t offset; // Cursor into `contents`
|
||||
|
||||
|
||||
+6
-4
@@ -10,16 +10,18 @@
|
||||
|
||||
#include "linkdefs.hpp"
|
||||
|
||||
#include "asm/intern.hpp"
|
||||
|
||||
struct Symbol;
|
||||
|
||||
struct RPNValue {
|
||||
RPNCommand command; // The RPN_* command ID
|
||||
std::variant<std::monostate, uint8_t, uint32_t, std::string> data; // Data after the ID, if any
|
||||
std::variant<std::monostate, uint8_t, uint32_t, InternedStr> data; // Data after the ID, if any
|
||||
|
||||
RPNValue(RPNCommand cmd);
|
||||
RPNValue(RPNCommand cmd, uint8_t val);
|
||||
RPNValue(RPNCommand cmd, uint32_t val);
|
||||
RPNValue(RPNCommand cmd, std::string const &name);
|
||||
RPNValue(RPNCommand cmd, InternedStr name);
|
||||
|
||||
void appendEncoded(std::vector<uint8_t> &buffer) const;
|
||||
};
|
||||
@@ -40,8 +42,8 @@ struct Expression {
|
||||
bool isDiffConstant(Symbol const *symName) const;
|
||||
|
||||
void makeNumber(uint32_t value);
|
||||
void makeSymbol(std::string const &symName);
|
||||
void makeBankSymbol(std::string const &symName);
|
||||
void makeSymbol(InternedStr symName);
|
||||
void makeBankSymbol(InternedStr symName);
|
||||
void makeBankSection(std::string const §Name);
|
||||
void makeSizeOfSection(std::string const §Name);
|
||||
void makeStartOfSection(std::string const §Name);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "intern.hpp"
|
||||
#include "linkdefs.hpp"
|
||||
|
||||
struct Expression;
|
||||
@@ -107,6 +108,6 @@ void sect_PushSection();
|
||||
void sect_PopSection();
|
||||
void sect_CheckStack();
|
||||
|
||||
std::string sect_PushSectionFragmentLiteral();
|
||||
InternedStr sect_PushSectionFragmentLiteral();
|
||||
|
||||
#endif // RGBDS_ASM_SECTION_HPP
|
||||
|
||||
+20
-21
@@ -10,6 +10,7 @@
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
|
||||
#include "asm/intern.hpp"
|
||||
#include "asm/lexer.hpp"
|
||||
#include "asm/section.hpp"
|
||||
|
||||
@@ -26,7 +27,7 @@ struct Symbol; // Forward declaration for `sym_IsPC`
|
||||
bool sym_IsPC(Symbol const *sym); // Forward declaration for `getSection`
|
||||
|
||||
struct Symbol {
|
||||
std::string name;
|
||||
InternedStr name;
|
||||
SymbolType type;
|
||||
bool isBuiltin;
|
||||
bool isExported; // Not relevant for SYM_MACRO or SYM_EQUS
|
||||
@@ -68,36 +69,34 @@ struct Symbol {
|
||||
uint32_t getConstantValue() const;
|
||||
};
|
||||
|
||||
bool sym_IsDotScope(std::string const &symName);
|
||||
bool sym_IsDotScope(InternedStr symName);
|
||||
|
||||
void sym_ForEach(void (*callback)(Symbol &));
|
||||
|
||||
Symbol *sym_AddLocalLabel(std::string const &symName);
|
||||
Symbol *sym_AddLabel(std::string const &symName);
|
||||
Symbol *sym_AddLocalLabel(InternedStr symName);
|
||||
Symbol *sym_AddLabel(InternedStr symName);
|
||||
Symbol *sym_AddAnonLabel();
|
||||
std::string sym_MakeAnonLabelName(uint32_t ofs, bool neg);
|
||||
void sym_Export(std::string const &symName);
|
||||
Symbol *sym_AddEqu(std::string const &symName, int32_t value);
|
||||
Symbol *sym_RedefEqu(std::string const &symName, int32_t value);
|
||||
Symbol *sym_AddVar(std::string const &symName, int32_t value);
|
||||
InternedStr sym_MakeAnonLabelName(uint32_t ofs, bool neg);
|
||||
void sym_Export(InternedStr symName);
|
||||
Symbol *sym_AddEqu(InternedStr symName, int32_t value);
|
||||
Symbol *sym_RedefEqu(InternedStr symName, int32_t value);
|
||||
Symbol *sym_AddVar(InternedStr symName, int32_t value);
|
||||
int32_t sym_GetRSValue();
|
||||
void sym_SetRSValue(int32_t value);
|
||||
// Find a symbol by exact name, bypassing expansion checks
|
||||
Symbol *sym_FindExactSymbol(std::string const &symName);
|
||||
Symbol *sym_FindExactSymbol(InternedStr symName);
|
||||
// Find a symbol, possibly scoped, by name
|
||||
Symbol *sym_FindScopedSymbol(std::string const &symName);
|
||||
Symbol *sym_FindScopedSymbol(InternedStr 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 *sym_FindScopedValidSymbol(InternedStr symName);
|
||||
Symbol const *sym_GetPC();
|
||||
Symbol *sym_AddMacro(
|
||||
std::string const &symName, int32_t defLineNo, ContentSpan const &span, bool isQuiet
|
||||
);
|
||||
Symbol *sym_Ref(std::string const &symName);
|
||||
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);
|
||||
void sym_Purge(std::string const &symName);
|
||||
bool sym_IsPurgedExact(std::string const &symName);
|
||||
bool sym_IsPurgedScoped(std::string const &symName);
|
||||
Symbol *sym_AddMacro(InternedStr symName, int32_t defLineNo, ContentSpan const &span, bool isQuiet);
|
||||
Symbol *sym_Ref(InternedStr symName);
|
||||
Symbol *sym_AddString(InternedStr symName, std::shared_ptr<std::string> value);
|
||||
Symbol *sym_RedefString(InternedStr symName, std::shared_ptr<std::string> value);
|
||||
void sym_Purge(InternedStr symName);
|
||||
bool sym_IsPurgedExact(InternedStr symName);
|
||||
bool sym_IsPurgedScoped(InternedStr symName);
|
||||
void sym_Init(time_t now);
|
||||
|
||||
// Functions to save and restore the current label scopes.
|
||||
|
||||
Reference in New Issue
Block a user