Skip to main content

aver/codegen/
mod.rs

1/// Aver → target language transpilation.
2///
3/// The codegen module transforms a type-checked Aver AST into source code
4/// for a target language. Current backends: Rust deployment and Lean proof export.
5pub(crate) mod common;
6pub mod lean;
7pub mod rust;
8
9use std::collections::{HashMap, HashSet};
10
11use crate::ast::{FnDef, TopLevel, TypeDef};
12use crate::types::checker::TypeCheckResult;
13
14/// Information about a dependent module loaded for codegen.
15pub struct ModuleInfo {
16    /// Qualified module path, e.g. "Models.User".
17    pub prefix: String,
18    /// Direct `depends [...]` entries from the source module.
19    pub depends: Vec<String>,
20    /// Type definitions from the module.
21    pub type_defs: Vec<TypeDef>,
22    /// Function definitions from the module (excluding `main`).
23    pub fn_defs: Vec<FnDef>,
24}
25
26/// Collected context from the Aver program, shared across all backends.
27pub struct CodegenContext {
28    /// All top-level items (post-TCO transform, post-typecheck).
29    pub items: Vec<TopLevel>,
30    /// Function signatures: name → (param_types, return_type, effects).
31    pub fn_sigs: HashMap<String, (Vec<crate::types::Type>, crate::types::Type, Vec<String>)>,
32    /// Functions eligible for auto-memoization.
33    pub memo_fns: HashSet<String>,
34    /// Set of type names whose values are memo-safe.
35    pub memo_safe_types: HashSet<String>,
36    /// User-defined type definitions (for struct/enum generation).
37    pub type_defs: Vec<TypeDef>,
38    /// User-defined function definitions.
39    pub fn_defs: Vec<FnDef>,
40    /// Project/binary name.
41    pub project_name: String,
42    /// Dependent modules loaded for inlining.
43    pub modules: Vec<ModuleInfo>,
44    /// Set of module prefixes for qualified name resolution (e.g. "Models.User").
45    pub module_prefixes: HashSet<String>,
46    /// Runtime policy from `aver.toml` (baked into generated code).
47    pub policy: Option<crate::config::ProjectConfig>,
48}
49
50/// Output files from a codegen backend.
51pub struct ProjectOutput {
52    /// Files to write: (relative_path, content).
53    pub files: Vec<(String, String)>,
54}
55
56/// Build a CodegenContext from parsed + type-checked items.
57pub fn build_context(
58    items: Vec<TopLevel>,
59    tc_result: &TypeCheckResult,
60    memo_fns: HashSet<String>,
61    project_name: String,
62    modules: Vec<ModuleInfo>,
63) -> CodegenContext {
64    let type_defs: Vec<TypeDef> = items
65        .iter()
66        .filter_map(|item| {
67            if let TopLevel::TypeDef(td) = item {
68                Some(td.clone())
69            } else {
70                None
71            }
72        })
73        .collect();
74
75    let fn_defs: Vec<FnDef> = items
76        .iter()
77        .filter_map(|item| {
78            if let TopLevel::FnDef(fd) = item {
79                Some(fd.clone())
80            } else {
81                None
82            }
83        })
84        .collect();
85
86    let module_prefixes: HashSet<String> = modules.iter().map(|m| m.prefix.clone()).collect();
87
88    CodegenContext {
89        items,
90        fn_sigs: tc_result.fn_sigs.clone(),
91        memo_fns,
92        memo_safe_types: tc_result.memo_safe_types.clone(),
93        type_defs,
94        fn_defs,
95        project_name,
96        modules,
97        module_prefixes,
98        policy: None,
99    }
100}