1use std::{collections::HashMap, rc::Rc};
2
3use crate::{errors::*, object::Object};
4
5pub struct Lisp<'a> {
6 scope: Vec<HashMap<String, Rc<Object>>>,
7 pub globals: &'a mut HashMap<String, Rc<Object>>,
8}
9
10impl<'a> Lisp<'a> {
11 pub fn new(globals: &'a mut HashMap<String, Rc<Object>>) -> Self {
12 Self {
13 scope: vec![HashMap::new()],
14 globals,
15 }
16 }
17
18 pub fn scope_create(&mut self) {
20 self.scope.push(HashMap::new());
21 }
22
23 pub fn scope_end(&mut self) {
25 self.scope.pop();
26 }
27
28 pub fn add_var(
29 &mut self,
30 global: bool,
31 name: &str,
32 object: Rc<Object>,
33 ) -> Result<&mut Self, LispError> {
34 if global {
35 match self.globals.get(name) {
36 Some(_) => {
37 return Err(LispError::new(
38 LispErrorKind::Eval,
39 EvalError::GlobalExists(name.to_string()),
40 ))
41 }
42 None => self.globals.insert(name.to_string(), object),
43 }
44 } else {
45 let len = self.scope.len();
46 self.scope[len - 1].insert(name.to_string(), object)
47 };
48
49 Ok(self)
50 }
51
52 pub fn add_func(
53 &mut self,
54 global: bool,
55 name: &str,
56 func: fn(&mut Lisp, Rc<Object>) -> RustFuncResult,
57 ) -> Result<&mut Self, LispError> {
58 self.add_var(global, name, Rc::new(Object::RustFunc(func)))
59 }
60
61 fn eval_symbol(&self, symbol: &str) -> LispResult {
62 if !symbol.is_empty() {
63 for s in self.scope.iter().rev() {
64 if let Some(o) = s.get(symbol) {
65 return Ok(o.clone());
66 }
67 }
68
69 match self.globals.get(symbol) {
71 Some(o) => Ok(o.clone()),
72 None => Err(LispError::new(
73 LispErrorKind::Eval,
74 EvalError::UnknownSymbol(symbol.to_string()),
75 )),
76 }
77 } else {
78 Ok(Rc::new(Object::Nil))
79 }
80 }
81
82 pub fn set_var(&mut self, symbol: &str, data: Rc<Object>) -> Result<(), LispError> {
83 for v in self.scope.iter_mut().rev() {
85 if let Some(s) = v.get_mut(symbol) {
86 *s = data;
87 return Ok(());
88 }
89 }
90
91 self.add_var(false, symbol, data)?;
93
94 Ok(())
95 }
96
97 pub fn eval_object(&mut self, object: Rc<Object>) -> LispResult {
98 match &*object {
101 Object::Pair(ref f, ref a) => {
102 match &*self.eval_object(f.clone())? {
104 Object::RustFunc(f) => match f(self, Rc::clone(a)) {
105 Ok(x) => Ok(x),
106 Err(e) => Err(LispError::new(LispErrorKind::RustFunc, e)),
107 },
108 Object::LispFunc(p, b) => {
109 let mut args = Vec::new();
110 let objects = b.iter().map(Rc::clone).collect(); let mut cur_object = a;
114
115 loop {
116 match &**cur_object {
117 Object::Pair(a, b) => {
118 args.push(self.eval_object(a.clone())?);
119
120 cur_object = b
121 }
122 Object::Nil => break,
123 _ => {
124 return Err(LispError::new(
125 LispErrorKind::RustFunc,
126 RustFuncError::new_args_error(ArgumentsError::DottedPair),
127 ))
128 }
129 }
130 }
131
132 let mut scope = Lisp::new(self.globals);
133
134 for (i, p) in p.iter().enumerate() {
135 match args.get(i) {
136 Some(a) => scope.add_var(false, p, a.clone())?,
137 None => {
138 return Err(LispError::new(
139 LispErrorKind::RustFunc,
140 RustFuncError::new_args_error(ArgumentsError::NotEnough),
141 ))
142 }
143 };
144 }
145
146 scope.eval_objects(objects)
148 }
149 Object::Character(_) => Ok(Rc::clone(&object)),
150 _ => Err(LispError::new(
151 LispErrorKind::Eval,
152 EvalError::NonFunction(Rc::clone(&object)),
153 )),
154 }
155 }
156 Object::Symbol(s) => Ok(self.eval_symbol(s)?),
157 Object::Quoted(o) => Ok(Rc::clone(o)),
158 _ => Ok(object),
159 }
160 }
161
162 pub fn eval_objects(&mut self, objects: Vec<Rc<Object>>) -> LispResult {
163 let mut ret = Rc::new(Object::Nil);
164
165 for o in objects {
166 ret = self.eval_object(o)?
167 }
168
169 Ok(ret)
170 }
171
172 pub fn eval(&mut self, input: &str) -> LispResult {
173 let objects = Object::eval(input)?; let objects = objects.into_iter().map(Rc::new).collect(); self.eval_objects(objects)
177 }
178}