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        let logger = devalang_utils::logger::Logger::new();
14        use devalang_utils::logger::LogLevel;
15
16        for stmt in &module.statements {
17            match &stmt.kind {
18                StatementKind::Let { name } => {
19                    if let Value::Null = stmt.value {
20                        logger.log_message(
21                            LogLevel::Error,
22                            &format!("Variable '{}' is declared but not initialized.", name),
23                        );
24
25                        module.variable_table.variables.insert(
26                            name.clone(),
27                            Value::StatementKind(Box::new(stmt.kind.clone())),
28                        );
29
30                        continue;
31                    }
32
33                    if module.variable_table.get(name).is_some() {
34                        logger.log_message(
35                            LogLevel::Error,
36                            &format!("Variable '{}' is already defined in this scope.", name),
37                        );
38                        continue;
39                    }
40
41                    if let Some(module_variable) = module.variable_table.variables.get(name) {
42                        logger.log_message(
43                            LogLevel::Error,
44                            &format!(
45                                "Variable '{}' is already defined globally with value: {:?}",
46                                name, module_variable
47                            ),
48                        );
49                        continue;
50                    }
51
52                    module
53                        .variable_table
54                        .variables
55                        .insert(name.clone(), stmt.value.clone());
56                }
57
58                StatementKind::Load { source, alias } => {
59                    let module_dir = Path::new(&module.path).parent().unwrap_or(Path::new(""));
60
61                    let resolved_path = normalize_path(module_dir.join(source));
62
63                    module
64                        .variable_table
65                        .variables
66                        .insert(alias.clone(), Value::Sample(resolved_path));
67                }
68
69                StatementKind::Export { names, source: _ } => {
70                    for name in names {
71                        if let Some(val) = module.variable_table.get(name) {
72                            module.export_table.add_export(name.clone(), val.clone());
73                        }
74                    }
75                }
76
77                StatementKind::Import { names, source } => {
78                    let resolved = resolve_relative_path(&module.path, source);
79                    for name in names {
80                        module
81                            .import_table
82                            .add_import(name.clone(), Value::String(resolved.clone()));
83                    }
84                }
85
86                StatementKind::Group => {
87                    if let Value::Map(map) = &stmt.value {
88                        if let (Some(Value::String(name)), Some(Value::Block(body))) =
89                            (map.get("identifier"), map.get("body"))
90                        {
91                            let mut stored_map = HashMap::new();
92
93                            stored_map
94                                .insert("identifier".to_string(), Value::String(name.clone()));
95
96                            stored_map.insert("body".to_string(), Value::Block(body.clone()));
97
98                            module
99                                .variable_table
100                                .set(name.to_string(), Value::Map(stored_map));
101                        } else {
102                            logger.log_message(
103                                LogLevel::Error,
104                                &format!("Invalid group definition: {:?}", stmt.value),
105                            );
106                        }
107                    }
108                }
109
110                _ => {}
111            }
112        }
113    }
114}