bubbles/compiler/
validate.rs1use crate::compiler::ast::Stmt;
4use crate::compiler::program::Program;
5use crate::error::{DialogueError, Result};
6
7pub fn validate(program: &Program) -> Result<()> {
12 for variants in program.nodes.values() {
13 for node in variants {
14 validate_stmts(node.body.as_ref(), program)?;
15 }
16 }
17 Ok(())
18}
19
20fn validate_stmts(stmts: &[Stmt], program: &Program) -> Result<()> {
21 for stmt in stmts {
22 match stmt {
23 Stmt::Jump(target) | Stmt::Detour(target) if !program.node_exists(target) => {
24 return Err(DialogueError::Validation(format!(
25 "reference to unknown node '{target}'"
26 )));
27 }
28 Stmt::If {
29 branches,
30 else_body,
31 } => {
32 for b in branches {
33 validate_stmts(&b.body, program)?;
34 }
35 validate_stmts(else_body, program)?;
36 }
37 Stmt::Once {
38 body, else_body, ..
39 } => {
40 validate_stmts(body, program)?;
41 validate_stmts(else_body, program)?;
42 }
43 Stmt::Options(items) => {
44 for item in items {
45 validate_stmts(&item.body, program)?;
46 }
47 }
48 _ => {}
49 }
50 }
51 Ok(())
52}
53
54#[cfg(test)]
55#[path = "validate_tests.rs"]
56mod tests;