diff options
Diffstat (limited to 'src/lisp')
-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 |
5 files changed, 34 insertions, 9 deletions
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), |