rsleigh 0.4.2

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

use crate::preprocessor::token::Token;
use crate::syntax::parser::{ident, this_ident};
use crate::syntax::BitRangeLsbLen;
use crate::{SleighError, Span};

#[derive(Clone, Debug)]
pub struct BitRangeDef {
    ranges: Vec<VarnodeField>,
}

impl BitRangeDef {
    pub fn parse(input: &[Token]) -> IResult<&[Token], Self, Box<SleighError>> {
        map(
            preceded(this_ident("bitrange"), cut(many0(VarnodeField::parse))),
            |ranges| BitRangeDef { ranges },
        )(input)
    }
}

impl IntoIterator for BitRangeDef {
    type Item = VarnodeField;
    type IntoIter = std::vec::IntoIter<VarnodeField>;

    fn into_iter(self) -> Self::IntoIter {
        self.ranges.into_iter()
    }
}

#[derive(Clone, Debug)]
pub struct VarnodeField {
    pub src: Span,
    pub name: String,
    pub varnode_name: String,
    pub varnode_name_span: Span,
    pub range: BitRangeLsbLen,
}

impl VarnodeField {
    fn parse(input: &[Token]) -> IResult<&[Token], Self, Box<SleighError>> {
        map(
            tuple((terminated(ident, tag!("=")), ident, BitRangeLsbLen::parse)),
            |((name, name_span), (varnode_name, varnode_name_span), range)| VarnodeField {
                name,
                src: name_span.clone(),
                varnode_name,
                varnode_name_span: varnode_name_span.clone(),
                range,
            },
        )(input)
    }
}