rsleigh 0.3.0

SLEIGH (.slaspec) parser and Rust decoder/P-code emitter codegen — Ghidra-compatible disassembly in pure Rust
Documentation
use nom::branch::alt;
use nom::combinator::{cut, eof, map};
use nom::sequence::{pair, preceded, terminated};
use nom::IResult;

use crate::preprocessor::token::Token;
use crate::{Number, SleighError, Span};

use super::parser::{fieldlist, numberlist, registerlist, stringlist, this_ident};

#[derive(Clone, Debug)]
pub struct Attach {
    pub src: Span,
    pub fields: Vec<(String, Span)>,
    pub meaning: Meaning,
}

#[derive(Clone, Debug)]
pub enum Meaning {
    Variable(Vec<(Option<String>, Span)>),
    Name(Vec<(Option<String>, Span)>),
    Number(Vec<(Option<Number>, Span)>),
}
impl Attach {
    pub fn parse(input: &[Token]) -> Result<Attach, Box<SleighError>> {
        let (_eof, (src, (fields, meaning))) = pair(
            this_ident("attach"),
            cut(terminated(
                alt((
                    Attach::attach_lists("variables", map(registerlist, Meaning::Variable)),
                    Attach::attach_lists("names", map(stringlist, Meaning::Name)),
                    Attach::attach_lists("values", map(numberlist, Meaning::Number)),
                )),
                pair(tag!(";"), eof),
            )),
        )(input)?;
        Ok(Attach {
            src: src.clone(),
            fields,
            meaning,
        })
    }
    fn attach_lists<'a, O, E>(
        name: &'a str,
        element: E,
    ) -> impl FnMut(&'a [Token]) -> IResult<&'a [Token], (Vec<(String, Span)>, O), Box<SleighError>>
    where
        E: FnMut(&'a [Token]) -> IResult<&'a [Token], O, Box<SleighError>>,
    {
        preceded(this_ident(name), pair(fieldlist, element))
    }
}