devalang_core/core/preprocessor/
processor.rs

1use std::{collections::HashMap, path::Path};
2
3use crate::core::{
4    parser::statement::StatementKind,
5    preprocessor::loader::ModuleLoader,
6    store::global::GlobalStore,
7    utils::path::{normalize_path, resolve_relative_path},
8};
9use devalang_types::Value;
10
11pub fn process_modules(_module_loader: &ModuleLoader, global_store: &mut GlobalStore) {
12    for module in global_store.modules.values_mut() {
13        for stmt in &module.statements {
14            match &stmt.kind {
15                StatementKind::Let { name } => {
16                    if let Value::Null = stmt.value {
17                        eprintln!("❌ Variable '{}' is declared but not initialized.", name);
18
19                        module.variable_table.variables.insert(
20                            name.clone(),
21                            Value::StatementKind(Box::new(stmt.kind.clone())),
22                        );
23
24                        continue;
25                    }
26
27                    if module.variable_table.get(name).is_some() {
28                        eprintln!("❌ Variable '{}' is already defined in this scope.", name);
29                        continue;
30                    }
31
32                    if let Some(module_variable) = module.variable_table.variables.get(name) {
33                        eprintln!(
34                            "❌ Variable '{}' is already defined globally with value: {:?}",
35                            name, module_variable
36                        );
37                        continue;
38                    }
39
40                    module
41                        .variable_table
42                        .variables
43                        .insert(name.clone(), stmt.value.clone());
44                }
45
46                StatementKind::Load { source, alias } => {
47                    let module_dir = Path::new(&module.path).parent().unwrap_or(Path::new(""));
48
49                    let resolved_path = normalize_path(module_dir.join(source));
50
51                    module
52                        .variable_table
53                        .variables
54                        .insert(alias.clone(), Value::Sample(resolved_path));
55                }
56
57                StatementKind::Export { names, source: _ } => {
58                    for name in names {
59                        if let Some(val) = module.variable_table.get(name) {
60                            module.export_table.add_export(name.clone(), val.clone());
61                        }
62                    }
63                }
64
65                StatementKind::Import { names, source } => {
66                    let resolved = resolve_relative_path(&module.path, source);
67                    for name in names {
68                        module
69                            .import_table
70                            .add_import(name.clone(), Value::String(resolved.clone()));
71                    }
72                }
73
74                StatementKind::Group => {
75                    if let Value::Map(map) = &stmt.value {
76                        if let (Some(Value::String(name)), Some(Value::Block(body))) =
77                            (map.get("identifier"), map.get("body"))
78                        {
79                            let mut stored_map = HashMap::new();
80
81                            stored_map
82                                .insert("identifier".to_string(), Value::String(name.clone()));
83
84                            stored_map.insert("body".to_string(), Value::Block(body.clone()));
85
86                            module
87                                .variable_table
88                                .set(name.to_string(), Value::Map(stored_map));
89                        } else {
90                            eprintln!("❌ Invalid group definition: {:?}", stmt.value);
91                        }
92                    }
93                }
94
95                _ => {}
96            }
97        }
98    }
99}