1use crate::{Environment, builtin::MultiFunctionType, eval::apply::eval_apply, value::Value};
10
11pub(crate) fn builtin(args: &[Value], func_type: MultiFunctionType, env: Environment) -> Result<Value, std::sync::Arc<str>> {
12 if let [v1, rest @ ..] = args {
13 match (eval_apply(v1, env.clone())?, &func_type) {
14 (Value::Number(n1), MultiFunctionType::Add) => {
15 let mut result = n1;
16 for val in rest.iter() {
17 match eval_apply(val, env.clone())? {
18 Value::Number(n) => result += n,
19 e => {
20 return Err(std::sync::Arc::from(format!(
21 concat!("Error[ksl::builtin::{:?}]: ", "Unexpected value: `{}`."),
22 func_type, e
23 )));
24 }
25 }
26 }
27 Ok(Value::Number(result))
28 }
29 (Value::Number(n1), MultiFunctionType::Mul) => {
30 let mut result = n1;
31 for val in rest.iter() {
32 match eval_apply(val, env.clone())? {
33 Value::Number(n) => result *= n,
34 e => {
35 return Err(std::sync::Arc::from(format!(
36 concat!("Error[ksl::builtin::{:?}]: ", "Unexpected value: `{}`."),
37 func_type, e
38 )));
39 }
40 }
41 }
42 Ok(Value::Number(result))
43 }
44 (Value::String(s1), MultiFunctionType::Concat) => {
45 let mut result = s1.to_string();
46 for val in rest.iter() {
47 match eval_apply(val, env.clone())? {
48 Value::String(s) => result.push_str(&s),
49 e => {
50 return Err(std::sync::Arc::from(format!(
51 concat!("Error[ksl::builtin::{:?}]: ", "Unexpected value: `{}`."),
52 func_type, e
53 )));
54 }
55 }
56 }
57 Ok(Value::String(std::sync::Arc::from(result)))
58 }
59 (Value::List(lst1), MultiFunctionType::Concat) => {
60 let mut result = lst1.to_vec();
61 for val in rest.iter() {
62 match eval_apply(val, env.clone())? {
63 Value::List(lst) => result.extend_from_slice(&lst),
64 e => {
65 return Err(std::sync::Arc::from(format!(
66 concat!("Error[ksl::builtin::{:?}]: ", "Unexpected value: `{}`."),
67 func_type, e
68 )));
69 }
70 }
71 }
72 Ok(Value::List(std::sync::Arc::from(result)))
73 }
74
75 (e @ (Value::String(_) | Value::List(_)), MultiFunctionType::Add | MultiFunctionType::Mul) => {
76 Err(std::sync::Arc::from(format!(
77 concat!("Error[ksl::builtin::{:?}]: ", "Unexpected value: `{}`."),
78 func_type, e
79 )))
80 }
81 (e @ Value::Number(_), MultiFunctionType::Concat) => Err(std::sync::Arc::from(format!(
82 concat!("Error[ksl::builtin::{:?}]: ", "Unexpected value: `{}`."),
83 func_type, e
84 ))),
85 (e, _) => Err(std::sync::Arc::from(format!(
86 concat!("Error[ksl::builtin::{:?}]: ", "Unexpected value: `{}`."),
87 func_type, e
88 ))),
89 }
90 } else {
91 Err(std::sync::Arc::from(format!(
92 concat!(
93 "Error[ksl::builtin::{:?}]: ",
94 "Expected at least 1 parameter, but {} were passed."
95 ),
96 func_type,
97 args.len()
98 )))
99 }
100}