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;
18mod virtualize;
19
20pub fn standard_env_minimal(
27 eval_fn: Option<fn(&Form, &mut Env) -> EvalResult>,
28 call_cljrs_fn: Option<fn(&CljxFn, &[Value], &mut Env) -> EvalResult>,
29 on_fn_defined: Option<fn(&CljxFn, &mut Env)>,
30) -> Arc<GlobalEnv> {
31 let globals = GlobalEnv::new(
32 eval_fn.unwrap_or(eval::eval),
33 call_cljrs_fn.unwrap_or(apply::call_cljrs_fn),
34 on_fn_defined,
35 );
36
37 builtins::register_all(&globals, "clojure.core");
39
40 globals.get_or_create_ns("user");
42 globals.refer_all("user", "clojure.core");
43
44 {
46 let mut env = Env::new(globals.clone(), "clojure.core");
47 let src = builtins::BOOTSTRAP_SOURCE;
48 let mut parser = cljrs_reader::Parser::new(src.to_string(), "<bootstrap>".to_string());
49 match parser.parse_all() {
50 Ok(forms) => {
51 for form in forms {
52 let _alloc_frame = cljrs_gc::push_alloc_frame();
53 if let Err(e) = eval::eval(&form, &mut env) {
54 eprintln!("[bootstrap warning] {}: {:?}", form.span.start, e);
55 }
56 }
57 }
58 Err(e) => eprintln!("[bootstrap parse error] {:?}", e),
59 }
60 }
61
62 globals.refer_all("user", "clojure.core");
64
65 globals.mark_loaded("clojure.core");
67
68 {
70 let mut env = Env::new(globals.clone(), "user");
71 special::sync_star_ns(&mut env);
72 }
73
74 globals
75}
76
77pub fn standard_env(
84 eval_fn: Option<fn(&Form, &mut Env) -> EvalResult>,
85 call_cljrs_fn: Option<fn(&CljxFn, &[Value], &mut Env) -> EvalResult>,
86 on_fn_defined: Option<fn(&CljxFn, &mut Env)>,
87) -> Arc<GlobalEnv> {
88 let globals = standard_env_minimal(eval_fn, call_cljrs_fn, on_fn_defined);
89
90 {
92 let mut env = Env::new(globals.clone(), "clojure.core");
93 let src = builtins::CLOJURE_TEST_SOURCE;
94 let mut parser = cljrs_reader::Parser::new(src.to_string(), "<clojure.test>".to_string());
95 match parser.parse_all() {
96 Ok(forms) => {
97 for form in forms {
98 let _alloc_frame = cljrs_gc::push_alloc_frame();
99 if let Err(e) = eval::eval(&form, &mut env) {
100 eprintln!("[clojure.test warning] {}: {:?}", form.span.start, e);
101 }
102 }
103 }
104 Err(e) => eprintln!("[clojure.test parse error] {:?}", e),
105 }
106 globals.mark_loaded("clojure.test");
107 }
108
109 {
116 let mut env = Env::new(globals.clone(), "user");
117 special::sync_star_ns(&mut env);
118 }
119
120 globals
121}
122
123pub fn standard_env_with_paths(
125 eval_fn: Option<fn(&Form, &mut Env) -> EvalResult>,
126 call_cljrs_fn: Option<fn(&CljxFn, &[Value], &mut Env) -> EvalResult>,
127 on_fn_defined: Option<fn(&CljxFn, &mut Env)>,
128 source_paths: Vec<std::path::PathBuf>,
129) -> Arc<GlobalEnv> {
130 let globals = standard_env(eval_fn, call_cljrs_fn, on_fn_defined);
131 globals.set_source_paths(source_paths);
132 globals
133}