use crate::preprocessor::token::Token;
use crate::preprocessor::FilePreProcessor;
use crate::syntax::parser::{ident, Parser};
use crate::{SleighError, Span, DISABLE_EXECUTION_PARSING};
use nom::branch::alt;
use nom::combinator::{cut, eof, map, opt, value};
use nom::sequence::{delimited, tuple};
use super::disassembly::Disassembly;
use super::display::Display;
use super::execution::Execution;
use super::pattern::Pattern;
#[derive(Clone, Debug)]
pub struct Constructor {
pub src: Span,
pub table_name: String,
pub display: Display,
pub pattern: Pattern,
pub disassembly: Option<Disassembly>,
pub execution: Option<Execution>,
}
impl Constructor {
pub fn table_name(&self) -> &str {
&self.table_name
}
pub fn parse(
input: &mut FilePreProcessor,
buf: &mut Vec<Token>,
) -> Result<Self, Box<SleighError>> {
input.parse_until(buf, |x| x.token_type == token_type!(":"))?;
let (_eof, ((table_name, table_src), _, _)) = tuple((ident, tag!(":"), eof))(buf)?;
let table_src = table_src.clone();
buf.clear();
Self::parse_table(input, buf, table_name, table_src)
}
pub fn parse_table(
input: &mut FilePreProcessor,
buf: &mut Vec<Token>,
table_name: String,
src: Span,
) -> Result<Self, Box<SleighError>> {
let display = Display::parse(input)?;
input.parse_until(buf, |token| {
matches!(&token.token_type, token_type!("}") | token_type!("unimpl"))
})?;
let (_eof, (pattern, disassembly, execution)) = tuple((
cut(Pattern::parse),
opt(delimited(tag!("["), Disassembly::parse, tag!("]"))),
cut(alt((
value(None, tag!("unimpl")),
delimited(tag!("{"), map(Execution::parse, Option::Some), tag!("}")),
))),
))(buf)?;
let execution = if DISABLE_EXECUTION_PARSING {
None
} else {
execution
};
Ok(Self {
src,
table_name,
display,
pattern,
execution,
disassembly,
})
}
}