nyavascript/evaluate/environment/fun_scope/
mod.rs1#[cfg(test)]
2mod test;
3
4use super::Scope;
5use crate::evaluate::{
6 evaluate,
7 Environment as Env,
8 Result as EvalResult,
9};
10use crate::s_expression::{
11 RustFunction,
12 RustMacro,
13 SExpression as SX,
14 SExpressionRef as SXRef,
15 util,
16};
17
18pub struct FunScope;
19
20impl FunScope {
21 pub fn new() -> Scope {
22 let mut ret = Scope::new();
23
24 ret.insert(
25 "|>".into(),
26 RustMacro::new(Self::pipe).into(),
27 );
28
29 ret.insert(
30 ";".into(),
31 RustMacro::new(Self::procedural).into(),
32 );
33
34 ret.insert(
35 "println".into(),
36 RustFunction::new(
37 |args, _env| {
38 match args.get(0) {
39 Some(sx) => match &**sx {
40 SX::Nil => println!(),
41 SX::Macro(_) => println!("[macro]"),
42 SX::Function(_) => println!("[function]"),
43 SX::Number(n) => println!("{}", n),
44 SX::String(s) => println!("{}", s),
45 SX::Symbol(s) => println!("{}", s),
46 SX::Quote(q) => println!("'{}", q),
47 SX::ConsCell(c) => println!("{}", c),
48 },
49 None => println!(),
50 }
51
52 Ok(SXRef::nil())
53 }
54 ).into(),
55 );
56
57 ret
58 }
59
60 pub fn pipe(sx: SXRef, env: &mut Env) -> EvalResult {
61 let mut it = sx.iter().skip(1);
62
63 if let Some(first) = it.next() {
64 let first = evaluate(first, env)?;
65
66 let mut last = first;
67
68 for arg in it {
69 let arg = util::push(&arg, &SXRef::quote(last));
70 last = evaluate(arg, env)?;
71 }
72
73 Ok(last)
74 } else {
75 Ok(SXRef::nil())
76 }
77 }
78
79 pub fn procedural(sx: SXRef, env: &mut Env) -> EvalResult {
80 let mut last = SXRef::nil();
81
82 for sx in sx.iter().skip(1) {
83 last = evaluate(sx, env)?;
84 }
85
86 Ok(last)
87 }
88}