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