mod exec;
mod op;
mod parser;
#[cfg(test)]
mod tests;
mod value;
pub use value::Value;
#[macro_export]
macro_rules! expand {
($e:expr) => { $crate::expand::expand($e, &[]) };
($e:expr, $($rest:tt)*) => { $crate::expand::expand($e, $crate::expand_args!($($rest)*)) };
}
#[doc(hidden)]
#[macro_export]
macro_rules! expand_args {
($($e:expr),+ $(,)?) => { &[$($crate::expand::Value::from($e)),+] };
}
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum Error {
ParseFailed,
DivisionByZero,
InvalidOperandType,
StackUnderflow,
ValueOutOfRange,
BrokenConditional,
}
#[doc(hidden)]
pub fn expand(str: impl AsRef<[u8]>, args: &[Value]) -> Result<Vec<u8>, Error> {
expand_inner(str.as_ref(), args)
}
fn expand_inner(str: &[u8], args: &[Value]) -> Result<Vec<u8>, Error> {
let ops = parser::parse(str)?;
let mut state = exec::State::new(args);
let mut out = Vec::with_capacity(str.len());
for op in ops {
state.execute(op, &mut out)?;
}
state.execute(op::Op::End, &mut out)?;
out.shrink_to_fit();
Ok(out)
}