diff --git a/include/asm/fstack.hpp b/include/asm/fstack.hpp index 5811938e..22292c1b 100644 --- a/include/asm/fstack.hpp +++ b/include/asm/fstack.hpp @@ -61,10 +61,10 @@ std::optional fstk_FindFile(char const *path); bool yywrap(); void fstk_RunInclude(char const *path); -void fstk_RunMacro(char const *macroName, MacroArgs &args); +void fstk_RunMacro(std::string const ¯oName, MacroArgs &args); void fstk_RunRept(uint32_t count, int32_t reptLineNo, char const *body, size_t size); void fstk_RunFor( - char const *symName, + std::string const &symName, int32_t start, int32_t stop, int32_t step, diff --git a/include/asm/rpn.hpp b/include/asm/rpn.hpp index 42c539d0..22a073e4 100644 --- a/include/asm/rpn.hpp +++ b/include/asm/rpn.hpp @@ -34,7 +34,7 @@ struct Expression { }; void rpn_Number(Expression &expr, uint32_t val); -void rpn_Symbol(Expression &expr, char const *symName); +void rpn_Symbol(Expression &expr, std::string const &symName); void rpn_LOGNOT(Expression &expr, Expression &&src); void rpn_BinaryOp(RPNCommand op, Expression &expr, Expression &&src1, Expression const &src2); void rpn_HIGH(Expression &expr, Expression &&src); @@ -42,7 +42,7 @@ void rpn_LOW(Expression &expr, Expression &&src); void rpn_ISCONST(Expression &expr, Expression const &src); void rpn_NEG(Expression &expr, Expression &&src); void rpn_NOT(Expression &expr, Expression &&src); -void rpn_BankSymbol(Expression &expr, char const *symName); +void rpn_BankSymbol(Expression &expr, std::string const &symName); void rpn_BankSection(Expression &expr, char const *sectionName); void rpn_BankSelf(Expression &expr); void rpn_SizeOfSection(Expression &expr, char const *sectionName); diff --git a/include/asm/symbol.hpp b/include/asm/symbol.hpp index 5d724aa3..6ddb77a2 100644 --- a/include/asm/symbol.hpp +++ b/include/asm/symbol.hpp @@ -68,27 +68,29 @@ struct Symbol { void sym_ForEach(void (*func)(Symbol &)); void sym_SetExportAll(bool set); -Symbol *sym_AddLocalLabel(char const *symName); -Symbol *sym_AddLabel(char const *symName); +Symbol *sym_AddLocalLabel(std::string const &symName); +Symbol *sym_AddLabel(std::string const &symName); Symbol *sym_AddAnonLabel(); std::string sym_MakeAnonLabelName(uint32_t ofs, bool neg); -void sym_Export(char const *symName); -Symbol *sym_AddEqu(char const *symName, int32_t value); -Symbol *sym_RedefEqu(char const *symName, int32_t value); -Symbol *sym_AddVar(char const *symName, int32_t value); +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); uint32_t sym_GetPCValue(); -uint32_t sym_GetConstantValue(char const *symName); +int32_t sym_GetRSValue(); +void sym_SetRSValue(int32_t value); +uint32_t sym_GetConstantValue(std::string const &symName); // Find a symbol by exact name, bypassing expansion checks -Symbol *sym_FindExactSymbol(char const *symName); +Symbol *sym_FindExactSymbol(std::string const &symName); // Find a symbol, possibly scoped, by name -Symbol *sym_FindScopedSymbol(char const *symName); +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(char const *symName); +Symbol *sym_FindScopedValidSymbol(std::string const &symName); Symbol const *sym_GetPC(); -Symbol *sym_AddMacro(char const *symName, int32_t defLineNo, char const *body, size_t size); -Symbol *sym_Ref(char const *symName); -Symbol *sym_AddString(char const *symName, char const *value); -Symbol *sym_RedefString(char const *symName, char const *value); +Symbol *sym_AddMacro(std::string const &symName, int32_t defLineNo, char const *body, size_t size); +Symbol *sym_Ref(std::string const &symName); +Symbol *sym_AddString(std::string const &symName, char const *value); +Symbol *sym_RedefString(std::string const &symName, char const *value); void sym_Purge(std::string const &symName); void sym_Init(time_t now); diff --git a/src/asm/fstack.cpp b/src/asm/fstack.cpp index ed7dccaf..a0bbf177 100644 --- a/src/asm/fstack.cpp +++ b/src/asm/fstack.cpp @@ -198,7 +198,7 @@ bool yywrap() { // Avoid arithmetic overflow runtime error uint32_t forValue = (uint32_t)context.forValue + (uint32_t)context.forStep; context.forValue = forValue <= INT32_MAX ? forValue : -(int32_t)~forValue - 1; - Symbol *sym = sym_AddVar(context.forName.c_str(), context.forValue); + Symbol *sym = sym_AddVar(context.forName, context.forValue); // This error message will refer to the current iteration if (sym->type != SYM_VAR) @@ -309,15 +309,15 @@ static void runPreIncludeFile() { context.uniqueID = macro_UndefUniqueID(); } -void fstk_RunMacro(char const *macroName, MacroArgs &args) { +void fstk_RunMacro(std::string const ¯oName, MacroArgs &args) { Symbol *macro = sym_FindExactSymbol(macroName); if (!macro) { - error("Macro \"%s\" not defined\n", macroName); + error("Macro \"%s\" not defined\n", macroName.c_str()); return; } if (macro->type != SYM_MACRO) { - error("\"%s\" is not a macro\n", macroName); + error("\"%s\" is not a macro\n", macroName.c_str()); return; } contextStack.top().macroArgs = macro_GetCurrentArgs(); @@ -392,7 +392,7 @@ void fstk_RunRept(uint32_t count, int32_t reptLineNo, char const *body, size_t s } void fstk_RunFor( - char const *symName, + std::string const &symName, int32_t start, int32_t stop, int32_t step, diff --git a/src/asm/lexer.cpp b/src/asm/lexer.cpp index df2b2f55..5e3765f8 100644 --- a/src/asm/lexer.cpp +++ b/src/asm/lexer.cpp @@ -558,7 +558,7 @@ static uint32_t readBracketedMacroArgNum() { shiftChar(); } - Symbol const *sym = sym_FindScopedValidSymbol(symName.c_str()); + Symbol const *sym = sym_FindScopedValidSymbol(symName); if (!sym) { error("Bracketed symbol \"%s\" does not exist\n", symName.c_str()); @@ -1188,7 +1188,7 @@ static char const *readInterpolation(size_t depth) { static char buf[MAXSTRLEN + 1]; - Symbol const *sym = sym_FindScopedValidSymbol(fmtBuf.c_str()); + Symbol const *sym = sym_FindScopedValidSymbol(fmtBuf); if (!sym) { error("Interpolated symbol \"%s\" does not exist\n", fmtBuf.c_str()); @@ -1820,8 +1820,7 @@ static Token yylex_NORMAL() { // Local symbols cannot be string expansions if (token.type == T_(ID) && lexerState->expandStrings) { // Attempt string expansion - Symbol const *sym = - sym_FindExactSymbol(std::get(token.value).c_str()); + Symbol const *sym = sym_FindExactSymbol(std::get(token.value)); if (sym && sym->type == SYM_EQUS) { char const *str = sym->getEqus()->c_str(); diff --git a/src/asm/output.cpp b/src/asm/output.cpp index db655d14..58d58dca 100644 --- a/src/asm/output.cpp +++ b/src/asm/output.cpp @@ -187,10 +187,10 @@ static void writerpn(std::vector &rpnexpr, std::vector const & } // The symbol name is always written expanded - sym = sym_FindExactSymbol(symName.c_str()); + sym = sym_FindExactSymbol(symName); if (sym->isConstant()) { rpnexpr[rpnptr++] = RPN_CONST; - value = sym_GetConstantValue(symName.c_str()); + value = sym_GetConstantValue(symName); } else { rpnexpr[rpnptr++] = RPN_SYM; value = getSymbolID(*sym); @@ -212,7 +212,7 @@ static void writerpn(std::vector &rpnexpr, std::vector const & } // The symbol name is always written expanded - sym = sym_FindExactSymbol(symName.c_str()); + sym = sym_FindExactSymbol(symName); value = getSymbolID(*sym); rpnexpr[rpnptr++] = RPN_BANK_SYM; diff --git a/src/asm/parser.y b/src/asm/parser.y index 2da2129e..4c91f357 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -68,6 +68,8 @@ #include "helpers.hpp" + using namespace std::literals; + static CaptureBody captureBody; // Captures a REPT/FOR or MACRO yy::parser::symbol_type yylex(); // Provided by lexer.cpp @@ -351,7 +353,7 @@ line: lexer_SetMode(LEXER_NORMAL); lexer_ToggleStringExpansion(true); } endofline { - Symbol *macro = sym_FindExactSymbol($1.c_str()); + Symbol *macro = sym_FindExactSymbol($1); if (macro && macro->type == SYM_MACRO) fprintf( @@ -488,21 +490,21 @@ label: sym_AddAnonLabel(); } | LOCAL_ID { - sym_AddLocalLabel($1.c_str()); + sym_AddLocalLabel($1); } | LOCAL_ID COLON { - sym_AddLocalLabel($1.c_str()); + sym_AddLocalLabel($1); } | LABEL COLON { - sym_AddLabel($1.c_str()); + sym_AddLabel($1); } | LOCAL_ID DOUBLE_COLON { - sym_AddLocalLabel($1.c_str()); - sym_Export($1.c_str()); + sym_AddLocalLabel($1); + sym_Export($1); } | LABEL DOUBLE_COLON { - sym_AddLabel($1.c_str()); - sym_Export($1.c_str()); + sym_AddLabel($1); + sym_Export($1); } ; @@ -511,7 +513,7 @@ macro: // Parsing 'macroargs' will restore the lexer's normal mode lexer_SetMode(LEXER_RAW); } macroargs { - fstk_RunMacro($1.c_str(), *$3); + fstk_RunMacro($1, *$3); } ; @@ -617,14 +619,14 @@ equ: $1.c_str(), $1.c_str() ); - sym_AddEqu($1.c_str(), $3); + sym_AddEqu($1, $3); } ; assignment: LABEL POP_EQUAL const { warning(WARNING_OBSOLETE, "`%s =` is deprecated; use `DEF %s =`\n", $1.c_str(), $1.c_str()); - sym_AddVar($1.c_str(), $3); + sym_AddVar($1, $3); } | LABEL compoundeq const { char const *compoundEqOperator = nullptr; @@ -662,7 +664,7 @@ equs: $1.c_str(), $1.c_str() ); - sym_AddString($1.c_str(), $3.c_str()); + sym_AddString($1, $3.c_str()); } ; @@ -674,8 +676,9 @@ rb: $1.c_str(), $1.c_str() ); - sym_AddEqu($1.c_str(), sym_GetConstantValue("_RS")); - sym_AddVar("_RS", sym_GetConstantValue("_RS") + $3); + uint32_t rs = sym_GetRSValue(); + sym_AddEqu($1, rs); + sym_SetRSValue(rs + $3); } ; @@ -687,8 +690,9 @@ rw: $1.c_str(), $1.c_str() ); - sym_AddEqu($1.c_str(), sym_GetConstantValue("_RS")); - sym_AddVar("_RS", sym_GetConstantValue("_RS") + 2 * $3); + uint32_t rs = sym_GetRSValue(); + sym_AddEqu($1, rs); + sym_SetRSValue(rs + 2 * $3); } ; @@ -700,8 +704,9 @@ rl: $1.c_str(), $1.c_str() ); - sym_AddEqu($1.c_str(), sym_GetConstantValue("_RS")); - sym_AddVar("_RS", sym_GetConstantValue("_RS") + 4 * $3); + uint32_t rs = sym_GetRSValue(); + sym_AddEqu($1, rs); + sym_SetRSValue(rs + 4 * $3); } ; @@ -872,7 +877,7 @@ for: } COMMA for_args NEWLINE capture_rept endofline { if ($8) fstk_RunFor( - $3.c_str(), + $3, $6.start, $6.stop, $6.step, @@ -921,7 +926,7 @@ macrodef: lexer_ToggleStringExpansion(true); } NEWLINE capture_macro endofline { if ($6) - sym_AddMacro($3.c_str(), captureBody.lineNo, captureBody.body, captureBody.size); + sym_AddMacro($3, captureBody.lineNo, captureBody.body, captureBody.size); } ; @@ -933,13 +938,13 @@ capture_macro: rsset: POP_RSSET uconst { - sym_AddVar("_RS", $2); + sym_SetRSValue($2); } ; rsreset: POP_RSRESET { - sym_AddVar("_RS", 0); + sym_SetRSValue(0); } ; @@ -1022,22 +1027,22 @@ dl: def_equ: def_id POP_EQU const { - sym_AddEqu($1.c_str(), $3); + sym_AddEqu($1, $3); } ; redef_equ: redef_id POP_EQU const { - sym_RedefEqu($1.c_str(), $3); + sym_RedefEqu($1, $3); } ; def_set: def_id POP_EQUAL const { - sym_AddVar($1.c_str(), $3); + sym_AddVar($1, $3); } | redef_id POP_EQUAL const { - sym_AddVar($1.c_str(), $3); + sym_AddVar($1, $3); } | def_id compoundeq const { compoundAssignment($1, $2, $3); @@ -1049,34 +1054,37 @@ def_set: def_rb: def_id POP_RB rs_uconst { - sym_AddEqu($1.c_str(), sym_GetConstantValue("_RS")); - sym_AddVar("_RS", sym_GetConstantValue("_RS") + $3); + uint32_t rs = sym_GetRSValue(); + sym_AddEqu($1, rs); + sym_SetRSValue(rs + $3); } ; def_rw: def_id POP_RW rs_uconst { - sym_AddEqu($1.c_str(), sym_GetConstantValue("_RS")); - sym_AddVar("_RS", sym_GetConstantValue("_RS") + 2 * $3); + uint32_t rs = sym_GetRSValue(); + sym_AddEqu($1, rs); + sym_SetRSValue(rs + 2 * $3); } ; def_rl: def_id Z80_RL rs_uconst { - sym_AddEqu($1.c_str(), sym_GetConstantValue("_RS")); - sym_AddVar("_RS", sym_GetConstantValue("_RS") + 4 * $3); + uint32_t rs = sym_GetRSValue(); + sym_AddEqu($1, rs); + sym_SetRSValue(rs + 4 * $3); } ; def_equs: def_id POP_EQUS string { - sym_AddString($1.c_str(), $3.c_str()); + sym_AddString($1, $3.c_str()); } ; redef_equs: redef_id POP_EQUS string { - sym_RedefString($1.c_str(), $3.c_str()); + sym_RedefString($1, $3.c_str()); } ; @@ -1109,7 +1117,7 @@ export_list: export_list_entry: scoped_id { - sym_Export($1.c_str()); + sym_Export($1); } ; @@ -1316,7 +1324,7 @@ relocexpr: relocexpr_no_str: scoped_anon_id { - rpn_Symbol($$, $1.c_str()); + rpn_Symbol($$, $1); } | NUMBER { rpn_Number($$, $1); @@ -1404,7 +1412,7 @@ relocexpr_no_str: } | OP_BANK LPAREN scoped_anon_id RPAREN { // '@' is also an ID; it is handled here - rpn_BankSymbol($$, $3.c_str()); + rpn_BankSymbol($$, $3); } | OP_BANK LPAREN string RPAREN { rpn_BankSection($$, $3.c_str()); @@ -1424,7 +1432,7 @@ relocexpr_no_str: | OP_DEF { lexer_ToggleStringExpansion(false); } LPAREN scoped_anon_id RPAREN { - rpn_Number($$, sym_FindScopedValidSymbol($4.c_str()) != nullptr); + rpn_Number($$, sym_FindScopedValidSymbol($4) != nullptr); lexer_ToggleStringExpansion(true); } | OP_ROUND LPAREN const opt_q_arg RPAREN { @@ -1581,7 +1589,7 @@ string: $$ = strfmt($3.format, $3.args); } | POP_SECTION LPAREN scoped_anon_id RPAREN { - Symbol *sym = sym_FindScopedValidSymbol($3.c_str()); + Symbol *sym = sym_FindScopedValidSymbol($3); if (!sym) fatalerror("Unknown symbol \"%s\"\n", $3.c_str()); @@ -2716,11 +2724,11 @@ static void compoundAssignment(std::string const &symName, RPNCommand op, int32_ Expression oldExpr, constExpr, newExpr; int32_t newValue; - rpn_Symbol(oldExpr, symName.c_str()); + rpn_Symbol(oldExpr, symName); rpn_Number(constExpr, constValue); rpn_BinaryOp(op, newExpr, std::move(oldExpr), constExpr); newValue = newExpr.getConstVal(); - sym_AddVar(symName.c_str(), newValue); + sym_AddVar(symName, newValue); } static void failAssert(AssertionType type) { diff --git a/src/asm/rpn.cpp b/src/asm/rpn.cpp index 7c987c2f..070f6399 100644 --- a/src/asm/rpn.cpp +++ b/src/asm/rpn.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "opmath.hpp" @@ -50,7 +51,7 @@ void rpn_Number(Expression &expr, uint32_t val) { expr.val = val; } -void rpn_Symbol(Expression &expr, char const *symName) { +void rpn_Symbol(Expression &expr, std::string const &symName) { initExpression(expr); Symbol *sym = sym_FindScopedSymbol(symName); @@ -92,7 +93,7 @@ static void bankSelf(Expression &expr) { } } -void rpn_BankSymbol(Expression &expr, char const *symName) { +void rpn_BankSymbol(Expression &expr, std::string const &symName) { Symbol const *sym = sym_FindScopedSymbol(symName); // The @ symbol is treated differently. diff --git a/src/asm/symbol.cpp b/src/asm/symbol.cpp index b7f7d289..44a50f71 100644 --- a/src/asm/symbol.cpp +++ b/src/asm/symbol.cpp @@ -22,11 +22,14 @@ #include "asm/output.hpp" #include "asm/warning.hpp" +using namespace std::literals; + std::unordered_map symbols; static std::optional labelScope = std::nullopt; // Current section's label scope static Symbol *PCSymbol; static Symbol *_NARGSymbol; +static Symbol *_RSSymbol; static char savedTIME[256]; static char savedDATE[256]; static char savedTIMESTAMP_ISO8601_LOCAL[256]; @@ -113,7 +116,7 @@ static void updateSymbolFilename(Symbol &sym) { } // Create a new symbol by name -static Symbol &createsymbol(char const *symName) { +static Symbol &createsymbol(std::string const &symName) { Symbol &sym = symbols[symName]; sym.name = symName; @@ -134,26 +137,25 @@ static void assignStringSymbol(Symbol &sym, char const *value) { sym.data = equs; } -Symbol *sym_FindExactSymbol(char const *symName) { +Symbol *sym_FindExactSymbol(std::string const &symName) { auto search = symbols.find(symName); return search != symbols.end() ? &search->second : nullptr; } -Symbol *sym_FindScopedSymbol(char const *symName) { - if (char const *localName = strchr(symName, '.'); localName) { - if (strchr(localName + 1, '.')) - fatalerror("'%s' is a nonsensical reference to a nested local symbol\n", symName); +Symbol *sym_FindScopedSymbol(std::string const &symName) { + if (size_t dotPos = symName.find('.'); dotPos != std::string::npos) { + if (symName.find('.', dotPos + 1) != std::string::npos) + fatalerror( + "'%s' is a nonsensical reference to a nested local symbol\n", symName.c_str() + ); // If auto-scoped local label, expand the name - if (localName == symName) { // Meaning, the name begins with the dot - std::string fullName = labelScope ? *labelScope + symName : symName; - - return sym_FindExactSymbol(fullName.c_str()); - } + if (dotPos == 0 && labelScope) + return sym_FindExactSymbol(*labelScope + symName); } return sym_FindExactSymbol(symName); } -Symbol *sym_FindScopedValidSymbol(char const *symName) { +Symbol *sym_FindScopedValidSymbol(std::string const &symName) { Symbol *sym = sym_FindScopedSymbol(symName); // `@` has no value outside a section @@ -173,7 +175,7 @@ Symbol const *sym_GetPC() { // Purge a symbol void sym_Purge(std::string const &symName) { - Symbol *sym = sym_FindScopedValidSymbol(symName.c_str()); + Symbol *sym = sym_FindScopedValidSymbol(symName); if (!sym) { error("'%s' not defined\n", symName.c_str()); @@ -205,6 +207,15 @@ uint32_t sym_GetPCValue() { return 0; } +int32_t sym_GetRSValue() { + return _RSSymbol->getOutputValue(); +} + +void sym_SetRSValue(int32_t value) { + updateSymbolFilename(*_RSSymbol); + _RSSymbol->data = value; +} + // Return a constant symbol's value, assuming it's defined uint32_t Symbol::getConstantValue() const { if (sym_IsPC(this)) @@ -218,11 +229,11 @@ uint32_t Symbol::getConstantValue() const { } // Return a constant symbol's value -uint32_t sym_GetConstantValue(char const *symName) { +uint32_t sym_GetConstantValue(std::string const &symName) { if (Symbol const *sym = sym_FindScopedSymbol(symName); sym) return sym->getConstantValue(); - error("'%s' not defined\n", symName); + error("'%s' not defined\n", symName.c_str()); return 0; } @@ -241,19 +252,19 @@ void sym_SetCurrentSymbolScope(std::optional const &newScope) { * @param symName The name of the symbol to create * @param numeric If false, the symbol may not have been referenced earlier */ -static Symbol *createNonrelocSymbol(char const *symName, bool numeric) { +static Symbol *createNonrelocSymbol(std::string const &symName, bool numeric) { Symbol *sym = sym_FindExactSymbol(symName); if (!sym) { sym = &createsymbol(symName); } else if (sym->isDefined()) { - error("'%s' already defined at ", symName); + error("'%s' already defined at ", symName.c_str()); dumpFilename(*sym); putc('\n', stderr); return nullptr; // Don't allow overriding the symbol, that'd be bad! } else if (!numeric) { // The symbol has already been referenced, but it's not allowed - error("'%s' already referenced at ", symName); + error("'%s' already referenced at ", symName.c_str()); dumpFilename(*sym); putc('\n', stderr); return nullptr; // Don't allow overriding the symbol, that'd be bad! @@ -263,7 +274,7 @@ static Symbol *createNonrelocSymbol(char const *symName, bool numeric) { } // Add an equated symbol -Symbol *sym_AddEqu(char const *symName, int32_t value) { +Symbol *sym_AddEqu(std::string const &symName, int32_t value) { Symbol *sym = createNonrelocSymbol(symName, true); if (!sym) @@ -275,19 +286,19 @@ Symbol *sym_AddEqu(char const *symName, int32_t value) { return sym; } -Symbol *sym_RedefEqu(char const *symName, int32_t value) { +Symbol *sym_RedefEqu(std::string const &symName, int32_t value) { Symbol *sym = sym_FindExactSymbol(symName); if (!sym) return sym_AddEqu(symName, value); if (sym->isDefined() && sym->type != SYM_EQU) { - error("'%s' already defined as non-EQU at ", symName); + error("'%s' already defined as non-EQU at ", symName.c_str()); dumpFilename(*sym); putc('\n', stderr); return nullptr; } else if (sym->isBuiltin) { - error("Built-in symbol '%s' cannot be redefined\n", symName); + error("Built-in symbol '%s' cannot be redefined\n", symName.c_str()); return nullptr; } @@ -302,15 +313,15 @@ Symbol *sym_RedefEqu(char const *symName, int32_t value) { * Add a string equated symbol. * * If the desired symbol is a string it needs to be passed to this function with - * quotes inside the string, like sym_AddString("name", "\"test\"), or the + * quotes inside the string, like sym_AddString("name"s, "\"test\"), or the * assembler won't be able to use it with DB and similar. This is equivalent to * ``` name EQUS "\"test\"" ``` * * If the desired symbol is a register or a number, just the terminator quotes - * of the string are enough: sym_AddString("M_PI", "3.1415"). This is the same + * of the string are enough: sym_AddString("M_PI"s, "3.1415"). This is the same * as ``` M_PI EQUS "3.1415" ``` */ -Symbol *sym_AddString(char const *symName, char const *value) { +Symbol *sym_AddString(std::string const &symName, char const *value) { Symbol *sym = createNonrelocSymbol(symName, false); if (!sym) @@ -320,7 +331,7 @@ Symbol *sym_AddString(char const *symName, char const *value) { return sym; } -Symbol *sym_RedefString(char const *symName, char const *value) { +Symbol *sym_RedefString(std::string const &symName, char const *value) { Symbol *sym = sym_FindExactSymbol(symName); if (!sym) @@ -328,14 +339,14 @@ Symbol *sym_RedefString(char const *symName, char const *value) { if (sym->type != SYM_EQUS) { if (sym->isDefined()) - error("'%s' already defined as non-EQUS at ", symName); + error("'%s' already defined as non-EQUS at ", symName.c_str()); else - error("'%s' already referenced at ", symName); + error("'%s' already referenced at ", symName.c_str()); dumpFilename(*sym); putc('\n', stderr); return nullptr; } else if (sym->isBuiltin) { - error("Built-in symbol '%s' cannot be redefined\n", symName); + error("Built-in symbol '%s' cannot be redefined\n", symName.c_str()); return nullptr; } @@ -348,14 +359,16 @@ Symbol *sym_RedefString(char const *symName, char const *value) { } // Alter a mutable symbol's value -Symbol *sym_AddVar(char const *symName, int32_t value) { +Symbol *sym_AddVar(std::string const &symName, int32_t value) { Symbol *sym = sym_FindExactSymbol(symName); if (!sym) { sym = &createsymbol(symName); } else if (sym->isDefined() && sym->type != SYM_VAR) { error( - "'%s' already defined as %s at ", symName, sym->type == SYM_LABEL ? "label" : "constant" + "'%s' already defined as %s at ", + symName.c_str(), + sym->type == SYM_LABEL ? "label" : "constant" ); dumpFilename(*sym); putc('\n', stderr); @@ -375,14 +388,14 @@ Symbol *sym_AddVar(char const *symName, int32_t value) { * @param symName The label's full name (so `.name` is invalid) * @return The created symbol */ -static Symbol *addLabel(char const *symName) { - assert(symName[0] != '.'); // The symbol name must have been expanded prior +static Symbol *addLabel(std::string const &symName) { + assert(!symName.starts_with('.')); // The symbol name must have been expanded prior Symbol *sym = sym_FindExactSymbol(symName); if (!sym) { sym = &createsymbol(symName); } else if (sym->isDefined()) { - error("'%s' already defined at ", symName); + error("'%s' already defined at ", symName.c_str()); dumpFilename(*sym); putc('\n', stderr); return nullptr; @@ -393,48 +406,45 @@ static Symbol *addLabel(char const *symName) { sym->type = SYM_LABEL; sym->data = (int32_t)sect_GetSymbolOffset(); // Don't export anonymous labels - if (exportAll && symName[0] != '!') + if (exportAll && !symName.starts_with('!')) sym->isExported = true; sym->section = sect_GetSymbolSection(); if (sym && !sym->section) - error("Label \"%s\" created outside of a SECTION\n", symName); + error("Label \"%s\" created outside of a SECTION\n", symName.c_str()); return sym; } // Add a local (`.name` or `Parent.name`) relocatable symbol -Symbol *sym_AddLocalLabel(char const *symName) { +Symbol *sym_AddLocalLabel(std::string const &symName) { // Assuming no dots in `labelScope` if defined assert(!labelScope.has_value() || labelScope->find('.') == std::string::npos); - char const *localName = strchr(symName, '.'); + size_t dotPos = symName.find('.'); - assert(localName); // There should be at least one dot in `symName` + assert(dotPos != std::string::npos); // There should be at least one dot in `symName` - // Check for something after the dot in `localName` - if (localName[1] == '\0') { - fatalerror("'%s' is a nonsensical reference to an empty local label\n", symName); + // Check for something after the dot + if (dotPos == symName.length() - 1) { + fatalerror("'%s' is a nonsensical reference to an empty local label\n", symName.c_str()); } - // Check for more than one dot in `localName` - if (strchr(localName + 1, '.')) - fatalerror("'%s' is a nonsensical reference to a nested local label\n", symName); + // Check for more than one dot + if (symName.find('.', dotPos + 1) != std::string::npos) + fatalerror("'%s' is a nonsensical reference to a nested local label\n", symName.c_str()); - if (localName == symName) { + if (dotPos == 0) { if (!labelScope.has_value()) { - error("Unqualified local label '%s' in main scope\n", symName); + error("Unqualified local label '%s' in main scope\n", symName.c_str()); return nullptr; } - std::string fullName = *labelScope + symName; - - return addLabel(fullName.c_str()); - } else { - return addLabel(symName); + return addLabel(*labelScope + symName); } + return addLabel(symName); } // Add a relocatable symbol -Symbol *sym_AddLabel(char const *symName) { +Symbol *sym_AddLabel(std::string const &symName) { Symbol *sym = addLabel(symName); // Set the symbol as the new scope @@ -454,7 +464,7 @@ Symbol *sym_AddAnonLabel() { std::string anon = sym_MakeAnonLabelName(0, true); // The direction is important! anonLabelID++; - return addLabel(anon.c_str()); + return addLabel(anon); } // Write an anonymous label's name to a buffer @@ -491,8 +501,8 @@ std::string sym_MakeAnonLabelName(uint32_t ofs, bool neg) { } // Export a symbol -void sym_Export(char const *symName) { - if (symName[0] == '!') { +void sym_Export(std::string const &symName) { + if (symName.starts_with('!')) { error("Anonymous labels cannot be exported\n"); return; } @@ -506,7 +516,7 @@ void sym_Export(char const *symName) { } // Add a macro definition -Symbol *sym_AddMacro(char const *symName, int32_t defLineNo, char const *body, size_t size) { +Symbol *sym_AddMacro(std::string const &symName, int32_t defLineNo, char const *body, size_t size) { Symbol *sym = createNonrelocSymbol(symName, false); if (!sym) @@ -528,16 +538,16 @@ Symbol *sym_AddMacro(char const *symName, int32_t defLineNo, char const *body, s // Flag that a symbol is referenced in an RPN expression // and create it if it doesn't exist yet -Symbol *sym_Ref(char const *symName) { +Symbol *sym_Ref(std::string const &symName) { Symbol *sym = sym_FindScopedSymbol(symName); if (!sym) { - if (symName[0] == '.') { + if (symName.starts_with('.')) { if (!labelScope.has_value()) - fatalerror("Local label reference '%s' in main scope\n", symName); + fatalerror("Local label reference '%s' in main scope\n", symName.c_str()); std::string fullName = *labelScope + symName; - sym = &createsymbol(fullName.c_str()); + sym = &createsymbol(fullName); } else { sym = &createsymbol(symName); } @@ -553,7 +563,7 @@ void sym_SetExportAll(bool set) { exportAll = set; } -static Symbol *createBuiltinSymbol(char const *symName) { +static Symbol *createBuiltinSymbol(std::string const &symName) { Symbol *sym = &createsymbol(symName); sym->isBuiltin = true; @@ -565,22 +575,23 @@ static Symbol *createBuiltinSymbol(char const *symName) { // Initialize the symboltable void sym_Init(time_t now) { - PCSymbol = createBuiltinSymbol("@"); + PCSymbol = createBuiltinSymbol("@"s); PCSymbol->type = SYM_LABEL; PCSymbol->data = CallbackPC; - _NARGSymbol = createBuiltinSymbol("_NARG"); + _NARGSymbol = createBuiltinSymbol("_NARG"s); _NARGSymbol->type = SYM_EQU; _NARGSymbol->data = Callback_NARG; - sym_AddVar("_RS", 0)->isBuiltin = true; + _RSSymbol = sym_AddVar("_RS"s, 0); + _RSSymbol->isBuiltin = true; - sym_AddString("__RGBDS_VERSION__", get_package_version_string())->isBuiltin = true; - sym_AddEqu("__RGBDS_MAJOR__", PACKAGE_VERSION_MAJOR)->isBuiltin = true; - sym_AddEqu("__RGBDS_MINOR__", PACKAGE_VERSION_MINOR)->isBuiltin = true; - sym_AddEqu("__RGBDS_PATCH__", PACKAGE_VERSION_PATCH)->isBuiltin = true; + sym_AddString("__RGBDS_VERSION__"s, get_package_version_string())->isBuiltin = true; + sym_AddEqu("__RGBDS_MAJOR__"s, PACKAGE_VERSION_MAJOR)->isBuiltin = true; + sym_AddEqu("__RGBDS_MINOR__"s, PACKAGE_VERSION_MINOR)->isBuiltin = true; + sym_AddEqu("__RGBDS_PATCH__"s, PACKAGE_VERSION_PATCH)->isBuiltin = true; #ifdef PACKAGE_VERSION_RC - sym_AddEqu("__RGBDS_RC__", PACKAGE_VERSION_RC)->isBuiltin = true; + sym_AddEqu("__RGBDS_RC__"s, PACKAGE_VERSION_RC)->isBuiltin = true; #endif if (now == (time_t)-1) { @@ -609,17 +620,17 @@ void sym_Init(time_t now) { time_utc ); - sym_AddString("__TIME__", savedTIME)->isBuiltin = true; - sym_AddString("__DATE__", savedDATE)->isBuiltin = true; - sym_AddString("__ISO_8601_LOCAL__", savedTIMESTAMP_ISO8601_LOCAL)->isBuiltin = true; - sym_AddString("__ISO_8601_UTC__", savedTIMESTAMP_ISO8601_UTC)->isBuiltin = true; + sym_AddString("__TIME__"s, savedTIME)->isBuiltin = true; + sym_AddString("__DATE__"s, savedDATE)->isBuiltin = true; + sym_AddString("__ISO_8601_LOCAL__"s, savedTIMESTAMP_ISO8601_LOCAL)->isBuiltin = true; + sym_AddString("__ISO_8601_UTC__"s, savedTIMESTAMP_ISO8601_UTC)->isBuiltin = true; - sym_AddEqu("__UTC_YEAR__", time_utc->tm_year + 1900)->isBuiltin = true; - sym_AddEqu("__UTC_MONTH__", time_utc->tm_mon + 1)->isBuiltin = true; - sym_AddEqu("__UTC_DAY__", time_utc->tm_mday)->isBuiltin = true; - sym_AddEqu("__UTC_HOUR__", time_utc->tm_hour)->isBuiltin = true; - sym_AddEqu("__UTC_MINUTE__", time_utc->tm_min)->isBuiltin = true; - sym_AddEqu("__UTC_SECOND__", time_utc->tm_sec)->isBuiltin = true; + sym_AddEqu("__UTC_YEAR__"s, time_utc->tm_year + 1900)->isBuiltin = true; + sym_AddEqu("__UTC_MONTH__"s, time_utc->tm_mon + 1)->isBuiltin = true; + sym_AddEqu("__UTC_DAY__"s, time_utc->tm_mday)->isBuiltin = true; + sym_AddEqu("__UTC_HOUR__"s, time_utc->tm_hour)->isBuiltin = true; + sym_AddEqu("__UTC_MINUTE__"s, time_utc->tm_min)->isBuiltin = true; + sym_AddEqu("__UTC_SECOND__"s, time_utc->tm_sec)->isBuiltin = true; labelScope = std::nullopt; anonLabelID = 0;