1use std::{
4 collections::HashMap,
5 error::Error,
6 fmt::Display,
7 ops::{Add, Div, Mul, Sub},
8};
9
10use crate::parser::{BinaryOperator, Expr, Literal, UnaryOperator};
11
12#[derive(Debug, Default, Clone)]
14pub struct Interpretter<'a> {
15 context: HashMap<String, Literal<'a>>,
17}
18
19#[derive(Debug, Clone, Copy)]
21pub struct RuntimeError;
22
23impl Display for RuntimeError {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 write!(f, "Runtime Error Occured :(")
26 }
27}
28
29impl Error for RuntimeError {}
30
31impl<'a> Interpretter<'a> {
32 pub fn eval(&mut self, ast: Expr<'a>) -> Result<Literal<'a>, RuntimeError> {
34 match ast {
35 Expr::Index { item, index } => {
36 let idx = self.eval(*index)?.uint()?;
37 let item = self.eval(*item)?;
38
39 match item {
40 Literal::String(s) => Ok(Literal::String(&s[idx..=idx])),
41 Literal::List(l) => Ok(l[idx].clone()),
42 _ => Err(RuntimeError),
43 }
44 }
45 Expr::List(items) => {
46 let mut literals = vec![];
47
48 for item in items {
49 literals.push(self.eval(item)?);
50 }
51
52 Ok(Literal::List(literals))
53 }
54 Expr::Inc(name, before) => {
55 if let Some(inc) = self.context.get_mut(name) {
56 let prev = inc.clone();
57 *inc = Literal::Number(inc.number()? + 1.0);
58
59 if before { Ok(prev) } else { Ok(inc.clone()) }
60 } else {
61 Err(RuntimeError)
63 }
64 }
65 Expr::AddAssign { name, add } => {
66 let val = self.eval(*add)?;
67 if let Some(inc) = self.context.get_mut(name) {
68 *inc = (inc.clone() + val)?;
69
70 Ok(Literal::Void)
71 } else {
72 Err(RuntimeError)
74 }
75 }
76 Expr::Reassignment { name, val } => {
77 let val = self.eval(*val)?;
78 if let Some(set) = self.context.get_mut(name) {
79 *set = val;
80 Ok(Literal::Void)
81 } else {
82 Err(RuntimeError)
84 }
85 }
86 Expr::Roar(expr) => {
87 let mut stringified = format!("{}", self.eval(*expr)?);
88 stringified = stringified.to_uppercase();
89 println!("{stringified}!!!");
90
91 Ok(Literal::Void)
92 }
93 Expr::ForLoop {
94 init,
95 check,
96 update,
97 exec,
98 } => {
99 self.eval(*init)?;
100 while self.eval(*check.clone())?.bool()? {
101 self.eval(*exec.clone())?;
102 self.eval(*update.clone())?;
103 }
104
105 Ok(Literal::Void)
106 }
107
108 Expr::WhileLoop { condition, exec } => {
109 while self.eval(*condition.clone())?.bool()? {
110 self.eval(*exec.clone())?;
111 }
112
113 Ok(Literal::Void)
114 }
115 Expr::Conditional {
116 condition,
117 true_branch,
118 else_branch,
119 } => {
120 let cond_check = self.eval(*condition)?.bool()?;
121
122 if cond_check {
123 self.eval(*true_branch)
124 } else if let Some(elb) = else_branch {
125 self.eval(*elb)
126 } else {
127 Ok(Literal::Void)
128 }
129 }
130
131 Expr::Block(exprs) => {
132 for expr in exprs {
133 self.eval(expr)?;
134 }
135
136 Ok(Literal::Void)
137 }
138 Expr::Variable(var) => Ok(self.context[var].clone()),
139 Expr::Print(node) => {
140 println!("{}", self.eval(*node)?);
141 Ok(Literal::Void)
142 }
143 Expr::Assignment { name, val } => {
144 let val = self.eval(*val)?;
145 self.context.insert(name.to_string(), val);
146 Ok(Literal::Void)
147 }
148 Expr::Literal(l) => Ok(l),
149 Expr::Grouping(inner) => self.eval(*inner),
150 Expr::Binary { op, left, right } => op.eval(self.eval(*left)?, self.eval(*right)?),
151 Expr::Unary { op, node } => op.eval(self.eval(*node)?),
152 }
153 }
154}
155
156impl BinaryOperator {
157 pub fn eval<'a>(
159 &self,
160 left: Literal<'a>,
161 right: Literal<'a>,
162 ) -> Result<Literal<'a>, RuntimeError> {
163 match self {
164 Self::Add => left + right,
165 Self::Sub => left - right,
166 Self::Mul => left * right,
167 Self::Div => left / right,
168
169 Self::Gt => Ok((left.number()? > right.number()?).into()),
170 Self::Gte => Ok((left.number()? >= right.number()?).into()),
171 Self::Lt => Ok((left.number()? < right.number()?).into()),
172 Self::Lte => Ok((left.number()? <= right.number()?).into()),
173
174 Self::Eq => left.equals(&right),
175 Self::Neq => left.not_equals(&right),
176 }
177 }
178}
179
180impl UnaryOperator {
181 pub fn eval<'a>(&self, node: Literal<'a>) -> Result<Literal<'a>, RuntimeError> {
183 match self {
184 Self::Neg => Ok(Literal::Number(-node.number()?)),
185 Self::Not => Ok(Literal::from(!node.bool()?)),
186 }
187 }
188}
189
190impl Add for Literal<'_> {
191 type Output = Result<Self, RuntimeError>;
192
193 fn add(self, rhs: Self) -> Self::Output {
194 match (self, rhs) {
195 (Self::Number(n1), Self::Number(n2)) => Ok(Literal::Number(n1 + n2)),
196
197 (Self::String(s1), Self::String(s2)) => Ok(Literal::Concat(
198 Box::new(Literal::String(s1)),
199 Box::new(Literal::String(s2)),
200 )),
201
202 (Self::Number(n1), Self::String(s2)) => Ok(Literal::Concat(
203 Box::new(Literal::Number(n1)),
204 Box::new(Literal::String(s2)),
205 )),
206
207 (Self::String(s1), Self::Number(n2)) => Ok(Literal::Concat(
208 Box::new(Literal::String(s1)),
209 Box::new(Literal::Number(n2)),
210 )),
211 _ => Err(RuntimeError),
212 }
213 }
214}
215
216impl Sub for Literal<'_> {
217 type Output = Result<Self, RuntimeError>;
218 fn sub(self, rhs: Self) -> Self::Output {
219 match (self, rhs) {
220 (Self::Number(n1), Self::Number(n2)) => Ok(Self::Number(n1 - n2)),
221
222 _ => Err(RuntimeError),
223 }
224 }
225}
226
227impl Mul for Literal<'_> {
228 type Output = Result<Self, RuntimeError>;
229 fn mul(self, rhs: Self) -> Self::Output {
230 match (self, rhs) {
231 (Self::Number(n1), Self::Number(n2)) => Ok(Self::Number(n1 * n2)),
232
233 _ => Err(RuntimeError),
234 }
235 }
236}
237
238impl Div for Literal<'_> {
239 type Output = Result<Self, RuntimeError>;
240 fn div(self, rhs: Self) -> Self::Output {
241 match (self, rhs) {
242 (Self::Number(n1), Self::Number(n2)) => Ok(Self::Number(n1 / n2)),
243 _ => Err(RuntimeError),
244 }
245 }
246}
247
248impl From<bool> for Literal<'_> {
249 fn from(value: bool) -> Self {
250 if value { Literal::True } else { Literal::False }
251 }
252}
253
254impl<'a> Literal<'a> {
255 pub fn uint(&self) -> Result<usize, RuntimeError> {
258 match self {
259 Self::Number(n) if *n >= 0.0 && n.round() == *n => Ok(*n as usize),
260 _ => Err(RuntimeError),
261 }
262 }
263 pub fn number(&self) -> Result<f64, RuntimeError> {
265 match self {
266 Self::Number(n) => Ok(*n),
267 _ => Err(RuntimeError),
268 }
269 }
270
271 pub fn bool(&self) -> Result<bool, RuntimeError> {
273 match self {
274 Self::True => Ok(true),
275 Self::False => Ok(false),
276 Self::Number(0.0) => Ok(false),
277 Self::Number(_) => Ok(true),
278 _ => Err(RuntimeError),
279 }
280 }
281
282 pub fn equals(&self, other: &Self) -> Result<Literal<'a>, RuntimeError> {
284 match (self, other) {
285 (Self::Number(n1), Self::Number(n2)) => Ok((n1 == n2).into()),
286 (Self::True, Self::True) => Ok(Self::True),
287 (Self::False, Self::False) => Ok(Self::True),
288
289 (Self::False, Self::True) => Ok(Self::False),
290 (Self::True, Self::False) => Ok(Self::False),
291
292 (Self::Void, Self::Void) => Ok(Self::True),
293
294 (crazy1, crazy2) => Ok((crazy1.to_string() == crazy2.to_string()).into()),
295 }
296 }
297
298 pub fn not_equals(&self, other: &Self) -> Result<Literal<'a>, RuntimeError> {
300 match (self, other) {
301 (Self::Number(n1), Self::Number(n2)) => Ok((n1 != n2).into()),
302 (Self::True, Self::True) => Ok(Self::False),
303 (Self::False, Self::False) => Ok(Self::False),
304
305 (Self::False, Self::True) => Ok(Self::True),
306 (Self::True, Self::False) => Ok(Self::True),
307
308 (Self::Void, Self::Void) => Ok(Self::False),
309
310 (crazy1, crazy2) => Ok((crazy1.to_string() != crazy2.to_string()).into()),
311 }
312 }
313}
314
315impl Display for Expr<'_> {
316 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
317 match self {
318 Expr::Index { item, index } => write!(f, "{item}[{index}]"),
319 Expr::List(items) => write!(f, "{items:?}"),
320 Expr::AddAssign { name, add } => write!(f, "{name} += {add}"),
321 Expr::Inc(name, before) => {
322 if *before {
323 write!(f, "++{name}")
324 } else {
325 write!(f, "{name}++")
326 }
327 }
328 Expr::Roar(r) => write!(f, "roar {r}!"),
329 Expr::ForLoop {
330 init,
331 check,
332 update,
333 exec,
334 } => {
335 writeln!(f, "for ({init}; {check}; {update}) {exec}")
336 }
337
338 Expr::WhileLoop { condition, exec } => {
339 writeln!(f, "while ({condition}) {{\n\t{exec}\n}}")
340 }
341
342 Expr::Conditional {
343 condition,
344 true_branch,
345 else_branch,
346 } => {
347 if let Some(elb) = else_branch {
348 writeln!(
349 f,
350 "if ({}) {{\n\t{}\n}} else {{\n\t{}\n}}",
351 condition, true_branch, elb
352 )
353 } else {
354 writeln!(f, "if ({}) {{\n\t{}\n}}", condition, true_branch)
355 }
356 }
357 Self::Block(b) => {
358 writeln!(f, "{{")?;
359
360 for expr in b {
361 writeln!(f, "\t{expr}")?;
362 }
363
364 write!(f, "}}")
365 }
366 Self::Variable(v) => write!(f, "{v}"),
367 Self::Print(node) => write!(f, "print {node}"),
368 Self::Assignment { name, val } => write!(f, "var {name} = {val}"),
369 Self::Reassignment { name, val } => write!(f, "{name} = {val}"),
370 Self::Literal(l) => write!(f, "{l}"),
371 Self::Unary { op, node } => match op {
372 UnaryOperator::Neg => write!(f, "-{node}"),
373 UnaryOperator::Not => write!(f, "!{node}"),
374 },
375 Self::Binary { op, left, right } => match op {
376 BinaryOperator::Add => write!(f, "{left} + {right}"),
377 BinaryOperator::Sub => write!(f, "{left} - {right}"),
378 BinaryOperator::Mul => write!(f, "{left} * {right}"),
379 BinaryOperator::Div => write!(f, "{left} / {right}"),
380
381 BinaryOperator::Eq => write!(f, "{left} == {right}"),
382 BinaryOperator::Neq => write!(f, "{left} != {right}"),
383 BinaryOperator::Gt => write!(f, "{left} > {right}"),
384 BinaryOperator::Gte => write!(f, "{left} >= {right}"),
385 BinaryOperator::Lt => write!(f, "{left} < {right}"),
386 BinaryOperator::Lte => write!(f, "{left} <= {right}"),
387 },
388 Self::Grouping(e) => write!(f, "({e})"),
389 }
390 }
391}
392
393#[cfg(test)]
394mod tests {
395 use crate::{
396 parser::{Literal, Parser},
397 tokenizer::Tokenizable,
398 };
399
400 use super::Interpretter;
401
402 #[test]
403 fn for_looping() {
404 let tokens = r#"
405 var foo = 10;
406 for (var i = 0; i < 10; var i = i + 1) {
407 var foo = foo + 1;
408 }
409 foo;
410 "#
411 .tokenize()
412 .expect("Tokenize");
413
414 let mut parser = Parser::with_tokens(&tokens);
415
416 let ast = parser.parse_many().expect("Failed to parse");
417 let mut interp = Interpretter::default();
418
419 let mut val = None;
420 for expr in ast {
421 val = Some(interp.eval(expr).expect("Interpret result"));
422 }
423
424 assert_eq!(val.unwrap(), Literal::Number(20.0))
425 }
426
427 #[test]
428 fn use_variables_later() {
429 let tokens = "var foo = 100;".tokenize().expect("Tokenize");
430 let mut parser = Parser::with_tokens(&tokens);
431
432 let ast = parser.parse().expect("Failed to parse");
433 let mut interp = Interpretter::default();
434 interp.eval(ast).expect("Interpret result");
435
436 let tokens = "foo + 1;".tokenize().expect("Tokenize");
437 let mut parser = Parser::with_tokens(&tokens);
438
439 let ast = parser.parse().expect("Failed to parse");
440
441 assert_eq!(interp.eval(ast).expect("Eval"), Literal::Number(101.0))
442 }
443
444 #[test]
445 fn simple_eval() {
446 let tokens = "var foo = 100;".tokenize().expect("Tokenize");
447 let mut parser = Parser::with_tokens(&tokens);
448
449 let ast = parser.parse().expect("Failed to parse");
450 let mut interp = Interpretter::default();
451 interp.eval(ast).expect("Interpret result");
452
453 assert_eq!(interp.context["foo"], Literal::Number(100.0))
454 }
455
456 #[test]
457 fn notting() {
458 let tokens = "!true;".tokenize().expect("Tokenize");
459 let mut parser = Parser::with_tokens(&tokens);
460
461 let ast = parser.parse().expect("Failed to parse");
462 let mut interp = Interpretter::default();
463 let res = interp.eval(ast).expect("Interpret result");
464 assert_eq!(res, Literal::False)
465 }
466
467 #[test]
468 fn negation() {
469 let tokens = "-100;".tokenize().expect("Tokenize");
470 let mut parser = Parser::with_tokens(&tokens);
471
472 let ast = parser.parse().expect("Failed to parse");
473 let mut interp = Interpretter::default();
474 let res = interp.eval(ast).expect("Interpret result");
475 assert_eq!(res, Literal::Number(-100.0))
476 }
477
478 #[test]
479 fn eval_addition() {
480 let tokens = "100 + 100;".tokenize().expect("Tokenize");
481 let mut parser = Parser::with_tokens(&tokens);
482
483 let ast = parser.parse().expect("Failed to parse");
484 let mut eval = Interpretter::default();
485
486 assert_eq!(eval.eval(ast).expect("Evaluate"), Literal::Number(200.0))
487 }
488
489 #[test]
490 fn eval_string_concat() {
491 let tokens = r#""100" + 100;"#.tokenize().expect("Tokenize");
492 let mut parser = Parser::with_tokens(&tokens);
493
494 let ast = parser.parse().expect("Failed to parse");
495 let mut eval = Interpretter::default();
496 let result = eval.eval(ast).expect("Eval").to_string();
497
498 assert_eq!(result, "100100");
499 }
500
501 #[test]
502 fn eval_string_concat_otherway() {
503 let tokens = r#"10 + "20";"#.tokenize().expect("Tokenize");
504 let mut parser = Parser::with_tokens(&tokens);
505
506 let ast = parser.parse().expect("Failed to parse");
507 let mut eval = Interpretter::default();
508 let result = eval.eval(ast).expect("Eval").to_string();
509
510 assert_eq!(result, "1020");
511 }
512
513 #[test]
514 fn loose_equality() {
515 let tokens = r#"1 == "1";"#.tokenize().expect("Tokenize");
516 let mut parser = Parser::with_tokens(&tokens);
517
518 let ast = parser.parse().expect("Failed to parse");
519 let mut eval = Interpretter::default();
520 assert_eq!(eval.eval(ast).expect("Eval"), Literal::True)
521 }
522
523 #[test]
524 fn pure_inequality() {
525 let tokens = "1 + 1 != 100 * 10;".tokenize().expect("Tokenize");
526 let mut parser = Parser::with_tokens(&tokens);
527
528 let ast = parser.parse().expect("Failed to parse");
529 let mut eval = Interpretter::default();
530 assert_eq!(eval.eval(ast).expect("Eval"), Literal::True)
531 }
532
533 #[test]
534 fn list() {
535 let tokens = r#"[12 == 1, 10 * 10, "hi"];"#.tokenize().expect("Tokenize");
536 let mut parser = Parser::with_tokens(&tokens);
537
538 let ast = parser.parse().expect("Failed to parse");
539 let mut eval = Interpretter::default();
540 assert_eq!(
541 eval.eval(ast).expect("Eval"),
542 Literal::List(vec![
543 Literal::False,
544 Literal::Number(100.0),
545 Literal::String("hi")
546 ])
547 )
548 }
549
550 #[test]
551 fn pure_equality() {
552 let tokens = "1 + 1 == 2;".tokenize().expect("Tokenize");
553 let mut parser = Parser::with_tokens(&tokens);
554
555 let ast = parser.parse().expect("Failed to parse");
556 let mut eval = Interpretter::default();
557 assert_eq!(eval.eval(ast).expect("Eval"), Literal::True)
558 }
559
560 #[test]
561 fn eval_pure_string_concat() {
562 let tokens = r#""Hello " + "World!";"#.tokenize().expect("Tokenize");
563 let mut parser = Parser::with_tokens(&tokens);
564
565 let ast = parser.parse().expect("Failed to parse");
566 let mut eval = Interpretter::default();
567 let result = eval.eval(ast).expect("Eval").to_string();
568
569 assert_eq!(result, "Hello World!");
570 }
571}