swamp_script_eval_loader/
lib.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/script
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5use swamp_script_analyzer::Analyzer;
6use swamp_script_analyzer::prelude::{Error, Program};
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::{InternalMainExpression, 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<InternalMainExpression>), 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 statements = {
50        for ast_def in ast_module.ast_module.definitions() {
51            resolver.analyze_definition(ast_def)?;
52        }
53
54        let maybe_resolved_expression = if let Some(expr) = ast_module.ast_module.expression() {
55            let internal_main = resolver.analyze_main_expression(expr)?;
56            Some(internal_main)
57        } else {
58            None
59        };
60        maybe_resolved_expression
61    };
62
63    Ok((resolver.shared.definition_table, statements))
64}
65
66/// # Errors
67///
68pub fn analyze_modules_in_order(
69    state: &mut ProgramState,
70    default_lookup_symbol_table: &SymbolTable,
71    modules: &mut Modules,
72    core_symbol_table: SymbolTableRef,
73    source_map: &SourceMap,
74    module_paths_in_order: &[Vec<String>],
75    parsed_modules: &DependencyParser,
76) -> Result<(), LoaderErr> {
77    debug!(?module_paths_in_order, "analyzing modules in order");
78    for module_path in module_paths_in_order {
79        if *module_path == ["core"] {
80            continue;
81        }
82        if let Some(parse_module) = parsed_modules.get_parsed_module(module_path) {
83            let process_span = span!(Level::TRACE, "analyze mod", path = ?module_path);
84            let _enter = process_span.enter();
85
86            let (analyzed_symbol_table, maybe_expression) = analyze_module(
87                state,
88                default_lookup_symbol_table,
89                modules,
90                &core_symbol_table,
91                source_map,
92                module_path,
93                parse_module,
94            )?;
95            let analyzed_module = Module::new(analyzed_symbol_table, maybe_expression);
96            modules.add(analyzed_module.into());
97        } else {
98            panic!("could not load")
99        }
100    }
101    Ok(())
102}
103
104pub fn compile_and_analyze_all_modules(
105    module_path: &[String],
106    resolved_program: &mut Program,
107    source_map: &mut SourceMap,
108    core_symbol_table: SymbolTableRef,
109) -> Result<(), LoaderErr> {
110    let mut dependency_parser = DependencyParser::new();
111
112    let module_paths_in_order =
113        parse_local_modules_and_get_order(module_path.to_vec(), &mut dependency_parser, source_map)
114            .unwrap(); // TODO: FIX THIS
115
116    analyze_modules_in_order(
117        &mut resolved_program.state,
118        &resolved_program.default_symbol_table,
119        &mut resolved_program.modules,
120        core_symbol_table,
121        source_map,
122        &module_paths_in_order,
123        &dependency_parser,
124    )?;
125
126    Ok(())
127}