1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//! # ksl::builtin::do_
//!
//! Built-in function `Do`.
use crate::{Environment, eval::apply::eval_apply, value::Value};
pub(crate) fn builtin(args: &[Value], env: &Environment) -> Option<(Value, Environment)> {
let mut local_environment = Environment::new();
if let [func, Value::Identity(id), lst] = &args[..] {
let mut final_result = Value::Unit;
match eval_apply(lst, env) {
Some((Value::List(vals), new_env)) => {
let mut local_env = env.clone();
local_env.extend(new_env);
for val in vals.iter() {
match eval_apply(val, &local_env) {
Some((element, new_env1)) => {
local_env.extend(new_env1);
let _ = local_env.insert(id.clone(), element);
match eval_apply(func, &local_env) {
Some((result, new_env2)) => {
local_env.extend(new_env2.clone());
local_environment.extend(new_env2);
final_result = result;
}
None => {
eprintln!(
concat!(
"Error[ksl::builtin::do]: ",
"Cannot evaluate expression {:?}."
),
func
);
return None;
}
}
}
None => {
eprintln!(
concat!(
"Error[ksl::builtin::do]: ",
"Cannot evaluate expression {:?}."
),
val
);
return None;
}
}
}
// clear leak entry
let _ = local_environment.remove(id);
Some((final_result, local_environment))
}
Some((e, _)) => {
eprintln!(
concat!(
"Error[ksl::builtin::do]: ",
"Expected a list, but got `{:?}`."
),
e
);
None
}
None => {
eprintln!(
concat!(
"Error[ksl::builtin::do]: ",
"Cannot evaluate expression {:?}."
),
lst
);
None
}
}
} else {
eprintln!(
concat!(
"Error[ksl::builtin::do]: ",
"Only accepts an expression, a symbol, ",
"and a list as arguments, but got {:?}.",
),
args
);
None
}
}