1use parser::{AST, Expr, Operation};
2use std::{
3 cell::RefCell,
4 collections::HashMap,
5 io,
6 result::Result as StdResult
7};
8use types::Value;
9
10#[derive(Debug, Fail)]
11pub enum Error {
12 #[fail(display = "attempt to divide by zero")]
13 DivideByZero,
14 #[fail(display = "cannot cast value to that type")]
15 InvalidCast,
16 #[fail(display = "loop variable cannot be casted to numbr")]
17 InvalidCastLoop,
18 #[fail(display = "function {:?} expected {} parameters", _0, _1)]
19 InvalidUsage(String, usize),
20 #[fail(display = "io error: {}", _0)]
21 IoError(io::Error),
22 #[fail(display = "recursion limit reached: can't go more than {} levels deep", _0)]
23 RecursionLimit(usize),
24 #[fail(display = "can't shadow variable from the same scope: {:?}", _0)]
25 ShadowVar(String),
26 #[fail(display = "undefined function {:?}", _0)]
27 UndefinedFunc(String),
28 #[fail(display = "undefined variable {:?}", _0)]
29 UndefinedVar(String)
30}
31
32type Result<T> = StdResult<T, Error>;
33
34pub enum Return {
35 None,
36 Gtfo,
37 Value(Value)
38}
39
40struct Function {
41 args: Vec<String>,
42 block: Vec<AST>
43}
44
45pub struct EvalParams<R: io::BufRead, W: io::Write> {
47 stdin: R,
48 stdout: W,
49
50 funcs: HashMap<String, (Option<usize>, Box<FnMut(Vec<Value>) -> Value>)>,
51 recursion_limit: usize,
52 recursion: usize
53}
54impl<R: io::BufRead, W: io::Write> EvalParams<R, W> {
55 pub fn new(stdin: R, stdout: W) -> Self {
56 Self {
57 stdin: stdin,
58 stdout: stdout,
59
60 funcs: HashMap::new(),
61 recursion_limit: 64,
62 recursion: 0
63 }
64 }
65 pub fn set_recursion_limit(&mut self, limit: usize) {
67 self.recursion_limit = limit;
68 }
69 pub fn bind_func<S, F>(&mut self, name: S, args: Option<usize>, func: F)
71 where S: Into<String>,
72 F: FnMut(Vec<Value>) -> Value + 'static
73 {
74 self.funcs.insert(name.into(), (args, Box::new(func)));
75 }
76 pub fn scope<'a>(self) -> Scope<'a, R, W> {
79 Scope {
80 params: Some(RefCell::new(self)),
81
82 it: RefCell::new(Value::Noob),
83 vars: RefCell::new(HashMap::new()),
84 funcs: RefCell::new(HashMap::new()),
85 parent: None
86 }
87 }
88}
89
90pub struct Scope<'a, R: io::BufRead + 'a, W: io::Write + 'a> {
92 params: Option<RefCell<EvalParams<R, W>>>,
93
94 it: RefCell<Value>,
95 vars: RefCell<HashMap<String, Value>>,
96 funcs: RefCell<HashMap<String, Function>>,
97 parent: Option<&'a Scope<'a, R, W>>
98}
99impl<'a, R: io::BufRead, W: io::Write> Scope<'a, R, W> {
100 pub fn params(&self) -> &RefCell<EvalParams<R, W>> {
101 let mut me = self;
102 while let Some(parent) = me.parent {
103 me = parent;
104 }
105 me.params.as_ref().expect("Missing 'params' on top-level scope")
106 }
107 pub fn find_var<F, T>(&self, name: &str, apply: F) -> Option<T>
108 where F: FnOnce(&mut Value) -> T
109 {
110 let mut me = self;
111 loop {
112 let mut vars = me.vars.borrow_mut();
113 if let Some(var) = vars.get_mut(name) {
114 break Some(apply(var));
115 } else if let Some(parent) = me.parent {
116 me = parent;
117 } else {
118 break None;
119 }
120 }
121 }
122 pub fn call_func(&self, name: &str, args: Vec<Value>) -> Result<Value> {
123 {
124 let params = self.params();
125 let params = &mut params.borrow_mut();
126
127 if let Some(&mut (nargs, ref mut func)) = params.funcs.get_mut(name) {
129 if let Some(nargs) = nargs {
130 if args.len() != nargs {
131 return Err(Error::InvalidUsage(name.to_string(), nargs));
132 }
133 }
134 return Ok(func(args));
135 }
136
137 params.recursion += 1;
139 if params.recursion > params.recursion_limit {
140 return Err(Error::RecursionLimit(params.recursion_limit));
141 }
142 }
143 let mut me = self;
145 Ok(loop {
146 let block = match me.funcs.borrow_mut().get_mut(name) {
147 None => None,
148 Some(the_func) => {
149 if args.len() != the_func.args.len() {
150 return Err(Error::InvalidUsage(name.to_string(), the_func.args.len()));
151 }
152
153 let mut vars = me.vars.borrow_mut();
154 for (i, arg) in args.iter().enumerate() {
155 vars.insert(the_func.args[i].clone(), arg.clone());
156 }
157 Some(the_func.block.clone())
158 }
159 };
160 if let Some(block) = block {
161 let scope = me.scope();
162 let val = match scope.eval_all(block)? {
163 Return::None => scope.it.borrow().clone(),
164 Return::Gtfo => Value::Noob,
165 Return::Value(val) => val
166 };
167 {
168 let params = &mut me.params();
169 params.borrow_mut().recursion -= 1;
170 }
171 break val;
172 } else if let Some(parent) = me.parent {
173 me = parent;
174 } else {
175 return Err(Error::UndefinedFunc(name.to_string()));
176 }
177 })
178 }
179 pub fn scope(&'a self) -> Self {
180 Self {
181 params: None,
182
183 it: self.it.clone(),
184 vars: RefCell::new(HashMap::new()),
185 funcs: RefCell::new(HashMap::new()),
186 parent: Some(self)
187 }
188 }
189
190 fn apply_num<F1, F2>(&self, one: Expr, two: Expr, if_numbr: F1, if_numbar: F2) -> Result<Value>
191 where F1: FnOnce(i64, i64) -> Result<i64>,
192 F2: FnOnce(f64, f64) -> f64
193 {
194 let one = self.eval_expr(one)?;
195 let two = self.eval_expr(two)?;
196 if one.is_numbar() || two.is_numbar() {
197 Ok(Value::Numbar(if_numbar(
198 one.cast_numbar().ok_or(Error::InvalidCast)?,
199 two.cast_numbar().ok_or(Error::InvalidCast)?
200 )))
201 } else {
202 Ok(Value::Numbr(if_numbr(
203 one.cast_numbr().ok_or(Error::InvalidCast)?,
204 two.cast_numbr().ok_or(Error::InvalidCast)?
205 )?))
206 }
207 }
208 fn apply_any<F>(&self, one: Expr, two: Expr, apply: F) -> Result<Value>
209 where F: FnOnce(Value, Value) -> bool
210 {
211 Ok(Value::Troof(apply(self.eval_expr(one)?, self.eval_expr(two)?)))
212 }
213 fn apply_bool<F>(&self, one: Expr, two: Expr, apply: F) -> Result<Value>
214 where F: FnOnce(bool, bool) -> bool
215 {
216 self.apply_any(one, two, |x, y| apply(x.cast_troof(), y.cast_troof()))
217 }
218 pub fn eval_expr(&self, expr: Expr) -> Result<Value> {
219 macro_rules! apply_num {
220 ($one:expr, $two:expr, $func:ident, $op:tt) => {
221 self.apply_num(*$one, *$two, |x, y| Ok(x.$func(y)), |x, y| x $op y)
222 }
223 }
224 match expr {
225 Expr::It => Ok(self.it.borrow().clone()),
226 Expr::Value(mut val) => {
227 if let Some(missing) = val.interpolate(|var| self.find_var(var, |var| var.clone())) {
228 return Err(Error::UndefinedVar(missing));
229 }
230 Ok(val)
231 },
232 Expr::Var(ident) => {
233 if let Some(val) = self.find_var(&ident, |var| var.clone()) {
234 return Ok(val);
235 } else {
236 return Err(Error::UndefinedVar(ident));
237 }
238 },
239 Expr::IIz(name, args) => {
240 let mut args_val = Vec::with_capacity(args.len());
241 for arg in args {
242 args_val.push(self.eval_expr(arg)?);
243 }
244 self.call_func(&name, args_val)
245 },
246
247 Expr::SumOf(one, two) => apply_num!(one, two, wrapping_add, +),
248 Expr::DiffOf(one, two) => apply_num!(one, two, wrapping_sub, -),
249 Expr::ProduktOf(one, two) => apply_num!(one, two, wrapping_mul, *),
250 Expr::QuoshuntOf(one, two) => self.apply_num(*one, *two, |x, y| {
251 if y == 0 {
252 return Err(Error::DivideByZero);
253 }
254 Ok(x / y)
255 }, |x, y| x / y),
256 Expr::ModOf(one, two) => self.apply_num(*one, *two, |x, y| {
257 if y == 0 {
258 return Err(Error::DivideByZero);
259 }
260 Ok(x % y)
261 }, |x, y| x % y),
262 Expr::BiggrOf(one, two) => self.apply_num(*one, *two, |x, y| Ok(x.max(y)), |x, y| x.max(y)),
263 Expr::SmallrOf(one, two) => self.apply_num(*one, *two, |x, y| Ok(x.min(y)), |x, y| x.min(y)),
264
265 Expr::BothOf(one, two) => self.apply_bool(*one, *two, |x, y| x && y),
266 Expr::EitherOf(one, two) => self.apply_bool(*one, *two, |x, y| x || y),
267 Expr::WonOf(one, two) => self.apply_bool(*one, *two, |x, y| x ^ y),
268 Expr::Not(inner) => Ok(Value::Troof(!self.eval_expr(*inner)?.cast_troof())),
269 Expr::AllOf(values) => {
270 for value in values {
271 if !self.eval_expr(value)?.cast_troof() {
272 return Ok(Value::Troof(false))
273 }
274 }
275 Ok(Value::Troof(true))
276 },
277 Expr::AnyOf(values) => {
278 for value in values {
279 if self.eval_expr(value)?.cast_troof() {
280 return Ok(Value::Troof(true))
281 }
282 }
283 Ok(Value::Troof(false))
284 },
285
286 Expr::BothSaem(one, two) => self.apply_any(*one, *two, |x, y| x.equals(&y)),
287 Expr::Diffrint(one, two) => self.apply_any(*one, *two, |x, y| !x.equals(&y)),
288
289 Expr::Smoosh(exprs) => {
290 let mut result = String::new();
291 for expr in exprs {
292 result.push_str(&self.eval_expr(expr)?.cast_yarn().ok_or(Error::InvalidCast)?);
293 }
294 Ok(Value::Yarn(result))
295 }
296 }
297 }
298 pub fn eval(&self, ast: AST) -> Result<Return> {
299 match ast {
300 AST::IHasA(ident, expr) => {
301 let val = self.eval_expr(expr)?;
302 {
303 let mut vars = self.vars.borrow_mut();
304 if vars.contains_key(&ident) {
305 return Err(Error::ShadowVar(ident));
306 }
307 vars.insert(ident, val);
308 }
309 },
310 AST::R(ident, expr) => {
311 let val = self.eval_expr(expr)?;
312 if self.find_var(&ident, |var| *var = val).is_none() {
313 return Err(Error::UndefinedVar(ident));
314 }
315 },
316 AST::It(expr) => {
317 let expr = self.eval_expr(expr)?;
318 *self.it.borrow_mut() = expr;
319 },
320 AST::ORly(yarly, mebbe, nowai) => {
321 if self.it.borrow().cast_troof() {
322 return self.eval_scope(yarly);
323 }
324 for (condition, block) in mebbe {
325 if self.eval_expr(condition)?.cast_troof() {
326 return self.eval_scope(block);
327 }
328 }
329 return self.eval_scope(nowai);
330 },
331 AST::Wtf(omg, omgwtf) => {
332 let mut matched = false;
333 let it = self.it.borrow();
334 for (condition, block) in omg {
335 if matched || *it == self.eval_expr(condition)? {
336 matched = true;
337 match self.eval_scope(block)? {
338 Return::None => (),
339 Return::Gtfo => return Ok(Return::None),
340 val @ Return::Value(_) => return Ok(val)
341 }
342 }
343 }
344 return self.eval_scope(omgwtf);
345 },
346 AST::ImInYr(operation, var, condition, block) => {
347 let mut scope = self.scope();
348 scope.vars.borrow_mut().insert(var.clone(), Value::Numbr(0));
349 while condition.is_none() || scope.eval_expr(condition.clone().unwrap())?.cast_troof() {
350 match scope.eval_scope(block.clone())? {
351 Return::None => (),
352 Return::Gtfo => return Ok(Return::None),
353 val @ Return::Value(_) => return Ok(val)
354 }
355 let val = scope.vars.borrow_mut()[&var].clone();
356 let val = match operation {
357 Operation::Uppin => Value::Numbr(val.cast_numbr().ok_or(Error::InvalidCastLoop)? + 1),
358 Operation::Nerfin => Value::Numbr(val.cast_numbr().ok_or(Error::InvalidCastLoop)? - 1),
359 Operation::IIz(ref name) => scope.call_func(&name, vec![val])?
360 };
361 *scope.vars.borrow_mut().get_mut(&var).unwrap() = val;
362 }
363 },
364 AST::HowIzI(name, args, block) => {
365 self.funcs.borrow_mut().insert(name, Function {
366 args: args,
367 block: block
368 });
369 },
370
371 AST::Gtfo => return Ok(Return::Gtfo),
372 AST::FoundYr(expr) => return Ok(Return::Value(self.eval_expr(expr)?)),
373
374 AST::Visible(exprs, newline) => {
375 let mut result = String::new();
376 for expr in exprs {
377 result.push_str(&self.eval_expr(expr)?.cast_yarn().ok_or(Error::InvalidCast)?);
378 }
379 let stdout = &mut self.params().borrow_mut().stdout;
380 stdout.write_all(result.as_bytes()).map_err(|err| Error::IoError(err))?;
381 if newline {
382 stdout.write_all(b"\n").map_err(|err| Error::IoError(err))?;
383 } else {
384 stdout.flush().map_err(|err| Error::IoError(err))?;
385 }
386 },
387 AST::Gimmeh(ident) => {
388 let stdin = &mut self.params().borrow_mut().stdin;
389
390 let mut text = String::new();
391 stdin.read_line(&mut text).map_err(|err| Error::IoError(err))?;
392
393 let text = text.trim().to_string();
394 self.vars.borrow_mut().insert(ident, Value::Yarn(text));
395 }
396 }
397 Ok(Return::None)
398 }
399 pub fn eval_all<I: IntoIterator<Item = AST>>(&self, asts: I) -> Result<Return> {
401 for line in asts.into_iter() {
402 match self.eval(line)? {
403 Return::None => (),
404 val => return Ok(val)
405 }
406 }
407 Ok(Return::None)
408 }
409 pub fn eval_scope<I: IntoIterator<Item = AST>>(&self, asts: I) -> Result<Return> {
411 self.scope().eval_all(asts)
412 }
413}