diff options
-rw-r--r-- | src/app.rs | 7 | ||||
-rw-r--r-- | src/lisp/error.rs | 2 | ||||
-rw-r--r-- | src/lisp/eval.rs (renamed from src/lisp/env.rs) | 13 | ||||
-rw-r--r-- | src/lisp/expr.rs | 2 | ||||
-rw-r--r-- | src/lisp/mod.rs | 2 | ||||
-rw-r--r-- | src/lisp/number.rs | 24 |
6 files changed, 37 insertions, 13 deletions
@@ -3,7 +3,7 @@ use crate::{ | |||
3 | command::CommandBox, | 3 | command::CommandBox, |
4 | consts::{colors::*, FONT_PATH}, | 4 | consts::{colors::*, FONT_PATH}, |
5 | dither, | 5 | dither, |
6 | lisp::{env, lex::Lexer, parse::Parser, Environment}, | 6 | lisp::{eval, lex::Lexer, parse::Parser, Environment}, |
7 | message::Message, | 7 | message::Message, |
8 | rect, | 8 | rect, |
9 | symmetry::Symmetry, | 9 | symmetry::Symmetry, |
@@ -13,7 +13,6 @@ use crate::{ | |||
13 | 13 | ||
14 | use std::{convert::From, fs::File, io::prelude::*}; | 14 | use std::{convert::From, fs::File, io::prelude::*}; |
15 | 15 | ||
16 | use log::{info, warn}; | ||
17 | use obi::Image; | 16 | use obi::Image; |
18 | use sdl2::{ | 17 | use sdl2::{ |
19 | event::Event, | 18 | event::Event, |
@@ -281,7 +280,7 @@ impl<'ctx> AppState<'ctx> { | |||
281 | let lisp_expr = &self.command_box.text; | 280 | let lisp_expr = &self.command_box.text; |
282 | let mut parser = Parser::new(Lexer::new(lisp_expr, 0)); | 281 | let mut parser = Parser::new(Lexer::new(lisp_expr, 0)); |
283 | let res = parser.parse_single_expr(); | 282 | let res = parser.parse_single_expr(); |
284 | match env::eval(&res.unwrap(), self, None) { | 283 | match eval::eval(&res.unwrap(), self, None) { |
285 | Ok(val) => { | 284 | Ok(val) => { |
286 | self.message.text = format!("{}", val); | 285 | self.message.text = format!("{}", val); |
287 | } | 286 | } |
@@ -519,7 +518,7 @@ impl<'ctx> AppState<'ctx> { | |||
519 | symmetry: Default::default(), | 518 | symmetry: Default::default(), |
520 | ttf_context, | 519 | ttf_context, |
521 | undo_stack: UndoStack::new(), | 520 | undo_stack: UndoStack::new(), |
522 | lisp_env: env::with_prelude(), | 521 | lisp_env: eval::with_prelude(), |
523 | zoom: 5, | 522 | zoom: 5, |
524 | } | 523 | } |
525 | } | 524 | } |
diff --git a/src/lisp/error.rs b/src/lisp/error.rs index 7214753..99dec3b 100644 --- a/src/lisp/error.rs +++ b/src/lisp/error.rs | |||
@@ -1,5 +1,3 @@ | |||
1 | use crate::lisp::lex::Span; | ||
2 | |||
3 | #[derive(Debug, PartialEq, Copy, Clone)] | 1 | #[derive(Debug, PartialEq, Copy, Clone)] |
4 | pub enum LispError { | 2 | pub enum LispError { |
5 | ParseError, | 3 | ParseError, |
diff --git a/src/lisp/env.rs b/src/lisp/eval.rs index c5ff6d3..63c963c 100644 --- a/src/lisp/env.rs +++ b/src/lisp/eval.rs | |||
@@ -9,8 +9,6 @@ use crate::{ | |||
9 | primitive, | 9 | primitive, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | use std::collections::HashMap; | ||
13 | |||
14 | use log::{error, info}; | 12 | use log::{error, info}; |
15 | 13 | ||
16 | pub fn with_prelude() -> Environment { | 14 | pub fn with_prelude() -> Environment { |
@@ -106,6 +104,17 @@ pub fn with_prelude() -> Environment { | |||
106 | Ok(args.into_iter().last().unwrap().clone()) | 104 | Ok(args.into_iter().last().unwrap().clone()) |
107 | } | 105 | } |
108 | }); | 106 | }); |
107 | primitive!(env, Some(2), "/", |args, _| { | ||
108 | if args.is_empty() || args.iter().any(|arg| !matches!(arg, LispExpr::Number(_))) { | ||
109 | Err(LispError::EvalError) | ||
110 | } else { | ||
111 | let mut acc = unwrap_number(&args[0]).clone(); | ||
112 | for arg in args.into_iter().skip(1) { | ||
113 | acc = acc.div(*unwrap_number(&arg))?; | ||
114 | } | ||
115 | Ok(LispExpr::Number(acc)) | ||
116 | } | ||
117 | }); | ||
109 | env | 118 | env |
110 | } | 119 | } |
111 | 120 | ||
diff --git a/src/lisp/expr.rs b/src/lisp/expr.rs index 651e41f..40b39eb 100644 --- a/src/lisp/expr.rs +++ b/src/lisp/expr.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::fmt; | 1 | use std::fmt; |
2 | 2 | ||
3 | use crate::app::AppState; | 3 | use crate::app::AppState; |
4 | use crate::lisp::{error::LispError, number::LispNumber, Environment}; | 4 | use crate::lisp::{error::LispError, number::LispNumber}; |
5 | 5 | ||
6 | #[derive(Clone)] | 6 | #[derive(Clone)] |
7 | pub struct PrimitiveFunc { | 7 | pub struct PrimitiveFunc { |
diff --git a/src/lisp/mod.rs b/src/lisp/mod.rs index dc08835..a52baa0 100644 --- a/src/lisp/mod.rs +++ b/src/lisp/mod.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | pub mod env; | ||
2 | pub mod error; | 1 | pub mod error; |
2 | pub mod eval; | ||
3 | pub mod expr; | 3 | pub mod expr; |
4 | pub mod lex; | 4 | pub mod lex; |
5 | pub mod number; | 5 | pub mod number; |
diff --git a/src/lisp/number.rs b/src/lisp/number.rs index ddadbe6..18a41f7 100644 --- a/src/lisp/number.rs +++ b/src/lisp/number.rs | |||
@@ -1,14 +1,32 @@ | |||
1 | use std::{ | 1 | use std::{ |
2 | fmt::*, | 2 | fmt, |
3 | ops::{Add, Div, Mul, Sub}, | 3 | ops::{Add, Div, Mul, Sub}, |
4 | }; | 4 | }; |
5 | 5 | ||
6 | use crate::lisp::error::LispError; | ||
7 | |||
6 | #[derive(Debug, Copy, Clone)] | 8 | #[derive(Debug, Copy, Clone)] |
7 | pub enum LispNumber { | 9 | pub enum LispNumber { |
8 | Integer(i64), | 10 | Integer(i64), |
9 | Float(f64), | 11 | Float(f64), |
10 | } | 12 | } |
11 | 13 | ||
14 | impl LispNumber { | ||
15 | pub fn div(self, rhs: Self) -> Result<LispNumber, LispError> { | ||
16 | use LispNumber::*; | ||
17 | if rhs == Integer(0) || rhs == Float(0.) { | ||
18 | return Err(LispError::EvalError); | ||
19 | } else { | ||
20 | return Ok(match (self, rhs) { | ||
21 | (Integer(a), Integer(b)) => Float(a as f64 / b as f64), | ||
22 | (Float(a), Integer(b)) => Float(a / b as f64), | ||
23 | (Integer(a), Float(b)) => Float(a as f64 / b), | ||
24 | (Float(a), Float(b)) => Float(a / b), | ||
25 | }); | ||
26 | } | ||
27 | } | ||
28 | } | ||
29 | |||
12 | impl Add for LispNumber { | 30 | impl Add for LispNumber { |
13 | type Output = Self; | 31 | type Output = Self; |
14 | fn add(self, rhs: Self) -> Self::Output { | 32 | fn add(self, rhs: Self) -> Self::Output { |
@@ -60,8 +78,8 @@ impl PartialEq for LispNumber { | |||
60 | } | 78 | } |
61 | } | 79 | } |
62 | 80 | ||
63 | impl Display for LispNumber { | 81 | impl fmt::Display for LispNumber { |
64 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { | 82 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
65 | match self { | 83 | match self { |
66 | LispNumber::Integer(v) => write!(f, "{}", v), | 84 | LispNumber::Integer(v) => write!(f, "{}", v), |
67 | LispNumber::Float(v) => write!(f, "{}", v), | 85 | LispNumber::Float(v) => write!(f, "{}", v), |