vicis 0.1.0

Manipulate LLVM-IR in Pure Rust
Documentation
use super::super::types::{TypeId, Types};
use crate::ir::util::spaces;
use nom::{
    branch::alt,
    bytes::complete::tag,
    character::complete::{char, digit1},
    combinator::map,
    error::VerboseError,
    multi::many0,
    sequence::preceded,
    IResult,
};

pub fn parse<'a>(
    source: &'a str,
    types: &Types,
) -> IResult<&'a str, TypeId, VerboseError<&'a str>> {
    let (source, mut base) = if let Ok((source, _)) = preceded(spaces, char('['))(source) {
        parse_array(source, types)?
    } else {
        preceded(
            spaces,
            alt((
                map(tag("void"), |_| types.base().void()),
                map(tag("i1"), |_| types.base().i1()),
                map(tag("i8"), |_| types.base().i8()),
                map(tag("i32"), |_| types.base().i32()),
                map(tag("i64"), |_| types.base().i64()),
            )),
        )(source)?
    };

    let (source, ptrs) = many0(preceded(spaces, char('*')))(source)?;
    for _ in 0..ptrs.len() {
        base = types.base_mut().pointer(base);
    }
    Ok((source, base))
}

pub fn parse_array<'a>(
    source: &'a str,
    types: &Types,
) -> IResult<&'a str, TypeId, VerboseError<&'a str>> {
    let (source, n) = preceded(spaces, digit1)(source)?;
    let (source, _) = preceded(spaces, char('x'))(source)?;
    let (source, ty) = parse(source, types)?;
    let (source, _) = preceded(spaces, char(']'))(source)?;
    let ary_ty = types.base_mut().array(ty, n.parse::<u32>().unwrap());
    Ok((source, ary_ty))
}