use crate::ast::{Function, Program, Stmt, ImportSource, ImportNames};
use crate::parser::Parser;
fn stdlib_source_for(path: &[String]) -> Option<&'static str> {
match path.join("::").as_str() {
"agents::coordinator" => Some(include_str!("../stdlib/agents/coordinator.tern")),
"agents::debate" => Some(include_str!("../stdlib/agents/debate.tern")),
"agents::memory" => Some(include_str!("../stdlib/agents/memory.tern")),
"agents::planner" => Some(include_str!("../stdlib/agents/planner.tern")),
"agents::reflection" => Some(include_str!("../stdlib/agents/reflection.tern")),
"agents::tool_use" => Some(include_str!("../stdlib/agents/tool_use.tern")),
"apps::anomaly_detector" => Some(include_str!("../stdlib/apps/anomaly_detector.tern")),
"apps::classifier" => Some(include_str!("../stdlib/apps/classifier.tern")),
"apps::multi_agent_consensus" => Some(include_str!("../stdlib/apps/multi_agent_consensus.tern")),
"apps::sentiment_engine" => Some(include_str!("../stdlib/apps/sentiment_engine.tern")),
"apps::sparse_inference_engine" => Some(include_str!("../stdlib/apps/sparse_inference_engine.tern")),
"apps::ternary_qa" => Some(include_str!("../stdlib/apps/ternary_qa.tern")),
"apps::ternary_rl_agent" => Some(include_str!("../stdlib/apps/ternary_rl_agent.tern")),
"benchmarks::agent_throughput" => Some(include_str!("../stdlib/benchmarks/agent_throughput.tern")),
"benchmarks::deliberation_speed" => Some(include_str!("../stdlib/benchmarks/deliberation_speed.tern")),
"benchmarks::encoding_efficiency" => Some(include_str!("../stdlib/benchmarks/encoding_efficiency.tern")),
"benchmarks::sparse_matmul" => Some(include_str!("../stdlib/benchmarks/sparse_matmul.tern")),
"bio::codon_map" => Some(include_str!("../stdlib/bio/codon_map.tern")),
"bio::mutation_track" => Some(include_str!("../stdlib/bio/mutation_track.tern")),
"bio::phylogeny" => Some(include_str!("../stdlib/bio/phylogeny.tern")),
"bio::sequence_align" => Some(include_str!("../stdlib/bio/sequence_align.tern")),
"classical::cross_validation" => Some(include_str!("../stdlib/classical/cross_validation.tern")),
"classical::dbscan" => Some(include_str!("../stdlib/classical/dbscan.tern")),
"classical::decision_tree" => Some(include_str!("../stdlib/classical/decision_tree.tern")),
"classical::feature_selection" => Some(include_str!("../stdlib/classical/feature_selection.tern")),
"classical::gradient_boosting" => Some(include_str!("../stdlib/classical/gradient_boosting.tern")),
"classical::kmeans" => Some(include_str!("../stdlib/classical/kmeans.tern")),
"classical::knn" => Some(include_str!("../stdlib/classical/knn.tern")),
"classical::linear_regression" => Some(include_str!("../stdlib/classical/linear_regression.tern")),
"classical::logistic_regression" => Some(include_str!("../stdlib/classical/logistic_regression.tern")),
"classical::metrics" => Some(include_str!("../stdlib/classical/metrics.tern")),
"classical::naive_bayes" => Some(include_str!("../stdlib/classical/naive_bayes.tern")),
"classical::pca" => Some(include_str!("../stdlib/classical/pca.tern")),
"classical::preprocessing" => Some(include_str!("../stdlib/classical/preprocessing.tern")),
"classical::random_forest" => Some(include_str!("../stdlib/classical/random_forest.tern")),
"classical::svm" => Some(include_str!("../stdlib/classical/svm.tern")),
"crypto::merkle_trit" => Some(include_str!("../stdlib/crypto/merkle_trit.tern")),
"crypto::stream_cipher" => Some(include_str!("../stdlib/crypto/stream_cipher.tern")),
"crypto::ternary_hash" => Some(include_str!("../stdlib/crypto/ternary_hash.tern")),
"data::batching" => Some(include_str!("../stdlib/data/batching.tern")),
"data::drift_detect" => Some(include_str!("../stdlib/data/drift_detect.tern")),
"data::feature_store" => Some(include_str!("../stdlib/data/feature_store.tern")),
"data::imputation" => Some(include_str!("../stdlib/data/imputation.tern")),
"data::normalization" => Some(include_str!("../stdlib/data/normalization.tern")),
"data::outlier_detect" => Some(include_str!("../stdlib/data/outlier_detect.tern")),
"data::schema" => Some(include_str!("../stdlib/data/schema.tern")),
"data::splitting" => Some(include_str!("../stdlib/data/splitting.tern")),
"distributed::data_parallel" => Some(include_str!("../stdlib/distributed/data_parallel.tern")),
"distributed::federated" => Some(include_str!("../stdlib/distributed/federated.tern")),
"distributed::gossip" => Some(include_str!("../stdlib/distributed/gossip.tern")),
"distributed::model_parallel" => Some(include_str!("../stdlib/distributed/model_parallel.tern")),
"ensemble::bagging" => Some(include_str!("../stdlib/ensemble/bagging.tern")),
"ensemble::boosting" => Some(include_str!("../stdlib/ensemble/boosting.tern")),
"ensemble::snapshot_ensemble" => Some(include_str!("../stdlib/ensemble/snapshot_ensemble.tern")),
"ensemble::stacking" => Some(include_str!("../stdlib/ensemble/stacking.tern")),
"ensemble::voting" => Some(include_str!("../stdlib/ensemble/voting.tern")),
"eval::calibration_curve" => Some(include_str!("../stdlib/eval/calibration_curve.tern")),
"eval::classification_metrics" => Some(include_str!("../stdlib/eval/classification_metrics.tern")),
"eval::confusion_matrix" => Some(include_str!("../stdlib/eval/confusion_matrix.tern")),
"eval::nlp_metrics" => Some(include_str!("../stdlib/eval/nlp_metrics.tern")),
"eval::pr_curve" => Some(include_str!("../stdlib/eval/pr_curve.tern")),
"eval::ranking_metrics" => Some(include_str!("../stdlib/eval/ranking_metrics.tern")),
"eval::regression_metrics" => Some(include_str!("../stdlib/eval/regression_metrics.tern")),
"eval::roc_curve" => Some(include_str!("../stdlib/eval/roc_curve.tern")),
"finance::arbitrage" => Some(include_str!("../stdlib/finance/arbitrage.tern")),
"finance::momentum" => Some(include_str!("../stdlib/finance/momentum.tern")),
"finance::moving_average" => Some(include_str!("../stdlib/finance/moving_average.tern")),
"finance::order_book" => Some(include_str!("../stdlib/finance/order_book.tern")),
"finance::risk_metrics" => Some(include_str!("../stdlib/finance/risk_metrics.tern")),
"gametheory::auction" => Some(include_str!("../stdlib/gametheory/auction.tern")),
"gametheory::nash_eq" => Some(include_str!("../stdlib/gametheory/nash_eq.tern")),
"gametheory::prisoners_dilemma" => Some(include_str!("../stdlib/gametheory/prisoners_dilemma.tern")),
"gametheory::voting_power" => Some(include_str!("../stdlib/gametheory/voting_power.tern")),
"graph::community" => Some(include_str!("../stdlib/graph/community.tern")),
"graph::gnn_layer" => Some(include_str!("../stdlib/graph/gnn_layer.tern")),
"graph::graph_algorithms" => Some(include_str!("../stdlib/graph/graph_algorithms.tern")),
"graph::graph_attention" => Some(include_str!("../stdlib/graph/graph_attention.tern")),
"graph::graph_core" => Some(include_str!("../stdlib/graph/graph_core.tern")),
"graph::graph_sage" => Some(include_str!("../stdlib/graph/graph_sage.tern")),
"graph::knowledge_graph" => Some(include_str!("../stdlib/graph/knowledge_graph.tern")),
"graph::pagerank" => Some(include_str!("../stdlib/graph/pagerank.tern")),
"hardware::alu_trit" => Some(include_str!("../stdlib/hardware/alu_trit.tern")),
"hardware::flipflop_trit" => Some(include_str!("../stdlib/hardware/flipflop_trit.tern")),
"hardware::memory_bus" => Some(include_str!("../stdlib/hardware/memory_bus.tern")),
"hardware::mux_trit" => Some(include_str!("../stdlib/hardware/mux_trit.tern")),
"hardware::register_file" => Some(include_str!("../stdlib/hardware/register_file.tern")),
"integrations::curl_examples" => Some(include_str!("../stdlib/integrations/curl_examples.tern")),
"integrations::mcp_tool_use" => Some(include_str!("../stdlib/integrations/mcp_tool_use.tern")),
"integrations::python_bridge" => Some(include_str!("../stdlib/integrations/python_bridge.tern")),
"ml::inference" => Some(include_str!("../stdlib/ml/inference.tern")),
"ml::layers::attention" => Some(include_str!("../stdlib/ml/layers/attention.tern")),
"ml::layers::conv" => Some(include_str!("../stdlib/ml/layers/conv.tern")),
"ml::layers::embedding" => Some(include_str!("../stdlib/ml/layers/embedding.tern")),
"ml::layers::linear" => Some(include_str!("../stdlib/ml/layers/linear.tern")),
"ml::layers::norm" => Some(include_str!("../stdlib/ml/layers/norm.tern")),
"ml::layers::recurrent" => Some(include_str!("../stdlib/ml/layers/recurrent.tern")),
"ml::layers::transformer" => Some(include_str!("../stdlib/ml/layers/transformer.tern")),
"ml::loss::cross_entropy" => Some(include_str!("../stdlib/ml/loss/cross_entropy.tern")),
"ml::optim::adam" => Some(include_str!("../stdlib/ml/optim/adam.tern")),
"ml::optim::sgd" => Some(include_str!("../stdlib/ml/optim/sgd.tern")),
"ml::quantize" => Some(include_str!("../stdlib/ml/quantize.tern")),
"ml::train::loop" => Some(include_str!("../stdlib/ml/train/loop.tern")),
"models::bert_analog" => Some(include_str!("../stdlib/models/bert_analog.tern")),
"models::cnn" => Some(include_str!("../stdlib/models/cnn.tern")),
"models::diffusion_analog" => Some(include_str!("../stdlib/models/diffusion_analog.tern")),
"models::gan_analog" => Some(include_str!("../stdlib/models/gan_analog.tern")),
"models::gpt_analog" => Some(include_str!("../stdlib/models/gpt_analog.tern")),
"models::mlp" => Some(include_str!("../stdlib/models/mlp.tern")),
"models::resnet_analog" => Some(include_str!("../stdlib/models/resnet_analog.tern")),
"models::rnn" => Some(include_str!("../stdlib/models/rnn.tern")),
"models::seq2seq" => Some(include_str!("../stdlib/models/seq2seq.tern")),
"models::vae_analog" => Some(include_str!("../stdlib/models/vae_analog.tern")),
"nlp::beam_search" => Some(include_str!("../stdlib/nlp/beam_search.tern")),
"nlp::embeddings" => Some(include_str!("../stdlib/nlp/embeddings.tern")),
"nlp::ner" => Some(include_str!("../stdlib/nlp/ner.tern")),
"nlp::positional" => Some(include_str!("../stdlib/nlp/positional.tern")),
"nlp::sentiment" => Some(include_str!("../stdlib/nlp/sentiment.tern")),
"nlp::summarizer" => Some(include_str!("../stdlib/nlp/summarizer.tern")),
"nlp::text_classifier" => Some(include_str!("../stdlib/nlp/text_classifier.tern")),
"nlp::tokenizer" => Some(include_str!("../stdlib/nlp/tokenizer.tern")),
"nlp::translation_gate" => Some(include_str!("../stdlib/nlp/translation_gate.tern")),
"nlp::vocab" => Some(include_str!("../stdlib/nlp/vocab.tern")),
"nn::activation" => Some(include_str!("../stdlib/nn/activation.tern")),
"nn::batch_norm" => Some(include_str!("../stdlib/nn/batch_norm.tern")),
"nn::conv1d" => Some(include_str!("../stdlib/nn/conv1d.tern")),
"nn::conv2d" => Some(include_str!("../stdlib/nn/conv2d.tern")),
"nn::dense" => Some(include_str!("../stdlib/nn/dense.tern")),
"nn::dropout" => Some(include_str!("../stdlib/nn/dropout.tern")),
"nn::embedding_table" => Some(include_str!("../stdlib/nn/embedding_table.tern")),
"nn::feedforward" => Some(include_str!("../stdlib/nn/feedforward.tern")),
"nn::gru_cell" => Some(include_str!("../stdlib/nn/gru_cell.tern")),
"nn::layer_norm" => Some(include_str!("../stdlib/nn/layer_norm.tern")),
"nn::loss::bce" => Some(include_str!("../stdlib/nn/loss/bce.tern")),
"nn::loss::contrastive" => Some(include_str!("../stdlib/nn/loss/contrastive.tern")),
"nn::loss::focal" => Some(include_str!("../stdlib/nn/loss/focal.tern")),
"nn::loss::huber" => Some(include_str!("../stdlib/nn/loss/huber.tern")),
"nn::loss::kl_div" => Some(include_str!("../stdlib/nn/loss/kl_div.tern")),
"nn::loss::mae" => Some(include_str!("../stdlib/nn/loss/mae.tern")),
"nn::loss::mse" => Some(include_str!("../stdlib/nn/loss/mse.tern")),
"nn::loss::triplet" => Some(include_str!("../stdlib/nn/loss/triplet.tern")),
"nn::lstm_cell" => Some(include_str!("../stdlib/nn/lstm_cell.tern")),
"nn::multihead_attn" => Some(include_str!("../stdlib/nn/multihead_attn.tern")),
"nn::optim::adagrad" => Some(include_str!("../stdlib/nn/optim/adagrad.tern")),
"nn::optim::adamw" => Some(include_str!("../stdlib/nn/optim/adamw.tern")),
"nn::optim::gradient_clip" => Some(include_str!("../stdlib/nn/optim/gradient_clip.tern")),
"nn::optim::lr_scheduler" => Some(include_str!("../stdlib/nn/optim/lr_scheduler.tern")),
"nn::optim::rmsprop" => Some(include_str!("../stdlib/nn/optim/rmsprop.tern")),
"nn::pooling" => Some(include_str!("../stdlib/nn/pooling.tern")),
"nn::positional_encoding" => Some(include_str!("../stdlib/nn/positional_encoding.tern")),
"nn::residual" => Some(include_str!("../stdlib/nn/residual.tern")),
"nn::train::augmentation" => Some(include_str!("../stdlib/nn/train/augmentation.tern")),
"nn::train::checkpointing" => Some(include_str!("../stdlib/nn/train/checkpointing.tern")),
"nn::train::data_loader" => Some(include_str!("../stdlib/nn/train/data_loader.tern")),
"nn::train::early_stopping" => Some(include_str!("../stdlib/nn/train/early_stopping.tern")),
"nn::train::profiler" => Some(include_str!("../stdlib/nn/train/profiler.tern")),
"nn::train::regularization" => Some(include_str!("../stdlib/nn/train/regularization.tern")),
"qnn::entanglement" => Some(include_str!("../stdlib/premium/qnn/entanglement.tern")),
"qnn::qnn_circuit" => Some(include_str!("../stdlib/premium/qnn/qnn_circuit.tern")),
"qnn::qnn_layer" => Some(include_str!("../stdlib/premium/qnn/qnn_layer.tern")),
"qnn::qutrit" => Some(include_str!("../stdlib/premium/qnn/qutrit.tern")),
"qnn::variational" => Some(include_str!("../stdlib/premium/qnn/variational.tern")),
"reasoning::bayesian" => Some(include_str!("../stdlib/premium/reasoning/bayesian.tern")),
"reasoning::causal" => Some(include_str!("../stdlib/premium/reasoning/causal.tern")),
"reasoning::contradiction" => Some(include_str!("../stdlib/premium/reasoning/contradiction.tern")),
"reasoning::temporal" => Some(include_str!("../stdlib/premium/reasoning/temporal.tern")),
"reasoning::uncertainty" => Some(include_str!("../stdlib/premium/reasoning/uncertainty.tern")),
"research::constitutional_trit" => Some(include_str!("../stdlib/research/constitutional_trit.tern")),
"research::moe_routing" => Some(include_str!("../stdlib/research/moe_routing.tern")),
"research::sparse_moe" => Some(include_str!("../stdlib/research/sparse_moe.tern")),
"research::ternary_ppo" => Some(include_str!("../stdlib/research/ternary_ppo.tern")),
"research::ternary_ssm" => Some(include_str!("../stdlib/research/ternary_ssm.tern")),
"research::trit_attention" => Some(include_str!("../stdlib/research/trit_attention.tern")),
"research::trit_diffusion" => Some(include_str!("../stdlib/research/trit_diffusion.tern")),
"research::trit_kv_cache" => Some(include_str!("../stdlib/research/trit_kv_cache.tern")),
"research::trit_memory" => Some(include_str!("../stdlib/research/trit_memory.tern")),
"research::trit_pruning" => Some(include_str!("../stdlib/research/trit_pruning.tern")),
"research::trit_quantization" => Some(include_str!("../stdlib/research/trit_quantization.tern")),
"research::tritformer" => Some(include_str!("../stdlib/research/tritformer.tern")),
"rl::actor_critic" => Some(include_str!("../stdlib/rl/actor_critic.tern")),
"rl::environment" => Some(include_str!("../stdlib/rl/environment.tern")),
"rl::episode" => Some(include_str!("../stdlib/rl/episode.tern")),
"rl::exploration" => Some(include_str!("../stdlib/rl/exploration.tern")),
"rl::policy" => Some(include_str!("../stdlib/rl/policy.tern")),
"rl::q_learning" => Some(include_str!("../stdlib/rl/q_learning.tern")),
"rl::reward_shaping" => Some(include_str!("../stdlib/rl/reward_shaping.tern")),
"rl::value_fn" => Some(include_str!("../stdlib/rl/value_fn.tern")),
"safety::adversarial" => Some(include_str!("../stdlib/safety/adversarial.tern")),
"safety::alignment_check" => Some(include_str!("../stdlib/safety/alignment_check.tern")),
"safety::calibration" => Some(include_str!("../stdlib/safety/calibration.tern")),
"safety::conformal" => Some(include_str!("../stdlib/safety/conformal.tern")),
"safety::content_gate" => Some(include_str!("../stdlib/safety/content_gate.tern")),
"safety::fairness" => Some(include_str!("../stdlib/safety/fairness.tern")),
"safety::ood_detect" => Some(include_str!("../stdlib/safety/ood_detect.tern")),
"safety::uncertainty_quant" => Some(include_str!("../stdlib/safety/uncertainty_quant.tern")),
"stats::bayesian_inference" => Some(include_str!("../stdlib/stats/bayesian_inference.tern")),
"stats::confidence_interval" => Some(include_str!("../stdlib/stats/confidence_interval.tern")),
"stats::correlation" => Some(include_str!("../stdlib/stats/correlation.tern")),
"stats::distributions" => Some(include_str!("../stdlib/stats/distributions.tern")),
"stats::hypothesis_test" => Some(include_str!("../stdlib/stats/hypothesis_test.tern")),
"stats::information_theory" => Some(include_str!("../stdlib/stats/information_theory.tern")),
"stats::regression_stats" => Some(include_str!("../stdlib/stats/regression_stats.tern")),
"std::collections" => Some(include_str!("../stdlib/std/collections.tern")),
"std::graph" => Some(include_str!("../stdlib/std/graph.tern")),
"std::io" => Some(include_str!("../stdlib/std/io.tern")),
"std::logic" => Some(include_str!("../stdlib/std/logic.tern")),
"std::math" => Some(include_str!("../stdlib/std/math.tern")),
"std::memory" => Some(include_str!("../stdlib/std/memory.tern")),
"std::signal" => Some(include_str!("../stdlib/std/signal.tern")),
"std::tensor" => Some(include_str!("../stdlib/std/tensor.tern")),
"std::trit" => Some(include_str!("../stdlib/std/trit.tern")),
"ternary::arithmetic" => Some(include_str!("../stdlib/ternary/arithmetic.tern")),
"ternary::consensus" => Some(include_str!("../stdlib/ternary/consensus.tern")),
"ternary::encoding" => Some(include_str!("../stdlib/ternary/encoding.tern")),
"ternary::gates" => Some(include_str!("../stdlib/ternary/gates.tern")),
"testing::assert" => Some(include_str!("../stdlib/testing/assert.tern")),
"testing::mock" => Some(include_str!("../stdlib/testing/mock.tern")),
"testing::suite" => Some(include_str!("../stdlib/testing/suite.tern")),
"timeseries::anomaly_ts" => Some(include_str!("../stdlib/timeseries/anomaly_ts.tern")),
"timeseries::changepoint" => Some(include_str!("../stdlib/timeseries/changepoint.tern")),
"timeseries::decomposition" => Some(include_str!("../stdlib/timeseries/decomposition.tern")),
"timeseries::features" => Some(include_str!("../stdlib/timeseries/features.tern")),
"timeseries::forecasting" => Some(include_str!("../stdlib/timeseries/forecasting.tern")),
"timeseries::lstm_forecast" => Some(include_str!("../stdlib/timeseries/lstm_forecast.tern")),
"timeseries::tcn" => Some(include_str!("../stdlib/timeseries/tcn.tern")),
"tutorials::01_hello_ternary" => Some(include_str!("../stdlib/tutorials/01_hello_ternary.tern")),
"tutorials::02_match_exhaustive" => Some(include_str!("../stdlib/tutorials/02_match_exhaustive.tern")),
"tutorials::03_tensors" => Some(include_str!("../stdlib/tutorials/03_tensors.tern")),
"tutorials::04_sparse_ops" => Some(include_str!("../stdlib/tutorials/04_sparse_ops.tern")),
"tutorials::05_functions" => Some(include_str!("../stdlib/tutorials/05_functions.tern")),
"tutorials::06_structs" => Some(include_str!("../stdlib/tutorials/06_structs.tern")),
"tutorials::07_agents" => Some(include_str!("../stdlib/tutorials/07_agents.tern")),
"tutorials::08_multi_agent" => Some(include_str!("../stdlib/tutorials/08_multi_agent.tern")),
"tutorials::09_ml_basics" => Some(include_str!("../stdlib/tutorials/09_ml_basics.tern")),
"tutorials::10_attention" => Some(include_str!("../stdlib/tutorials/10_attention.tern")),
"tutorials::11_training_loop" => Some(include_str!("../stdlib/tutorials/11_training_loop.tern")),
"tutorials::12_uncertainty" => Some(include_str!("../stdlib/tutorials/12_uncertainty.tern")),
"tutorials::13_consensus" => Some(include_str!("../stdlib/tutorials/13_consensus.tern")),
"tutorials::14_full_pipeline" => Some(include_str!("../stdlib/tutorials/14_full_pipeline.tern")),
"tutorials::15_ternary_philosophy" => Some(include_str!("../stdlib/tutorials/15_ternary_philosophy.tern")),
"vision::augmentation_2d" => Some(include_str!("../stdlib/vision/augmentation_2d.tern")),
"vision::feature_extractor" => Some(include_str!("../stdlib/vision/feature_extractor.tern")),
"vision::image_classifier" => Some(include_str!("../stdlib/vision/image_classifier.tern")),
"vision::image_ops" => Some(include_str!("../stdlib/vision/image_ops.tern")),
"vision::object_gate" => Some(include_str!("../stdlib/vision/object_gate.tern")),
"vision::segmentation_gate" => Some(include_str!("../stdlib/vision/segmentation_gate.tern")),
_ => None,
}
}
fn collect_use_paths(stmts: &[Stmt]) -> Vec<Vec<String>> {
let mut paths = Vec::new();
for stmt in stmts {
match stmt {
Stmt::Use { path } => paths.push(path.clone()),
Stmt::Block(inner) => paths.extend(collect_use_paths(inner)),
Stmt::IfTernary { on_pos, on_zero, on_neg, .. } => {
paths.extend(collect_use_paths(&[*on_pos.clone()]));
paths.extend(collect_use_paths(&[*on_zero.clone()]));
paths.extend(collect_use_paths(&[*on_neg.clone()]));
}
Stmt::Match { arms, .. } => {
for (_, arm_stmt) in arms {
paths.extend(collect_use_paths(&[arm_stmt.clone()]));
}
}
_ => {}
}
}
paths
}
fn parse_extract_and_discover(
src: &str,
key: &str,
known: &mut std::collections::HashSet<String>,
filter: Option<&std::collections::HashSet<String>>,
) -> (Vec<Function>, Vec<Vec<String>>) {
let mut parser = Parser::new(src);
match parser.parse_program() {
Ok(prog) => {
let mut discovered: Vec<Vec<String>> = prog.imports.clone();
for f in &prog.functions {
discovered.extend(collect_use_paths(&f.body));
}
let funcs = prog.functions.into_iter()
.filter(|f| filter.map_or(true, |names| names.contains(&f.name)))
.filter(|f| known.insert(f.name.clone()))
.collect();
(funcs, discovered)
}
Err(e) => { eprintln!("[MOD-000] Failed to parse module '{key}': {e}"); (vec![], vec![]) }
}
}
fn resolve_with<F>(program: &mut Program, extra_source: F)
where
F: Fn(&[String]) -> Option<String>,
{
use std::collections::{HashSet, VecDeque};
let mut known: HashSet<String> =
program.functions.iter().map(|f| f.name.clone()).collect();
let mut visited: HashSet<String> = HashSet::new();
let mut queue: VecDeque<Vec<String>> = VecDeque::new();
for path in &program.imports {
let key = path.join("::");
if visited.insert(key) { queue.push_back(path.clone()); }
}
for f in &program.functions {
for path in collect_use_paths(&f.body) {
let key = path.join("::");
if visited.insert(key) { queue.push_back(path); }
}
}
for agent in &program.agents {
for method in &agent.methods {
for path in collect_use_paths(&method.body) {
let key = path.join("::");
if visited.insert(key) { queue.push_back(path); }
}
}
}
let mut injected: Vec<Function> = Vec::new();
let specs = program.import_specs.clone();
for spec in &specs {
let filter: Option<HashSet<String>> = match &spec.names {
ImportNames::Wildcard => None,
ImportNames::Named(names) => Some(names.iter().cloned().collect()),
};
let filter_ref = filter.as_ref();
match &spec.source {
ImportSource::Module(path) => {
let key = path.join("::");
let src_opt = stdlib_source_for(path).map(|s| s.to_string())
.or_else(|| extra_source(path));
match src_opt {
Some(src) => {
let (funcs, trans) = parse_extract_and_discover(&src, &key, &mut known, filter_ref);
injected.extend(funcs);
for p in trans {
let k = p.join("::");
if visited.insert(k) { queue.push_back(p); }
}
}
None => eprintln!("[MOD-002] Unknown module '{key}' in `from` import — no stdlib match and no file found."),
}
}
ImportSource::File(file_path) => {
if !file_path.ends_with(".tern") {
let ext = std::path::Path::new(file_path)
.extension()
.and_then(|e| e.to_str())
.unwrap_or("unknown");
eprintln!(
"[MOD-003] Foreign import '{file_path}' (.{ext}) — cross-language FFI is not yet supported. \
Coming in Phase 13 (TernTranslator). For now, rewrite the logic in .tern."
);
continue;
}
let sentinel = vec!["__file__".to_string(), file_path.clone()];
match extra_source(&sentinel) {
Some(src) => {
let (funcs, trans) = parse_extract_and_discover(&src, file_path, &mut known, filter_ref);
injected.extend(funcs);
for p in trans {
let k = p.join("::");
if visited.insert(k) { queue.push_back(p); }
}
}
None => eprintln!("[MOD-004] Could not load file '{file_path}' — file not found or not readable."),
}
}
}
}
while let Some(path) = queue.pop_front() {
let key = path.join("::");
let src_opt = stdlib_source_for(&path).map(|s| s.to_string())
.or_else(|| extra_source(&path));
match src_opt {
Some(src) => {
let (funcs, trans) = parse_extract_and_discover(&src, &key, &mut known, None);
injected.extend(funcs);
for p in trans {
let k = p.join("::");
if visited.insert(k) { queue.push_back(p); }
}
}
None => {
eprintln!("[MOD-001] Unknown module '{key}' — no stdlib match and no file found. Did you mean std::trit?");
}
}
}
injected.extend(program.functions.drain(..));
program.functions = injected;
}
pub struct StdlibLoader;
impl StdlibLoader {
pub fn resolve(program: &mut Program) {
resolve_with(program, |_| None);
}
}
pub struct ModuleResolver {
base_dir: Option<std::path::PathBuf>,
}
impl ModuleResolver {
pub fn from_source_file(source_file: &std::path::Path) -> Self {
Self { base_dir: source_file.parent().map(|p| p.to_path_buf()) }
}
pub fn from_dir(dir: std::path::PathBuf) -> Self {
Self { base_dir: Some(dir) }
}
pub fn stdlib_only() -> Self {
Self { base_dir: None }
}
fn load_user_module(&self, path: &[String]) -> Option<String> {
let base = self.base_dir.as_ref()?;
if path.len() == 2 && path[0] == "__file__" {
let raw = &path[1];
let file_path = if std::path::Path::new(raw).is_absolute() {
std::path::PathBuf::from(raw)
} else {
base.join(raw)
};
return std::fs::read_to_string(&file_path).ok();
}
let mut file_path = base.clone();
for (i, segment) in path.iter().enumerate() {
if i == path.len() - 1 {
file_path = file_path.join(format!("{segment}.tern"));
} else {
file_path = file_path.join(segment);
}
}
std::fs::read_to_string(&file_path).ok()
}
pub fn resolve(&self, program: &mut Program) {
resolve_with(program, |path| self.load_user_module(path));
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::parser::Parser;
#[test]
fn all_stdlib_modules_parse() {
let modules = [
vec!["std".to_string(), "trit".to_string()],
vec!["std".to_string(), "math".to_string()],
vec!["std".to_string(), "tensor".to_string()],
vec!["std".to_string(), "io".to_string()],
vec!["ml".to_string(), "quantize".to_string()],
vec!["ml".to_string(), "inference".to_string()],
vec!["classical".to_string(), "svm".to_string()],
vec!["nn".to_string(), "dense".to_string()],
vec!["models".to_string(), "gpt_analog".to_string()],
vec!["research".to_string(), "tritformer".to_string()],
];
for path in &modules {
let src = stdlib_source_for(path)
.unwrap_or_else(|| panic!("Missing stdlib source for {}", path.join("::")));
let mut parser = Parser::new(src);
parser.parse_program()
.unwrap_or_else(|e| panic!("Parse error in {}: {:?}", path.join("::"), e));
}
}
#[test]
fn resolve_injects_trit_stdlib() {
let src = r#"
fn main() -> trit {
use std::trit;
let x: trit = abs(-1);
return x;
}
"#;
let mut parser = Parser::new(src);
let mut prog = parser.parse_program().expect("parse failed");
assert!(!prog.functions.iter().any(|f| f.name == "abs"),
"abs should not be present before resolve");
StdlibLoader::resolve(&mut prog);
assert!(prog.functions.iter().any(|f| f.name == "abs"),
"abs should be injected after resolve");
assert!(prog.functions.iter().any(|f| f.name == "min"));
assert!(prog.functions.iter().any(|f| f.name == "majority"));
}
#[test]
fn resolve_multiple_modules_no_duplicates() {
let src = r#"
fn main() -> trit {
use std::trit;
use std::math;
let x: trit = neg(1);
return x;
}
"#;
let mut parser = Parser::new(src);
let mut prog = parser.parse_program().expect("parse failed");
StdlibLoader::resolve(&mut prog);
let neg_count = prog.functions.iter().filter(|f| f.name == "neg").count();
assert_eq!(neg_count, 1, "neg should appear exactly once");
assert!(prog.functions.iter().any(|f| f.name == "abs")); assert!(prog.functions.iter().any(|f| f.name == "rectify")); }
#[test]
fn resolve_is_idempotent() {
let src = r#"
fn main() -> trit {
use std::trit;
return 0;
}
"#;
let mut parser = Parser::new(src);
let mut prog = parser.parse_program().expect("parse failed");
StdlibLoader::resolve(&mut prog);
StdlibLoader::resolve(&mut prog);
let abs_count = prog.functions.iter().filter(|f| f.name == "abs").count();
assert_eq!(abs_count, 1, "abs should not be duplicated by double resolve");
}
#[test]
fn unknown_module_skipped_gracefully() {
let src = r#"
fn main() -> trit {
use std::nonexistent;
return 0;
}
"#;
let mut parser = Parser::new(src);
let mut prog = parser.parse_program().expect("parse failed");
StdlibLoader::resolve(&mut prog);
}
}