diff --git a/src/parser/instruction/encoding/primary_operand.rs b/src/parser/instruction/encoding/primary_operand.rs index a2a4fad..84784a5 100644 --- a/src/parser/instruction/encoding/primary_operand.rs +++ b/src/parser/instruction/encoding/primary_operand.rs @@ -68,11 +68,11 @@ impl Parsable for PrimaryOperand { fn parse<'text, T>(p: &Parser, stream: &mut T) -> Result where T: crate::TokenStream<'text> { use PrimaryOperand::*; - // Try parsing as Register Direct + // Try parsing as Register (Direct) if let Some(r) = Register::try_parse(p, stream)? { return Ok(Self::Direct(r)); } - // Try parsing as Number Indexed + // Try parsing as Number (Indexed) if let Some(idx) = Number::try_parse(p, stream)? { stream.expect(Type::LParen)?; let reg = Register::parse(p, stream)?; @@ -80,10 +80,14 @@ impl Parsable for PrimaryOperand { return Ok(Self::Indexed(reg, idx)); } // Or directly match any of the valid prefix markers - let token = stream.expect_any_of([Type::Indirect, Type::Absolute, Type::Immediate])?; + // Type::Register and Type::Number are included here to make error messages clearer. + // their inclusion will cause a negligible slowdown when the next token is not a prefix marker + // (a failure condition) + let token = + stream.expect_any_of([Type::Indirect, Type::Absolute, Type::Immediate, Type::Register, Type::Number])?; Ok(match token.variant() { Type::Indirect => { - let reg = stream.expect(Type::Register)?.parse()?; + let reg = Register::parse(p, stream)?; match stream.expect(Type::Plus) { Ok(_) => PostInc(reg), Err(_) => Indirect(reg), @@ -93,7 +97,7 @@ impl Parsable for PrimaryOperand { Type::Immediate => { let number = Number::parse(p, stream)?; match number.into() { - // There are two representations for the all-ones constant, since Number preserves absolute + // There are two representations for the all-ones constant, since Number preserves // signedness. -1 | 0xffff => MinusOne, 0 => Zero, diff --git a/src/parser/instruction/encoding/secondary_operand.rs b/src/parser/instruction/encoding/secondary_operand.rs index 09a9e6b..f94574a 100644 --- a/src/parser/instruction/encoding/secondary_operand.rs +++ b/src/parser/instruction/encoding/secondary_operand.rs @@ -55,28 +55,28 @@ impl Parsable for SecondaryOperand { where T: crate::TokenStream<'text> { use SecondaryOperand::*; stream.allow(Type::Separator); - // Try parsing as Register Direct + // Try parsing as Register (Direct) if let Some(r) = Register::try_parse(p, stream)? { return Ok(Self::Direct(r)); } - // Try parsing as Number Indexed + // Try parsing as Number (Indexed) if let Some(idx) = Number::try_parse(p, stream)? { stream.expect(Type::LParen)?; let reg = Register::parse(p, stream)?; stream.expect(Type::RParen)?; return Ok(Self::Indexed(reg, idx)); } - let token = stream.expect_any_of([Type::Absolute, Type::Immediate])?; + // Type::Register and Type::Number are included here to make error messages clearer. + // their inclusion will cause a negligible slowdown when the next token is not a prefix marker + // (a failure condition) but should not match a token + let token = stream.expect_any_of([Type::Absolute, Type::Immediate, Type::Register, Type::Number])?; Ok(match token.variant() { Type::Absolute => Absolute(Number::parse(p, stream)?), - Type::Immediate => { - let number = Number::parse(p, stream)?; - match number.into() { - 0 => Zero, - 1 => One, - n => Err(Error::FatSecondaryImmediate(n as isize).context(stream.context()))?, - } - } + Type::Immediate => match Number::parse(p, stream)?.into() { + 0 => Zero, + 1 => One, + n => Err(Error::FatSecondaryImmediate(n as isize).context(stream.context()))?, + }, _ => unreachable!("Token {token:?} passed expectation but failed match!"), }) }