Skip to main content

ternlang_core/
stdlib.rs

1/// StdlibLoader / ModuleResolver — resolves `use` statements into parsed function definitions.
2///
3/// Two resolution strategies, tried in order:
4///   1. Built-in stdlib (embedded at compile time via `include_str!`) — zero filesystem I/O.
5///   2. User-defined modules: looks for `<segment>/<segment>.tern` relative to the source file.
6///
7/// Use `StdlibLoader::resolve()` for quick stdlib-only resolution (backwards-compat API).
8/// Use `ModuleResolver::from_source_file(path).resolve(program)` for full module support.
9use crate::ast::{Function, Program, Stmt};
10use crate::parser::Parser;
11
12// ─── Built-in stdlib sources (compile-time embedded) ─────────────────────────
13
14fn stdlib_source_for(path: &[String]) -> Option<&'static str> {
15    match path.join("::").as_str() {
16        "agents::coordinator" => Some(include_str!("../stdlib/agents/coordinator.tern")),
17        "agents::debate" => Some(include_str!("../stdlib/agents/debate.tern")),
18        "agents::memory" => Some(include_str!("../stdlib/agents/memory.tern")),
19        "agents::planner" => Some(include_str!("../stdlib/agents/planner.tern")),
20        "agents::reflection" => Some(include_str!("../stdlib/agents/reflection.tern")),
21        "agents::tool_use" => Some(include_str!("../stdlib/agents/tool_use.tern")),
22        "apps::anomaly_detector" => Some(include_str!("../stdlib/apps/anomaly_detector.tern")),
23        "apps::classifier" => Some(include_str!("../stdlib/apps/classifier.tern")),
24        "apps::multi_agent_consensus" => Some(include_str!("../stdlib/apps/multi_agent_consensus.tern")),
25        "apps::sentiment_engine" => Some(include_str!("../stdlib/apps/sentiment_engine.tern")),
26        "apps::sparse_inference_engine" => Some(include_str!("../stdlib/apps/sparse_inference_engine.tern")),
27        "apps::ternary_qa" => Some(include_str!("../stdlib/apps/ternary_qa.tern")),
28        "apps::ternary_rl_agent" => Some(include_str!("../stdlib/apps/ternary_rl_agent.tern")),
29        "benchmarks::agent_throughput" => Some(include_str!("../stdlib/benchmarks/agent_throughput.tern")),
30        "benchmarks::deliberation_speed" => Some(include_str!("../stdlib/benchmarks/deliberation_speed.tern")),
31        "benchmarks::encoding_efficiency" => Some(include_str!("../stdlib/benchmarks/encoding_efficiency.tern")),
32        "benchmarks::sparse_matmul" => Some(include_str!("../stdlib/benchmarks/sparse_matmul.tern")),
33        "bio::codon_map" => Some(include_str!("../stdlib/bio/codon_map.tern")),
34        "bio::mutation_track" => Some(include_str!("../stdlib/bio/mutation_track.tern")),
35        "bio::phylogeny" => Some(include_str!("../stdlib/bio/phylogeny.tern")),
36        "bio::sequence_align" => Some(include_str!("../stdlib/bio/sequence_align.tern")),
37        "classical::cross_validation" => Some(include_str!("../stdlib/classical/cross_validation.tern")),
38        "classical::dbscan" => Some(include_str!("../stdlib/classical/dbscan.tern")),
39        "classical::decision_tree" => Some(include_str!("../stdlib/classical/decision_tree.tern")),
40        "classical::feature_selection" => Some(include_str!("../stdlib/classical/feature_selection.tern")),
41        "classical::gradient_boosting" => Some(include_str!("../stdlib/classical/gradient_boosting.tern")),
42        "classical::kmeans" => Some(include_str!("../stdlib/classical/kmeans.tern")),
43        "classical::knn" => Some(include_str!("../stdlib/classical/knn.tern")),
44        "classical::linear_regression" => Some(include_str!("../stdlib/classical/linear_regression.tern")),
45        "classical::logistic_regression" => Some(include_str!("../stdlib/classical/logistic_regression.tern")),
46        "classical::metrics" => Some(include_str!("../stdlib/classical/metrics.tern")),
47        "classical::naive_bayes" => Some(include_str!("../stdlib/classical/naive_bayes.tern")),
48        "classical::pca" => Some(include_str!("../stdlib/classical/pca.tern")),
49        "classical::preprocessing" => Some(include_str!("../stdlib/classical/preprocessing.tern")),
50        "classical::random_forest" => Some(include_str!("../stdlib/classical/random_forest.tern")),
51        "classical::svm" => Some(include_str!("../stdlib/classical/svm.tern")),
52        "crypto::merkle_trit" => Some(include_str!("../stdlib/crypto/merkle_trit.tern")),
53        "crypto::stream_cipher" => Some(include_str!("../stdlib/crypto/stream_cipher.tern")),
54        "crypto::ternary_hash" => Some(include_str!("../stdlib/crypto/ternary_hash.tern")),
55        "data::batching" => Some(include_str!("../stdlib/data/batching.tern")),
56        "data::drift_detect" => Some(include_str!("../stdlib/data/drift_detect.tern")),
57        "data::feature_store" => Some(include_str!("../stdlib/data/feature_store.tern")),
58        "data::imputation" => Some(include_str!("../stdlib/data/imputation.tern")),
59        "data::normalization" => Some(include_str!("../stdlib/data/normalization.tern")),
60        "data::outlier_detect" => Some(include_str!("../stdlib/data/outlier_detect.tern")),
61        "data::schema" => Some(include_str!("../stdlib/data/schema.tern")),
62        "data::splitting" => Some(include_str!("../stdlib/data/splitting.tern")),
63        "distributed::data_parallel" => Some(include_str!("../stdlib/distributed/data_parallel.tern")),
64        "distributed::federated" => Some(include_str!("../stdlib/distributed/federated.tern")),
65        "distributed::gossip" => Some(include_str!("../stdlib/distributed/gossip.tern")),
66        "distributed::model_parallel" => Some(include_str!("../stdlib/distributed/model_parallel.tern")),
67        "ensemble::bagging" => Some(include_str!("../stdlib/ensemble/bagging.tern")),
68        "ensemble::boosting" => Some(include_str!("../stdlib/ensemble/boosting.tern")),
69        "ensemble::snapshot_ensemble" => Some(include_str!("../stdlib/ensemble/snapshot_ensemble.tern")),
70        "ensemble::stacking" => Some(include_str!("../stdlib/ensemble/stacking.tern")),
71        "ensemble::voting" => Some(include_str!("../stdlib/ensemble/voting.tern")),
72        "eval::calibration_curve" => Some(include_str!("../stdlib/eval/calibration_curve.tern")),
73        "eval::classification_metrics" => Some(include_str!("../stdlib/eval/classification_metrics.tern")),
74        "eval::confusion_matrix" => Some(include_str!("../stdlib/eval/confusion_matrix.tern")),
75        "eval::nlp_metrics" => Some(include_str!("../stdlib/eval/nlp_metrics.tern")),
76        "eval::pr_curve" => Some(include_str!("../stdlib/eval/pr_curve.tern")),
77        "eval::ranking_metrics" => Some(include_str!("../stdlib/eval/ranking_metrics.tern")),
78        "eval::regression_metrics" => Some(include_str!("../stdlib/eval/regression_metrics.tern")),
79        "eval::roc_curve" => Some(include_str!("../stdlib/eval/roc_curve.tern")),
80        "finance::arbitrage" => Some(include_str!("../stdlib/finance/arbitrage.tern")),
81        "finance::momentum" => Some(include_str!("../stdlib/finance/momentum.tern")),
82        "finance::moving_average" => Some(include_str!("../stdlib/finance/moving_average.tern")),
83        "finance::order_book" => Some(include_str!("../stdlib/finance/order_book.tern")),
84        "finance::risk_metrics" => Some(include_str!("../stdlib/finance/risk_metrics.tern")),
85        "gametheory::auction" => Some(include_str!("../stdlib/gametheory/auction.tern")),
86        "gametheory::nash_eq" => Some(include_str!("../stdlib/gametheory/nash_eq.tern")),
87        "gametheory::prisoners_dilemma" => Some(include_str!("../stdlib/gametheory/prisoners_dilemma.tern")),
88        "gametheory::voting_power" => Some(include_str!("../stdlib/gametheory/voting_power.tern")),
89        "graph::community" => Some(include_str!("../stdlib/graph/community.tern")),
90        "graph::gnn_layer" => Some(include_str!("../stdlib/graph/gnn_layer.tern")),
91        "graph::graph_algorithms" => Some(include_str!("../stdlib/graph/graph_algorithms.tern")),
92        "graph::graph_attention" => Some(include_str!("../stdlib/graph/graph_attention.tern")),
93        "graph::graph_core" => Some(include_str!("../stdlib/graph/graph_core.tern")),
94        "graph::graph_sage" => Some(include_str!("../stdlib/graph/graph_sage.tern")),
95        "graph::knowledge_graph" => Some(include_str!("../stdlib/graph/knowledge_graph.tern")),
96        "graph::pagerank" => Some(include_str!("../stdlib/graph/pagerank.tern")),
97        "hardware::alu_trit" => Some(include_str!("../stdlib/hardware/alu_trit.tern")),
98        "hardware::flipflop_trit" => Some(include_str!("../stdlib/hardware/flipflop_trit.tern")),
99        "hardware::memory_bus" => Some(include_str!("../stdlib/hardware/memory_bus.tern")),
100        "hardware::mux_trit" => Some(include_str!("../stdlib/hardware/mux_trit.tern")),
101        "hardware::register_file" => Some(include_str!("../stdlib/hardware/register_file.tern")),
102        "integrations::curl_examples" => Some(include_str!("../stdlib/integrations/curl_examples.tern")),
103        "integrations::mcp_tool_use" => Some(include_str!("../stdlib/integrations/mcp_tool_use.tern")),
104        "integrations::python_bridge" => Some(include_str!("../stdlib/integrations/python_bridge.tern")),
105        "ml::inference" => Some(include_str!("../stdlib/ml/inference.tern")),
106        "ml::layers::attention" => Some(include_str!("../stdlib/ml/layers/attention.tern")),
107        "ml::layers::conv" => Some(include_str!("../stdlib/ml/layers/conv.tern")),
108        "ml::layers::embedding" => Some(include_str!("../stdlib/ml/layers/embedding.tern")),
109        "ml::layers::linear" => Some(include_str!("../stdlib/ml/layers/linear.tern")),
110        "ml::layers::norm" => Some(include_str!("../stdlib/ml/layers/norm.tern")),
111        "ml::layers::recurrent" => Some(include_str!("../stdlib/ml/layers/recurrent.tern")),
112        "ml::layers::transformer" => Some(include_str!("../stdlib/ml/layers/transformer.tern")),
113        "ml::loss::cross_entropy" => Some(include_str!("../stdlib/ml/loss/cross_entropy.tern")),
114        "ml::optim::adam" => Some(include_str!("../stdlib/ml/optim/adam.tern")),
115        "ml::optim::sgd" => Some(include_str!("../stdlib/ml/optim/sgd.tern")),
116        "ml::quantize" => Some(include_str!("../stdlib/ml/quantize.tern")),
117        "ml::train::loop" => Some(include_str!("../stdlib/ml/train/loop.tern")),
118        "models::bert_analog" => Some(include_str!("../stdlib/models/bert_analog.tern")),
119        "models::cnn" => Some(include_str!("../stdlib/models/cnn.tern")),
120        "models::diffusion_analog" => Some(include_str!("../stdlib/models/diffusion_analog.tern")),
121        "models::gan_analog" => Some(include_str!("../stdlib/models/gan_analog.tern")),
122        "models::gpt_analog" => Some(include_str!("../stdlib/models/gpt_analog.tern")),
123        "models::mlp" => Some(include_str!("../stdlib/models/mlp.tern")),
124        "models::resnet_analog" => Some(include_str!("../stdlib/models/resnet_analog.tern")),
125        "models::rnn" => Some(include_str!("../stdlib/models/rnn.tern")),
126        "models::seq2seq" => Some(include_str!("../stdlib/models/seq2seq.tern")),
127        "models::vae_analog" => Some(include_str!("../stdlib/models/vae_analog.tern")),
128        "nlp::beam_search" => Some(include_str!("../stdlib/nlp/beam_search.tern")),
129        "nlp::embeddings" => Some(include_str!("../stdlib/nlp/embeddings.tern")),
130        "nlp::ner" => Some(include_str!("../stdlib/nlp/ner.tern")),
131        "nlp::positional" => Some(include_str!("../stdlib/nlp/positional.tern")),
132        "nlp::sentiment" => Some(include_str!("../stdlib/nlp/sentiment.tern")),
133        "nlp::summarizer" => Some(include_str!("../stdlib/nlp/summarizer.tern")),
134        "nlp::text_classifier" => Some(include_str!("../stdlib/nlp/text_classifier.tern")),
135        "nlp::tokenizer" => Some(include_str!("../stdlib/nlp/tokenizer.tern")),
136        "nlp::translation_gate" => Some(include_str!("../stdlib/nlp/translation_gate.tern")),
137        "nlp::vocab" => Some(include_str!("../stdlib/nlp/vocab.tern")),
138        "nn::activation" => Some(include_str!("../stdlib/nn/activation.tern")),
139        "nn::batch_norm" => Some(include_str!("../stdlib/nn/batch_norm.tern")),
140        "nn::conv1d" => Some(include_str!("../stdlib/nn/conv1d.tern")),
141        "nn::conv2d" => Some(include_str!("../stdlib/nn/conv2d.tern")),
142        "nn::dense" => Some(include_str!("../stdlib/nn/dense.tern")),
143        "nn::dropout" => Some(include_str!("../stdlib/nn/dropout.tern")),
144        "nn::embedding_table" => Some(include_str!("../stdlib/nn/embedding_table.tern")),
145        "nn::feedforward" => Some(include_str!("../stdlib/nn/feedforward.tern")),
146        "nn::gru_cell" => Some(include_str!("../stdlib/nn/gru_cell.tern")),
147        "nn::layer_norm" => Some(include_str!("../stdlib/nn/layer_norm.tern")),
148        "nn::loss::bce" => Some(include_str!("../stdlib/nn/loss/bce.tern")),
149        "nn::loss::contrastive" => Some(include_str!("../stdlib/nn/loss/contrastive.tern")),
150        "nn::loss::focal" => Some(include_str!("../stdlib/nn/loss/focal.tern")),
151        "nn::loss::huber" => Some(include_str!("../stdlib/nn/loss/huber.tern")),
152        "nn::loss::kl_div" => Some(include_str!("../stdlib/nn/loss/kl_div.tern")),
153        "nn::loss::mae" => Some(include_str!("../stdlib/nn/loss/mae.tern")),
154        "nn::loss::mse" => Some(include_str!("../stdlib/nn/loss/mse.tern")),
155        "nn::loss::triplet" => Some(include_str!("../stdlib/nn/loss/triplet.tern")),
156        "nn::lstm_cell" => Some(include_str!("../stdlib/nn/lstm_cell.tern")),
157        "nn::multihead_attn" => Some(include_str!("../stdlib/nn/multihead_attn.tern")),
158        "nn::optim::adagrad" => Some(include_str!("../stdlib/nn/optim/adagrad.tern")),
159        "nn::optim::adamw" => Some(include_str!("../stdlib/nn/optim/adamw.tern")),
160        "nn::optim::gradient_clip" => Some(include_str!("../stdlib/nn/optim/gradient_clip.tern")),
161        "nn::optim::lr_scheduler" => Some(include_str!("../stdlib/nn/optim/lr_scheduler.tern")),
162        "nn::optim::rmsprop" => Some(include_str!("../stdlib/nn/optim/rmsprop.tern")),
163        "nn::pooling" => Some(include_str!("../stdlib/nn/pooling.tern")),
164        "nn::positional_encoding" => Some(include_str!("../stdlib/nn/positional_encoding.tern")),
165        "nn::residual" => Some(include_str!("../stdlib/nn/residual.tern")),
166        "nn::train::augmentation" => Some(include_str!("../stdlib/nn/train/augmentation.tern")),
167        "nn::train::checkpointing" => Some(include_str!("../stdlib/nn/train/checkpointing.tern")),
168        "nn::train::data_loader" => Some(include_str!("../stdlib/nn/train/data_loader.tern")),
169        "nn::train::early_stopping" => Some(include_str!("../stdlib/nn/train/early_stopping.tern")),
170        "nn::train::profiler" => Some(include_str!("../stdlib/nn/train/profiler.tern")),
171        "nn::train::regularization" => Some(include_str!("../stdlib/nn/train/regularization.tern")),
172        "qnn::entanglement" => Some(include_str!("../stdlib/premium/qnn/entanglement.tern")),
173        "qnn::qnn_circuit" => Some(include_str!("../stdlib/premium/qnn/qnn_circuit.tern")),
174        "qnn::qnn_layer" => Some(include_str!("../stdlib/premium/qnn/qnn_layer.tern")),
175        "qnn::qutrit" => Some(include_str!("../stdlib/premium/qnn/qutrit.tern")),
176        "qnn::variational" => Some(include_str!("../stdlib/premium/qnn/variational.tern")),
177        "reasoning::bayesian" => Some(include_str!("../stdlib/premium/reasoning/bayesian.tern")),
178        "reasoning::causal" => Some(include_str!("../stdlib/premium/reasoning/causal.tern")),
179        "reasoning::contradiction" => Some(include_str!("../stdlib/premium/reasoning/contradiction.tern")),
180        "reasoning::temporal" => Some(include_str!("../stdlib/premium/reasoning/temporal.tern")),
181        "reasoning::uncertainty" => Some(include_str!("../stdlib/premium/reasoning/uncertainty.tern")),
182        "research::constitutional_trit" => Some(include_str!("../stdlib/research/constitutional_trit.tern")),
183        "research::moe_routing" => Some(include_str!("../stdlib/research/moe_routing.tern")),
184        "research::sparse_moe" => Some(include_str!("../stdlib/research/sparse_moe.tern")),
185        "research::ternary_ppo" => Some(include_str!("../stdlib/research/ternary_ppo.tern")),
186        "research::ternary_ssm" => Some(include_str!("../stdlib/research/ternary_ssm.tern")),
187        "research::trit_attention" => Some(include_str!("../stdlib/research/trit_attention.tern")),
188        "research::trit_diffusion" => Some(include_str!("../stdlib/research/trit_diffusion.tern")),
189        "research::trit_kv_cache" => Some(include_str!("../stdlib/research/trit_kv_cache.tern")),
190        "research::trit_memory" => Some(include_str!("../stdlib/research/trit_memory.tern")),
191        "research::trit_pruning" => Some(include_str!("../stdlib/research/trit_pruning.tern")),
192        "research::trit_quantization" => Some(include_str!("../stdlib/research/trit_quantization.tern")),
193        "research::tritformer" => Some(include_str!("../stdlib/research/tritformer.tern")),
194        "rl::actor_critic" => Some(include_str!("../stdlib/rl/actor_critic.tern")),
195        "rl::environment" => Some(include_str!("../stdlib/rl/environment.tern")),
196        "rl::episode" => Some(include_str!("../stdlib/rl/episode.tern")),
197        "rl::exploration" => Some(include_str!("../stdlib/rl/exploration.tern")),
198        "rl::policy" => Some(include_str!("../stdlib/rl/policy.tern")),
199        "rl::q_learning" => Some(include_str!("../stdlib/rl/q_learning.tern")),
200        "rl::reward_shaping" => Some(include_str!("../stdlib/rl/reward_shaping.tern")),
201        "rl::value_fn" => Some(include_str!("../stdlib/rl/value_fn.tern")),
202        "safety::adversarial" => Some(include_str!("../stdlib/safety/adversarial.tern")),
203        "safety::alignment_check" => Some(include_str!("../stdlib/safety/alignment_check.tern")),
204        "safety::calibration" => Some(include_str!("../stdlib/safety/calibration.tern")),
205        "safety::conformal" => Some(include_str!("../stdlib/safety/conformal.tern")),
206        "safety::content_gate" => Some(include_str!("../stdlib/safety/content_gate.tern")),
207        "safety::fairness" => Some(include_str!("../stdlib/safety/fairness.tern")),
208        "safety::ood_detect" => Some(include_str!("../stdlib/safety/ood_detect.tern")),
209        "safety::uncertainty_quant" => Some(include_str!("../stdlib/safety/uncertainty_quant.tern")),
210        "stats::bayesian_inference" => Some(include_str!("../stdlib/stats/bayesian_inference.tern")),
211        "stats::confidence_interval" => Some(include_str!("../stdlib/stats/confidence_interval.tern")),
212        "stats::correlation" => Some(include_str!("../stdlib/stats/correlation.tern")),
213        "stats::distributions" => Some(include_str!("../stdlib/stats/distributions.tern")),
214        "stats::hypothesis_test" => Some(include_str!("../stdlib/stats/hypothesis_test.tern")),
215        "stats::information_theory" => Some(include_str!("../stdlib/stats/information_theory.tern")),
216        "stats::regression_stats" => Some(include_str!("../stdlib/stats/regression_stats.tern")),
217        "std::collections" => Some(include_str!("../stdlib/std/collections.tern")),
218        "std::graph" => Some(include_str!("../stdlib/std/graph.tern")),
219        "std::io" => Some(include_str!("../stdlib/std/io.tern")),
220        "std::logic" => Some(include_str!("../stdlib/std/logic.tern")),
221        "std::math" => Some(include_str!("../stdlib/std/math.tern")),
222        "std::memory" => Some(include_str!("../stdlib/std/memory.tern")),
223        "std::signal" => Some(include_str!("../stdlib/std/signal.tern")),
224        "std::tensor" => Some(include_str!("../stdlib/std/tensor.tern")),
225        "std::trit" => Some(include_str!("../stdlib/std/trit.tern")),
226        "ternary::arithmetic" => Some(include_str!("../stdlib/ternary/arithmetic.tern")),
227        "ternary::consensus" => Some(include_str!("../stdlib/ternary/consensus.tern")),
228        "ternary::encoding" => Some(include_str!("../stdlib/ternary/encoding.tern")),
229        "ternary::gates" => Some(include_str!("../stdlib/ternary/gates.tern")),
230        "testing::assert" => Some(include_str!("../stdlib/testing/assert.tern")),
231        "testing::mock" => Some(include_str!("../stdlib/testing/mock.tern")),
232        "testing::suite" => Some(include_str!("../stdlib/testing/suite.tern")),
233        "timeseries::anomaly_ts" => Some(include_str!("../stdlib/timeseries/anomaly_ts.tern")),
234        "timeseries::changepoint" => Some(include_str!("../stdlib/timeseries/changepoint.tern")),
235        "timeseries::decomposition" => Some(include_str!("../stdlib/timeseries/decomposition.tern")),
236        "timeseries::features" => Some(include_str!("../stdlib/timeseries/features.tern")),
237        "timeseries::forecasting" => Some(include_str!("../stdlib/timeseries/forecasting.tern")),
238        "timeseries::lstm_forecast" => Some(include_str!("../stdlib/timeseries/lstm_forecast.tern")),
239        "timeseries::tcn" => Some(include_str!("../stdlib/timeseries/tcn.tern")),
240        "tutorials::01_hello_ternary" => Some(include_str!("../stdlib/tutorials/01_hello_ternary.tern")),
241        "tutorials::02_match_exhaustive" => Some(include_str!("../stdlib/tutorials/02_match_exhaustive.tern")),
242        "tutorials::03_tensors" => Some(include_str!("../stdlib/tutorials/03_tensors.tern")),
243        "tutorials::04_sparse_ops" => Some(include_str!("../stdlib/tutorials/04_sparse_ops.tern")),
244        "tutorials::05_functions" => Some(include_str!("../stdlib/tutorials/05_functions.tern")),
245        "tutorials::06_structs" => Some(include_str!("../stdlib/tutorials/06_structs.tern")),
246        "tutorials::07_agents" => Some(include_str!("../stdlib/tutorials/07_agents.tern")),
247        "tutorials::08_multi_agent" => Some(include_str!("../stdlib/tutorials/08_multi_agent.tern")),
248        "tutorials::09_ml_basics" => Some(include_str!("../stdlib/tutorials/09_ml_basics.tern")),
249        "tutorials::10_attention" => Some(include_str!("../stdlib/tutorials/10_attention.tern")),
250        "tutorials::11_training_loop" => Some(include_str!("../stdlib/tutorials/11_training_loop.tern")),
251        "tutorials::12_uncertainty" => Some(include_str!("../stdlib/tutorials/12_uncertainty.tern")),
252        "tutorials::13_consensus" => Some(include_str!("../stdlib/tutorials/13_consensus.tern")),
253        "tutorials::14_full_pipeline" => Some(include_str!("../stdlib/tutorials/14_full_pipeline.tern")),
254        "tutorials::15_ternary_philosophy" => Some(include_str!("../stdlib/tutorials/15_ternary_philosophy.tern")),
255        "vision::augmentation_2d" => Some(include_str!("../stdlib/vision/augmentation_2d.tern")),
256        "vision::feature_extractor" => Some(include_str!("../stdlib/vision/feature_extractor.tern")),
257        "vision::image_classifier" => Some(include_str!("../stdlib/vision/image_classifier.tern")),
258        "vision::image_ops" => Some(include_str!("../stdlib/vision/image_ops.tern")),
259        "vision::object_gate" => Some(include_str!("../stdlib/vision/object_gate.tern")),
260        "vision::segmentation_gate" => Some(include_str!("../stdlib/vision/segmentation_gate.tern")),
261
262        _ => None,
263    }
264}
265
266// ─── Shared helpers ──────────────────────────────────────────────────────────
267
268/// Recursively collect `use` paths from a slice of statements.
269fn collect_use_paths(stmts: &[Stmt]) -> Vec<Vec<String>> {
270    let mut paths = Vec::new();
271    for stmt in stmts {
272        match stmt {
273            Stmt::Use { path } => paths.push(path.clone()),
274            Stmt::Block(inner) => paths.extend(collect_use_paths(inner)),
275            Stmt::IfTernary { on_pos, on_zero, on_neg, .. } => {
276                paths.extend(collect_use_paths(&[*on_pos.clone()]));
277                paths.extend(collect_use_paths(&[*on_zero.clone()]));
278                paths.extend(collect_use_paths(&[*on_neg.clone()]));
279            }
280            Stmt::Match { arms, .. } => {
281                for (_, arm_stmt) in arms {
282                    paths.extend(collect_use_paths(&[arm_stmt.clone()]));
283                }
284            }
285            _ => {}
286        }
287    }
288    paths
289}
290
291/// Parse source string and extract its functions; deduplicate against `known`.
292fn parse_and_extract(src: &str, key: &str, known: &mut std::collections::HashSet<String>) -> Vec<Function> {
293    let mut parser = Parser::new(src);
294    match parser.parse_program() {
295        Ok(prog) => prog.functions.into_iter().filter(|f| known.insert(f.name.clone())).collect(),
296        Err(e)   => { eprintln!("[MOD-000] Failed to parse module '{key}': {e}"); vec![] }
297    }
298}
299
300/// Resolve all `use` paths, injecting matching functions into `program`.
301/// `extra_source` is called for paths not found in the stdlib — returns `Option<String>`.
302fn resolve_with<F>(program: &mut Program, extra_source: F)
303where
304    F: Fn(&[String]) -> Option<String>,
305{
306    let mut known: std::collections::HashSet<String> =
307        program.functions.iter().map(|f| f.name.clone()).collect();
308
309    let mut all_paths: Vec<Vec<String>> = program.imports.clone();
310
311    // Collect from regular functions
312    for f in &program.functions {
313        all_paths.extend(collect_use_paths(&f.body));
314    }
315
316    // Collect from agents
317    for agent in &program.agents {
318        for method in &agent.methods {
319            all_paths.extend(collect_use_paths(&method.body));
320        }
321    }
322
323    all_paths.sort();
324    all_paths.dedup();
325
326    let mut injected: Vec<Function> = Vec::new();
327
328    for path in &all_paths {
329        let key = path.join("::");
330        if let Some(src) = stdlib_source_for(path) {
331            injected.extend(parse_and_extract(src, &key, &mut known));
332        } else if let Some(src) = extra_source(path) {
333            injected.extend(parse_and_extract(&src, &key, &mut known));
334        } else {
335            eprintln!("[MOD-001] Unknown module '{key}' — no stdlib match and no file found. Did you mean std::trit?");
336        }
337    }
338
339    injected.extend(program.functions.drain(..));
340    program.functions = injected;
341}
342
343// ─── StdlibLoader (backwards-compat, stdlib-only) ────────────────────────────
344
345pub struct StdlibLoader;
346
347impl StdlibLoader {
348    /// Resolve stdlib `use` statements in `program`.  User-defined modules are
349    /// left for a `ModuleResolver` to handle.
350    pub fn resolve(program: &mut Program) {
351        resolve_with(program, |_| None);
352    }
353}
354
355// ─── ModuleResolver (stdlib + user-defined cross-file modules) ───────────────
356
357/// Full module resolver.  Resolves stdlib built-ins AND user `.tern` modules
358/// found relative to a source file's directory.
359///
360/// # Usage
361/// ```ignore
362/// let mut resolver = ModuleResolver::from_source_file(Path::new("src/main.tern"));
363/// resolver.resolve(&mut program);
364/// ```
365pub struct ModuleResolver {
366    base_dir: Option<std::path::PathBuf>,
367}
368
369impl ModuleResolver {
370    /// Resolve relative to the directory containing `source_file`.
371    pub fn from_source_file(source_file: &std::path::Path) -> Self {
372        Self { base_dir: source_file.parent().map(|p| p.to_path_buf()) }
373    }
374
375    /// Resolve relative to `dir` (directory, not file).
376    pub fn from_dir(dir: std::path::PathBuf) -> Self {
377        Self { base_dir: Some(dir) }
378    }
379
380    /// Stdlib-only resolver (no file-system access). Equivalent to `StdlibLoader`.
381    pub fn stdlib_only() -> Self {
382        Self { base_dir: None }
383    }
384
385    /// Attempt to load `path` (e.g. `["mymod", "utils"]`) as `base_dir/mymod/utils.tern`.
386    fn load_user_module(&self, path: &[String]) -> Option<String> {
387        let base = self.base_dir.as_ref()?;
388        let mut file_path = base.clone();
389        for (i, segment) in path.iter().enumerate() {
390            if i == path.len() - 1 {
391                file_path = file_path.join(format!("{segment}.tern"));
392            } else {
393                file_path = file_path.join(segment);
394            }
395        }
396        match std::fs::read_to_string(&file_path) {
397            Ok(src) => Some(src),
398            Err(_)  => None,
399        }
400    }
401
402    /// Resolve all `use` statements: stdlib first, then user files.
403    pub fn resolve(&self, program: &mut Program) {
404        resolve_with(program, |path| self.load_user_module(path));
405    }
406}
407
408#[cfg(test)]
409mod tests {
410    use super::*;
411    use crate::parser::Parser;
412
413    /// Verify that each stdlib module parses without errors.
414    #[test]
415    fn all_stdlib_modules_parse() {
416        let modules = [
417            vec!["std".to_string(), "trit".to_string()],
418            vec!["std".to_string(), "math".to_string()],
419            vec!["std".to_string(), "tensor".to_string()],
420            vec!["std".to_string(), "io".to_string()],
421            vec!["ml".to_string(), "quantize".to_string()],
422            vec!["ml".to_string(), "inference".to_string()],
423            vec!["classical".to_string(), "svm".to_string()],
424            vec!["nn".to_string(), "dense".to_string()],
425            vec!["models".to_string(), "gpt_analog".to_string()],
426            vec!["research".to_string(), "tritformer".to_string()],
427        ];
428        for path in &modules {
429            let src = stdlib_source_for(path)
430                .unwrap_or_else(|| panic!("Missing stdlib source for {}", path.join("::")));
431            let mut parser = Parser::new(src);
432            parser.parse_program()
433                .unwrap_or_else(|e| panic!("Parse error in {}: {:?}", path.join("::"), e));
434        }
435    }
436
437    /// A program with `use std::trit;` should gain abs/min/max/etc after resolve.
438    #[test]
439    fn resolve_injects_trit_stdlib() {
440        let src = r#"
441fn main() -> trit {
442    use std::trit;
443    let x: trit = abs(-1);
444    return x;
445}
446"#;
447        let mut parser = Parser::new(src);
448        let mut prog = parser.parse_program().expect("parse failed");
449        assert!(!prog.functions.iter().any(|f| f.name == "abs"),
450            "abs should not be present before resolve");
451        StdlibLoader::resolve(&mut prog);
452        assert!(prog.functions.iter().any(|f| f.name == "abs"),
453            "abs should be injected after resolve");
454        assert!(prog.functions.iter().any(|f| f.name == "min"));
455        assert!(prog.functions.iter().any(|f| f.name == "majority"));
456    }
457
458    /// Multiple use statements should all be resolved, with no duplicates.
459    #[test]
460    fn resolve_multiple_modules_no_duplicates() {
461        let src = r#"
462fn main() -> trit {
463    use std::trit;
464    use std::math;
465    let x: trit = neg(1);
466    return x;
467}
468"#;
469        let mut parser = Parser::new(src);
470        let mut prog = parser.parse_program().expect("parse failed");
471        StdlibLoader::resolve(&mut prog);
472
473        // Count how many times "neg" appears — should be exactly 1
474        let neg_count = prog.functions.iter().filter(|f| f.name == "neg").count();
475        assert_eq!(neg_count, 1, "neg should appear exactly once");
476
477        // Both modules should be present
478        assert!(prog.functions.iter().any(|f| f.name == "abs"));   // std::trit
479        assert!(prog.functions.iter().any(|f| f.name == "rectify")); // std::math
480    }
481
482    /// Resolve is idempotent — calling it twice should not duplicate functions.
483    #[test]
484    fn resolve_is_idempotent() {
485        let src = r#"
486fn main() -> trit {
487    use std::trit;
488    return 0;
489}
490"#;
491        let mut parser = Parser::new(src);
492        let mut prog = parser.parse_program().expect("parse failed");
493        StdlibLoader::resolve(&mut prog);
494        StdlibLoader::resolve(&mut prog);
495        let abs_count = prog.functions.iter().filter(|f| f.name == "abs").count();
496        assert_eq!(abs_count, 1, "abs should not be duplicated by double resolve");
497    }
498
499    /// Unknown module paths are silently skipped (not a hard error).
500    #[test]
501    fn unknown_module_skipped_gracefully() {
502        let src = r#"
503fn main() -> trit {
504    use std::nonexistent;
505    return 0;
506}
507"#;
508        let mut parser = Parser::new(src);
509        let mut prog = parser.parse_program().expect("parse failed");
510        // Should not panic
511        StdlibLoader::resolve(&mut prog);
512    }
513}