summaryrefslogtreecommitdiff
path: root/src/extended_environment.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/extended_environment.rs')
-rw-r--r--src/extended_environment.rs76
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()))
+ }),
+ );
+}