1use logicaffeine_compile::ast::{Expr, Stmt, TypeExpr};
10use logicaffeine_compile::drs::WorldState;
11use logicaffeine_compile::{Arena, AstContext, DiscoveryPass, Interner, Lexer, ParseError, Parser};
12
13pub fn with_program<R>(
20 source: &str,
21 optimize: bool,
22 f: impl FnOnce(&[Stmt], &Interner) -> R,
23) -> Result<R, ParseError> {
24 let mut interner = Interner::new();
25 let mut lexer = Lexer::new(source, &mut interner);
26 let tokens = lexer.tokenize();
27
28 let type_registry = {
29 let mut discovery = DiscoveryPass::new(&tokens, &mut interner);
30 discovery.run_full().types
31 };
32
33 let mut world_state = WorldState::new();
34 let expr_arena = Arena::new();
35 let term_arena = Arena::new();
36 let np_arena = Arena::new();
37 let sym_arena = Arena::new();
38 let role_arena = Arena::new();
39 let pp_arena = Arena::new();
40 let stmt_arena: Arena<Stmt> = Arena::new();
41 let imperative_expr_arena: Arena<Expr> = Arena::new();
42 let type_expr_arena: Arena<TypeExpr> = Arena::new();
43
44 let ast_ctx = AstContext::with_types(
45 &expr_arena,
46 &term_arena,
47 &np_arena,
48 &sym_arena,
49 &role_arena,
50 &pp_arena,
51 &stmt_arena,
52 &imperative_expr_arena,
53 &type_expr_arena,
54 );
55
56 let mut parser = Parser::new(tokens, &mut world_state, &mut interner, ast_ctx, type_registry);
57 let stmts = parser.parse_program()?;
58 drop(parser);
59
60 let stmts = if optimize {
61 logicaffeine_compile::optimize::optimize_program(
62 stmts,
63 &imperative_expr_arena,
64 &stmt_arena,
65 &mut interner,
66 &logicaffeine_compile::optimization::OptimizationConfig::from_env(),
67 )
68 } else {
69 stmts
70 };
71
72 Ok(f(&stmts, &interner))
73}