Converted Interner to work with Rc-s

- Interner no longer contains unsafe code
- Tokens now hold a reference to the value they represent directly

This will enable many future improvements
This commit is contained in:
2023-08-19 14:03:05 +01:00
parent ab0b57b1b8
commit 0b887ced70
62 changed files with 592 additions and 762 deletions

61
src/systems/stl/state.rs Normal file
View File

@@ -0,0 +1,61 @@
use std::cell::RefCell;
use std::rc::Rc;
use crate::foreign::cps_box::{const_cps, init_cps, CPSBox};
use crate::foreign::Atomic;
use crate::interpreted::ExprInst;
use crate::interpreter::HandlerTable;
use crate::systems::codegen::call;
use crate::{atomic_inert, define_fn, ConstTree, Interner};
#[derive(Debug, Clone)]
pub struct State(Rc<RefCell<ExprInst>>);
atomic_inert!(State, "a state");
#[derive(Debug, Clone)]
struct NewStateCmd;
#[derive(Debug, Clone)]
struct SetStateCmd(State);
#[derive(Debug, Clone)]
struct GetStateCmd(State);
define_fn! { SetState = |x| Ok(init_cps(2, SetStateCmd(x.try_into()?))) }
define_fn! { GetState = |x| Ok(init_cps(2, GetStateCmd(x.try_into()?))) }
fn new_state_handler<E>(cmd: &CPSBox<NewStateCmd>) -> Result<ExprInst, E> {
let (_, default, handler) = cmd.unpack2();
let state = State(Rc::new(RefCell::new(default.clone())));
Ok(call(handler.clone(), [state.atom_exi()]).wrap())
}
fn set_state_handler<E>(cmd: &CPSBox<SetStateCmd>) -> Result<ExprInst, E> {
let (SetStateCmd(state), value, handler) = cmd.unpack2();
*state.0.as_ref().borrow_mut() = value.clone();
Ok(handler.clone())
}
fn get_state_handler<E>(cmd: &CPSBox<GetStateCmd>) -> Result<ExprInst, E> {
let (GetStateCmd(state), handler) = cmd.unpack1();
Ok(call(handler.clone(), [state.0.as_ref().borrow().clone()]).wrap())
}
pub fn state_handlers() -> HandlerTable<'static> {
let mut handlers = HandlerTable::new();
handlers.register(new_state_handler);
handlers.register(get_state_handler);
handlers.register(set_state_handler);
handlers
}
pub fn state_lib(i: &Interner) -> ConstTree {
ConstTree::namespace(
[i.i("state")],
ConstTree::tree([
(i.i("new_state"), const_cps(2, NewStateCmd)),
(i.i("get_state"), ConstTree::xfn(GetState)),
(i.i("set_state"), ConstTree::xfn(SetState)),
]),
)
}