diff options
Diffstat (limited to 'src/lisp/prelude.rs')
-rw-r--r-- | src/lisp/prelude.rs | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/src/lisp/prelude.rs b/src/lisp/prelude.rs index 54c831f..4a6a4ed 100644 --- a/src/lisp/prelude.rs +++ b/src/lisp/prelude.rs | |||
@@ -1,4 +1,5 @@ | |||
1 | use crate::{ | 1 | use crate::{ |
2 | bitmap::MapPoint, | ||
2 | brush::Brush, | 3 | brush::Brush, |
3 | lisp::{ | 4 | lisp::{ |
4 | error::{EvalError, LispError}, | 5 | error::{EvalError, LispError}, |
@@ -7,6 +8,7 @@ use crate::{ | |||
7 | Environment, | 8 | Environment, |
8 | }, | 9 | }, |
9 | primitive, | 10 | primitive, |
11 | undo::PaintRecord, | ||
10 | utils::load_script, | 12 | utils::load_script, |
11 | }; | 13 | }; |
12 | 14 | ||
@@ -39,7 +41,8 @@ macro_rules! type_match { | |||
39 | { | 41 | { |
40 | let mut temp_vec = vec![]; | 42 | let mut temp_vec = vec![]; |
41 | $( | 43 | $( |
42 | for arg in &$args[$range] { | 44 | let arg_range: &[LispExpr] = &$args[$range]; |
45 | for arg in arg_range { | ||
43 | temp_vec.push(matches!(arg, $kind)); | 46 | temp_vec.push(matches!(arg, $kind)); |
44 | } | 47 | } |
45 | )+ | 48 | )+ |
@@ -334,5 +337,44 @@ pub fn new_env() -> Result<Environment, LispError> { | |||
334 | } | 337 | } |
335 | }); | 338 | }); |
336 | 339 | ||
340 | primitive!(env, Arity::Exact(0), "canvas-width", |_, app| { | ||
341 | return Ok(LispExpr::Number(LispNumber::Integer(app.width() as i64))); | ||
342 | }); | ||
343 | |||
344 | primitive!(env, Arity::Exact(0), "canvas-height", |_, app| { | ||
345 | return Ok(LispExpr::Number(LispNumber::Integer(app.height() as i64))); | ||
346 | }); | ||
347 | |||
348 | primitive!(env, Arity::Exact(3), "set-pixel!", |args, app| { | ||
349 | if type_match!( | ||
350 | args, 0 => LispExpr::Number(LispNumber::Integer(_)), | ||
351 | 1 => LispExpr::Number(LispNumber::Integer(_)), | ||
352 | 2 => LispExpr::BoolLit(_) | ||
353 | ) { | ||
354 | let x = args[0].unwrap_number(); | ||
355 | let y = args[1].unwrap_number(); | ||
356 | let val = args[2].cast_bool(); | ||
357 | |||
358 | let set_loc: MapPoint = (x.unwrap_integer(), y.unwrap_integer()) | ||
359 | .try_into() | ||
360 | .map_err(|_| -> LispError { EvalError::InvalidCoordinates((x, y)).into() })?; | ||
361 | if !app.pixmap.contains(set_loc) { | ||
362 | return Err(EvalError::InvalidCoordinates((x, y)).into()); | ||
363 | } else { | ||
364 | let old_val = app.pixmap.set(set_loc, val); | ||
365 | app.current_operation | ||
366 | .push(PaintRecord::new(set_loc, old_val, val)); | ||
367 | return Ok(LispExpr::Unit); | ||
368 | } | ||
369 | } else { | ||
370 | return Err(EvalError::TypeMismatch.into()); | ||
371 | } | ||
372 | }); | ||
373 | |||
374 | primitive!(env, Arity::Exact(0), "commit", |_, app| { | ||
375 | app.commit_operation(); | ||
376 | return Ok(LispExpr::Unit); | ||
377 | }); | ||
378 | |||
337 | Ok(env) | 379 | Ok(env) |
338 | } | 380 | } |