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