Begin integrating lisp.
This commit is contained in:
parent
81790d4308
commit
0f24273c93
1 changed files with 124 additions and 4 deletions
128
src/main.rs
128
src/main.rs
|
@ -1,5 +1,6 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use tokio::time::{timeout, Duration};
|
use tokio::time::{timeout, Duration};
|
||||||
|
|
||||||
|
@ -7,16 +8,133 @@ mod i3ipc;
|
||||||
|
|
||||||
use i3ipc::{Connection, MessageType};
|
use i3ipc::{Connection, MessageType};
|
||||||
|
|
||||||
|
fn serde_lisp_value(value: &serde_json::Value) -> rust_lisp::model::Value {
|
||||||
|
match value {
|
||||||
|
serde_json::Value::Null => rust_lisp::model::Value::NIL,
|
||||||
|
serde_json::Value::Bool(b) => {
|
||||||
|
if *b {
|
||||||
|
rust_lisp::model::Value::True
|
||||||
|
} else {
|
||||||
|
rust_lisp::model::Value::False
|
||||||
|
}
|
||||||
|
}
|
||||||
|
serde_json::Value::Number(n) => {
|
||||||
|
if n.is_i64() {
|
||||||
|
rust_lisp::model::Value::Int(n.as_i64().unwrap() as rust_lisp::model::IntType)
|
||||||
|
} else if n.is_u64() {
|
||||||
|
rust_lisp::model::Value::Int(n.as_u64().unwrap() as rust_lisp::model::IntType)
|
||||||
|
} else if n.is_f64() {
|
||||||
|
rust_lisp::model::Value::Float(n.as_f64().unwrap() as rust_lisp::model::FloatType)
|
||||||
|
} else {
|
||||||
|
panic!("should never happen");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
serde_json::Value::String(s) => rust_lisp::model::Value::String(s.clone()),
|
||||||
|
serde_json::Value::Array(a) => {
|
||||||
|
let mut l = rust_lisp::model::List::NIL;
|
||||||
|
for li in a.into_iter().rev() {
|
||||||
|
l = l.cons(serde_lisp_value(li));
|
||||||
|
}
|
||||||
|
rust_lisp::model::Value::List(l)
|
||||||
|
}
|
||||||
|
serde_json::Value::Object(o) => {
|
||||||
|
let mut r = HashMap::new();
|
||||||
|
for (k, v) in o.into_iter() {
|
||||||
|
let k_ = rust_lisp::model::Value::String(k.clone());
|
||||||
|
let v_ = serde_lisp_value(v);
|
||||||
|
r.insert(k_, v_);
|
||||||
|
}
|
||||||
|
rust_lisp::model::Value::HashMap(Rc::new(RefCell::new(r)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn new_window_cb(
|
fn new_window_cb(
|
||||||
b: MessageType,
|
b: MessageType,
|
||||||
c: serde_json::Value,
|
c: serde_json::Value,
|
||||||
|
d: bool,
|
||||||
) -> futures::future::BoxFuture<'static, Vec<(MessageType, Vec<u8>)>> {
|
) -> futures::future::BoxFuture<'static, Vec<(MessageType, Vec<u8>)>> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
//println!("{:?}", c);
|
let mut environment = rust_lisp::default_env();
|
||||||
let environment = rust_lisp::default_env();
|
environment.define(
|
||||||
let code = "(= 1 1)";
|
rust_lisp::model::Symbol::from("__input__"),
|
||||||
|
serde_lisp_value(&c),
|
||||||
|
);
|
||||||
|
environment.define(
|
||||||
|
rust_lisp::model::Symbol::from("load"),
|
||||||
|
rust_lisp::model::Value::NativeClosure(Rc::new(RefCell::new(
|
||||||
|
move |e: Rc<RefCell<rust_lisp::model::Env>>, args: Vec<rust_lisp::model::Value>| {
|
||||||
|
let path: &String =
|
||||||
|
rust_lisp::utils::require_typed_arg::<&String>("load", &args, 0)?;
|
||||||
|
let path = (*path).as_str().split('.');
|
||||||
|
let mut i: rust_lisp::model::Value = e
|
||||||
|
.as_ref()
|
||||||
|
.borrow()
|
||||||
|
.get(&rust_lisp::model::Symbol::from("__input__"))
|
||||||
|
.unwrap();
|
||||||
|
for p in path
|
||||||
|
.into_iter()
|
||||||
|
.filter(|x| !(*x).eq(""))
|
||||||
|
.map(|x| rust_lisp::model::Value::String(x.into()))
|
||||||
|
{
|
||||||
|
match i {
|
||||||
|
rust_lisp::model::Value::HashMap(x) => {
|
||||||
|
if let Some(_i) = x.as_ref().borrow().get(&p) {
|
||||||
|
i = _i.clone();
|
||||||
|
} else {
|
||||||
|
return Err(rust_lisp::model::RuntimeError {
|
||||||
|
msg: format!(r#"No such key {:?}"#, p).into(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err(rust_lisp::model::RuntimeError {
|
||||||
|
msg: format!(r#"No such key {:?}"#, p).into(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Ok(i)
|
||||||
|
},
|
||||||
|
))),
|
||||||
|
);
|
||||||
|
environment.define(
|
||||||
|
rust_lisp::model::Symbol::from("has-key"),
|
||||||
|
rust_lisp::model::Value::NativeClosure(Rc::new(RefCell::new(
|
||||||
|
move |e: Rc<RefCell<rust_lisp::model::Env>>, args: Vec<rust_lisp::model::Value>| {
|
||||||
|
let path: &String =
|
||||||
|
rust_lisp::utils::require_typed_arg::<&String>("has-key", &args, 0)?;
|
||||||
|
let path = (*path).as_str().split('.');
|
||||||
|
let mut i: rust_lisp::model::Value = e
|
||||||
|
.as_ref()
|
||||||
|
.borrow()
|
||||||
|
.get(&rust_lisp::model::Symbol::from("__input__"))
|
||||||
|
.unwrap();
|
||||||
|
for p in path
|
||||||
|
.into_iter()
|
||||||
|
.filter(|x| !(*x).eq(""))
|
||||||
|
.map(|x| rust_lisp::model::Value::String(x.into()))
|
||||||
|
{
|
||||||
|
match i {
|
||||||
|
rust_lisp::model::Value::HashMap(x) => {
|
||||||
|
if let Some(_i) = x.as_ref().borrow().get(&p) {
|
||||||
|
i = _i.clone();
|
||||||
|
} else {
|
||||||
|
return Ok(rust_lisp::model::Value::False);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => return Ok(rust_lisp::model::Value::False),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Ok(rust_lisp::model::Value::True)
|
||||||
|
},
|
||||||
|
))),
|
||||||
|
);
|
||||||
|
let environment = environment;
|
||||||
|
let code = r#"(load ".container.geometry")"#;
|
||||||
let ast = rust_lisp::parser::parse(code).filter_map(|a| a.ok());
|
let ast = rust_lisp::parser::parse(code).filter_map(|a| a.ok());
|
||||||
let result = rust_lisp::interpreter::eval_block(Rc::new(RefCell::new(environment)), ast);
|
let result = rust_lisp::interpreter::eval_block(Rc::new(RefCell::new(environment)), ast);
|
||||||
|
println!("{:?}", result);
|
||||||
|
|
||||||
Vec::new()
|
Vec::new()
|
||||||
})
|
})
|
||||||
|
@ -36,8 +154,10 @@ async fn main() -> Result<()> {
|
||||||
let mut connection = Connection::connect((i3ipc::get_socket_path().await?).as_ref())?;
|
let mut connection = Connection::connect((i3ipc::get_socket_path().await?).as_ref())?;
|
||||||
let mut sub_connection = connection.clone();
|
let mut sub_connection = connection.clone();
|
||||||
|
|
||||||
|
let b_ = true;
|
||||||
|
let cb = move |a, b| {new_window_cb(a,b,b_)};
|
||||||
sub_connection
|
sub_connection
|
||||||
.subscribe(&[MessageType::SubWindow], &new_window_cb)
|
.subscribe(&[MessageType::SubWindow], &cb)
|
||||||
.await?;
|
.await?;
|
||||||
tokio::join!(
|
tokio::join!(
|
||||||
timeout(Duration::from_secs(1), sub_connection.run()),
|
timeout(Duration::from_secs(1), sub_connection.run()),
|
||||||
|
|
Loading…
Reference in a new issue