use crate::Error;
use crate::ast::*;
use crate::typechecking::TypeInfo;
use crate::util::SymbolGen;
use std::sync::Arc;
pub trait CommandMacro: Send + Sync {
fn transform(
&self,
command: Command,
symbol_gen: &mut SymbolGen,
type_info: &TypeInfo,
) -> Result<Vec<Command>, Error>;
}
#[derive(Default, Clone)]
pub struct CommandMacroRegistry {
macros: Vec<Arc<dyn CommandMacro>>,
}
impl CommandMacroRegistry {
pub fn new() -> Self {
Self::default()
}
pub fn register(&mut self, macro_impl: Arc<dyn CommandMacro>) {
self.macros.push(macro_impl);
}
pub fn apply(
&self,
command: Command,
symbol_gen: &mut SymbolGen,
type_info: &TypeInfo,
) -> Result<Vec<Command>, Error> {
let mut commands = vec![command];
for macro_impl in &self.macros {
let mut next_commands = Vec::new();
for cmd in commands {
next_commands.extend(macro_impl.transform(cmd, symbol_gen, type_info)?);
}
commands = next_commands;
}
Ok(commands)
}
}