summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/extended_environment.rs76
-rw-r--r--src/main.rs44
2 files changed, 112 insertions, 8 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()))
+ }),
+ );
+}
diff --git a/src/main.rs b/src/main.rs
index dbc60fb..62a3562 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,33 +3,61 @@ use macroquad::prelude::*;
use std::{cell::RefCell, rc::Rc};
use rust_lisp::default_env;
+use rust_lisp::lisp;
use rust_lisp::parser::parse;
use rust_lisp::interpreter::eval;
+use rust_lisp::model::{Symbol, Value};
+mod extended_environment;
#[macroquad::main("BasicShapes")]
async fn main() {
// create a base environment
let env = Rc::new(RefCell::new(default_env()));
+ // define new methods
+ extended_environment::extend_environment(&env);
+
// parse into an iterator of syntax trees (one for each root)
- let mut ast_iter = parse("(+ \"Hello \" \"world!\")");
- let first_expression = ast_iter.next().unwrap().unwrap();
+ // let mut ast_iter = parse("(+ \"Hello \" \"world!\")");
+ // let first_expression = ast_iter.next().unwrap().unwrap();
// evaluate
- let evaluation_result = eval(env.clone(), &first_expression).unwrap();
+ // let evaluation_result = eval(env.clone(), &first_expression).unwrap();
+ // let mut ast_iter = parse("(test_draw)");
+ // let first_expression = ast_iter.next().unwrap().unwrap();
+
+ // let first_expression = lisp! {(test_draw)};
+
+ // let mut inc = parse("(begin (set a 0) (+ a 1))");
+ // let mut inc = parse("(begin (define a 0) (set a (+ a 1)))");
+ // let inc_exp = inc.next().unwrap().unwrap();
+
+ // let inc_exp = lisp! {
+ // (begin (define a 0) (set a (+ a 1)))
+ // };
+ // eval(env.clone(), &inc_exp).unwrap();
- // use result
- println!("{}", &evaluation_result);
+ // let inc_exp = lisp! {
+ // (set a (+ a 1))
+ // };
+
+ let gol_exp = parse(include_str!("../scripts/main.el"));
+ for exp in gol_exp {
+ eval(env.clone(), &exp.unwrap()).unwrap();
+ }
+
+ // let mut inc = parse("(set a (+ a 1))");
+ // let inc_exp = inc.next().unwrap().unwrap();
loop {
clear_background(RED);
draw_line(40.0, 40.0, 100.0, 200.0, 15.0, BLUE);
draw_rectangle(screen_width() / 2.0 - 60.0, 100.0, 120.0, 60.0, GREEN);
- draw_circle(screen_width() - 30.0, screen_height() - 30.0, 15.0, YELLOW);
-
- draw_text(&format!("IT WORKS! {}!", &evaluation_result), 20.0, 20.0, 30.0, DARKGRAY);
+ eval(env.clone(), &first_expression).unwrap();
+ let inc_eval = eval(env.clone(), &inc_exp).unwrap();
+ draw_text(&format!("IT WORKS! {}!", &inc_eval), 20.0, 20.0, 30.0, DARKGRAY);
next_frame().await
}