1pub(crate) mod builtins;
6pub(crate) mod common;
7#[cfg(feature = "runtime")]
8pub mod dafny;
9#[cfg(feature = "runtime")]
10pub mod lean;
11#[cfg(feature = "runtime")]
12pub mod rust;
13#[cfg(feature = "wasm-compile")]
14pub mod wasm;
15
16use std::collections::{HashMap, HashSet};
17
18use crate::ast::{FnDef, TopLevel, TypeDef};
19use crate::types::checker::TypeCheckResult;
20
21pub struct ModuleInfo {
23 pub prefix: String,
25 pub depends: Vec<String>,
27 pub type_defs: Vec<TypeDef>,
29 pub fn_defs: Vec<FnDef>,
31}
32
33pub struct CodegenContext {
35 pub items: Vec<TopLevel>,
37 pub fn_sigs: HashMap<String, (Vec<crate::types::Type>, crate::types::Type, Vec<String>)>,
39 pub memo_fns: HashSet<String>,
41 pub memo_safe_types: HashSet<String>,
43 pub type_defs: Vec<TypeDef>,
45 pub fn_defs: Vec<FnDef>,
47 pub project_name: String,
49 pub modules: Vec<ModuleInfo>,
51 pub module_prefixes: HashSet<String>,
53 #[cfg(feature = "runtime")]
55 pub policy: Option<crate::config::ProjectConfig>,
56 pub emit_replay_runtime: bool,
58 pub runtime_policy_from_env: bool,
60 pub guest_entry: Option<String>,
62 pub emit_self_host_support: bool,
64 pub extra_fn_defs: Vec<FnDef>,
68 pub mutual_tco_members: HashSet<String>,
71}
72
73pub struct ProjectOutput {
75 pub files: Vec<(String, String)>,
77}
78
79pub fn build_context(
81 items: Vec<TopLevel>,
82 tc_result: &TypeCheckResult,
83 memo_fns: HashSet<String>,
84 project_name: String,
85 modules: Vec<ModuleInfo>,
86) -> CodegenContext {
87 let type_defs: Vec<TypeDef> = items
88 .iter()
89 .filter_map(|item| {
90 if let TopLevel::TypeDef(td) = item {
91 Some(td.clone())
92 } else {
93 None
94 }
95 })
96 .collect();
97
98 let fn_defs: Vec<FnDef> = items
99 .iter()
100 .filter_map(|item| {
101 if let TopLevel::FnDef(fd) = item {
102 Some(fd.clone())
103 } else {
104 None
105 }
106 })
107 .collect();
108
109 let module_prefixes: HashSet<String> = modules.iter().map(|m| m.prefix.clone()).collect();
110
111 let mut mutual_tco_members = HashSet::new();
113 {
114 let entry_fns: Vec<&FnDef> = fn_defs.iter().filter(|fd| fd.name != "main").collect();
116 for group in crate::call_graph::tailcall_scc_components(&entry_fns) {
117 for fd in &group {
118 mutual_tco_members.insert(fd.name.clone());
119 }
120 }
121 for module in &modules {
123 let mod_fns: Vec<&FnDef> = module.fn_defs.iter().collect();
124 for group in crate::call_graph::tailcall_scc_components(&mod_fns) {
125 for fd in &group {
126 mutual_tco_members.insert(fd.name.clone());
127 }
128 }
129 }
130 }
131
132 CodegenContext {
133 items,
134 fn_sigs: tc_result.fn_sigs.clone(),
135 memo_fns,
136 memo_safe_types: tc_result.memo_safe_types.clone(),
137 type_defs,
138 fn_defs,
139 project_name,
140 modules,
141 module_prefixes,
142 #[cfg(feature = "runtime")]
143 policy: None,
144 emit_replay_runtime: false,
145 runtime_policy_from_env: false,
146 guest_entry: None,
147 emit_self_host_support: false,
148 extra_fn_defs: Vec::new(),
149 mutual_tco_members,
150 }
151}