From 8eb49b860b8c933e72e6855d79402d1e7cb0aa21 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Tue, 1 Oct 2024 22:13:49 +0900 Subject: [PATCH] Separate OperatorParser::readOperator to readPrefix and readInfix Also added ValueStack and ParserContext to ValueParser and OperatorEval. --- src/operators.cpp | 434 ++++++++++++++++++++++--------------------- src/operators.h | 30 ++- src/value_parser.cpp | 9 +- 3 files changed, 244 insertions(+), 229 deletions(-) diff --git a/src/operators.cpp b/src/operators.cpp index bb8c32bc..3ea45b5e 100644 --- a/src/operators.cpp +++ b/src/operators.cpp @@ -38,22 +38,22 @@ Error Operator::eval(ValueStack &stack, ParserContext &context, uint_fast8_t arg return _fn->eval(stack, context, argc); return argc > nargs ? TOO_MANY_FUNC_ARGUMENT : TOO_FEW_FUNC_ARGUMENT; } - return argc >= _nargs ? (*_op)(stack) : MISSING_OPERAND; + return argc >= _nargs ? (*_op)(stack, context) : MISSING_OPERAND; } -static Error bitwise_not(ValueStack &stack) { +static Error bitwise_not(ValueStack &stack, ParserContext &) { const auto v = stack.pop(); stack.push(~v); return OK; } -static Error logical_not(ValueStack &stack) { +static Error logical_not(ValueStack &stack, ParserContext &) { const auto v = stack.pop().getUnsigned(); stack.pushUnsigned(!v); return OK; } -static Error unary_minus(ValueStack &stack) { +static Error unary_minus(ValueStack &stack, ParserContext &) { const auto v = stack.pop(); stack.push(-v); #ifdef LIBASM_ASM_NOFLOAT @@ -63,7 +63,7 @@ static Error unary_minus(ValueStack &stack) { return OK; } -static Error unary_plus(ValueStack &stack) { +static Error unary_plus(ValueStack &stack, ParserContext &) { const auto v = stack.pop(); stack.push(v); #ifdef LIBASM_ASM_NOFLOAT @@ -73,14 +73,14 @@ static Error unary_plus(ValueStack &stack) { return OK; } -static Error multiply(ValueStack &stack) { +static Error multiply(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); stack.push(lhs * rhs); return OK; } -static Error divide(ValueStack &stack) { +static Error divide(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); if (rhs.isZero()) @@ -89,7 +89,7 @@ static Error divide(ValueStack &stack) { return OK; } -static Error modulo(ValueStack &stack) { +static Error modulo(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); if (rhs.isZero()) @@ -98,21 +98,21 @@ static Error modulo(ValueStack &stack) { return OK; } -static Error add(ValueStack &stack) { +static Error add(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); stack.push(lhs + rhs); return OK; } -static Error subtract(ValueStack &stack) { +static Error subtract(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); stack.push(lhs - rhs); return OK; } -static Error logical_shift_left_32bit(ValueStack &stack) { +static Error logical_shift_left_32bit(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop().getUnsigned(); const auto lhs = stack.pop().getUnsigned() & UINT32_MAX; const auto value = (rhs < 32) ? (lhs << rhs) : 0; @@ -120,77 +120,77 @@ static Error logical_shift_left_32bit(ValueStack &stack) { return OK; } -static Error arithmetic_shift_right(ValueStack &stack) { +static Error arithmetic_shift_right(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); stack.push(lhs >> rhs); return OK; } -static Error less_than(ValueStack &stack) { +static Error less_than(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); stack.pushUnsigned(lhs < rhs); return OK; } -static Error less_than_or_equal(ValueStack &stack) { +static Error less_than_or_equal(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); stack.pushUnsigned(lhs < rhs || lhs == rhs); return OK; } -static Error greater_than_or_equal(ValueStack &stack) { +static Error greater_than_or_equal(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); stack.pushUnsigned(!(lhs < rhs)); return OK; } -static Error greater_than(ValueStack &stack) { +static Error greater_than(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); stack.pushUnsigned(!(lhs < rhs) && !(lhs == rhs)); return OK; } -static Error logical_equal(ValueStack &stack) { +static Error logical_equal(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); stack.pushUnsigned(lhs == rhs); return OK; } -static Error logical_not_equal(ValueStack &stack) { +static Error logical_not_equal(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); stack.pushUnsigned(!(lhs == rhs)); return OK; } -static Error bitwise_and(ValueStack &stack) { +static Error bitwise_and(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); stack.push(lhs & rhs); return OK; } -static Error bitwise_xor(ValueStack &stack) { +static Error bitwise_xor(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); stack.push(lhs ^ rhs); return OK; } -static Error bitwise_or(ValueStack &stack) { +static Error bitwise_or(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); stack.push(lhs | rhs); return OK; } -static Error logical_and(ValueStack &stack) { +static Error logical_and(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); Value v; @@ -199,7 +199,7 @@ static Error logical_and(ValueStack &stack) { return OK; } -static Error logical_or(ValueStack &stack) { +static Error logical_or(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); Value v; @@ -236,75 +236,90 @@ static const Operator OP_LOGICAL_AND(14, L, 2, logical_and); static const Operator OP_LOGICAL_OR( 15, L, 2, logical_or); // clang-format on -const Operator *CStyleOperatorParser::readOperator( - StrScanner &scan, ErrorAt &error, Operator::Type type) const { - UNUSED(error); +const Operator *OperatorParser::readPrefix( + StrScanner &scan, ValueStack &stack, ParserContext &context) const { + return CStyleOperatorParser::singleton().readPrefix(scan, stack, context); +} + +const Operator *OperatorParser::readInfix( + StrScanner &scan, ValueStack &stack, ParserContext &context) const { + return CStyleOperatorParser::singleton().readInfix(scan, stack, context); +} + +const Operator *CStyleOperatorParser::readPrefix( + StrScanner &scan, ValueStack &, ParserContext &) const { auto p = scan; const Operator *opr = nullptr; - if (type == Operator::PREFIX) { - if (p.expect('~')) { - opr = &OP_BITWISE_NOT; - } else if (p.expect('!') && *p != '=') { - opr = &OP_LOGICAL_NOT; - } else if (p.expect('-')) { - opr = &OP_UNARY_MINUS; - } else if (p.expect('+')) { - opr = &OP_UNARY_PLUS; + if (p.expect('~')) { + opr = &OP_BITWISE_NOT; + } else if (p.expect('!') && *p != '=') { + opr = &OP_LOGICAL_NOT; + } else if (p.expect('-')) { + opr = &OP_UNARY_MINUS; + } else if (p.expect('+')) { + opr = &OP_UNARY_PLUS; + } + if (opr) + scan = p; + return opr; +} + +const Operator *CStyleOperatorParser::readInfix( + StrScanner &scan, ValueStack &, ParserContext &) const { + auto p = scan; + const Operator *opr = nullptr; + if (p.expect('*')) { + opr = &OP_MUL; + } else if (p.expect('/')) { + opr = &OP_DIV; + } else if (p.expect('%')) { + opr = &OP_MOD; + } else if (p.expect('+')) { + opr = &OP_ADD; + } else if (p.expect('-')) { + opr = &OP_SUB; + } else if (p.expect('<')) { + if (p.expect('<')) { + opr = &OP_SHIFT_LEFT; + } else if (p.expect('=')) { + opr = &OP_LOGICAL_LE; + } else { + opr = &OP_LOGICAL_LT; } - } else if (type == Operator::INFIX) { - if (p.expect('*')) { - opr = &OP_MUL; - } else if (p.expect('/')) { - opr = &OP_DIV; - } else if (p.expect('%')) { - opr = &OP_MOD; - } else if (p.expect('+')) { - opr = &OP_ADD; - } else if (p.expect('-')) { - opr = &OP_SUB; - } else if (p.expect('<')) { - if (p.expect('<')) { - opr = &OP_SHIFT_LEFT; - } else if (p.expect('=')) { - opr = &OP_LOGICAL_LE; - } else { - opr = &OP_LOGICAL_LT; - } - } else if (p.expect('>')) { - if (p.expect('>')) { - opr = &OP_SHIFT_RIGHT; - } else if (p.expect('=')) { - opr = &OP_LOGICAL_GE; - } else { - opr = &OP_LOGICAL_GT; - } - } else if (p.expect('&')) { - opr = p.expect('&') ? &OP_LOGICAL_AND : &OP_BITWISE_AND; - } else if (p.expect('^')) { - opr = &OP_BITWISE_XOR; - } else if (p.expect('|')) { - opr = p.expect('|') ? &OP_LOGICAL_OR : &OP_BITWISE_OR; - } else if (p.expect('!')) { - if (p.expect('=')) - opr = &OP_LOGICAL_NE; + } else if (p.expect('>')) { + if (p.expect('>')) { + opr = &OP_SHIFT_RIGHT; } else if (p.expect('=')) { - if (p.expect('=')) - opr = &OP_LOGICAL_EQ; + opr = &OP_LOGICAL_GE; + } else { + opr = &OP_LOGICAL_GT; } + } else if (p.expect('&')) { + opr = p.expect('&') ? &OP_LOGICAL_AND : &OP_BITWISE_AND; + } else if (p.expect('^')) { + opr = &OP_BITWISE_XOR; + } else if (p.expect('|')) { + opr = p.expect('|') ? &OP_LOGICAL_OR : &OP_BITWISE_OR; + } else if (p.expect('!')) { + if (p.expect('=')) + opr = &OP_LOGICAL_NE; + } else if (p.expect('=')) { + if (p.expect('=')) + opr = &OP_LOGICAL_EQ; } if (opr) scan = p; return opr; } -static Error exponential(ValueStack &stack) { +static Error exponential(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop(); const auto lhs = stack.pop(); stack.push(lhs.exponential(rhs)); return OK; } -static Error rotate_left_16bit(ValueStack &stack) { +static Error rotate_left_16bit(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop().getUnsigned() % 16; const auto lhs = stack.pop().getUnsigned() & UINT16_MAX; const auto v = (lhs << rhs) | (lhs >> (16 - rhs)); @@ -312,7 +327,7 @@ static Error rotate_left_16bit(ValueStack &stack) { return OK; } -static Error rotate_right_16bit(ValueStack &stack) { +static Error rotate_right_16bit(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop().getUnsigned() % 16; const auto lhs = stack.pop().getUnsigned() & UINT16_MAX; const auto v = (lhs >> rhs) | (lhs << (16 - rhs)); @@ -320,7 +335,7 @@ static Error rotate_right_16bit(ValueStack &stack) { return OK; } -static Error logical_shift_left_16bit(ValueStack &stack) { +static Error logical_shift_left_16bit(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop().getUnsigned(); const auto lhs = stack.pop().getUnsigned() & UINT16_MAX; const auto value = (rhs < 16) ? (lhs << rhs) : 0; @@ -328,7 +343,7 @@ static Error logical_shift_left_16bit(ValueStack &stack) { return OK; } -static Error logical_shift_right_16bit(ValueStack &stack) { +static Error logical_shift_right_16bit(ValueStack &stack, ParserContext &) { const auto rhs = stack.pop().getUnsigned(); const auto lhs = stack.pop().getUnsigned() & UINT16_MAX; const auto value = (rhs < 16) ? (lhs >> rhs) : 0; @@ -347,57 +362,55 @@ static const Operator MC68_BITWISE_XOR( 5, L, 2, bitwise_xor); static const Operator MC68_BITWISE_OR( 5, L, 2, bitwise_or); // clang-format on -const Operator *Mc68xxOperatorParser::readOperator( - StrScanner &scan, ErrorAt &error, Operator::Type type) const { - if (type == Operator::INFIX) { - auto p = scan; - if (p.expect('!')) { - const Operator *opr = nullptr; - if (p.expect('.')) { - opr = &MC68_BITWISE_AND; - } else if (p.expect('+')) { - opr = &MC68_BITWISE_OR; - } else if (p.expect('X') && !isalnum(*p)) { - opr = &MC68_BITWISE_XOR; - } else if (p.expect('^')) { - opr = &MC68_EXPONENTIAL; - } else if (p.expect('<')) { - opr = &MC68_SHIFT_LEFT; - } else if (p.expect('>')) { - opr = &MC68_SHIFT_RIGHT; - } else if (p.expect('L') && !isalnum(*p)) { - opr = &MC68_ROTATE_LEFT; - } else if (p.expect('R') && !isalnum(*p)) { - opr = &MC68_ROTATE_RIGHT; - } - if (opr) { - scan = p; - return opr; - } +const Operator *Mc68xxOperatorParser::readInfix( + StrScanner &scan, ValueStack &stack, ParserContext &context) const { + auto p = scan; + const Operator *opr = nullptr; + if (p.expect('!')) { + if (p.expect('.')) { + opr = &MC68_BITWISE_AND; + } else if (p.expect('+')) { + opr = &MC68_BITWISE_OR; + } else if (p.expect('X') && !isalnum(*p)) { + opr = &MC68_BITWISE_XOR; + } else if (p.expect('^')) { + opr = &MC68_EXPONENTIAL; + } else if (p.expect('<')) { + opr = &MC68_SHIFT_LEFT; + } else if (p.expect('>')) { + opr = &MC68_SHIFT_RIGHT; + } else if (p.expect('L') && !isalnum(*p)) { + opr = &MC68_ROTATE_LEFT; + } else if (p.expect('R') && !isalnum(*p)) { + opr = &MC68_ROTATE_RIGHT; } } - return CStyleOperatorParser::singleton().readOperator(scan, error, type); + if (opr) { + scan = p; + return opr; + } + return CStyleOperatorParser::singleton().readInfix(scan, stack, context); } -static Error most_siginificant_byte(ValueStack &stack) { +static Error most_siginificant_byte(ValueStack &stack, ParserContext &) { const auto v = stack.pop().getUnsigned(); stack.pushUnsigned((v >> 8) & UINT8_MAX); return OK; } -static Error least_significant_byte(ValueStack &stack) { +static Error least_significant_byte(ValueStack &stack, ParserContext &) { const auto v = stack.pop().getUnsigned(); stack.pushUnsigned(v & UINT8_MAX); return OK; } -static Error most_siginificant_word(ValueStack &stack) { +static Error most_siginificant_word(ValueStack &stack, ParserContext &) { const auto v = stack.pop().getUnsigned(); stack.pushUnsigned((v >> 16) & UINT16_MAX); return OK; } -static Error least_significant_word(ValueStack &stack) { +static Error least_significant_word(ValueStack &stack, ParserContext &) { const auto v = stack.pop().getUnsigned(); stack.pushUnsigned(v & UINT16_MAX); return OK; @@ -420,82 +433,80 @@ static const Operator INTEL_BITWISE_XOR(12, L, 2, bitwise_xor); static const Operator INTEL_BITWISE_OR( 12, L, 2, bitwise_or); // clang-format on -const Operator *IntelOperatorParser::readOperator( - StrScanner &scan, ErrorAt &error, Operator::Type type) const { +const Operator *IntelOperatorParser::readPrefix( + StrScanner &scan, ValueStack &stack, ParserContext &context) const { + if (scan.expect('-')) { + return &INTEL_UNARY_MINUS; + } else if (scan.expect('+')) { + return &INTEL_UNARY_PLUS; + } auto p = scan; // TODO: Use SymbolParser p.trimStart(isalnum); const StrScanner name(scan.str(), p.str()); const Operator *opr = nullptr; - if (type == Operator::PREFIX) { - if (scan.expect('-')) { - return &INTEL_UNARY_MINUS; - } else if (scan.expect('+')) { - return &INTEL_UNARY_PLUS; - } - if (name.iequals_P(PSTR("NOT"))) { - opr = &INTEL_BITWISE_NOT; - } else if (name.iequals_P(PSTR("HIGH"))) { - opr = &INTEL_HIGH; - } else if (name.iequals_P(PSTR("LOW"))) { - opr = &INTEL_LOW; - } else if (name.iequals_P(PSTR("MSW"))) { - opr = &INTEL_MSW; - } else if (name.iequals_P(PSTR("LSW"))) { - opr = &INTEL_LSW; - } - if (opr) { - scan += name.size(); - return opr; - } - } else if (type == Operator::INFIX) { - if (name.iequals_P(PSTR("MOD"))) { - opr = &OP_MOD; - } else if (name.iequals_P(PSTR("AND"))) { - opr = &INTEL_BITWISE_AND; - } else if (name.iequals_P(PSTR("OR"))) { - opr = &INTEL_BITWISE_OR; - } else if (name.iequals_P(PSTR("XOR"))) { - opr = &INTEL_BITWISE_XOR; - } else if (name.iequals_P(PSTR("SHR"))) { - opr = &INTEL_SHIFT_RIGHT; - } else if (name.iequals_P(PSTR("SHL"))) { - opr = &INTEL_SHIFT_LEFT; - } else if (name.iequals_P(PSTR("EQ"))) { - opr = &INTEL_LOGICAL_EQ; - } else if (name.iequals_P(PSTR("NE"))) { - opr = &INTEL_LOGICAL_NE; - } else if (name.iequals_P(PSTR("LT"))) { - opr = &OP_LOGICAL_LT; - } else if (name.iequals_P(PSTR("LE"))) { - opr = &OP_LOGICAL_LE; - } else if (name.iequals_P(PSTR("GE"))) { - opr = &OP_LOGICAL_GE; - } else if (name.iequals_P(PSTR("GT"))) { - opr = &OP_LOGICAL_GT; - } - if (opr) { - scan += name.size(); - return opr; - } + if (name.iequals_P(PSTR("NOT"))) { + opr = &INTEL_BITWISE_NOT; + } else if (name.iequals_P(PSTR("HIGH"))) { + opr = &INTEL_HIGH; + } else if (name.iequals_P(PSTR("LOW"))) { + opr = &INTEL_LOW; + } else if (name.iequals_P(PSTR("MSW"))) { + opr = &INTEL_MSW; + } else if (name.iequals_P(PSTR("LSW"))) { + opr = &INTEL_LSW; + } + if (opr) { + scan = p; + return opr; } - return CStyleOperatorParser::singleton().readOperator(scan, error, type); + return CStyleOperatorParser::singleton().readPrefix(scan, stack, context); } -const Operator *Pdp8OperatorParser::readOperator( - StrScanner &scan, ErrorAt &error, Operator::Type type) const { - UNUSED(error); +const Operator *IntelOperatorParser::readInfix( + StrScanner &scan, ValueStack &stack, ParserContext &context) const { auto p = scan; + // TODO: Use SymbolParser + p.trimStart(isalnum); + const StrScanner name(scan.str(), p.str()); const Operator *opr = nullptr; - if (type == Operator::INFIX) { - if (p.expect('!')) - opr = &OP_BITWISE_OR; + if (name.iequals_P(PSTR("MOD"))) { + opr = &OP_MOD; + } else if (name.iequals_P(PSTR("AND"))) { + opr = &INTEL_BITWISE_AND; + } else if (name.iequals_P(PSTR("OR"))) { + opr = &INTEL_BITWISE_OR; + } else if (name.iequals_P(PSTR("XOR"))) { + opr = &INTEL_BITWISE_XOR; + } else if (name.iequals_P(PSTR("SHR"))) { + opr = &INTEL_SHIFT_RIGHT; + } else if (name.iequals_P(PSTR("SHL"))) { + opr = &INTEL_SHIFT_LEFT; + } else if (name.iequals_P(PSTR("EQ"))) { + opr = &INTEL_LOGICAL_EQ; + } else if (name.iequals_P(PSTR("NE"))) { + opr = &INTEL_LOGICAL_NE; + } else if (name.iequals_P(PSTR("LT"))) { + opr = &OP_LOGICAL_LT; + } else if (name.iequals_P(PSTR("LE"))) { + opr = &OP_LOGICAL_LE; + } else if (name.iequals_P(PSTR("GE"))) { + opr = &OP_LOGICAL_GE; + } else if (name.iequals_P(PSTR("GT"))) { + opr = &OP_LOGICAL_GT; } if (opr) { scan = p; return opr; } - return CStyleOperatorParser::singleton().readOperator(scan, error, type); + return CStyleOperatorParser::singleton().readInfix(scan, stack, context); +} + +const Operator *Pdp8OperatorParser::readInfix( + StrScanner &scan, ValueStack &stack, ParserContext &context) const { + if (scan.expect('!')) + return &OP_BITWISE_OR; + return CStyleOperatorParser::singleton().readInfix(scan, stack, context); } // clang-format off @@ -508,49 +519,56 @@ static const Operator ZILOG_BITWISE_XOR(6, L, 2, bitwise_xor); static const Operator ZILOG_BITWISE_OR( 6, L, 2, bitwise_or); // clang-format on -const Operator *ZilogOperatorParser::readOperator( - StrScanner &scan, ErrorAt &error, Operator::Type type) const { +const Operator *ZilogOperatorParser::readPrefix( + StrScanner &scan, ValueStack &stack, ParserContext &context) const { auto p = scan; // TODO: Use SymbolParser p.trimStart(isalnum); const StrScanner name(scan.str(), p.str()); const Operator *opr = nullptr; - if (type == Operator::PREFIX) { - if (name.iequals_P(PSTR("LNOT"))) { - opr = &OP_BITWISE_NOT; - } else if (name.iequals_P(PSTR("HIGH"))) { - opr = &INTEL_HIGH; - } else if (name.iequals_P(PSTR("LOW"))) { - opr = &INTEL_LOW; - } else if (name.iequals_P(PSTR("HIGH16"))) { - opr = &ZILOG_HIGH16; - } else if (name.iequals_P(PSTR("LOW16"))) { - opr = &ZILOG_LOW16; - } - if (opr) { - scan += name.size(); - return opr; - } - } else if (type == Operator::INFIX) { - if (name.iequals_P(PSTR("MOD"))) { - opr = &OP_MOD; - } else if (name.iequals_P(PSTR("SHR"))) { - opr = &ZILOG_SHIFT_RIGHT; - } else if (name.iequals_P(PSTR("SHL"))) { - opr = &ZILOG_SHIFT_LEFT; - } else if (name.iequals_P(PSTR("LAND"))) { - opr = &ZILOG_BITWISE_AND; - } else if (name.iequals_P(PSTR("LOR"))) { - opr = &ZILOG_BITWISE_OR; - } else if (name.iequals_P(PSTR("LXOR"))) { - opr = &ZILOG_BITWISE_XOR; - } - if (opr) { - scan += name.size(); - return opr; - } + if (name.iequals_P(PSTR("LNOT"))) { + opr = &OP_BITWISE_NOT; + } else if (name.iequals_P(PSTR("HIGH"))) { + opr = &INTEL_HIGH; + } else if (name.iequals_P(PSTR("LOW"))) { + opr = &INTEL_LOW; + } else if (name.iequals_P(PSTR("HIGH16"))) { + opr = &ZILOG_HIGH16; + } else if (name.iequals_P(PSTR("LOW16"))) { + opr = &ZILOG_LOW16; + } + if (opr) { + scan = p; + return opr; + } + return CStyleOperatorParser::singleton().readPrefix(scan, stack, context); +} + +const Operator *ZilogOperatorParser::readInfix( + StrScanner &scan, ValueStack &stack, ParserContext &context) const { + auto p = scan; + // TODO: Use SymbolParser + p.trimStart(isalnum); + const StrScanner name(scan.str(), p.str()); + const Operator *opr = nullptr; + if (name.iequals_P(PSTR("MOD"))) { + opr = &OP_MOD; + } else if (name.iequals_P(PSTR("SHR"))) { + opr = &ZILOG_SHIFT_RIGHT; + } else if (name.iequals_P(PSTR("SHL"))) { + opr = &ZILOG_SHIFT_LEFT; + } else if (name.iequals_P(PSTR("LAND"))) { + opr = &ZILOG_BITWISE_AND; + } else if (name.iequals_P(PSTR("LOR"))) { + opr = &ZILOG_BITWISE_OR; + } else if (name.iequals_P(PSTR("LXOR"))) { + opr = &ZILOG_BITWISE_XOR; + } + if (opr) { + scan = p; + return opr; } - return CStyleOperatorParser::singleton().readOperator(scan, error, type); + return CStyleOperatorParser::singleton().readInfix(scan, stack, context); } } // namespace libasm diff --git a/src/operators.h b/src/operators.h index 961f4ad0..bf5cae5d 100644 --- a/src/operators.h +++ b/src/operators.h @@ -43,17 +43,13 @@ struct Functor { /** Returns the number of required arguments. Negative value means variable arguments. */ virtual int_fast8_t nargs() const { return -1; } /** Evaluate function with |arguments|. */ - virtual Error eval(ValueStack &, ParserContext &context, uint_fast8_t) const { return OK; } + virtual Error eval(ValueStack &, ParserContext &, uint_fast8_t) const { return OK; } }; /** * Immutable instance to represent prefix or infix operators and functions. */ struct Operator : ErrorAt { - enum Type : uint_fast8_t { - PREFIX, - INFIX, - }; /** Associativity of an operator */ enum Assoc : uint8_t { LEFT, @@ -84,7 +80,7 @@ struct Operator : ErrorAt { bool isNoneAssoc(const Operator &o) const; /** Constructor for operators */ - typedef Error(OperatorEval)(ValueStack &stack); + typedef Error(OperatorEval)(ValueStack &stack, ParserContext &); 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) {} @@ -115,35 +111,33 @@ struct Operator : ErrorAt { * Parsing prefix and infix operator. */ struct OperatorParser { - virtual const Operator *readOperator( - StrScanner &scan, ErrorAt &error, Operator::Type type) const = 0; + virtual const Operator *readPrefix(StrScanner &, ValueStack &, ParserContext &) const; + virtual const Operator *readInfix(StrScanner &, ValueStack &, ParserContext &) const; virtual bool isOpenExpr(StrScanner &scan) const { return scan.expect('('); } virtual bool isCloseExpr(StrScanner &scan) const { return scan.expect(')'); } }; struct CStyleOperatorParser final : OperatorParser, Singleton { - const Operator *readOperator( - StrScanner &scan, ErrorAt &error, Operator::Type type) const override; + const Operator *readPrefix(StrScanner &, ValueStack &, ParserContext &) const override; + const Operator *readInfix(StrScanner &, ValueStack &, ParserContext &) const override; }; struct Mc68xxOperatorParser final : OperatorParser, Singleton { - const Operator *readOperator( - StrScanner &scan, ErrorAt &error, Operator::Type type) const override; + const Operator *readInfix(StrScanner &, ValueStack &, ParserContext &) const override; }; struct IntelOperatorParser final : OperatorParser, Singleton { - const Operator *readOperator( - StrScanner &scan, ErrorAt &error, Operator::Type type) const override; + const Operator *readPrefix(StrScanner &, ValueStack &, ParserContext &) const override; + const Operator *readInfix(StrScanner &, ValueStack &, ParserContext &) const override; }; struct Pdp8OperatorParser final : OperatorParser, Singleton { - const Operator *readOperator( - StrScanner &scan, ErrorAt &error, Operator::Type type) const override; + const Operator *readInfix(StrScanner &, ValueStack &, ParserContext &) const override; }; struct ZilogOperatorParser final : OperatorParser, Singleton { - const Operator *readOperator( - StrScanner &scan, ErrorAt &error, Operator::Type type) const override; + const Operator *readPrefix(StrScanner &, ValueStack &, ParserContext &) const override; + const Operator *readInfix(StrScanner &, ValueStack &, ParserContext &) const override; }; } // namespace libasm diff --git a/src/value_parser.cpp b/src/value_parser.cpp index fc3a702e..596c1826 100644 --- a/src/value_parser.cpp +++ b/src/value_parser.cpp @@ -85,7 +85,7 @@ Value ValueParser::_eval(StrScanner &scan, ErrorAt &error, ParserContext &contex if (maybe_prefix) { // Prefix operator may consist of alpha numeric text. Check operator before handling // symbols. - opr = _operators.readOperator(scan, error, Operator::PREFIX); + opr = _operators.readPrefix(scan, vstack, context); if (error.hasError()) return Value(); } @@ -147,8 +147,11 @@ Value ValueParser::_eval(StrScanner &scan, ErrorAt &error, ParserContext &contex } if (opr == nullptr) { - const auto oprType = maybe_prefix ? Operator::PREFIX : Operator::INFIX; - opr = _operators.readOperator(scan, error, oprType); + if (maybe_prefix) { + opr = _operators.readPrefix(scan, vstack, context); + } else { + opr = _operators.readInfix(scan, vstack, context); + } if (error.hasError()) return Value(); }