1#![allow(clippy::result_large_err)]
2#![allow(clippy::type_complexity)]
3
4use cljrs_builtins::builtins;
5use cljrs_env::env::{Env, GlobalEnv};
6use cljrs_env::error::EvalResult;
7use cljrs_reader::Form;
8use cljrs_value::{CljxFn, Value};
9use std::sync::Arc;
10
11pub mod apply;
12mod arity;
13pub mod destructure;
14pub mod eval;
15pub mod macros;
16pub mod special;
17pub mod syntax_quote;
18#[cfg(not(target_arch = "wasm32"))]
19pub mod versioned;
20mod virtualize;
21
22pub fn standard_env_minimal(
29 eval_fn: Option<fn(&Form, &mut Env) -> EvalResult>,
30 call_cljrs_fn: Option<fn(&CljxFn, &[Value], &mut Env) -> EvalResult>,
31 on_fn_defined: Option<fn(&CljxFn, &mut Env)>,
32) -> Arc<GlobalEnv> {
33 let globals = GlobalEnv::new(
34 eval_fn.unwrap_or(eval::eval),
35 call_cljrs_fn.unwrap_or(apply::call_cljrs_fn),
36 on_fn_defined,
37 );
38
39 builtins::register_all(&globals, "clojure.core");
41
42 globals.get_or_create_ns("user");
44 globals.refer_all("user", "clojure.core");
45
46 {
48 let mut env = Env::new(globals.clone(), "clojure.core");
49 let src = builtins::BOOTSTRAP_SOURCE;
50 let mut parser = cljrs_reader::Parser::new(src.to_string(), "<bootstrap>".to_string());
51 match parser.parse_all() {
52 Ok(forms) => {
53 for form in forms {
54 let _alloc_frame = cljrs_gc::push_alloc_frame();
55 if let Err(e) = eval::eval(&form, &mut env) {
56 eprintln!("[bootstrap warning] {}: {:?}", form.span.start, e);
57 }
58 }
59 }
60 Err(e) => eprintln!("[bootstrap parse error] {:?}", e),
61 }
62 }
63
64 globals.refer_all("user", "clojure.core");
66
67 globals.mark_loaded("clojure.core");
69
70 {
72 let mut env = Env::new(globals.clone(), "user");
73 special::sync_star_ns(&mut env);
74 }
75
76 globals
77}
78
79pub fn standard_env(
86 eval_fn: Option<fn(&Form, &mut Env) -> EvalResult>,
87 call_cljrs_fn: Option<fn(&CljxFn, &[Value], &mut Env) -> EvalResult>,
88 on_fn_defined: Option<fn(&CljxFn, &mut Env)>,
89) -> Arc<GlobalEnv> {
90 let globals = standard_env_minimal(eval_fn, call_cljrs_fn, on_fn_defined);
91
92 {
94 let mut env = Env::new(globals.clone(), "clojure.core");
95 let src = builtins::CLOJURE_TEST_SOURCE;
96 let mut parser = cljrs_reader::Parser::new(src.to_string(), "<clojure.test>".to_string());
97 match parser.parse_all() {
98 Ok(forms) => {
99 for form in forms {
100 let _alloc_frame = cljrs_gc::push_alloc_frame();
101 if let Err(e) = eval::eval(&form, &mut env) {
102 eprintln!("[clojure.test warning] {}: {:?}", form.span.start, e);
103 }
104 }
105 }
106 Err(e) => eprintln!("[clojure.test parse error] {:?}", e),
107 }
108 globals.mark_loaded("clojure.test");
109 }
110
111 {
118 let mut env = Env::new(globals.clone(), "user");
119 special::sync_star_ns(&mut env);
120 }
121
122 globals
123}
124
125pub fn standard_env_with_paths(
127 eval_fn: Option<fn(&Form, &mut Env) -> EvalResult>,
128 call_cljrs_fn: Option<fn(&CljxFn, &[Value], &mut Env) -> EvalResult>,
129 on_fn_defined: Option<fn(&CljxFn, &mut Env)>,
130 source_paths: Vec<std::path::PathBuf>,
131) -> Arc<GlobalEnv> {
132 let globals = standard_env(eval_fn, call_cljrs_fn, on_fn_defined);
133 globals.set_source_paths(source_paths);
134 globals
135}