1pub mod evaluate;
2pub mod s_expression;
3pub mod parse;
4
5use evaluate::{ Environment, evaluate, McCarthyScope, FunScope };
6use s_expression::SExpressionRef;
7use parse::parse;
8use std::error::Error;
9
10pub fn run(text: &str) -> Result<SExpressionRef, Box<dyn Error>> {
11 let parsed = parse(text)?;
12
13 let mut context = Environment::new();
14 context.push_lib(McCarthyScope::new());
15 context.push_lib(FunScope::new());
16
17 let ret = evaluate(parsed, &mut context)?;
18
19 Ok(ret)
20}
21
22#[cfg(test)]
23mod test {
24 use super::*;
25 use crate::s_expression::{
26 SExpressionRef as SXRef,
27 ConsCell,
28 };
29
30 #[test]
31 fn pipe() {
32 let code = "(|> '(1 2) (cdr) (cons 4) (quote))";
33
34 let expected = SXRef::from(vec![
35 SXRef::number(4),
36 SXRef::number(2),
37 ]);
38
39 let actual = run(code).unwrap();
40
41 assert_eq!(expected, actual);
42 }
43
44 #[test]
45 fn list_fns() {
46 let code = "(cons (car '(1 2)) (cdr '(3 4)))";
47
48 let expected = SXRef::from(vec![
49 SXRef::number(1),
50 SXRef::number(4),
51 ]);
52
53 let actual = run(code).unwrap();
54
55 assert_eq!(expected, actual);
56 }
57
58 #[test]
59 fn dot_notation() {
60 let code = "(cons (car '(1 . 2)) (cdr '(3 . 4)))";
61
62 let expected = SXRef::cons_cell(ConsCell::new(
63 SXRef::number(1),
64 SXRef::number(4),
65 ));
66
67 let actual = run(code).unwrap();
68
69 assert_eq!(expected, actual);
70 }
71}