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
//! # ksl::builtin::object
//!
//! Built-in function `Object`.
use crate::{Dict, Environment, eval::apply::eval_apply, value::Value};
pub(crate) fn builtin(args: &[Value], env: Environment) -> Result<Value, std::sync::Arc<str>> {
if let [sym] = args {
match sym {
Value::Symbol(type_sym) => Ok(Value::Object(type_sym.clone(), Box::default())),
e => Err(std::sync::Arc::from(format!(
concat!(
"Error[ksl::builtin::Object]: ",
"Expected a symbol as type tag, but got: `{}`."
),
e
))),
}
} else if let [sym, pairs] = args {
match (sym, eval_apply(pairs, env)?) {
(Value::Symbol(type_sym), Value::List(assocs)) => {
let mut dict = Dict::with_capacity_and_hasher(assocs.len(), rustc_hash::FxBuildHasher);
for assoc in assocs.iter() {
match assoc {
Value::List(kv) => match kv.as_ref() {
[Value::Atom(key), e] => {
let _ = dict.insert(key.clone(), std::sync::Arc::new(e.clone()));
}
[e, _] => {
return Err(std::sync::Arc::from(format!(
concat!(
"Error[ksl::builtin::Object]: ",
"Expected an atom as key, but got `{}`."
),
e
)));
}
_ => {
return Err(std::sync::Arc::from(format!(
concat!(
"Error[ksl::builtin::Object]: ",
"Expected a list with length 2, but got `{}`."
),
kv.len()
)));
}
},
e => {
return Err(std::sync::Arc::from(format!(
concat!(
"Error[ksl::builtin::Object]: ",
"Expected a list, but got: `{}`."
),
e
)));
}
}
}
Ok(Value::Object(type_sym.clone(), Box::new(dict)))
}
(Value::Symbol(_), e) => Err(std::sync::Arc::from(format!(
concat!(
"Error[ksl::builtin::Object]: ",
"Expected a list, but got: `{}`."
),
e
))),
(e, _) => Err(std::sync::Arc::from(format!(
concat!(
"Error[ksl::builtin::Object]: ",
"Expected a symbol as type tag, but got: `{}`."
),
e
))),
}
} else {
Err(std::sync::Arc::from(format!(
concat!(
"Error[ksl::builtin::Object]: ",
"Expected 1 or 2 parameters, but {} were passed."
),
args.len()
)))
}
}