pub mod ast;
pub mod expr;
pub mod interpolation;
pub mod lexer;
pub mod markup;
pub(crate) mod parser;
pub mod program;
pub(crate) mod validate;
pub use ast::{BinOp, Expr, IfBranch, LineVariant, Node, OptionItem, Stmt, TextSegment, UnOp};
pub use lexer::{Spanned, Token, tokenise};
pub use program::{Program, VariableDecl};
pub use validate::validate;
use crate::error::Result;
pub fn compile(source: &str) -> Result<Program> {
compile_many(&[("<source>", source)])
}
pub fn compile_many(sources: &[(&str, &str)]) -> Result<Program> {
let mut all_nodes = Vec::new();
for (name, source) in sources {
if source.trim().is_empty() {
return Err(crate::error::DialogueError::Validation(format!(
"source is empty ({name})"
)));
}
let nodes = parser::parse(name, source)?;
all_nodes.extend(nodes);
}
let prog = Program::from_nodes(all_nodes)?;
if prog.node_titles().next().is_none() {
return Err(crate::error::DialogueError::Validation(
"no nodes in source".into(),
));
}
validate(&prog)?;
Ok(prog)
}