nyavascript/evaluate/environment/fun_scope/
mod.rs

1#[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}