diff options
-rw-r--r-- | src/brush.rs | 73 | ||||
-rw-r--r-- | src/lisp/error.rs | 2 | ||||
-rw-r--r-- | src/lisp/eval.rs | 1 | ||||
-rw-r--r-- | src/lisp/expr.rs | 1 | ||||
-rw-r--r-- | src/lisp/prelude.rs | 21 | ||||
-rw-r--r-- | src/main.rs | 1 |
6 files changed, 98 insertions, 1 deletions
diff --git a/src/brush.rs b/src/brush.rs new file mode 100644 index 0000000..98c2b23 --- /dev/null +++ b/src/brush.rs | |||
@@ -0,0 +1,73 @@ | |||
1 | use std::fmt; | ||
2 | |||
3 | use crate::bitmap::MapPoint; | ||
4 | |||
5 | #[derive(Debug, Copy, Clone)] | ||
6 | pub enum Brush { | ||
7 | Line { | ||
8 | size: u8, | ||
9 | start: Option<MapPoint>, | ||
10 | extend: bool, | ||
11 | }, | ||
12 | Circle { | ||
13 | size: u8, | ||
14 | }, | ||
15 | RectSelect { | ||
16 | start: MapPoint, | ||
17 | end: MapPoint, | ||
18 | }, | ||
19 | Fill, | ||
20 | Custom { | ||
21 | size: u8, | ||
22 | }, | ||
23 | } | ||
24 | |||
25 | impl Brush { | ||
26 | pub fn grow(&mut self) -> Result<(), BrushError> { | ||
27 | match self { | ||
28 | Brush::Line { ref mut size, .. } => *size += 1, | ||
29 | Brush::Circle { ref mut size, .. } => *size += 1, | ||
30 | Brush::Custom { ref mut size, .. } => *size += 1, | ||
31 | _ => return Err(BrushError::CannotIncreaseSize), | ||
32 | } | ||
33 | Ok(()) | ||
34 | } | ||
35 | pub fn shrink(&mut self) -> Result<(), BrushError> { | ||
36 | match self { | ||
37 | Brush::Line { ref mut size, .. } => *size += size.saturating_sub(1), | ||
38 | Brush::Circle { ref mut size, .. } => *size += size.saturating_sub(1), | ||
39 | Brush::Custom { ref mut size, .. } => *size += size.saturating_sub(1), | ||
40 | _ => return Err(BrushError::CannotIncreaseSize), | ||
41 | } | ||
42 | Ok(()) | ||
43 | } | ||
44 | pub fn new() -> Self { | ||
45 | Brush::Circle { size: 0 } | ||
46 | } | ||
47 | pub fn line(size: u8, extend: bool) -> Self { | ||
48 | Brush::Line { | ||
49 | size, | ||
50 | start: None, | ||
51 | extend, | ||
52 | } | ||
53 | } | ||
54 | pub fn is_line(&self) -> bool { | ||
55 | matches!(self, Self::Line { .. }) | ||
56 | } | ||
57 | } | ||
58 | |||
59 | impl fmt::Display for Brush { | ||
60 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
61 | match self { | ||
62 | Brush::Line { extend, .. } => write!(f, "LINE{}", if *extend { "+" } else { "" }), | ||
63 | Brush::Circle { .. } => write!(f, "CIRCLE"), | ||
64 | Brush::RectSelect { .. } => write!(f, "SELECT"), | ||
65 | Brush::Fill => write!(f, "FILL"), | ||
66 | Brush::Custom { .. } => write!(f, "CUSTOM"), | ||
67 | } | ||
68 | } | ||
69 | } | ||
70 | |||
71 | pub enum BrushError { | ||
72 | CannotIncreaseSize, | ||
73 | } | ||
diff --git a/src/lisp/error.rs b/src/lisp/error.rs index b90e211..a360eb2 100644 --- a/src/lisp/error.rs +++ b/src/lisp/error.rs | |||
@@ -90,6 +90,7 @@ pub enum EvalError { | |||
90 | DivByZero, | 90 | DivByZero, |
91 | TypeMismatch, | 91 | TypeMismatch, |
92 | NoFileName, | 92 | NoFileName, |
93 | CustomInternal(&'static str), | ||
93 | } | 94 | } |
94 | 95 | ||
95 | impl fmt::Display for EvalError { | 96 | impl fmt::Display for EvalError { |
@@ -112,6 +113,7 @@ impl fmt::Display for EvalError { | |||
112 | Self::TypeMismatch => write!(f, "mismatched types"), | 113 | Self::TypeMismatch => write!(f, "mismatched types"), |
113 | Self::DivByZero => write!(f, "attempt to divide by zero"), | 114 | Self::DivByZero => write!(f, "attempt to divide by zero"), |
114 | Self::NoFileName => write!(f, "no file name specified"), | 115 | Self::NoFileName => write!(f, "no file name specified"), |
116 | Self::CustomInternal(s) => write!(f, "{}", s), | ||
115 | } | 117 | } |
116 | } | 118 | } |
117 | } | 119 | } |
diff --git a/src/lisp/eval.rs b/src/lisp/eval.rs index 370b624..6ffff23 100644 --- a/src/lisp/eval.rs +++ b/src/lisp/eval.rs | |||
@@ -20,6 +20,7 @@ pub fn eval(expr: &LispExpr, app: &mut AppState) -> Result<LispExpr, LispError> | |||
20 | LispExpr::Number(_) => Ok(expr.clone()), | 20 | LispExpr::Number(_) => Ok(expr.clone()), |
21 | LispExpr::BoolLit(_) => Ok(expr.clone()), | 21 | LispExpr::BoolLit(_) => Ok(expr.clone()), |
22 | LispExpr::Ident(ref id) => lookup_extended(&app.lisp_env, id), | 22 | LispExpr::Ident(ref id) => lookup_extended(&app.lisp_env, id), |
23 | LispExpr::Quote(_, _) => Ok(expr.clone()), | ||
23 | LispExpr::List(li) => { | 24 | LispExpr::List(li) => { |
24 | let func_expr = &li[0]; | 25 | let func_expr = &li[0]; |
25 | match func_expr { | 26 | match func_expr { |
diff --git a/src/lisp/expr.rs b/src/lisp/expr.rs index 40420a1..9ef9f65 100644 --- a/src/lisp/expr.rs +++ b/src/lisp/expr.rs | |||
@@ -222,6 +222,7 @@ impl AsRef<str> for LispExpr { | |||
222 | fn as_ref(&self) -> &str { | 222 | fn as_ref(&self) -> &str { |
223 | match self { | 223 | match self { |
224 | LispExpr::StringLit(i) => &i, | 224 | LispExpr::StringLit(i) => &i, |
225 | LispExpr::Ident(i) => &i, | ||
225 | _ => panic!("invalid downcast!"), | 226 | _ => panic!("invalid downcast!"), |
226 | } | 227 | } |
227 | } | 228 | } |
diff --git a/src/lisp/prelude.rs b/src/lisp/prelude.rs index 6153e4f..d2a6ae6 100644 --- a/src/lisp/prelude.rs +++ b/src/lisp/prelude.rs | |||
@@ -1,7 +1,8 @@ | |||
1 | use crate::{ | 1 | use crate::{ |
2 | brush::Brush, | ||
2 | lisp::{ | 3 | lisp::{ |
3 | error::{EvalError, LispError}, | 4 | error::{EvalError, LispError}, |
4 | expr::{Arity, LispExpr}, | 5 | expr::{is_ident, Arity, LispExpr}, |
5 | number::LispNumber, | 6 | number::LispNumber, |
6 | Environment, | 7 | Environment, |
7 | }, | 8 | }, |
@@ -193,5 +194,23 @@ pub fn new_env() -> Environment { | |||
193 | return Ok(LispExpr::Unit); | 194 | return Ok(LispExpr::Unit); |
194 | }); | 195 | }); |
195 | 196 | ||
197 | primitive!(env, Arity::Atmost(1), "brush", |args, app| { | ||
198 | info!("brush {}", &args[0]); | ||
199 | if let [LispExpr::Quote(kind, _)] = args { | ||
200 | if is_ident(kind) { | ||
201 | match (&**kind).as_ref() { | ||
202 | "fill" => app.brush = Brush::Fill, | ||
203 | "circle" => app.brush = Brush::new(), | ||
204 | "line" => app.brush = Brush::line(0, false), | ||
205 | "line-extend" => app.brush = Brush::line(0, true), | ||
206 | _ => return Err(EvalError::CustomInternal("unknown brush type").into()), | ||
207 | } | ||
208 | } | ||
209 | } else { | ||
210 | return Err(EvalError::TypeMismatch.into()); | ||
211 | } | ||
212 | return Ok(LispExpr::Unit); | ||
213 | }); | ||
214 | |||
196 | env | 215 | env |
197 | } | 216 | } |
diff --git a/src/main.rs b/src/main.rs index 1ecad69..34f087a 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -1,5 +1,6 @@ | |||
1 | mod app; | 1 | mod app; |
2 | mod bitmap; | 2 | mod bitmap; |
3 | mod brush; | ||
3 | mod command; | 4 | mod command; |
4 | mod consts; | 5 | mod consts; |
5 | mod dither; | 6 | mod dither; |