bubbles/compiler/mod.rs
1//! Compilation pipeline: source text → [`Program`].
2
3pub mod ast;
4pub mod expr;
5pub mod interpolation;
6pub mod lexer;
7pub mod markup;
8pub(crate) mod parser;
9pub mod program;
10pub(crate) mod validate;
11
12pub use ast::{BinOp, Expr, IfBranch, LineVariant, Node, OptionItem, Stmt, TextSegment, UnOp};
13pub use lexer::{Spanned, Token, tokenise};
14pub use program::{Program, VariableDecl};
15pub use validate::validate;
16
17use crate::error::Result;
18
19/// Compiles a single `.bub` source string into a [`Program`].
20///
21/// Jump and detour targets are validated immediately; a
22/// [`crate::DialogueError::Validation`] error is returned for any reference
23/// to a node that does not exist in the compiled program.
24///
25/// For compiling multiple source files together use [`compile_many`].
26///
27/// # Errors
28/// Returns [`crate::DialogueError::Parse`] if the source is malformed,
29/// [`crate::DialogueError::DuplicateNode`] if two nodes share a title without
30/// `when:` grouping conditions, or [`crate::DialogueError::Validation`] if a
31/// jump or detour target cannot be resolved.
32pub fn compile(source: &str) -> Result<Program> {
33 compile_many(&[("<source>", source)])
34}
35
36/// Compiles multiple named `.bub` sources into a single [`Program`].
37///
38/// Sources are merged in order; duplicate node titles without `when:` grouping
39/// conditions cause a [`crate::DialogueError::DuplicateNode`] error. Jump and
40/// detour targets are validated across all sources after merging.
41///
42/// # Errors
43/// Returns a [`crate::DialogueError`] variant on any parse, merge, or
44/// validation failure.
45pub fn compile_many(sources: &[(&str, &str)]) -> Result<Program> {
46 let mut all_nodes = Vec::new();
47 for (name, source) in sources {
48 let nodes = parser::parse(name, source)?;
49 all_nodes.extend(nodes);
50 }
51 let prog = Program::from_nodes(all_nodes)?;
52 validate(&prog)?;
53 Ok(prog)
54}