diff --git a/driver/asm_directive.cpp b/driver/asm_directive.cpp index a0686a35..d5897e4c 100644 --- a/driver/asm_directive.cpp +++ b/driver/asm_directive.cpp @@ -194,7 +194,8 @@ Error AsmDirective::defineSymbol( auto &parser = _assembler.parser(); ErrorAt error; - context.value = parser.eval(scan, error, &context.symbols); + ParserContext c{_assembler.currentLocation(), &context.symbols}; + context.value = parser.eval(scan, error, c); if (error.hasError()) { context.value.clear(); return setError(scan, error); diff --git a/driver/function_store.cpp b/driver/function_store.cpp index 3a953af4..f422a131 100644 --- a/driver/function_store.cpp +++ b/driver/function_store.cpp @@ -84,11 +84,14 @@ const Functor *FunctionStore::Binding::lookupFunction(const StrScanner &symbol) return parent->lookupFunction(symbol); } -Error FunctionStore::Function::eval(ValueStack &stack, uint8_t argc) const { - Binding binding{paramsAt, stack, symtab}; +Error FunctionStore::Function::eval( + ValueStack &stack, ParserContext &parent, uint_fast8_t argc) const { StrScanner body_scan(body.c_str()); ErrorAt error; - const auto val = parser.eval(body_scan, error, &binding); + Binding binding{paramsAt, stack, parent.symbolTable}; + ParserContext context{parent}; + context.symbolTable = &binding; + const auto val = parser.eval(body_scan, error, context); while (argc) { stack.pop(); argc--; diff --git a/driver/function_store.h b/driver/function_store.h index 5a713471..f8fbbe94 100644 --- a/driver/function_store.h +++ b/driver/function_store.h @@ -54,8 +54,8 @@ struct FunctionStore final { bool operator==(const Function &other) const; bool operator!=(const Function &other) const { return !(*this == other); } - int8_t nargs() const override { return paramsAt.size(); } - Error eval(ValueStack &stack, uint8_t argc) const override; + int_fast8_t nargs() const override { return paramsAt.size(); } + Error eval(ValueStack &stack, ParserContext &context, uint_fast8_t argc) const override; private: const std::string body; diff --git a/src/asm_base.cpp b/src/asm_base.cpp index ae41a604..03f8f0e7 100644 --- a/src/asm_base.cpp +++ b/src/asm_base.cpp @@ -46,7 +46,7 @@ PROGMEM constexpr Pseudos PSEUDO_TABLE{ARRAY_RANGE(PSEUDOS)}; Assembler::Assembler( const ValueParser::Plugins &plugins, const Pseudos &pseudos, const OptionBase *option) - : _parser(plugins, *this), + : _parser(plugins), _pseudos(pseudos), _commonOptions(&_opt_listRadix), _options(option), @@ -77,7 +77,7 @@ Error Assembler::setCurrentLocation(uint32_t location, bool align) { return config().checkAddr(_currentLocation = location, align); } -Error Assembler::encode(const char *line, Insn &insn, SymbolTable *symtab) { +Error Assembler::encode(const char *line, Insn &insn, const SymbolTable *symtab) { _symtab = symtab; StrScanner scan{line}; insn.setError(scan.skipSpaces(), OK); @@ -113,7 +113,7 @@ Error Assembler::processPseudo(StrScanner &scan, Insn &insn) { Value Assembler::parseInteger(StrScanner &expr, ErrorAt &error, char delim) const { auto p = expr; - const auto value = _parser.eval(p, error, _symtab, delim); + const auto value = parseExpr(p, error, delim); if (value.isFloat()) error.setErrorIf(expr, INTEGER_REQUIRED); expr = p; @@ -121,7 +121,8 @@ Value Assembler::parseInteger(StrScanner &expr, ErrorAt &error, char delim) cons } Value Assembler::parseExpr(StrScanner &expr, ErrorAt &error, char delim) const { - return _parser.eval(expr, error, _symtab, delim); + ParserContext context{_currentLocation, _symtab, delim}; + return _parser.eval(expr, error, context); } int32_t Assembler::branchDelta( diff --git a/src/asm_base.h b/src/asm_base.h index 4e616560..6fda013d 100644 --- a/src/asm_base.h +++ b/src/asm_base.h @@ -31,8 +31,8 @@ namespace libasm { -struct Assembler : private ValueParser::Locator { - Error encode(const char *line, Insn &insn, SymbolTable *symtab = nullptr); +struct Assembler { + Error encode(const char *line, Insn &insn, const SymbolTable *symtab = nullptr); virtual const ConfigBase &config() const = 0; virtual void reset(); @@ -97,7 +97,7 @@ struct Assembler : private ValueParser::Locator { Radix _listRadix; bool _smartBranch; - SymbolTable *_symtab; + const SymbolTable *_symtab; uint32_t _currentLocation; Assembler(const ValueParser::Plugins &plugins, const pseudo::Pseudos &pseudos, diff --git a/src/asm_cdp1802.cpp b/src/asm_cdp1802.cpp index 0051ee39..f6fdace4 100644 --- a/src/asm_cdp1802.cpp +++ b/src/asm_cdp1802.cpp @@ -132,8 +132,8 @@ Error AsmCdp1802::setUseReg(bool enable) { namespace { const struct : Functor { - int8_t nargs() const override { return 1; } - Error eval(ValueStack &stack, uint8_t) const override { + int_fast8_t nargs() const override { return 1; } + Error eval(ValueStack &stack, ParserContext &, uint_fast8_t) const override { // Mark that this is 2 bytes value. stack.pushUnsigned((stack.pop().getUnsigned() & UINT16_MAX) | UINT32_C(0x1000'0000)); return OK; @@ -141,16 +141,16 @@ const struct : Functor { } FN_A; const struct : Functor { - int8_t nargs() const override { return 1; } - Error eval(ValueStack &stack, uint8_t) const override { + int_fast8_t nargs() const override { return 1; } + Error eval(ValueStack &stack, ParserContext &, uint_fast8_t) const override { stack.pushUnsigned(stack.pop().getUnsigned() & UINT8_MAX); return OK; } } FN_A0; const struct : Functor { - int8_t nargs() const override { return 1; } - Error eval(ValueStack &stack, uint8_t) const override { + int_fast8_t nargs() const override { return 1; } + Error eval(ValueStack &stack, ParserContext &, uint_fast8_t) const override { stack.pushUnsigned((stack.pop().getUnsigned() >> 8) & UINT8_MAX); return OK; } diff --git a/src/asm_ins8060.cpp b/src/asm_ins8060.cpp index 2703ef6a..4a32764d 100644 --- a/src/asm_ins8060.cpp +++ b/src/asm_ins8060.cpp @@ -74,24 +74,24 @@ AsmIns8060::AsmIns8060(const ValueParser::Plugins &plugins) namespace { const struct : Functor { - int8_t nargs() const override { return 1; } - Error eval(ValueStack &stack, uint8_t) const override { + int_fast8_t nargs() const override { return 1; } + Error eval(ValueStack &stack, ParserContext &, uint_fast8_t) const override { stack.pushUnsigned((stack.pop().getUnsigned() >> 8) & 0xFF); return OK; } } FN_HIGH; const struct : Functor { - int8_t nargs() const override { return 1; } - Error eval(ValueStack &stack, uint8_t) const override { + int_fast8_t nargs() const override { return 1; } + Error eval(ValueStack &stack, ParserContext &, uint_fast8_t) const override { stack.pushUnsigned(stack.pop().getUnsigned() & 0xFF); return OK; } } FN_LOW; const struct : Functor { - int8_t nargs() const override { return 1; } - Error eval(ValueStack &stack, uint8_t) const override { + int_fast8_t nargs() const override { return 1; } + Error eval(ValueStack &stack, ParserContext &, uint_fast8_t) const override { const auto v = stack.pop().getUnsigned(); stack.pushUnsigned(page(v) | offset(v - 1)); return OK; diff --git a/src/asm_ins8070.cpp b/src/asm_ins8070.cpp index 69dcd2ed..422e688c 100644 --- a/src/asm_ins8070.cpp +++ b/src/asm_ins8070.cpp @@ -74,24 +74,24 @@ AsmIns8070::AsmIns8070(const ValueParser::Plugins &plugins) namespace { const struct : Functor { - int8_t nargs() const override { return 1; } - Error eval(ValueStack &stack, uint8_t) const override { + int_fast8_t nargs() const override { return 1; } + Error eval(ValueStack &stack, ParserContext &, uint_fast8_t) const override { stack.pushUnsigned((stack.pop().getUnsigned() >> 8) & 0xFF); return OK; } } FN_HIGH; const struct : Functor { - int8_t nargs() const override { return 1; } - Error eval(ValueStack &stack, uint8_t) const override { + int_fast8_t nargs() const override { return 1; } + Error eval(ValueStack &stack, ParserContext &, uint_fast8_t) const override { stack.pushUnsigned(stack.pop().getUnsigned() & 0xFF); return OK; } } FN_LOW; const struct : Functor { - int8_t nargs() const override { return 1; } - Error eval(ValueStack &stack, uint8_t) const override { + int_fast8_t nargs() const override { return 1; } + Error eval(ValueStack &stack, ParserContext &, uint_fast8_t) const override { stack.pushUnsigned((stack.pop().getUnsigned() - 1) & 0xFFFF); return OK; } @@ -111,7 +111,7 @@ const Functor *Ins8070FunctionTable::lookupFunction(const StrScanner &name) cons void AsmIns8070::emitAbsolute(AsmInsn &insn, const Operand &op) const { // PC will be +1 before fetching instruction. - const auto target = op.getError() ? 0 : op.val.getUnsigned()- 1; + const auto target = op.getError() ? 0 : op.val.getUnsigned() - 1; insn.emitOperand16(target); } diff --git a/src/operators.cpp b/src/operators.cpp index 753bb8bc..01ef6c19 100644 --- a/src/operators.cpp +++ b/src/operators.cpp @@ -29,13 +29,13 @@ bool Operator::isNoneAssoc(const Operator &o) const { return _prec == o._prec && _assoc == NONE; } -Error Operator::eval(ValueStack &stack, uint8_t argc) const { +Error Operator::eval(ValueStack &stack, ParserContext &context, uint_fast8_t argc) const { if (argc == 0) argc = stack.size(); if (_fn) { const auto nargs = _fn->nargs(); if (nargs < 0 || argc == nargs) - return _fn->eval(stack, argc); + return _fn->eval(stack, context, argc); return argc > nargs ? TOO_MANY_FUNC_ARGUMENT : TOO_FEW_FUNC_ARGUMENT; } return argc >= _nargs ? (*_op)(stack) : MISSING_OPERAND; diff --git a/src/operators.h b/src/operators.h index b40f0f20..5f7bb2e3 100644 --- a/src/operators.h +++ b/src/operators.h @@ -25,6 +25,8 @@ namespace libasm { +struct ParserContext; + struct ValueStack : Stack { ValueStack() : Stack() {} void push(const Value &value) { _contents[_size++] = value; } @@ -39,16 +41,16 @@ struct ValueStack : Stack { */ struct Functor { /** Returns the number of required arguments. Negative value means variable arguments. */ - virtual int8_t nargs() const { return -1; } + virtual int_fast8_t nargs() const { return -1; } /** Evaluate function with |arguments|. */ - virtual Error eval(ValueStack &, uint8_t) const { return OK; } + virtual Error eval(ValueStack &, ParserContext &context, uint_fast8_t) const { return OK; } }; /** * Immutable instance to represent prefix or infix operators and functions. */ struct Operator : ErrorAt { - enum Type : uint8_t { + enum Type : uint_fast8_t { PREFIX, INFIX, }; @@ -74,7 +76,7 @@ struct Operator : ErrorAt { } /** Pop operands in |stack|, evaluate and push result onto |stack|. */ - Error eval(ValueStack &stack, uint8_t argc = 0) const; + Error eval(ValueStack &stack, ParserContext &context, uint_fast8_t argc = 0) const; /** Returns true when |this| operator has higher precedence than |o| */ bool isHigher(const Operator &o) const; /** Returns true when |this| operator is none associative and has the same precedence of @@ -83,7 +85,7 @@ struct Operator : ErrorAt { /** Constructor for operators */ typedef Error(OperatorEval)(ValueStack &stack); - Operator(uint8_t prec, Assoc assoc, int8_t nargs = 0, OperatorEval *op = nullptr) + Operator(uint8_t prec, Assoc assoc, int_fast8_t nargs = 0, OperatorEval *op = nullptr) : ErrorAt(), _prec(prec), _assoc(assoc), _nargs(nargs), _op(op), _fn(nullptr) {} /** Constructor for function */ diff --git a/src/parsers.h b/src/parsers.h index 7ad04223..84702e3e 100644 --- a/src/parsers.h +++ b/src/parsers.h @@ -20,7 +20,6 @@ #include "error_reporter.h" #include "operators.h" #include "str_scanner.h" -#include "symbol_table.h" #include "value.h" namespace libasm { @@ -54,10 +53,7 @@ struct SymbolParser : Singleton { virtual bool instructionLetter(char c) const { return symbolLetter(c); } /** Instruction terminates when this returns true */ - virtual bool instructionTerminator(char c) const { - UNUSED(c); - return false; - } + virtual bool instructionTerminator(char) const { return false; } /** Function name is same as symbol */ virtual bool functionNameLetter(char c) const { return symbolLetter(c); } @@ -70,10 +66,7 @@ struct FunctionTable : Singleton { /** * Look up |name| and returns a Functor pointer for a function, otherwise return nullptr. */ - virtual const Functor *lookupFunction(const StrScanner &name) const { - UNUSED(name); - return nullptr; - } + virtual const Functor *lookupFunction(const StrScanner &) const { return nullptr; } }; /** @@ -95,10 +88,7 @@ struct LetterParser { * Returns true and consumes prefix for a letter surrounded by letterdelimiters. Also returns * true if no prefix is required. */ - virtual bool letterPrefix(StrScanner &scan) const { - UNUSED(scan); - return true; - } + virtual bool letterPrefix(StrScanner &) const { return true; } /** * Returns a delimiters for a letter and cosume it. Returns zero if no delimiter exists. @@ -117,10 +107,7 @@ struct LetterParser { * Returns true and consumes prefix for a string surrounded by string delimiters. Also returns * true if no prefix is required. */ - virtual bool stringPrefix(StrScanner &scan) const { - UNUSED(scan); - return true; - } + virtual bool stringPrefix(StrScanner &) const { return true; } /** * Returns a delimiter which encloses a string and cosume it. Returns zero if no delimiter diff --git a/src/value_parser.cpp b/src/value_parser.cpp index d85d4f6c..cecc51f2 100644 --- a/src/value_parser.cpp +++ b/src/value_parser.cpp @@ -55,20 +55,18 @@ struct OperatorStack : Stack { Operator &top() { return _contents[_size - 1]; } }; -Value ValueParser::eval( - StrScanner &scan, ErrorAt &error, const SymbolTable *symtab, char delim) const { +Value ValueParser::eval(StrScanner &scan, ErrorAt &error, ParserContext &context) const { const auto start = scan.skipSpaces(); - const auto value = _eval(scan, error, symtab, delim); + const auto value = _eval(scan, error, context); if (scan.str() == start.str()) error.setErrorIf(start, NOT_AN_EXPECTED); return value; } -Value ValueParser::_eval( - StrScanner &scan, ErrorAt &error, const SymbolTable *symtab, char delim) const { +Value ValueParser::_eval(StrScanner &scan, ErrorAt &error, ParserContext &context) const { ValueStack vstack; OperatorStack ostack; - char end_of_expr = delim; + char end_of_expr = context.delimitor; uint8_t in_paren = 0; bool maybe_prefix = true; bool expect_fn_args = false; @@ -93,29 +91,29 @@ Value ValueParser::_eval( } if (maybe_prefix && opr == nullptr) { Value val; - auto err = parseConstant(scan, val, delim); + auto err = parseConstant(scan, val, context); if (err == OK) { if (vstack.full()) { - error.setError(at, TOO_COMPLEX_EXPRESSION); + error.setErrorIf(at, TOO_COMPLEX_EXPRESSION); return Value(); } vstack.push(val); maybe_prefix = false; continue; } else if (err != NOT_AN_EXPECTED) { - error.setError(at, err); + error.setErrorIf(at, err); return val; } StrScanner symbol; if (readFunctionName(scan, symbol) == OK) { auto fn = _function.lookupFunction(symbol); - if (fn == nullptr && symtab) - fn = symtab->lookupFunction(symbol); + if (fn == nullptr && context.symbolTable) + fn = context.symbolTable->lookupFunction(symbol); if (fn) { const auto open = scan.skipSpaces(); if (!_operators.isOpenExpr(scan)) { - error.setError(at, MISSING_FUNC_ARGUMENT); + error.setErrorIf(at, MISSING_FUNC_ARGUMENT); return val; } scan = open; @@ -132,12 +130,13 @@ Value ValueParser::_eval( if (readSymbol(scan, symbol) == OK) { if (vstack.full()) { - error.setError(at, TOO_COMPLEX_EXPRESSION); + error.setErrorIf(at, TOO_COMPLEX_EXPRESSION); return Value(); } - if (symtab && symtab->hasSymbol(symbol)) { - const auto value = *symtab->lookupSymbol(symbol); - vstack.push(value); + const auto *value = + context.symbolTable ? context.symbolTable->lookupSymbol(symbol) : nullptr; + if (value) { + vstack.push(*value); } else { error.setErrorIf(at, UNDEFINED_SYMBOL); vstack.push(Value()); @@ -164,7 +163,7 @@ Value ValueParser::_eval( if (!top.isHigher(*opr)) break; const auto op = ostack.pop(); - const auto err = op.eval(vstack); + const auto err = op.eval(vstack, context); if (err) { error.setErrorIf(op, err); return Value(); @@ -184,7 +183,7 @@ Value ValueParser::_eval( // non-zero |in_fn_args| ensures the existence of open parenthesis in |ostack|. while (!ostack.top().isOpenParen()) { const auto op = ostack.pop(); - const auto err = op.eval(vstack); + const auto err = op.eval(vstack, context); if (err) { error.setErrorIf(op, err); return Value(); @@ -217,7 +216,7 @@ Value ValueParser::_eval( if (_operators.isCloseExpr(scan)) { while (!ostack.empty() && !ostack.top().isOpenParen()) { const auto op = ostack.pop(); - const auto err = op.eval(vstack); + const auto err = op.eval(vstack, context); if (err) { error.setErrorIf(op, err); return Value(); @@ -231,7 +230,7 @@ Value ValueParser::_eval( if (!ostack.empty() && ostack.top().isFunction()) { const auto argc = vstack.size() - openParen.stackPosition(); const auto fn = ostack.pop(); - const auto err = fn.eval(vstack, argc); + const auto err = fn.eval(vstack, context, argc); if (err) { error.setErrorIf(fn, err); return Value(); @@ -239,7 +238,7 @@ Value ValueParser::_eval( in_fn_args--; } if (--in_paren == 0) - end_of_expr = delim; + end_of_expr = context.delimitor; maybe_prefix = false; continue; } @@ -254,7 +253,7 @@ Value ValueParser::_eval( error.setErrorIf(op, MISSING_CLOSING_PAREN); return Value(); } - const auto err = op.eval(vstack); + const auto err = op.eval(vstack, context); if (err) { error.setErrorIf(op, err); return Value(); @@ -263,7 +262,7 @@ Value ValueParser::_eval( return vstack.pop(); } -Error ValueParser::parseConstant(StrScanner &scan, Value &val, char delim) const { +Error ValueParser::parseConstant(StrScanner &scan, Value &val, ParserContext &context) const { auto p = scan; char letter; @@ -280,7 +279,7 @@ Error ValueParser::parseConstant(StrScanner &scan, Value &val, char delim) const #ifdef LIBASM_ASM_NOFLOAT UNUSED(delim); #else - const auto fpnum = (err == OK && (*p == '.' || toupper(*p) == 'E')) && delim != '.'; + const auto fpnum = (err == OK && (*p == '.' || toupper(*p) == 'E')) && context.delimitor != '.'; if (fpnum || err == OVERFLOW_RANGE || err == NOT_AN_EXPECTED) { char *end; Value::float_t f80; @@ -298,7 +297,7 @@ Error ValueParser::parseConstant(StrScanner &scan, Value &val, char delim) const } if (_location.locationSymbol(p)) { - val.setUnsigned(_locator.currentLocation()); + val.setUnsigned(context.currentLocation); scan = p; return OK; } diff --git a/src/value_parser.h b/src/value_parser.h index 4448abd6..ac6eb453 100644 --- a/src/value_parser.h +++ b/src/value_parser.h @@ -18,11 +18,21 @@ #define __LIBASM_VALUE_PARSER_H__ #include - #include "parsers.h" +#include "symbol_table.h" namespace libasm { +struct ParserContext final { + ParserContext(uint32_t loc = 0, const SymbolTable *symtab = nullptr, char delim = 0) + : currentLocation(loc), symbolTable(symtab), delimitor(delim) {} + ParserContext(const ParserContext &) = default; + + uint32_t currentLocation; + const SymbolTable *symbolTable; + char delimitor; +}; + struct ValueParser { struct Plugins : Singleton { virtual const NumberParser &number() const; @@ -34,26 +44,21 @@ struct ValueParser { virtual const FunctionTable &function() const; }; - struct Locator : Singleton { - virtual uint32_t currentLocation() const { return 0; } - }; - - ValueParser(const Plugins &plugins = Plugins::singleton(), - const Locator &locator = Locator::singleton()) + ValueParser(const Plugins &plugins = Plugins::singleton()) : _number(plugins.number()), _comment(plugins.comment()), _symbol(plugins.symbol()), _letter(plugins.letter()), _location(plugins.location()), _operators(plugins.operators()), - _function(plugins.function()), - _locator(locator) {} + _function(plugins.function()) {} /** - * Parse |scan| text and return expression |value|. Undefined symbol reference in expression - * will be checked by UNDEFINED_SYMBOL in |error|. + * Parse |scan| text using |context| and return expression valu|. Undefined + * symbol reference in expression will be checked by UNDEFINED_SYMBOL in + * |error|. */ - Value eval(StrScanner &scan, ErrorAt &error, const SymbolTable *symtab, char delim = 0) const; + Value eval(StrScanner &scan, ErrorAt &error, ParserContext &context) const; /** * Parse |scan| text and return letter constant. @@ -82,10 +87,9 @@ struct ValueParser { const LocationParser &_location; const OperatorParser &_operators; const FunctionTable &_function; - const Locator &_locator; - Value _eval(StrScanner &scan, ErrorAt &error, const SymbolTable *symtab, char delim) const; - Error parseConstant(StrScanner &scan, Value &val, char delim) const; + Value _eval(StrScanner &scan, ErrorAt &error, ParserContext &context) const; + Error parseConstant(StrScanner &scan, Value &val, ParserContext &context) const; Error readFunctionName(StrScanner &scan, StrScanner &name) const; }; diff --git a/test/driver/Makefile b/test/driver/Makefile index c682e6c3..9fe30bf1 100644 --- a/test/driver/Makefile +++ b/test/driver/Makefile @@ -32,7 +32,7 @@ vpath %.cpp ../../driver vpath %.cpp ../../src vpath %.cpp ../../test -CXXFLAGS = -std=c++14 -Wall -O $(DEBUG_FLAGS) +CXXFLAGS = -std=c++14 -Wall -O $(DEBUG_FLAGS) -DLIBASM_DEBUG_VALUE CPPFLAGS = -I../../driver -I../../src -I../../test -MD -MF $@.d OBJS_common = \ diff --git a/test/test_expr_base.cpp b/test/test_expr_base.cpp index eae795b3..b26915a0 100644 --- a/test/test_expr_base.cpp +++ b/test/test_expr_base.cpp @@ -19,8 +19,7 @@ using namespace libasm; using namespace libasm::test; -TestLocator locator{}; -const ValueParser parser{ValueParser::Plugins::singleton(), locator}; +const ValueParser parser{ValueParser::Plugins::singleton()}; const ValueFormatter formatter{ValueFormatter::Plugins::cstyle()}; @@ -409,7 +408,7 @@ static void test_symbol() { } static void test_current_address() { - locator.location = 0x1000; + context.currentLocation = 0x1000; E16("$", 0x1000); E16("$+2", 0x1002); E16("$-2", 0x0FFE); @@ -419,7 +418,7 @@ static void test_current_address() { E32("$-0x1001", 0xFFFFFFFF); symtab.intern(0x1000, "table"); - locator.location = 0x1100; + context.currentLocation = 0x1100; E16("$-table", 0x100); E16("($-table)/2", 0x080); } @@ -428,14 +427,14 @@ static void test_function() { // clang-format on static const struct : Functor { int8_t nargs() const override { return 0; } - Error eval(ValueStack &stack, uint8_t argc) const override { + Error eval(ValueStack &stack, ParserContext &, uint8_t) const override { stack.pushUnsigned(0x31415926); return OK; } } FN_PI; static const struct : Functor { int8_t nargs() const override { return 2; } - Error eval(ValueStack &stack, uint8_t argc) const override { + Error eval(ValueStack &stack, ParserContext &, uint8_t) const override { const auto rhs = stack.pop().getSigned(); const auto lhs = stack.pop().getSigned(); stack.pushSigned(lhs - rhs); @@ -443,7 +442,7 @@ static void test_function() { } } FN_SUB; static const struct : Functor { - Error eval(ValueStack &stack, uint8_t argc) const override { + Error eval(ValueStack &stack, ParserContext &, uint8_t argc) const override { int32_t sum = 0; while (argc--) sum += stack.pop().getSigned(); diff --git a/test/test_expr_fairchild.cpp b/test/test_expr_fairchild.cpp index 3612b7df..f6fbbcf4 100644 --- a/test/test_expr_fairchild.cpp +++ b/test/test_expr_fairchild.cpp @@ -25,8 +25,7 @@ const struct final : ValueParser::Plugins { const LetterParser &letter() const override { return FairchildLetterParser::singleton(); } const LocationParser &location() const override { return AsteriskLocationParser::singleton(); } } plugins{}; -TestLocator locator{}; -const ValueParser parser{plugins, locator}; +const ValueParser parser{plugins}; const ValueFormatter formatter{ValueFormatter::Plugins::fairchild()}; @@ -181,7 +180,7 @@ static void test_bin_constant() { } static void test_current_address() { - locator.location = 0x1000; + context.currentLocation = 0x1000; E16("*", 0x1000); E16("*+2", 0x1002); E16("*-2", 0x0FFE); @@ -199,7 +198,7 @@ static void test_current_address() { E32("*-0x1001", 0xFFFFFFFF); symtab.intern(0x1000, "table"); - locator.location = 0x1100; + context.currentLocation = 0x1100; E16("*-table", 0x100); E16("(*-table)/2", 0x080); } diff --git a/test/test_expr_helper.cpp b/test/test_expr_helper.cpp index 2bb2c8ad..2512972e 100644 --- a/test/test_expr_helper.cpp +++ b/test/test_expr_helper.cpp @@ -24,12 +24,14 @@ namespace test { TestAsserter asserter; TestSymtab symtab; +ParserContext context{0, &symtab}; void val_assert(const char *file, int line, StrScanner &expr, char delim, uint32_t expected, const ErrorAt &expected_error, size_t size, const ValueParser &parser) { ErrorAt actual_error; StrScanner remain = expr; - auto val = parser.eval(remain, actual_error, &symtab, delim); + context.delimitor = delim; + auto val = parser.eval(remain, actual_error, context); auto actual = val.getUnsigned(); if (size == sizeof(uint8_t)) { if (val.overflowUint8()) diff --git a/test/test_expr_helper.h b/test/test_expr_helper.h index fa198a5f..93fca9bc 100644 --- a/test/test_expr_helper.h +++ b/test/test_expr_helper.h @@ -30,6 +30,7 @@ namespace test { extern TestSymtab symtab; extern TestAsserter asserter; +extern ParserContext context; void val_assert(const char *file, int line, StrScanner &expr, char delim, uint32_t expected, const ErrorAt &expected_error, size_t size, const ValueParser &); @@ -44,11 +45,6 @@ void hex_assert(const char *file, int line, uint32_t value, int8_t bitWidth, con void run_test(void (*test)(), const char *name, void (*set_up)(), void (*tear_down)()); -struct TestLocator : ValueParser::Locator { - uint32_t location = 0; - uint32_t currentLocation() const override { return location; } -}; - } // namespace test } // namespace libasm diff --git a/test/test_expr_intel.cpp b/test/test_expr_intel.cpp index 398d4288..5c811370 100644 --- a/test/test_expr_intel.cpp +++ b/test/test_expr_intel.cpp @@ -27,11 +27,7 @@ const struct final : ValueParser::Plugins { const OperatorParser &operators() const override { return IntelOperatorParser::singleton(); } const SimpleSymbolParser _symbol{PSTR("_?@")}; } plugins{}; -struct : ValueParser::Locator { - uint32_t location = 0; - uint32_t currentLocation() const { return location; } -} locator; -const ValueParser parser{plugins, locator}; +const ValueParser parser{plugins}; const ValueFormatter formatter{ValueFormatter::Plugins::intel()}; @@ -310,7 +306,7 @@ static void test_precedence() { } static void test_current_address() { - locator.location = 0x1000; + context.currentLocation = 0x1000; E16("$", 0x1000); E16("$+2", 0x1002); E16("$-2", 0x0FFE); @@ -320,7 +316,7 @@ static void test_current_address() { E32("$-1001H", 0xFFFFFFFF); symtab.intern(0x1000, "table"); - locator.location = 0x1100; + context.currentLocation = 0x1100; E16("$-table", 0x100); E16("($-table)/2", 0x080); } diff --git a/test/test_expr_motorola.cpp b/test/test_expr_motorola.cpp index f666106b..af7dd960 100644 --- a/test/test_expr_motorola.cpp +++ b/test/test_expr_motorola.cpp @@ -28,11 +28,7 @@ const struct MotorolaPlugins : ValueParser::Plugins { const OperatorParser &operators() const override { return Mc68xxOperatorParser::singleton(); } const SimpleSymbolParser _symbol{PSTR(".$")}; } plugins{}; -struct : ValueParser::Locator { - uint32_t location = 0; - uint32_t currentLocation() const { return location; } -} locator; -const ValueParser parser{plugins, locator}; +const ValueParser parser{plugins}; const ValueFormatter formatter{ValueFormatter::Plugins::motorola()}; @@ -63,7 +59,7 @@ static void test_char_closing() { const struct : MotorolaPlugins { const LetterParser &letter() const override { return DefaultLetterParser::singleton(); } } plugins{}; - const ValueParser parser{plugins, locator}; + const ValueParser parser{plugins}; X8("'a", MISSING_CLOSING_QUOTE, "'a", "'a"); X8("'a+5", MISSING_CLOSING_QUOTE, "'a+5", "'a+5"); @@ -490,7 +486,7 @@ static void test_precedence() { } static void test_current_address() { - locator.location = 0x1000; + context.currentLocation = 0x1000; E16("*", 0x1000); E16("*+2", 0x1002); E16("*-2", 0x0FFE); @@ -500,7 +496,7 @@ static void test_current_address() { E32("*-$1001", 0xFFFFFFFF); symtab.intern(0x1000, "table"); - locator.location = 0x1100; + context.currentLocation = 0x1100; E16("*-table", 0x100); E16("(*-table)/2", 0x080); } diff --git a/test/test_expr_national.cpp b/test/test_expr_national.cpp index 1ade688c..057472d6 100644 --- a/test/test_expr_national.cpp +++ b/test/test_expr_national.cpp @@ -36,11 +36,7 @@ const struct final : ValueParser::Plugins { } } _letter{}; } plugins{}; -struct : ValueParser::Locator { - uint32_t location = 0; - uint32_t currentLocation() const { return location; } -} locator; -const ValueParser parser{plugins, locator}; +const ValueParser parser{plugins}; const ValueFormatter formatter{ValueFormatter::Plugins::national()}; @@ -180,7 +176,7 @@ static void test_bin_constant() { } static void test_current_address() { - locator.location = 0x1000; + context.currentLocation = 0x1000; E16("$", 0x1000); E16("$+2", 0x1002); E16("$-2", 0x0FFE); @@ -190,7 +186,7 @@ static void test_current_address() { E32("$-x'1001", 0xFFFFFFFF); symtab.intern(0x1000, "table"); - locator.location = 0x1100; + context.currentLocation = 0x1100; E16("$-table", 0x100); E16("($-table)/2", 0x080); } diff --git a/test/test_expr_zilog.cpp b/test/test_expr_zilog.cpp index d468ef85..cb62cc37 100644 --- a/test/test_expr_zilog.cpp +++ b/test/test_expr_zilog.cpp @@ -26,11 +26,7 @@ const struct final : ValueParser::Plugins { const LetterParser &letter() const override { return ZilogLetterParser::singleton(); } const OperatorParser &operators() const override { return ZilogOperatorParser::singleton(); } } plugins{}; -struct : ValueParser::Locator { - uint32_t location = 0; - uint32_t currentLocation() const { return location; } -} locator; -const ValueParser parser{plugins, locator}; +const ValueParser parser{plugins}; const ValueFormatter formatter{ValueFormatter::Plugins::zilog()}; @@ -291,7 +287,7 @@ static void test_precedence() { } static void test_current_address() { - locator.location = 0x1000; + context.currentLocation = 0x1000; E16("$", 0x1000); E16("$+2", 0x1002); E16("$-2", 0x0FFE); @@ -301,7 +297,7 @@ static void test_current_address() { E32("$-%1001", 0xFFFFFFFF); symtab.intern(0x1000, "table"); - locator.location = 0x1100; + context.currentLocation = 0x1100; E16("$-table", 0x100); E16("($-table)/2", 0x080); }