forked from Orchid/orchid
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:
@@ -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),
|
||||
|
||||
@@ -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
61
src/systems/stl/state.rs
Normal 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)),
|
||||
]),
|
||||
)
|
||||
}
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user