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

View File

@@ -1,7 +1,6 @@
use std::fmt::Debug;
use crate::foreign::{Atomic, AtomicReturn};
use crate::interner::InternedDisplay;
use crate::interpreter::Context;
use crate::representations::interpreted::ExprInst;
use crate::{atomic_defaults, write_fn_step, ConstTree, Interner};
@@ -19,7 +18,7 @@ struct Inspect1 {
impl Atomic for Inspect1 {
atomic_defaults!();
fn run(&self, ctx: Context) -> crate::foreign::AtomicResult {
println!("{}", self.expr_inst.bundle(ctx.interner));
println!("{}", self.expr_inst);
Ok(AtomicReturn {
clause: self.expr_inst.expr().clause.clone(),
gas: ctx.gas.map(|g| g - 1),

View File

@@ -9,6 +9,7 @@ mod num;
mod panic;
mod stl_system;
mod str;
mod state;
pub use arithmetic_error::ArithmeticError;
pub use bin::Binary;
pub use num::Numeric;

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)),
]),
)
}

View File

@@ -8,10 +8,10 @@ use super::conv::conv;
use super::inspect::inspect;
use super::num::num;
use super::panic::panic;
use super::state::{state_handlers, state_lib};
use super::str::str;
use crate::facade::{IntoSystem, System};
use crate::interner::Interner;
use crate::interpreter::HandlerTable;
use crate::pipeline::file_loader::embed_to_map;
use crate::sourcefile::{FileEntry, Import};
@@ -33,7 +33,8 @@ struct StlEmbed;
impl IntoSystem<'static> for StlConfig {
fn into_system(self, i: &Interner) -> System<'static> {
let pure_fns = conv(i) + bool(i) + str(i) + num(i) + bin(i) + panic(i);
let pure_fns =
conv(i) + bool(i) + str(i) + num(i) + bin(i) + panic(i) + state_lib(i);
let mk_impure_fns = || inspect(i);
let fns = if self.impure { pure_fns + mk_impure_fns() } else { pure_fns };
System {
@@ -44,7 +45,7 @@ impl IntoSystem<'static> for StlConfig {
path: vec![i.i("std"), i.i("prelude")],
name: None,
}])],
handlers: HandlerTable::new(),
handlers: state_handlers(),
}
}
}