parser: Refactor Parsable
to align with assembler::Assemble
This commit is contained in:
parent
af89541af1
commit
860c9d4a97
@ -37,7 +37,7 @@ impl<'t> Parser<'t> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse<T: Parsable<'t>>(&mut self) -> PResult<T> {
|
pub fn parse<T: Parsable<'t>>(&mut self) -> PResult<T> {
|
||||||
Parsable::parse(self)
|
Parsable::parse_with(self)
|
||||||
}
|
}
|
||||||
pub fn error(&self, kind: ErrorKind, parsing: Parsing) -> Error {
|
pub fn error(&self, kind: ErrorKind, parsing: Parsing) -> Error {
|
||||||
Error { parsing, kind, loc: self.loc }
|
Error { parsing, kind, loc: self.loc }
|
||||||
@ -194,11 +194,14 @@ impl<'t> Parser<'t> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait Parsable<'t>: Sized {
|
pub trait Parsable<'t>: Sized {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self>;
|
fn parse(text: &'t str) -> PResult<Self> {
|
||||||
|
Self::parse_with(&mut Parser::new(text))
|
||||||
|
}
|
||||||
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'t> Parsable<'t> for Statements<'t> {
|
impl<'t> Parsable<'t> for Statements<'t> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
let mut stmts = vec![];
|
let mut stmts = vec![];
|
||||||
while p.peek(Parsing::File)?.kind != Kind::Eof {
|
while p.peek(Parsing::File)?.kind != Kind::Eof {
|
||||||
stmts.push(p.parse()?)
|
stmts.push(p.parse()?)
|
||||||
@ -208,7 +211,7 @@ impl<'t> Parsable<'t> for Statements<'t> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'t> Parsable<'t> for Statement<'t> {
|
impl<'t> Parsable<'t> for Statement<'t> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
let token = *p.peek(Parsing::Stmt)?;
|
let token = *p.peek(Parsing::Stmt)?;
|
||||||
Ok(match token.kind {
|
Ok(match token.kind {
|
||||||
Kind::Comment => {
|
Kind::Comment => {
|
||||||
@ -222,7 +225,7 @@ impl<'t> Parsable<'t> for Statement<'t> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t> Parsable<'t> for Directive<'t> {
|
impl<'t> Parsable<'t> for Directive<'t> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
let parsing = Parsing::Directive;
|
let parsing = Parsing::Directive;
|
||||||
let Token { lexeme, kind, pos: _ } = *p.peek(parsing)?;
|
let Token { lexeme, kind, pos: _ } = *p.peek(parsing)?;
|
||||||
let Kind::Directive = kind else { return Err(p.error(Unexpected(kind), parsing)) };
|
let Kind::Directive = kind else { return Err(p.error(Unexpected(kind), parsing)) };
|
||||||
@ -238,7 +241,7 @@ impl<'t> Parsable<'t> for Directive<'t> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t> Parsable<'t> for Vec<Token<'t>> {
|
impl<'t> Parsable<'t> for Vec<Token<'t>> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
let parsing = Parsing::Directive;
|
let parsing = Parsing::Directive;
|
||||||
let mut tokens = vec![];
|
let mut tokens = vec![];
|
||||||
loop {
|
loop {
|
||||||
@ -252,13 +255,13 @@ impl<'t> Parsable<'t> for Vec<Token<'t>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t> Parsable<'t> for Instruction<'t> {
|
impl<'t> Parsable<'t> for Instruction<'t> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
let start = p.peek(Parsing::Instruction)?.pos.start;
|
let start = p.peek(Parsing::Instruction)?.pos.start;
|
||||||
Ok(Self { kind: p.parse()?, span: Span { start, end: p.loc.end } })
|
Ok(Self { kind: p.parse()?, span: Span { start, end: p.loc.end } })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t> Parsable<'t> for InstructionKind<'t> {
|
impl<'t> Parsable<'t> for InstructionKind<'t> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
use crate::lexer::token::OneArg;
|
use crate::lexer::token::OneArg;
|
||||||
// an instruction starts with an opcode
|
// an instruction starts with an opcode
|
||||||
Ok(match p.peek(Parsing::Instruction)?.kind() {
|
Ok(match p.peek(Parsing::Instruction)?.kind() {
|
||||||
@ -274,7 +277,7 @@ impl<'t> Parsable<'t> for InstructionKind<'t> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t> Parsable<'t> for NoEm {
|
impl<'t> Parsable<'t> for NoEm {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
match p.next(Parsing::NoEm)?.kind {
|
match p.next(Parsing::NoEm)?.kind {
|
||||||
Kind::NoEm(opcode) => Ok(Self { opcode }),
|
Kind::NoEm(opcode) => Ok(Self { opcode }),
|
||||||
ty => Err(p.error(Unexpected(ty), Parsing::NoEm)),
|
ty => Err(p.error(Unexpected(ty), Parsing::NoEm)),
|
||||||
@ -282,7 +285,7 @@ impl<'t> Parsable<'t> for NoEm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t> Parsable<'t> for OneEm<'t> {
|
impl<'t> Parsable<'t> for OneEm<'t> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
opcode: match p.next(Parsing::OneEm)?.kind {
|
opcode: match p.next(Parsing::OneEm)?.kind {
|
||||||
Kind::OneEm(opcode) => opcode,
|
Kind::OneEm(opcode) => opcode,
|
||||||
@ -294,7 +297,7 @@ impl<'t> Parsable<'t> for OneEm<'t> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t> Parsable<'t> for OneArg<'t> {
|
impl<'t> Parsable<'t> for OneArg<'t> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
opcode: match p.next(Parsing::OneArg)?.kind {
|
opcode: match p.next(Parsing::OneArg)?.kind {
|
||||||
Kind::OneArg(opcode) => opcode,
|
Kind::OneArg(opcode) => opcode,
|
||||||
@ -306,7 +309,7 @@ impl<'t> Parsable<'t> for OneArg<'t> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t> Parsable<'t> for TwoArg<'t> {
|
impl<'t> Parsable<'t> for TwoArg<'t> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
let parsing = Parsing::TwoArg;
|
let parsing = Parsing::TwoArg;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
opcode: match p.next(parsing)?.kind {
|
opcode: match p.next(parsing)?.kind {
|
||||||
@ -320,7 +323,7 @@ impl<'t> Parsable<'t> for TwoArg<'t> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t> Parsable<'t> for Jump<'t> {
|
impl<'t> Parsable<'t> for Jump<'t> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
let parsing = Parsing::Jump;
|
let parsing = Parsing::Jump;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
opcode: match p.next(parsing)?.kind {
|
opcode: match p.next(parsing)?.kind {
|
||||||
@ -332,21 +335,21 @@ impl<'t> Parsable<'t> for Jump<'t> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t> Parsable<'t> for Reti {
|
impl<'t> Parsable<'t> for Reti {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
use crate::lexer::token::OneArg;
|
use crate::lexer::token::OneArg;
|
||||||
p.assert(Kind::OneArg(OneArg::Reti), Parsing::Reti)?;
|
p.assert(Kind::OneArg(OneArg::Reti), Parsing::Reti)?;
|
||||||
Ok(Reti)
|
Ok(Reti)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t> Parsable<'t> for Br<'t> {
|
impl<'t> Parsable<'t> for Br<'t> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
p.assert(Kind::Special(Special::Br), Parsing::Br)?;
|
p.assert(Kind::Special(Special::Br), Parsing::Br)?;
|
||||||
Ok(Self { src: p.parse()? })
|
Ok(Self { src: p.parse()? })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'t> Parsable<'t> for Src<'t> {
|
impl<'t> Parsable<'t> for Src<'t> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
let parsing = Parsing::Src;
|
let parsing = Parsing::Src;
|
||||||
Ok(match p.peek(parsing)?.kind {
|
Ok(match p.peek(parsing)?.kind {
|
||||||
Kind::Hash => Src::Immediate(p.then(parsing)?.parse()?), // #imm, #special
|
Kind::Hash => Src::Immediate(p.then(parsing)?.parse()?), // #imm, #special
|
||||||
@ -379,7 +382,7 @@ impl<'t> Parsable<'t> for Src<'t> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t> Parsable<'t> for Dst<'t> {
|
impl<'t> Parsable<'t> for Dst<'t> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
let parsing = Parsing::Dst;
|
let parsing = Parsing::Dst;
|
||||||
Ok(match p.peek(parsing)?.kind {
|
Ok(match p.peek(parsing)?.kind {
|
||||||
Kind::Hash => match p.then(parsing)?.next(parsing)?.kind {
|
Kind::Hash => match p.then(parsing)?.next(parsing)?.kind {
|
||||||
@ -399,7 +402,7 @@ impl<'t> Parsable<'t> for Dst<'t> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t> Parsable<'t> for JumpDst<'t> {
|
impl<'t> Parsable<'t> for JumpDst<'t> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
let parsing = Parsing::Jump;
|
let parsing = Parsing::Jump;
|
||||||
let mut neg = false;
|
let mut neg = false;
|
||||||
let out = loop {
|
let out = loop {
|
||||||
@ -420,7 +423,7 @@ impl<'t> Parsable<'t> for JumpDst<'t> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t> Parsable<'t> for Width {
|
impl<'t> Parsable<'t> for Width {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
let out = match p.peek(Parsing::Width)?.kind() {
|
let out = match p.peek(Parsing::Width)?.kind() {
|
||||||
Kind::Byte => Width::Byte,
|
Kind::Byte => Width::Byte,
|
||||||
Kind::Word => Width::Word,
|
Kind::Word => Width::Word,
|
||||||
@ -431,7 +434,7 @@ impl<'t> Parsable<'t> for Width {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t> Parsable<'t> for Reg {
|
impl<'t> Parsable<'t> for Reg {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
let out = match p.peek(Parsing::Reg)?.kind {
|
let out = match p.peek(Parsing::Reg)?.kind {
|
||||||
Kind::Reg(r) => r,
|
Kind::Reg(r) => r,
|
||||||
ty => Err(p.error(Unexpected(ty), Parsing::Reg))?,
|
ty => Err(p.error(Unexpected(ty), Parsing::Reg))?,
|
||||||
@ -441,17 +444,17 @@ impl<'t> Parsable<'t> for Reg {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t> Parsable<'t> for Expr<'t> {
|
impl<'t> Parsable<'t> for Expr<'t> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
p.expr()
|
p.expr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t, T: Parsable<'t>> Parsable<'t> for Box<T> {
|
impl<'t, T: Parsable<'t>> Parsable<'t> for Box<T> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
Ok(Box::new(p.parse()?))
|
Ok(Box::new(p.parse()?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'t, T: Parsable<'t>> Parsable<'t> for Vec<T> {
|
impl<'t, T: Parsable<'t>> Parsable<'t> for Vec<T> {
|
||||||
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
|
fn parse_with(p: &mut Parser<'t>) -> PResult<Self> {
|
||||||
let parsing = Parsing::Vec;
|
let parsing = Parsing::Vec;
|
||||||
p.assert(Kind::OpenBrace, parsing)?;
|
p.assert(Kind::OpenBrace, parsing)?;
|
||||||
let mut out = vec![];
|
let mut out = vec![];
|
||||||
@ -589,3 +592,6 @@ pub mod error {
|
|||||||
}
|
}
|
||||||
impl std::error::Error for Error {}
|
impl std::error::Error for Error {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
Loading…
Reference in New Issue
Block a user