1use crate::{do_parse, do_walk, Action, Block, Error, Expr, IfPart, Namespace, Op, Table};
2use smartstring::alias::String;
3use std::collections::VecDeque;
4use std::fs;
5use std::io::{self, Write};
6
7#[derive(Debug)]
8pub struct Interpreter<'a> {
9 pub env: Namespace<'a>,
10 pub return_value: Option<Expr>,
11 pub do_break: bool,
12 pub do_continue: bool,
13}
14
15impl<'a> Interpreter<'a> {
16 pub fn new() -> Self {
17 Self {
18 env: Namespace::new(),
19 return_value: None,
20 do_break: false,
21 do_continue: false,
22 }
23 }
24
25 pub fn run_block(&mut self, block: &[Action]) -> Result<(), Error> {
26 for act in block {
27 self.run(act)?;
28 if self.return_value.is_some() || self.do_continue || self.do_break {
29 break;
30 }
31 }
32 Ok(())
33 }
34
35 pub fn run(&mut self, act: &Action) -> Result<(), Error> {
36 match act {
37 Action::Comment(_) => Ok(()),
38 Action::VarAssign(id, val) => self.var_assign(id, val),
39 Action::SingleShot(id, op, val) => self.single_shot(id, op, val),
40 Action::If(parts) => self.if_stmt(parts),
41 Action::FnDef(id, args, block) => {
42 self.fn_def(id, args, block.to_owned());
43 Ok(())
44 }
45 Action::FnCall(id, args) => {
46 self.fn_call(id, args)?;
47 self.return_value = None;
48 Ok(())
49 }
50 Action::Return(value) => {
51 if self.env.in_function() {
52 self.return_value =
53 Some(self.expr(value.as_ref().unwrap_or(&Expr::Boolean(false)))?);
54 Ok(())
55 } else {
56 Err(Error::ReturnOutOfFunction)
57 }
58 }
59 Action::Loop(block) => self.loop_stmt(block),
60 Action::For(id, expr, block) => self.for_stmt(id, expr, block),
61 Action::While(expr, block) => self.while_stmt(expr, block),
62 Action::Break => self.break_stmt(),
63 Action::Continue => self.continue_stmt(),
64 Action::Import(id, into) => self.import_stmt(id, into),
65 }
66 }
67
68 fn import_stmt(&mut self, id: &Expr, _into: &Option<Expr>) -> Result<(), Error> {
69 if let Expr::Identifier(parts) = id {
70 let raw = fs::read_to_string(format!("{}.psi", parts[0].to_string()))?;
71 let parse = do_parse(&raw)?;
72 let walk = do_walk(parse)?;
73 self.run_block(&walk)?;
74 }
75 Ok(())
76 }
77
78 fn while_stmt(&mut self, expr: &Expr, block: &[Action]) -> Result<(), Error> {
79 self.env.enter("while");
80 while !self.do_break
81 && self.expr(expr)? == Expr::Boolean(true)
82 && self.return_value.is_none()
83 {
84 self.run_block(block)?;
85 }
86 self.do_break = false;
87 self.do_continue = false;
88 self.env.leave();
89 Ok(())
90 }
91
92 fn for_stmt(&mut self, id: &[String], expr: &Expr, block: &[Action]) -> Result<(), Error> {
93 let expr = self.expr(expr)?;
94 self.env.enter("for");
95 let mut iteration = 0;
96 while !self.do_break && self.return_value.is_none() {
97 if let Ok(this) = self.var_index(&expr, vec![Expr::Integer(iteration)].into()) {
98 self.env.raw_expr(&id[0], &this);
99 self.run_block(block)?;
100 iteration += 1;
101 } else if let Expr::Table(ref items) = expr {
102 if id.len() != 2 {
103 return Err(Error::IndexError);
104 }
105 self.env.raw_expr(
106 &id[0],
107 if let Some(i) = items.keys().get(iteration as usize) {
108 i
109 } else {
110 break;
111 },
112 );
113 self.env.raw_expr(
114 &id[1],
115 if let Some(i) = items.values().get(iteration as usize) {
116 i
117 } else {
118 break;
119 },
120 );
121 self.run_block(block)?;
122 iteration += 1;
123 } else {
124 break;
125 }
126 }
127 self.do_break = false;
128 self.do_continue = false;
129 self.env.leave();
130 Ok(())
131 }
132
133 fn break_stmt(&mut self) -> Result<(), Error> {
134 if self.env.in_loop() {
135 self.do_break = true;
136 Ok(())
137 } else {
138 Err(Error::BreakOutOfLoop)
139 }
140 }
141
142 fn continue_stmt(&mut self) -> Result<(), Error> {
143 if self.env.in_loop() {
144 self.do_continue = true;
145 Ok(())
146 } else {
147 Err(Error::ContinueOutOfLoop)
148 }
149 }
150
151 fn loop_stmt(&mut self, block: &[Action]) -> Result<(), Error> {
152 self.env.enter("loop");
153 while !self.do_break {
154 self.run_block(block)?;
155 }
156 self.do_break = false;
157 self.env.leave();
158 Ok(())
159 }
160
161 fn fn_def(&mut self, id: &Expr, args: &[String], block: Block) {
162 if let Expr::Identifier(id) = id {
163 self.env.insert_fn(&id.join("."), args, &block);
164 }
165 }
166
167 fn if_stmt(&mut self, parts: &[IfPart]) -> Result<(), Error> {
168 for part in parts {
169 match part {
170 IfPart::If(e, b) | IfPart::IfElse(e, b) => {
171 if let Expr::Boolean(true) = self.expr(e)? {
172 self.run_block(b)?;
173 break;
174 }
175 }
176 IfPart::Else(b) => self.run_block(b)?,
177 }
178 }
179 Ok(())
180 }
181
182 fn single_shot(&mut self, id: &Expr, op: &Op, val: &Expr) -> Result<(), Error> {
183 let exist = self.expr(id)?;
184 if let Expr::Identifier(i) = id {
185 let val = self.expr(val)?;
186 let new = match op {
187 Op::Add => exist + val,
188 Op::Sub => exist - val,
189 Op::Mul => exist * val,
190 Op::Div => exist / val,
191 Op::Rem => exist % val,
192 Op::Pow => exist.pow(val),
193 _ => unreachable!(),
194 };
195 self.env.insert_expr(&i.join("."), &new);
196 }
197 Ok(())
198 }
199
200 fn var_assign(&mut self, id: &Expr, val: &Expr) -> Result<(), Error> {
201 let val = self.expr(val)?;
202 if let Expr::Identifier(id) = id {
203 self.env.insert_expr(&id.join("."), &val);
204 }
205 Ok(())
206 }
207
208 fn expr(&mut self, e: &Expr) -> Result<Expr, Error> {
209 Ok(match e {
210 Expr::Float(_) | Expr::Integer(_) | Expr::Boolean(_) | Expr::StringRaw(_) => {
211 e.to_owned()
212 }
213 Expr::StringFmt(parts) => self.string_fmt(parts)?,
214 Expr::Identifier(id) => self.identifier(id)?,
215 Expr::Inclusive(s, e) => self.inclusive(s, e)?,
216 Expr::Exclusive(s, e) => self.exclusive(s, e)?,
217 Expr::Array(items) => self.array(items)?,
218 Expr::Table(items) => self.table(items.to_owned())?,
219 Expr::Not(e) => self.not(e)?,
220 Expr::BinOp(left, op, right) => self.bin_op(*left.clone(), *op, *right.clone())?,
221 Expr::FnCall(id, args) => {
222 self.fn_call(id, args)?;
223 let val = if let Some(val) = self.return_value.clone() {
224 val
225 } else {
226 return Err(Error::NoReturnValue);
227 };
228 self.return_value = None;
229 val
230 }
231 Expr::VarIndex(id, inds) => self.var_index(&*id, inds.to_owned())?,
232 Expr::Impossible => return Err(Error::ImpossibleOperation),
233 })
234 }
235
236 fn var_index(&mut self, id: &Expr, mut inds: VecDeque<Expr>) -> Result<Expr, Error> {
237 let mut result = self.expr(id)?;
238 while let Some(ind) = inds.pop_front() {
239 let ind = self.expr(&ind)?;
240 match result {
241 Expr::StringRaw(s) => result = self.index_string(&s, &ind)?,
242 Expr::Inclusive(s, e) => {
243 let (s, e, i) = if let Some(rp) = self.range_parts(&s, &e, &ind) {
244 rp
245 } else {
246 return Err(Error::InvalidIndex);
247 };
248 if s + i <= e {
249 return Ok(Expr::Integer(s + i));
250 } else {
251 return Err(Error::IndexError);
252 }
253 }
254 Expr::Exclusive(s, e) => {
255 let (s, e, i) = if let Some(rp) = self.range_parts(&s, &e, &ind) {
256 rp
257 } else {
258 return Err(Error::InvalidIndex);
259 };
260 if s + i < e {
261 return Ok(Expr::Integer(s + i));
262 } else {
263 return Err(Error::IndexError);
264 }
265 }
266 Expr::Array(items) => {
267 if let Expr::Integer(i) = ind {
268 result = if let Some(item) = items.get(i as usize) {
269 item.to_owned()
270 } else {
271 return Err(Error::IndexError);
272 }
273 } else {
274 return Err(Error::IndexError);
275 }
276 }
277 Expr::Table(items) => {
278 result = if let Some(ind) = items.get(ind) {
279 ind
280 } else {
281 return Err(Error::IndexError);
282 }
283 }
284 Expr::VarIndex(id, inds) => result = self.var_index(&id, inds)?,
285 _ => return Err(Error::IndexError),
286 }
287 }
288 Ok(result)
289 }
290
291 fn index_string(&mut self, s: &str, ind: &Expr) -> Result<Expr, Error> {
292 if let Expr::Integer(i) = ind {
293 Ok(Expr::StringRaw(
294 if let Some(c) = s.chars().nth(*i as usize) {
295 c.to_string().into()
296 } else {
297 return Err(Error::IndexError);
298 },
299 ))
300 } else {
301 Err(Error::InvalidIndex)
302 }
303 }
304
305 fn range_parts(&self, s: &Expr, e: &Expr, ind: &Expr) -> Option<(i64, i64, i64)> {
306 if let (Expr::Integer(s), Expr::Integer(e), Expr::Integer(i)) = (s, e, ind) {
307 Some((*s, *e, *i))
308 } else {
309 None
310 }
311 }
312
313 fn fn_call(&mut self, id: &Expr, args: &[Expr]) -> Result<(), Error> {
314 self.return_value = None;
315 let mut args_result = vec![];
316 for i in args {
317 args_result.push(self.expr(i)?);
318 }
319 let args = args_result;
320 if let Expr::Identifier(ref parts) = id {
321 self.env.enter("function");
322 if let Some((needed_arguments, block)) = self.env.get_fn(&parts.join(".")) {
323 for (k, v) in needed_arguments.iter().zip(&args) {
324 self.env.insert_expr(k, v);
325 }
326 self.run_block(&block)?;
327 } else {
328 match parts
329 .iter()
330 .map(|x| x.as_str())
331 .collect::<Vec<_>>()
332 .as_slice()
333 {
334 ["print"] => println!("{}", args[0]),
335 ["input"] => {
336 let mut input = std::string::String::new();
337 print!("{}", args[0]);
338 io::stdout().flush().unwrap();
339 io::stdin().read_line(&mut input).unwrap();
340 self.return_value =
341 Some(Expr::StringRaw(input.trim_end_matches('\n').into()))
342 }
343 _ => return Err(Error::FunctionNotFound(parts.join(".").into())),
344 }
345 }
346 self.env.leave();
347 } else {
348 unreachable!()
349 }
350 Ok(())
351 }
352
353 fn bin_op(&mut self, mut left: Expr, op: Op, mut right: Expr) -> Result<Expr, Error> {
354 left = self.expr(&left)?;
355 right = self.expr(&right)?;
356 Ok(match op {
357 Op::Add => left + right,
358 Op::Sub => left - right,
359 Op::Mul => left * right,
360 Op::Div => left / right,
361 Op::Pow => left.pow(right),
362 Op::Rem => left % right,
363 Op::Equals => Expr::Boolean(left == right),
364 Op::NotEquals => Expr::Boolean(left != right),
365 Op::Greater => Expr::Boolean(left > right),
366 Op::Less => Expr::Boolean(left < right),
367 Op::GreaterEq => Expr::Boolean(left >= right),
368 Op::LessEq => Expr::Boolean(left <= right),
369 Op::Or => Expr::Boolean(left.as_bool()? || right.as_bool()?),
370 Op::And => Expr::Boolean(left.as_bool()? && right.as_bool()?),
371 Op::In => self.in_expr(&left, &right)?,
372 })
373 }
374
375 fn in_expr(&mut self, left: &Expr, right: &Expr) -> Result<Expr, Error> {
376 let (left, right) = (self.expr(left)?, self.expr(right)?);
377 Ok(match right {
378 Expr::StringRaw(fish) => {
379 if let Expr::StringRaw(sea) = left {
380 Expr::Boolean(fish.contains(sea.as_str()))
381 } else {
382 return Err(Error::InvalidIndex);
383 }
384 }
385 Expr::Inclusive(s, e) => self.in_inc(&s, &e, &left)?,
386 Expr::Exclusive(s, e) => self.in_exc(&s, &e, &left)?,
387 Expr::Array(ref items) => Expr::Boolean(items.contains(&left)),
388 Expr::Table(ref items) => Expr::Boolean(items.contains(&left)),
389 _ => return Err(Error::InvalidIndex),
390 })
391 }
392
393 fn in_inc(&mut self, s: &Expr, e: &Expr, left: &Expr) -> Result<Expr, Error> {
394 let (s, e) = (self.expr(s)?, self.expr(e)?);
395 if let (Expr::Integer(s), Expr::Integer(e), Expr::Integer(l)) = (s, e, left) {
396 Ok(Expr::Boolean(l <= &e && l >= &s))
397 } else {
398 Err(Error::InvalidIndex)
399 }
400 }
401
402 fn in_exc(&mut self, s: &Expr, e: &Expr, left: &Expr) -> Result<Expr, Error> {
403 let (s, e) = (self.expr(s)?, self.expr(e)?);
404 if let (Expr::Integer(s), Expr::Integer(e), Expr::Integer(l)) = (s, e, left) {
405 Ok(Expr::Boolean(l < &e && l >= &s))
406 } else {
407 Err(Error::InvalidIndex)
408 }
409 }
410
411 fn not(&mut self, e: &Expr) -> Result<Expr, Error> {
412 if let Expr::Boolean(b) = self.expr(e)? {
413 Ok(Expr::Boolean(!b))
414 } else {
415 Err(Error::EvalNotBool)
416 }
417 }
418
419 fn array(&mut self, items: &[Expr]) -> Result<Expr, Error> {
420 let mut items_result = vec![];
421 for i in items {
422 items_result.push(self.expr(i)?);
423 }
424 Ok(Expr::Array(items_result))
425 }
426
427 fn table(&mut self, mut items: Table) -> Result<Expr, Error> {
428 items.simplify(&mut |x| self.expr(&x))?;
429 Ok(Expr::Table(items))
430 }
431
432 fn inclusive(&mut self, start: &Expr, end: &Expr) -> Result<Expr, Error> {
433 Ok(Expr::Inclusive(
434 Box::new(self.expr(start)?),
435 Box::new(self.expr(end)?),
436 ))
437 }
438
439 fn exclusive(&mut self, start: &Expr, end: &Expr) -> Result<Expr, Error> {
440 Ok(Expr::Exclusive(
441 Box::new(self.expr(start)?),
442 Box::new(self.expr(end)?),
443 ))
444 }
445
446 fn string_fmt(&mut self, parts: &[Expr]) -> Result<Expr, Error> {
447 let mut result = String::new();
448 for part in parts {
449 result.push_str(&format!("{}", self.expr(part)?));
450 }
451 Ok(Expr::StringRaw(result))
452 }
453
454 fn identifier(&mut self, id: &[String]) -> Result<Expr, Error> {
455 if let Some(e) = self.env.get_expr(&id.join(".")) {
456 Ok(e)
457 } else {
458 Err(Error::VariableNotFound(id.join(".").into()))
459 }
460 }
461}
462
463impl<'a> Default for Interpreter<'a> {
464 fn default() -> Self {
465 Self::new()
466 }
467}