diff options
Diffstat (limited to 'src/extended_environment.rs')
-rw-r--r-- | src/extended_environment.rs | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/extended_environment.rs b/src/extended_environment.rs new file mode 100644 index 0000000..d13cc2b --- /dev/null +++ b/src/extended_environment.rs @@ -0,0 +1,76 @@ +use macroquad::prelude::*; +use std::{cell::RefCell, collections::HashMap, rc::Rc}; +use rust_lisp::model::{Env, FloatType, RuntimeError, Symbol, Value}; +use rust_lisp::utils::{require_arg, require_typed_arg}; + +pub type HashMapRc = Rc<RefCell<HashMap<Value, Value>>>; + +pub fn extend_environment(env: &Rc<RefCell<Env>>) { + env.borrow_mut().define( + Symbol::from("mq-draw-circle"), + Value::NativeFunc( + |_env, args| { + let x = require_typed_arg::<FloatType>("mq-draw-circle", &args, 0).unwrap(); + let y = require_typed_arg::<FloatType>("mq-draw-circle", &args, 1).unwrap(); + let radius = require_typed_arg::<FloatType>("mq-draw-circle", &args, 2).unwrap(); + let color = GREEN; + + draw_circle(x, y, radius, color); + return Ok(Value::NIL); + }) + ); + + + // Hashtable functions + // TODO: convert to elisp compatible hash table command + env.borrow_mut().define( + Symbol::from("make-hash-table"), + Value::NativeFunc(|_env, args| { + let chunks = args.chunks(2); + + let mut hash = HashMap::new(); + + for pair in chunks { + let key = pair.get(0).unwrap(); + let value = pair.get(1); + + if let Some(value) = value { + hash.insert(key.clone(), value.clone()); + } else { + return Err(RuntimeError { + msg: format!("Must pass an even number of arguments to 'hash', because they're used as key/value pairs; found extra argument {}", key) + }); + } + } + + Ok(Value::HashMap(Rc::new(RefCell::new(hash)))) + }), + ); + + env.borrow_mut().define( + Symbol::from("hash_get"), + Value::NativeFunc(|_env, args| { + let hash = require_typed_arg::<&HashMapRc>("hash_get", &args, 0)?; + let key = require_arg("hash_get", &args, 1)?; + + Ok(hash + .borrow() + .get(key) + .map(|v| v.clone()) + .unwrap_or(Value::NIL)) + }), + ); + + env.borrow_mut().define( + Symbol::from("hash_set"), + Value::NativeFunc(|_env, args| { + let hash = require_typed_arg::<&HashMapRc>("hash_set", &args, 0)?; + let key = require_arg("hash_set", &args, 1)?; + let value = require_arg("hash_set", &args, 2)?; + + hash.borrow_mut().insert(key.clone(), value.clone()); + + Ok(Value::HashMap(hash.clone())) + }), + ); +} |