diff options
author | Akshay <[email protected]> | 2021-03-31 12:23:09 +0100 |
---|---|---|
committer | Akshay <[email protected]> | 2021-03-31 12:23:09 +0100 |
commit | 92b532e70f7650d7a5fc942cc3a56bc838e57f8c (patch) | |
tree | 901a6c89cea67c39f468556ca4cb1d3b88a0259c /src | |
parent | dbc0ab93141784dc07a7e193024fc5716dd34214 (diff) |
add save and save-as procedures
Diffstat (limited to 'src')
-rw-r--r-- | src/lisp/prelude.rs | 93 |
1 files changed, 54 insertions, 39 deletions
diff --git a/src/lisp/prelude.rs b/src/lisp/prelude.rs index 27e7ad2..54c831f 100644 --- a/src/lisp/prelude.rs +++ b/src/lisp/prelude.rs | |||
@@ -2,7 +2,6 @@ use crate::{ | |||
2 | brush::Brush, | 2 | brush::Brush, |
3 | lisp::{ | 3 | lisp::{ |
4 | error::{EvalError, LispError}, | 4 | error::{EvalError, LispError}, |
5 | eval::Evaluator, | ||
6 | expr::{Arity, LispExpr}, | 5 | expr::{Arity, LispExpr}, |
7 | number::LispNumber, | 6 | number::LispNumber, |
8 | Environment, | 7 | Environment, |
@@ -11,9 +10,7 @@ use crate::{ | |||
11 | utils::load_script, | 10 | utils::load_script, |
12 | }; | 11 | }; |
13 | 12 | ||
14 | use std::{convert::TryInto, fs::File, io::Write}; | 13 | use std::convert::TryInto; |
15 | |||
16 | use log::info; | ||
17 | 14 | ||
18 | #[macro_export] | 15 | #[macro_export] |
19 | macro_rules! primitive { | 16 | macro_rules! primitive { |
@@ -142,12 +139,26 @@ pub fn new_env() -> Result<Environment, LispError> { | |||
142 | Ok(LispExpr::Unit) | 139 | Ok(LispExpr::Unit) |
143 | }); | 140 | }); |
144 | 141 | ||
145 | primitive!(env, Arity::Exact(2), "eq?", |args, app| { | 142 | primitive!(env, Arity::Exact(2), "eq?", |args, _| { |
146 | let s = &args[0]; | 143 | let s = &args[0]; |
147 | let o = &args[1]; | 144 | let o = &args[1]; |
148 | info!("comparing s: {} and o: {}", s, o); | 145 | match (s, o) { |
149 | let result = s.compare(o, &app.lisp_env); | 146 | (LispExpr::Unit, LispExpr::Unit) => Ok(true), |
150 | result.map(LispExpr::BoolLit) | 147 | (LispExpr::Number(s), LispExpr::Number(o)) => Ok(s == o), |
148 | (LispExpr::List(s), LispExpr::List(o)) => Ok(s.iter().zip(o).all(|(a, b)| a == b)), | ||
149 | (LispExpr::List(s), LispExpr::Unit) => Ok(s.len() == 0), | ||
150 | (LispExpr::Unit, LispExpr::List(s)) => Ok(s.len() == 0), | ||
151 | (LispExpr::StringLit(s), LispExpr::StringLit(o)) => Ok(s == o), | ||
152 | (LispExpr::Char(s), LispExpr::Char(o)) => Ok(s == o), | ||
153 | (LispExpr::BoolLit(s), LispExpr::BoolLit(o)) => Ok(s == o), | ||
154 | (LispExpr::Ident(s), LispExpr::Ident(o)) => Ok(s == o), | ||
155 | (s @ LispExpr::Quote(_, _), o @ LispExpr::Quote(_, _)) => { | ||
156 | // text of quotation should be equal | ||
157 | Ok(format!("{}", s) == format!("{}", o)) | ||
158 | } | ||
159 | _ => Err(EvalError::TypeMismatch.into()), | ||
160 | } | ||
161 | .map(LispExpr::BoolLit) | ||
151 | }); | 162 | }); |
152 | 163 | ||
153 | primitive!(env, Arity::Atleast(2), ">", |args, _| { | 164 | primitive!(env, Arity::Atleast(2), ">", |args, _| { |
@@ -204,42 +215,26 @@ pub fn new_env() -> Result<Environment, LispError> { | |||
204 | } | 215 | } |
205 | }); | 216 | }); |
206 | 217 | ||
207 | primitive!(env, Arity::Atmost(1), "save", |args, app| { | 218 | primitive!(env, Arity::Exact(0), "save", |_, app| { |
208 | let image = app.export().encode().unwrap(); | 219 | if let Some(file_name) = &app.file_name { |
209 | if type_match!(args, 0 => LispExpr::StringLit(_)) { | 220 | return app |
210 | let mut buffer = File::create(&args[0].as_ref()).unwrap(); | 221 | .save_as(&file_name) |
211 | buffer.write_all(&image[..]).unwrap(); | 222 | .map_err(|e| LispError::Stringified(e.to_string())) |
212 | } else if let Some(p) = app.file_name { | 223 | .map(|_| LispExpr::Unit); |
213 | let file_name = p; | ||
214 | let mut buffer = File::create(&file_name).unwrap(); | ||
215 | buffer.write_all(&image[..]).unwrap(); | ||
216 | } else { | ||
217 | return Err(EvalError::NoFileName.into()); | ||
218 | } | 224 | } |
219 | 225 | return Err(EvalError::NoFileName.into()); | |
220 | return Ok(LispExpr::Unit); | ||
221 | }); | 226 | }); |
222 | 227 | ||
223 | primitive!(env, Arity::Atmost(1), "brush", |args, app| { | 228 | primitive!(env, Arity::Exact(1), "save-as", |args, app| { |
224 | let old_size = if matches!(app.brush, Brush::Line { .. } | Brush::Circle { .. }) { | 229 | match &args[0] { |
225 | app.brush.size().unwrap() | 230 | LispExpr::StringLit(s) => { |
226 | } else { | 231 | return app |
227 | 0 | 232 | .save_as(&s) |
228 | }; | 233 | .map_err(|e| LispError::Stringified(e.to_string())) |
229 | if let [LispExpr::Quote(kind, _)] = args { | 234 | .map(|_| LispExpr::Unit); |
230 | if matches!(kind.as_ref(), LispExpr::Ident(_)) { | ||
231 | match (&**kind).as_ref() { | ||
232 | "fill" => app.brush = Brush::Fill, | ||
233 | "circle" => app.brush = Brush::new(old_size), | ||
234 | "line" => app.brush = Brush::line(old_size, false), | ||
235 | "line-extend" => app.brush = Brush::line(old_size, true), | ||
236 | _ => return Err(EvalError::CustomInternal("unknown brush type").into()), | ||
237 | } | ||
238 | } | 235 | } |
239 | } else { | 236 | _ => return Err(EvalError::TypeMismatch.into()), |
240 | return Err(EvalError::TypeMismatch.into()); | ||
241 | } | 237 | } |
242 | return Ok(LispExpr::Unit); | ||
243 | }); | 238 | }); |
244 | 239 | ||
245 | primitive!(env, Arity::Exact(2), "cons", |args, _| { | 240 | primitive!(env, Arity::Exact(2), "cons", |args, _| { |
@@ -254,6 +249,26 @@ pub fn new_env() -> Result<Environment, LispError> { | |||
254 | } | 249 | } |
255 | }); | 250 | }); |
256 | 251 | ||
252 | primitive!(env, Arity::Exact(0), "brush-fill", |_, app| { | ||
253 | app.brush = Brush::Fill; | ||
254 | return Ok(LispExpr::Unit); | ||
255 | }); | ||
256 | |||
257 | primitive!(env, Arity::Exact(0), "brush-circle", |_, app| { | ||
258 | app.brush = Brush::new(0); | ||
259 | return Ok(LispExpr::Unit); | ||
260 | }); | ||
261 | |||
262 | primitive!(env, Arity::Exact(0), "brush-line", |_, app| { | ||
263 | app.brush = Brush::line(0, false); | ||
264 | return Ok(LispExpr::Unit); | ||
265 | }); | ||
266 | |||
267 | primitive!(env, Arity::Exact(0), "brush-line-extend", |_, app| { | ||
268 | app.brush = Brush::line(0, true); | ||
269 | return Ok(LispExpr::Unit); | ||
270 | }); | ||
271 | |||
257 | primitive!(env, Arity::Exact(1), "car", |args, _| { | 272 | primitive!(env, Arity::Exact(1), "car", |args, _| { |
258 | if type_match!(args, 0 => LispExpr::List(_)) { | 273 | if type_match!(args, 0 => LispExpr::List(_)) { |
259 | return Ok(args[0].unwrap_list().swap_remove(0)); | 274 | return Ok(args[0].unwrap_list().swap_remove(0)); |