pub(crate) mod builtin_helpers;
pub(crate) mod builtin_records;
pub(crate) mod builtins;
pub mod common;
#[cfg(feature = "runtime")]
pub mod dafny;
#[cfg(feature = "runtime")]
pub mod lean;
#[cfg(feature = "runtime")]
pub mod recursion;
#[cfg(feature = "runtime")]
pub mod rust;
#[cfg(feature = "wasm-compile")]
pub mod wasm;
use std::collections::{HashMap, HashSet};
use crate::ast::{FnDef, TopLevel, TypeDef};
use crate::types::checker::TypeCheckResult;
pub struct ModuleInfo {
pub prefix: String,
pub depends: Vec<String>,
pub type_defs: Vec<TypeDef>,
pub fn_defs: Vec<FnDef>,
}
pub struct CodegenContext {
pub items: Vec<TopLevel>,
pub fn_sigs: HashMap<String, (Vec<crate::types::Type>, crate::types::Type, Vec<String>)>,
pub memo_fns: HashSet<String>,
pub memo_safe_types: HashSet<String>,
pub type_defs: Vec<TypeDef>,
pub fn_defs: Vec<FnDef>,
pub project_name: String,
pub modules: Vec<ModuleInfo>,
pub module_prefixes: HashSet<String>,
#[cfg(feature = "runtime")]
pub policy: Option<crate::config::ProjectConfig>,
pub emit_replay_runtime: bool,
pub runtime_policy_from_env: bool,
pub guest_entry: Option<String>,
pub emit_self_host_support: bool,
pub extra_fn_defs: Vec<FnDef>,
pub mutual_tco_members: HashSet<String>,
}
pub struct ProjectOutput {
pub files: Vec<(String, String)>,
}
pub fn build_context(
items: Vec<TopLevel>,
tc_result: &TypeCheckResult,
memo_fns: HashSet<String>,
project_name: String,
modules: Vec<ModuleInfo>,
) -> CodegenContext {
let type_defs: Vec<TypeDef> = items
.iter()
.filter_map(|item| {
if let TopLevel::TypeDef(td) = item {
Some(td.clone())
} else {
None
}
})
.collect();
let fn_defs: Vec<FnDef> = items
.iter()
.filter_map(|item| {
if let TopLevel::FnDef(fd) = item {
Some(fd.clone())
} else {
None
}
})
.collect();
let module_prefixes: HashSet<String> = modules.iter().map(|m| m.prefix.clone()).collect();
let mut mutual_tco_members = HashSet::new();
{
let entry_fns: Vec<&FnDef> = fn_defs.iter().filter(|fd| fd.name != "main").collect();
for group in crate::call_graph::tailcall_scc_components(&entry_fns) {
for fd in &group {
mutual_tco_members.insert(fd.name.clone());
}
}
for module in &modules {
let mod_fns: Vec<&FnDef> = module.fn_defs.iter().collect();
for group in crate::call_graph::tailcall_scc_components(&mod_fns) {
for fd in &group {
mutual_tco_members.insert(fd.name.clone());
}
}
}
}
let mut fn_sigs = tc_result.fn_sigs.clone();
{
let pairs: Vec<(String, Vec<TopLevel>)> = modules
.iter()
.map(|m| {
let items: Vec<TopLevel> = m
.fn_defs
.iter()
.map(|fd| TopLevel::FnDef(fd.clone()))
.chain(m.type_defs.iter().map(|td| TopLevel::TypeDef(td.clone())))
.collect();
(m.prefix.clone(), items)
})
.collect();
let registry = crate::visibility::SymbolRegistry::from_modules_all(&pairs);
for entry in ®istry.entries {
if fn_sigs.contains_key(&entry.canonical_name) {
continue;
}
if let crate::visibility::SymbolKind::Function {
params,
return_type,
effects,
..
} = &entry.kind
{
let parsed_params: Vec<crate::types::Type> = params
.iter()
.map(|(_, ty_str)| crate::types::parse_type_str(ty_str))
.collect();
let ret = crate::types::parse_type_str(return_type);
fn_sigs.insert(
entry.canonical_name.clone(),
(parsed_params, ret, effects.clone()),
);
}
}
}
CodegenContext {
items,
fn_sigs,
memo_fns,
memo_safe_types: tc_result.memo_safe_types.clone(),
type_defs,
fn_defs,
project_name,
modules,
module_prefixes,
#[cfg(feature = "runtime")]
policy: None,
emit_replay_runtime: false,
runtime_policy_from_env: false,
guest_entry: None,
emit_self_host_support: false,
extra_fn_defs: Vec::new(),
mutual_tco_members,
}
}