aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app.rs7
-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
6 files changed, 37 insertions, 13 deletions
diff --git a/src/app.rs b/src/app.rs
index 7417dae..008b273 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -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
14use std::{convert::From, fs::File, io::prelude::*}; 14use std::{convert::From, fs::File, io::prelude::*};
15 15
16use log::{info, warn};
17use obi::Image; 16use obi::Image;
18use sdl2::{ 17use 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 @@
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),