Skip to main content

devalang_wasm/language/preprocessor/loader/
mod.rs

1use crate::language::syntax::ast::{Statement, StatementKind, Value};
2use crate::language::syntax::parser::driver::SimpleParser;
3/// Module loader - handles file loading and module dependencies
4use anyhow::{Result, anyhow};
5use std::collections::HashMap;
6use std::path::Path;
7
8/// Load and parse a module from a file path.
9pub fn load_module_from_path(path: &Path) -> Result<Vec<Statement>> {
10    SimpleParser::parse_file(path)
11}
12
13/// Inject exported variables into a destination variable map.
14pub fn inject_dependencies(
15    exports: &ModuleExports,
16    destination: &mut HashMap<String, Value>,
17) -> Result<()> {
18    for (name, value) in &exports.variables {
19        if destination.insert(name.clone(), value.clone()).is_some() {
20            return Err(anyhow!("Duplicate dependency '{}'", name));
21        }
22    }
23
24    Ok(())
25}
26
27/// Read a module file and return a map of exported variable names -> Value
28pub struct ModuleExports {
29    pub variables: HashMap<String, Value>,
30    pub groups: HashMap<String, Vec<Statement>>,
31    pub patterns: HashMap<String, Statement>,
32}
33
34pub fn load_module_exports(path: &Path) -> Result<ModuleExports> {
35    let mut variables: HashMap<String, Value> = HashMap::new();
36    let mut groups: HashMap<String, Vec<Statement>> = HashMap::new();
37    let mut patterns: HashMap<String, Statement> = HashMap::new();
38
39    let stmts = SimpleParser::parse_file(path)?;
40
41    // collect exported names
42    let mut exports: Vec<String> = Vec::new();
43    for s in &stmts {
44        if let StatementKind::Export { names, .. } = &s.kind {
45            for n in names {
46                exports.push(n.clone());
47            }
48        }
49    }
50
51    for s in &stmts {
52        match &s.kind {
53            StatementKind::Let { name, value }
54            | StatementKind::Var { name, value }
55            | StatementKind::Const { name, value } => {
56                if exports.contains(name) {
57                    if let Some(v) = value {
58                        variables.insert(name.clone(), v.clone());
59                    }
60                }
61            }
62            StatementKind::Group {
63                name,
64                body,
65                duration: _,
66            } => {
67                if exports.contains(name) {
68                    groups.insert(name.clone(), body.clone());
69                }
70            }
71            StatementKind::Pattern { name, .. } => {
72                if exports.contains(name) {
73                    patterns.insert(name.clone(), s.clone());
74                }
75            }
76            _ => {}
77        }
78    }
79
80    Ok(ModuleExports {
81        variables,
82        groups,
83        patterns,
84    })
85}