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::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 let Some(parse_module) = parsed_modules.get_parsed_module(module_path) {
78            let process_span = span!(Level::TRACE, "analyze mod", path = ?module_path);
79            let enter_ = process_span.enter();
80
81            let (analyzed_symbol_table, maybe_expression) = analyze_module(
82                state,
83                default_lookup_symbol_table,
84                modules,
85                &core_symbol_table,
86                source_map,
87                module_path,
88                parse_module,
89            )?;
90            let analyzed_module = Module::new(analyzed_symbol_table, maybe_expression);
91            modules.add(analyzed_module.into());
92        } else {
93            panic!("could not load")
94        }
95    }
96    Ok(())
97}
98
99pub fn compile_and_analyze_all_modules(
100    module_path: &[String],
101    resolved_program: &mut Program,
102    source_map: &mut SourceMap,
103    core_symbol_table: SymbolTableRef,
104) -> Result<(), LoaderErr> {
105    let mut dependency_parser = DependencyParser::new();
106
107    let module_paths_in_order =
108        parse_local_modules_and_get_order(module_path.to_vec(), &mut dependency_parser, source_map)
109            .unwrap(); // TODO: FIX THIS
110
111    analyze_modules_in_order(
112        &mut resolved_program.state,
113        &resolved_program.default_symbol_table,
114        &mut resolved_program.modules,
115        core_symbol_table,
116        source_map,
117        &module_paths_in_order,
118        &dependency_parser,
119    )?;
120
121    Ok(())
122}