swamp_script_eval_loader/
lib.rs1use swamp_script_analyzer::prelude::{Error, Program};
6use swamp_script_analyzer::{Analyzer, AutoUseModules, TypeContext, TypeContextScope};
7use swamp_script_dep_loader::{
8 DepLoaderError, DependencyParser, ParsedAstModule, parse_local_modules_and_get_order,
9};
10use swamp_script_semantic::modules::Module;
11use swamp_script_semantic::prelude::Modules;
12use swamp_script_semantic::symtbl::SymbolTable;
13use swamp_script_semantic::{Expression, ProgramState};
14use swamp_script_source_map::SourceMap;
15
16#[derive(Debug)]
17pub enum EvalLoaderError {
18 DepLoaderError(DepLoaderError),
19 AnalyzerError(Error),
20}
21
22impl From<DepLoaderError> for EvalLoaderError {
23 fn from(err: DepLoaderError) -> Self {
24 Self::DepLoaderError(err)
25 }
26}
27
28impl From<Error> for EvalLoaderError {
29 fn from(err: Error) -> Self {
30 Self::AnalyzerError(err)
31 }
32}
33
34pub fn analyze_module(
35 state: &mut ProgramState,
36 auto_use_modules: &AutoUseModules,
37 modules: &mut Modules,
38 source_map: &SourceMap,
39 ast_module: &ParsedAstModule,
40) -> Result<(SymbolTable, Option<Expression>), Error> {
41 let mut resolver = Analyzer::new(state, modules, source_map, ast_module.file_id);
42 if !auto_use_modules.modules.is_empty() {
43 let target = &mut resolver.shared.lookup_table;
44 for symbol_table in &auto_use_modules.modules {
45 for (name, symbol) in symbol_table.symbols() {
46 target.add_symbol(name, symbol.clone())?;
47 }
48 }
49 }
50
51 let outside_context = TypeContext::new(None, None, TypeContextScope::ArgumentOrOutsideFunction);
52 let statements = {
53 for ast_def in ast_module.ast_module.definitions() {
54 resolver.analyze_definition(ast_def)?;
55 }
56
57 let maybe_resolved_expression = if let Some(expr) = ast_module.ast_module.expression() {
58 Some(resolver.analyze_expression(expr, &outside_context)?)
59 } else {
60 None
61 };
62 maybe_resolved_expression
63 };
64
65 Ok((resolver.shared.definition_table, statements))
66}
67
68pub fn analyze_modules_in_order(
69 state: &mut ProgramState,
70 auto_use: &AutoUseModules,
71 modules: &mut Modules,
72 source_map: &SourceMap,
73 module_paths_in_order: &[Vec<String>],
74 parsed_modules: &DependencyParser,
75) -> Result<(), Error> {
76 for module_path in module_paths_in_order {
77 if let Some(parse_module) = parsed_modules.get_parsed_module(module_path) {
78 let (analyzed_symbol_table, maybe_expression) =
79 analyze_module(state, auto_use, modules, source_map, parse_module)?;
80 let analyzed_module = Module::new(module_path, analyzed_symbol_table, maybe_expression);
81 modules.add(analyzed_module.into());
82 } else {
83 panic!("could not load")
84 }
85 }
86 Ok(())
87}
88
89pub fn compile_and_analyze_all_modules(
90 module_path: &[String],
91 resolved_program: &mut Program,
92 source_map: &mut SourceMap,
93) -> Result<(), EvalLoaderError> {
94 let mut dependency_parser = DependencyParser::new();
95
96 let module_paths_in_order = parse_local_modules_and_get_order(
97 module_path.to_vec(),
98 &mut dependency_parser,
99 source_map,
100 )?;
101
102 analyze_modules_in_order(
103 &mut resolved_program.state,
104 &resolved_program.auto_use_modules,
105 &mut resolved_program.modules,
106 source_map,
107 &module_paths_in_order,
108 &dependency_parser,
109 )?;
110
111 Ok(())
112}