devalang_core/core/preprocessor/resolver/
synth.rs

1use crate::core::{
2    parser::statement::{Statement, StatementKind},
3    preprocessor::{module::Module, resolver::driver::resolve_statement},
4    store::global::GlobalStore,
5};
6use devalang_types::Value;
7use devalang_utils::logger::{LogLevel, Logger};
8
9pub fn resolve_synth(
10    stmt: &Statement,
11    module: &Module,
12    path: &str,
13    global_store: &mut GlobalStore,
14) -> Statement {
15    let logger = Logger::new();
16
17    let Value::Map(synth_map) = &stmt.value else {
18        return type_error(
19            &logger,
20            module,
21            stmt,
22            "Expected a map in synth statement".to_string(),
23        );
24    };
25
26    let mut resolved_map = synth_map.clone();
27
28    if let Some(Value::Block(body)) = synth_map.get("body") {
29        let resolved_body = body
30            .iter()
31            .map(|s| resolve_statement(s, module, path, global_store))
32            .collect::<Vec<_>>();
33        resolved_map.insert("body".to_string(), Value::Block(resolved_body));
34    } else {
35        logger.log_message(LogLevel::Warning, "synth without a body");
36    }
37
38    Statement {
39        kind: StatementKind::Synth,
40        value: Value::Map(resolved_map),
41        ..stmt.clone()
42    }
43}
44
45fn type_error(logger: &Logger, module: &Module, stmt: &Statement, message: String) -> Statement {
46    let stacktrace = format!("{}:{}:{}", module.path, stmt.line, stmt.column);
47    logger.log_error_with_stacktrace(&message, &stacktrace);
48
49    Statement {
50        kind: StatementKind::Error { message },
51        value: Value::Null,
52        ..stmt.clone()
53    }
54}