1use crate::inline_modules;
2use cl_ast::{At, Expr};
3use cl_interpret::{builtin::builtins, convalue::ConValue, env::Environment, interpret::Interpret};
4use cl_lexer::Lexer;
5use cl_parser::Parser;
6
7pub fn get_env() -> Environment {
8 let mut env = Environment::new();
9 env.add_builtins(&builtins! {
10 fn eval(string) @env {
12 use cl_interpret::error::Error;
13 let string = match string {
14 ConValue::Str(string) => string.to_ref(),
15 ConValue::String(string) => string.as_str(),
16 ConValue::Ref(v) => {
17 let string = v.get(env).cloned().unwrap_or_default();
18 return eval(env, &[string])
19 }
20 _ => Err(Error::TypeError("string", string.typename()))?
21 };
22
23
24
25 match Parser::new(Lexer::new("eval".into(), string)).parse::<At<Expr>>(0).map(inline_modules) {
26 Err(e) => Ok(ConValue::String(format!("{e}"))),
27 Ok(v) => v.interpret(env),
28 }
29 }
30
31 fn putchar(ConValue::Char(c)) {
32 print!("{c}");
33 Ok(ConValue::Empty)
34 }
35
36 fn get_line(prompt) {
38 use cl_interpret::error::Error;
39 let prompt = match prompt {
40 ConValue::Str(prompt) => prompt.to_ref(),
41 ConValue::String(prompt) => prompt.as_str(),
42 _ => Err(Error::TypeError("string", prompt.typename()))?,
43 };
44 match repline::Repline::new("", prompt, "").read() {
45 Ok(line) => Ok(ConValue::String(line)),
46 Err(repline::Error::CtrlD(line)) => Ok(ConValue::String(line)),
47 Err(repline::Error::CtrlC(_)) => Err(cl_interpret::error::Error::Break(ConValue::Empty)),
48 Err(e) => Ok(ConValue::String(e.to_string())),
49 }
50 }
51 });
52 env
53}