From adea12b74952bc79b35eb17cf46d0bb7abc71803 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Tue, 1 Oct 2024 03:54:20 +0900 Subject: [PATCH] [Asm] Add default input RADIX --- src/asm_base.cpp | 3 ++- src/asm_base.h | 6 ++++++ src/asm_cdp1802.cpp | 4 ++-- src/asm_pdp8.cpp | 36 ++++++------------------------- src/asm_pdp8.h | 1 - src/parsers.cpp | 47 +++++++++++++++++++++-------------------- src/parsers.h | 22 +++++++++---------- src/value_parser.cpp | 2 +- src/value_parser.h | 6 ++++-- test/test_asm_pdp8.cpp | 6 +++++- test/test_expr_base.cpp | 13 +++++++++++- 11 files changed, 74 insertions(+), 72 deletions(-) diff --git a/src/asm_base.cpp b/src/asm_base.cpp index 03f8f0e7..78848c55 100644 --- a/src/asm_base.cpp +++ b/src/asm_base.cpp @@ -59,6 +59,7 @@ Assembler::Assembler( } void Assembler::reset() { + setInputRadix(RADIX_10); setListRadix(RADIX_16); setSmartBranch(false); } @@ -121,7 +122,7 @@ Value Assembler::parseInteger(StrScanner &expr, ErrorAt &error, char delim) cons } Value Assembler::parseExpr(StrScanner &expr, ErrorAt &error, char delim) const { - ParserContext context{_currentLocation, _symtab, delim}; + ParserContext context{_currentLocation, _symtab, delim, _inputRadix}; return _parser.eval(expr, error, context); } diff --git a/src/asm_base.h b/src/asm_base.h index 6fda013d..5202c84f 100644 --- a/src/asm_base.h +++ b/src/asm_base.h @@ -95,6 +95,7 @@ struct Assembler { const BoolOption _opt_smartBranch; const TextOption _opt_fpu; + Radix _inputRadix; Radix _listRadix; bool _smartBranch; const SymbolTable *_symtab; @@ -103,6 +104,11 @@ struct Assembler { Assembler(const ValueParser::Plugins &plugins, const pseudo::Pseudos &pseudos, const OptionBase *option = nullptr); + Error setInputRadix(Radix radix) { + _inputRadix = radix; + return OK; + } + int32_t branchDelta(uint32_t base, uint32_t target, ErrorAt &error, const ErrorAt &at) const; void generateString(StrScanner &scan, const StrScanner &end, Insn &insn, DataType type, diff --git a/src/asm_cdp1802.cpp b/src/asm_cdp1802.cpp index f6fdace4..ca56886a 100644 --- a/src/asm_cdp1802.cpp +++ b/src/asm_cdp1802.cpp @@ -43,7 +43,7 @@ PROGMEM constexpr Pseudos PSEUDO_TABLE{ARRAY_RANGE(PSEUDOS)}; * RCA style numbers are the same as IBM plus '#hh' for hexadecimal. */ struct RcaNumberParser final : NumberParser { - Error parseNumber(StrScanner &scan, Value &val) const override { + Error parseNumber(StrScanner &scan, Value &val, Radix defaultRadix) const override { auto p = scan; if (*p == '#' && isxdigit(p[1])) { const auto error = val.read(++p, RADIX_16); @@ -51,7 +51,7 @@ struct RcaNumberParser final : NumberParser { scan = p; return error; } - return _ibm.parseNumber(scan, val); + return _ibm.parseNumber(scan, val, defaultRadix); } private: diff --git a/src/asm_pdp8.cpp b/src/asm_pdp8.cpp index 42e2724c..d810d8d9 100644 --- a/src/asm_pdp8.cpp +++ b/src/asm_pdp8.cpp @@ -47,22 +47,6 @@ constexpr Pseudo PSEUDOS[] PROGMEM = { // clang-format on PROGMEM constexpr Pseudos PSEUDO_TABLE{ARRAY_RANGE(PSEUDOS)}; -struct RadixNumberParser final : NumberParser { - RadixNumberParser() : _radix(RADIX_8) {} - Radix radix() const { return _radix; } - void setRadix(Radix radix) { _radix = radix; } - Error parseNumber(StrScanner &scan, Value &val) const { - auto p = scan; - const auto radix = IntelNumberParser::hasSuffix(p); - if (radix != RADIX_NONE) - return IntelNumberParser::singleton().parseNumber(scan, val, radix, p); - return val.read(scan, _radix); - } - -private: - Radix _radix; -} NUMBER_PARSER; - struct Pdp8SymbolParser final : SymbolParser { bool labelDelimitor(StrScanner &scan) const override { return scan.expect(','); } bool instructionLetter(char c) const override { @@ -128,7 +112,7 @@ struct Pdp8OperatorParser final : OperatorParser { const ValueParser::Plugins &AsmPdp8::defaultPlugins() { static const struct final : ValueParser::Plugins { - const NumberParser &number() const override { return NUMBER_PARSER; } + const NumberParser &number() const override { return IntelNumberParser::singleton(); } const SymbolParser &symbol() const override { return _symbol; } const LetterParser &letter() const override { return _letter; } const CommentParser &comment() const override { return _comment; } @@ -153,17 +137,11 @@ AsmPdp8::AsmPdp8(const ValueParser::Plugins &plugins) void AsmPdp8::reset() { Assembler::reset(); + setInputRadix(RADIX_8); setListRadix(RADIX_8); setImplicitWord(false); } -Error AsmPdp8::setInputRadix(StrScanner &scan, Insn &insn, uint8_t extra) { - UNUSED(scan); - UNUSED(insn); - NUMBER_PARSER.setRadix(static_cast(extra)); - return OK; -} - Error AsmPdp8::setImplicitWord(bool enable) { _implicitWord = enable; return OK; @@ -171,8 +149,8 @@ Error AsmPdp8::setImplicitWord(bool enable) { Error AsmPdp8::defineDoubleDecimal(StrScanner &scan, Insn &insn, uint8_t extra) { UNUSED(extra); - const auto radix = NUMBER_PARSER.radix(); - NUMBER_PARSER.setRadix(RADIX_10); + const auto radix = _inputRadix; + setInputRadix(RADIX_10); const auto save = scan; const auto val = parseInteger(scan, insn); constexpr auto UINT24_MAX = INT32_C(0x00FF'FFFF); @@ -184,7 +162,7 @@ Error AsmPdp8::defineDoubleDecimal(StrScanner &scan, Insn &insn, uint8_t extra) insn.setErrorIf(insn.emitUint16Be((val24 >> 12) & 07777)); insn.setErrorIf(insn.emitUint16Be(val24 & 07777)); } - NUMBER_PARSER.setRadix(radix); + setInputRadix(radix); return insn.getError(); } @@ -361,9 +339,9 @@ Error AsmPdp8::parseOperateOperand(StrScanner &scan, AsmInsn &insn) const { Error AsmPdp8::processPseudo(StrScanner &scan, Insn &insn) { if (strcasecmp_P(insn.name(), TEXT_OCTAL) == 0) - return setInputRadix(scan, insn, RADIX_8); + return setInputRadix(RADIX_8); if (strcasecmp_P(insn.name(), TEXT_DECIMAL) == 0) - return setInputRadix(scan, insn, RADIX_10); + return setInputRadix(RADIX_10); if (strcasecmp_P(insn.name(), TEXT_DUBL) == 0) return defineDoubleDecimal(scan, insn); if (strcasecmp_P(insn.name(), TEXT_PAGE) == 0) diff --git a/src/asm_pdp8.h b/src/asm_pdp8.h index 77d804e3..cb0a0848 100644 --- a/src/asm_pdp8.h +++ b/src/asm_pdp8.h @@ -36,7 +36,6 @@ struct AsmPdp8 final : Assembler, Config { bool _implicitWord; - Error setInputRadix(StrScanner &scan, Insn &insn, uint8_t extra); Error defineDoubleDecimal(StrScanner &scan, Insn &insn, uint8_t extra = 0); Error alignOnPage(StrScanner &scan, Insn &insn, uint8_t extra = 0); Error defineField(StrScanner &scan, Insn &insn, uint8_t extra = 0); diff --git a/src/parsers.cpp b/src/parsers.cpp index 5b633648..99c6e612 100644 --- a/src/parsers.cpp +++ b/src/parsers.cpp @@ -58,22 +58,22 @@ Radix PrefixNumberParser::hasPrefix(StrScanner &scan) const { return RADIX_NONE; } -Error PrefixNumberParser::parseNumber(StrScanner &scan, Value &val) const { +Error PrefixNumberParser::parseNumber(StrScanner &scan, Value &val, Radix defaultRadix) const { auto p = scan; const auto radix = hasPrefix(p); if (radix == RADIX_NONE) - return IntelNumberParser::singleton().parseNumber(scan, val); + return IntelNumberParser::singleton().parseNumber(scan, val, defaultRadix); const auto error = val.read(p, radix); if (error != NOT_AN_EXPECTED) scan = p; return error; } -Error IbmNumberParser::parseNumber(StrScanner &scan, Value &val) const { +Error IbmNumberParser::parseNumber(StrScanner &scan, Value &val, Radix defaultRadix) const { auto p = scan; const auto radix = hasPrefix(p); if (radix == RADIX_NONE) - return IntelNumberParser::singleton().parseNumber(scan, val); + return IntelNumberParser::singleton().parseNumber(scan, val, defaultRadix); if (!p.expect('\'') || !isValidDigit(*p, radix)) return NOT_AN_EXPECTED; @@ -94,11 +94,11 @@ Radix NationalNumberParser::hasPrefix(StrScanner &scan) const { return PrefixNumberParser::hasPrefix(scan); } -Error NationalNumberParser::parseNumber(StrScanner &scan, Value &val) const { +Error NationalNumberParser::parseNumber(StrScanner &scan, Value &val, Radix defaultRadix) const { auto p = scan; const auto radix = hasPrefix(p); if (radix == RADIX_NONE) - return IntelNumberParser::singleton().parseNumber(scan, val); + return IntelNumberParser::singleton().parseNumber(scan, val, defaultRadix); if (!p.expect('\'') || !isValidDigit(*p, radix)) return NOT_AN_EXPECTED; @@ -110,21 +110,21 @@ Error NationalNumberParser::parseNumber(StrScanner &scan, Value &val) const { return error; } -Radix CStyleNumberParser::hasPrefix(StrScanner &scan) const { +Radix CStyleNumberParser::hasPrefix(StrScanner &scan, Radix defaultRadix) const { if (scan.iexpectText_P(text::common::PSTR_ZERO_X)) return RADIX_16; if (scan.iexpectText_P(text::common::PSTR_ZERO_B)) return RADIX_2; if (*scan == '0' && isoctal(scan[1])) return RADIX_8; - if (isdigit(*scan)) - return RADIX_10; + if (isValidDigit(*scan, defaultRadix)) + return defaultRadix; return RADIX_NONE; } -Error CStyleNumberParser::parseNumber(StrScanner &scan, Value &val) const { +Error CStyleNumberParser::parseNumber(StrScanner &scan, Value &val, Radix defaultRadix) const { auto p = scan; - const auto radix = hasPrefix(p); + const auto radix = hasPrefix(p, defaultRadix); if (radix == RADIX_NONE) return NOT_AN_EXPECTED; @@ -134,7 +134,7 @@ Error CStyleNumberParser::parseNumber(StrScanner &scan, Value &val) const { return error; } -Radix IntelNumberParser::hasSuffix(StrScanner &scan) { +Radix IntelNumberParser::hasSuffix(StrScanner &scan, Radix defaultRadix) { if (scanNumberEnd(scan, RADIX_16, 'H') == OK) return RADIX_16; if (scanNumberEnd(scan, RADIX_8, 'O') == OK || scanNumberEnd(scan, RADIX_8, 'Q') == OK) @@ -146,18 +146,19 @@ Radix IntelNumberParser::hasSuffix(StrScanner &scan) { return RADIX_NONE; } -Error IntelNumberParser::parseNumber(StrScanner &scan, Value &val) const { - auto p = scan; - return parseNumber(scan, val, hasSuffix(p), p); +Error IntelNumberParser::parseNumber(StrScanner &scan, Value &val, Radix defaultRadix) const { + auto end = scan; + const auto radix = hasSuffix(end, defaultRadix); + if (radix == RADIX_NONE) + return CStyleNumberParser::singleton().parseNumber(scan, val, defaultRadix); + return parseNumber(scan, val, radix, end); } Error IntelNumberParser::parseNumber( - StrScanner &scan, Value &val, Radix radix, StrScanner &next) const { - if (radix == RADIX_NONE) - return CStyleNumberParser::singleton().parseNumber(scan, val); + StrScanner &scan, Value &val, Radix radix, StrScanner &end) const { const auto error = val.read(scan, radix); if (error != NOT_AN_EXPECTED) - scan = next; + scan = end; return error; } @@ -196,11 +197,11 @@ Radix ZilogNumberParser::hasPrefix(StrScanner &scan) const { return RADIX_NONE; } -Error ZilogNumberParser::parseNumber(StrScanner &scan, Value &val) const { +Error ZilogNumberParser::parseNumber(StrScanner &scan, Value &val, Radix defaultRadix) const { auto p = scan; const auto radix = hasPrefix(p); if (radix == RADIX_NONE) - return IntelNumberParser::singleton().parseNumber(scan, val); + return IntelNumberParser::singleton().parseNumber(scan, val, defaultRadix); const auto error = val.read(p, radix); if (error != NOT_AN_EXPECTED) @@ -208,7 +209,7 @@ Error ZilogNumberParser::parseNumber(StrScanner &scan, Value &val) const { return error; } -Error FairchildNumberParser::parseNumber(StrScanner &scan, Value &val) const { +Error FairchildNumberParser::parseNumber(StrScanner &scan, Value &val, Radix defaultRadix) const { auto p = scan; if (*p == '$' && isxdigit(p[1])) { const auto error = val.read(++p, RADIX_16); @@ -216,7 +217,7 @@ Error FairchildNumberParser::parseNumber(StrScanner &scan, Value &val) const { scan = p; return error; } - return _ibm.parseNumber(scan, val); + return _ibm.parseNumber(scan, val, defaultRadix); } bool SymbolParser::symbolLetter(char c, bool headOfSymbol) const { diff --git a/src/parsers.h b/src/parsers.h index 84702e3e..5fc09f81 100644 --- a/src/parsers.h +++ b/src/parsers.h @@ -126,7 +126,7 @@ struct LetterParser { * - Returns NOT_AN_EXPECTED when |scan| doesn't look like a number. |scan| is unchanged. */ struct NumberParser { - virtual Error parseNumber(StrScanner &scan, Value &val) const = 0; + virtual Error parseNumber(StrScanner &scan, Value &val, Radix defaultRadix) const = 0; }; /** @@ -137,10 +137,10 @@ struct NumberParser { * - Binary: "[01]+[bB]" */ struct IntelNumberParser final : NumberParser, Singleton { - Error parseNumber(StrScanner &scan, Value &val) const override; - Error parseNumber(StrScanner &scan, Value &val, Radix radix, StrScanner &next) const; + Error parseNumber(StrScanner &scan, Value &val, Radix defaultRadix) const override; + Error parseNumber(StrScanner &scan, Value &val, Radix radix, StrScanner &end) const; - static Radix hasSuffix(StrScanner &scan); + static Radix hasSuffix(StrScanner &scan, Radix defaultRadix); private: /** @@ -161,10 +161,10 @@ struct IntelNumberParser final : NumberParser, Singleton { * - Binary: "0[bB][01]+" */ struct CStyleNumberParser final : NumberParser, Singleton { - Error parseNumber(StrScanner &scan, Value &val) const override; + Error parseNumber(StrScanner &scan, Value &val, Radix defaultRadix) const override; private: - Radix hasPrefix(StrScanner &scan) const; + Radix hasPrefix(StrScanner &scan, Radix defaultRadix) const; }; /** @@ -175,7 +175,7 @@ struct CStyleNumberParser final : NumberParser, Singleton { * - Binary: "%(2)[01]+" */ struct ZilogNumberParser final : NumberParser, Singleton { - Error parseNumber(StrScanner &scan, Value &val) const override; + Error parseNumber(StrScanner &scan, Value &val, Radix defaultRadix) const override; private: Radix hasPrefix(StrScanner &scan) const; @@ -187,7 +187,7 @@ struct ZilogNumberParser final : NumberParser, Singleton { struct PrefixNumberParser : NumberParser { PrefixNumberParser(char hex, char bin, char oct, char dec); - Error parseNumber(StrScanner &scan, Value &val) const override; + Error parseNumber(StrScanner &scan, Value &val, Radix defaultRadix) const override; protected: const char _hex; @@ -219,7 +219,7 @@ struct MotorolaNumberParser final : PrefixNumberParser, Singleton { - Error parseNumber(StrScanner &scan, Value &val) const override; + Error parseNumber(StrScanner &scan, Value &val, Radix defaultRadix) const override; private: IbmNumberParser _ibm{'H', 'B', 'O', 'D'}; diff --git a/src/value_parser.cpp b/src/value_parser.cpp index cecc51f2..fc3a702e 100644 --- a/src/value_parser.cpp +++ b/src/value_parser.cpp @@ -275,7 +275,7 @@ Error ValueParser::parseConstant(StrScanner &scan, Value &val, ParserContext &co if (err != NOT_AN_EXPECTED) return err; - err = _number.parseNumber(p, val); + err = _number.parseNumber(p, val, context.defaultRadix); #ifdef LIBASM_ASM_NOFLOAT UNUSED(delim); #else diff --git a/src/value_parser.h b/src/value_parser.h index ac6eb453..1cde98c0 100644 --- a/src/value_parser.h +++ b/src/value_parser.h @@ -24,13 +24,15 @@ namespace libasm { struct ParserContext final { - ParserContext(uint32_t loc = 0, const SymbolTable *symtab = nullptr, char delim = 0) - : currentLocation(loc), symbolTable(symtab), delimitor(delim) {} + ParserContext(uint32_t loc = 0, const SymbolTable *symtab = nullptr, char delim = 0, + Radix radix = RADIX_10) + : currentLocation(loc), symbolTable(symtab), delimitor(delim), defaultRadix(radix) {} ParserContext(const ParserContext &) = default; uint32_t currentLocation; const SymbolTable *symbolTable; char delimitor; + Radix defaultRadix; }; struct ValueParser { diff --git a/test/test_asm_pdp8.cpp b/test/test_asm_pdp8.cpp index 5de6e972..bf17d785 100644 --- a/test/test_asm_pdp8.cpp +++ b/test/test_asm_pdp8.cpp @@ -692,6 +692,10 @@ void test_data_constant() { TEST("OCTAL"); TEST( "7777", 07777); TEST( " -1", 07777); + TEST( " 7+5", 07+05); + TEST( "17-5", 017-05); + TEST( "15&5", 015&05); + TEST( "16!5", 016|05); TEST( "4000", 04000); ERRT( "10000", OVERFLOW_RANGE, "10000", 00000); ERRT(" -4001", OVERFLOW_RANGE, "-4001", 03777); @@ -700,7 +704,7 @@ void test_data_constant() { TEST("OCTAL"); TEST(" 10", 00010); - TEST("DUBL 10", 00000, 00012); + TEST("DUBL 10", 0, 10); TEST("DUBL -10", 07777, 07766); TEST("DUBL 16777215", 07777, 07777); TEST("DUBL 8388608", 04000, 00000); diff --git a/test/test_expr_base.cpp b/test/test_expr_base.cpp index b26915a0..2a74d703 100644 --- a/test/test_expr_base.cpp +++ b/test/test_expr_base.cpp @@ -23,7 +23,9 @@ const ValueParser parser{ValueParser::Plugins::singleton()}; const ValueFormatter formatter{ValueFormatter::Plugins::cstyle()}; -static void set_up() {} +static void set_up() { + context.defaultRadix = RADIX_10; +} static void tear_down() { symtab.reset(); @@ -65,6 +67,15 @@ static void test_dec_constant() { E32("4294967295", 0xffffffff); X32("4294967296", OVERFLOW_RANGE, "4294967296", ""); X32("9999999999", OVERFLOW_RANGE, "9999999999", ""); + + context.defaultRadix = RADIX_16; + E32("101", 0x101); + context.defaultRadix = RADIX_10; + E32("101", 101); + context.defaultRadix = RADIX_8; + E32("101", 0101); + context.defaultRadix = RADIX_2; + E32("101", 0b101); } static void test_hex_constant() {