aboutsummaryrefslogtreecommitdiff
path: root/src/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lisp')
-rw-r--r--src/lisp/error.rs2
-rw-r--r--src/lisp/eval.rs (renamed from src/lisp/env.rs)13
-rw-r--r--src/lisp/expr.rs2
-rw-r--r--src/lisp/mod.rs2
-rw-r--r--src/lisp/number.rs24
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 @@
1use crate::lisp::lex::Span;
2
3#[derive(Debug, PartialEq, Copy, Clone)] 1#[derive(Debug, PartialEq, Copy, Clone)]
4pub enum LispError { 2pub 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
12use std::collections::HashMap;
13
14use log::{error, info}; 12use log::{error, info};
15 13
16pub fn with_prelude() -> Environment { 14pub 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 @@
1use std::fmt; 1use std::fmt;
2 2
3use crate::app::AppState; 3use crate::app::AppState;
4use crate::lisp::{error::LispError, number::LispNumber, Environment}; 4use crate::lisp::{error::LispError, number::LispNumber};
5 5
6#[derive(Clone)] 6#[derive(Clone)]
7pub struct PrimitiveFunc { 7pub 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 @@
1pub mod env;
2pub mod error; 1pub mod error;
2pub mod eval;
3pub mod expr; 3pub mod expr;
4pub mod lex; 4pub mod lex;
5pub mod number; 5pub 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 @@
1use std::{ 1use std::{
2 fmt::*, 2 fmt,
3 ops::{Add, Div, Mul, Sub}, 3 ops::{Add, Div, Mul, Sub},
4}; 4};
5 5
6use crate::lisp::error::LispError;
7
6#[derive(Debug, Copy, Clone)] 8#[derive(Debug, Copy, Clone)]
7pub enum LispNumber { 9pub enum LispNumber {
8 Integer(i64), 10 Integer(i64),
9 Float(f64), 11 Float(f64),
10} 12}
11 13
14impl 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
12impl Add for LispNumber { 30impl 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
63impl Display for LispNumber { 81impl 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),