send messages, motherfucker!
This commit is contained in:
parent
c144702b98
commit
888f5b62da
|
@ -1211,7 +1211,35 @@ fn penwidth {
|
|||
|
||||
box state = nil
|
||||
|
||||
fn self {
|
||||
"Returns the current process's pid, as a keyword."
|
||||
() -> base :process (:self)
|
||||
}
|
||||
|
||||
fn send {
|
||||
"Sends a message to the specified process."
|
||||
(pid as :keyword, msg) -> base :process (:send, pid, msg)
|
||||
}
|
||||
|
||||
fn spawn! {
|
||||
"Spawns a new process running the function passed in."
|
||||
(f as :fn) -> base :process (:spawn, f)
|
||||
}
|
||||
|
||||
fn yield! {
|
||||
"Forces a process to yield."
|
||||
() -> base :process (:yield)
|
||||
}
|
||||
|
||||
fn msgs () -> base :process (:msgs)
|
||||
|
||||
#{
|
||||
self
|
||||
send
|
||||
msgs
|
||||
spawn!
|
||||
yield!
|
||||
|
||||
abs
|
||||
abs
|
||||
add
|
||||
|
|
12
sandbox.ld
12
sandbox.ld
|
@ -1 +1,11 @@
|
|||
let true = false
|
||||
let pid = spawn! (fn () -> {
|
||||
print! (self ())
|
||||
print! (msgs ())
|
||||
})
|
||||
|
||||
send (pid, :foo)
|
||||
send (pid, :bar)
|
||||
|
||||
yield! ()
|
||||
|
||||
:done
|
||||
|
|
|
@ -609,6 +609,7 @@ pub fn make_base() -> Value {
|
|||
("number", Value::BaseFn(BaseFn::Unary("number", number))),
|
||||
("pi", Value::Number(std::f64::consts::PI)),
|
||||
("print!", Value::BaseFn(BaseFn::Unary("print!", print))),
|
||||
("process", Value::Process),
|
||||
("random", Value::BaseFn(BaseFn::Nullary("random", random))),
|
||||
("range", Value::BaseFn(BaseFn::Binary("range", range))),
|
||||
("rest", Value::BaseFn(BaseFn::Unary("rest", rest))),
|
||||
|
|
|
@ -20,6 +20,12 @@ pub struct Chunk {
|
|||
pub msgs: Vec<String>,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Chunk {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "Chunk.")
|
||||
}
|
||||
}
|
||||
|
||||
impl Chunk {
|
||||
pub fn dissasemble_instr(&self, i: &mut usize) {
|
||||
let op = Op::from_u8(self.bytecode[*i]).unwrap();
|
||||
|
|
13
src/lib.rs
13
src/lib.rs
|
@ -3,7 +3,7 @@ use imbl::HashMap;
|
|||
use wasm_bindgen::prelude::*;
|
||||
|
||||
const DEBUG_SCRIPT_COMPILE: bool = false;
|
||||
const DEBUG_SCRIPT_RUN: bool = false;
|
||||
const DEBUG_SCRIPT_RUN: bool = true;
|
||||
const DEBUG_PRELUDE_COMPILE: bool = false;
|
||||
const DEBUG_PRELUDE_RUN: bool = false;
|
||||
|
||||
|
@ -84,8 +84,9 @@ fn prelude() -> HashMap<&'static str, Value> {
|
|||
compiler.compile();
|
||||
|
||||
let chunk = compiler.chunk;
|
||||
let mut vm = Creature::new(chunk, DEBUG_PRELUDE_RUN);
|
||||
let prelude = vm.run().clone().unwrap();
|
||||
let mut world = World::new(chunk, DEBUG_PRELUDE_RUN);
|
||||
world.run();
|
||||
let prelude = world.result.unwrap().unwrap();
|
||||
match prelude {
|
||||
Value::Dict(hashmap) => *hashmap,
|
||||
_ => unreachable!(),
|
||||
|
@ -146,10 +147,8 @@ pub fn ludus(src: String) -> String {
|
|||
|
||||
let vm_chunk = compiler.chunk;
|
||||
|
||||
let vm = Creature::new(vm_chunk, DEBUG_SCRIPT_RUN);
|
||||
let grip = World::new(vm);
|
||||
grip.borrow_mut().run();
|
||||
let world = grip.borrow();
|
||||
let mut world = World::new(vm_chunk, DEBUG_SCRIPT_RUN);
|
||||
world.run();
|
||||
let result = world.result.clone().unwrap();
|
||||
|
||||
let console = postlude.get("console").unwrap();
|
||||
|
|
141
src/vm.rs
141
src/vm.rs
|
@ -4,7 +4,7 @@ use crate::op::Op;
|
|||
use crate::parser::Ast;
|
||||
use crate::spans::Spanned;
|
||||
use crate::value::{LFn, Value};
|
||||
use crate::world::Grasp;
|
||||
use crate::world::Zoo;
|
||||
use imbl::{HashMap, Vector};
|
||||
use num_traits::FromPrimitive;
|
||||
use std::cell::RefCell;
|
||||
|
@ -77,26 +77,35 @@ fn combine_bytes(high: u8, low: u8) -> usize {
|
|||
out as usize
|
||||
}
|
||||
|
||||
const REGISTER_SIZE: usize = 8;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Creature {
|
||||
pub stack: Vec<Value>,
|
||||
pub call_stack: Vec<CallFrame>,
|
||||
pub frame: CallFrame,
|
||||
pub ip: usize,
|
||||
pub return_register: [Value; 8],
|
||||
pub register: [Value; REGISTER_SIZE],
|
||||
pub matches: bool,
|
||||
pub match_depth: u8,
|
||||
pub result: Option<Result<Value, Panic>>,
|
||||
debug: bool,
|
||||
last_code: usize,
|
||||
pub id: &'static str,
|
||||
pub world: Grasp,
|
||||
pub mbx: VecDeque<Value>,
|
||||
pub reductions: usize,
|
||||
pub zoo: Rc<RefCell<Zoo>>,
|
||||
pub r#yield: bool,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Creature {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "Creature. {} @{}", self.id, self.ip)
|
||||
}
|
||||
}
|
||||
|
||||
impl Creature {
|
||||
pub fn new(chunk: Chunk, debug: bool) -> Creature {
|
||||
pub fn new(chunk: Chunk, zoo: Rc<RefCell<Zoo>>, debug: bool) -> Creature {
|
||||
let lfn = LFn::Defined {
|
||||
name: "user script",
|
||||
doc: None,
|
||||
|
@ -106,8 +115,12 @@ impl Creature {
|
|||
closed: RefCell::new(vec![]),
|
||||
};
|
||||
let base_fn = Value::Fn(Rc::new(lfn));
|
||||
Creature::spawn(base_fn, zoo, debug)
|
||||
}
|
||||
|
||||
pub fn spawn(function: Value, zoo: Rc<RefCell<Zoo>>, debug: bool) -> Creature {
|
||||
let base_frame = CallFrame {
|
||||
function: base_fn.clone(),
|
||||
function,
|
||||
stack_base: 0,
|
||||
ip: 0,
|
||||
arity: 0,
|
||||
|
@ -117,16 +130,17 @@ impl Creature {
|
|||
call_stack: Vec::with_capacity(64),
|
||||
frame: base_frame,
|
||||
ip: 0,
|
||||
return_register: [const { Value::Nothing }; 8],
|
||||
register: [const { Value::Nothing }; REGISTER_SIZE],
|
||||
matches: false,
|
||||
match_depth: 0,
|
||||
result: None,
|
||||
debug,
|
||||
last_code: 0,
|
||||
id: "",
|
||||
world: None,
|
||||
zoo,
|
||||
mbx: VecDeque::new(),
|
||||
reductions: 0,
|
||||
r#yield: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,6 +148,11 @@ impl Creature {
|
|||
self.reductions += 1;
|
||||
}
|
||||
|
||||
pub fn reset_reductions(&mut self) {
|
||||
self.reductions = 0;
|
||||
self.r#yield = false;
|
||||
}
|
||||
|
||||
pub fn receive(&mut self, value: Value) {
|
||||
self.mbx.push_back(value);
|
||||
}
|
||||
|
@ -165,12 +184,21 @@ impl Creature {
|
|||
}
|
||||
let inner = inner.join("|");
|
||||
let register = self
|
||||
.return_register
|
||||
.register
|
||||
.iter()
|
||||
.map(|val| val.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
println!("{:04}: [{inner}] ({register})", self.last_code);
|
||||
let mbx = self
|
||||
.mbx
|
||||
.iter()
|
||||
.map(|val| val.show())
|
||||
.collect::<Vec<_>>()
|
||||
.join("/");
|
||||
println!(
|
||||
"{:04}: [{inner}] ({register}) {} {{{mbx}}}",
|
||||
self.last_code, self.id
|
||||
);
|
||||
}
|
||||
|
||||
fn print_debug(&self) {
|
||||
|
@ -179,12 +207,12 @@ impl Creature {
|
|||
self.chunk().dissasemble_instr(&mut ip);
|
||||
}
|
||||
|
||||
pub fn run(&mut self) -> &Result<Value, Panic> {
|
||||
while self.result.is_none() {
|
||||
self.interpret();
|
||||
}
|
||||
self.result.as_ref().unwrap()
|
||||
}
|
||||
// pub fn run(&mut self) -> &Result<Value, Panic> {
|
||||
// while self.result.is_none() {
|
||||
// self.interpret();
|
||||
// }
|
||||
// self.result.as_ref().unwrap()
|
||||
// }
|
||||
|
||||
pub fn call_stack(&mut self) -> String {
|
||||
let mut stack = format!(" calling {}", self.frame.function.show());
|
||||
|
@ -237,13 +265,54 @@ impl Creature {
|
|||
self.ip >= self.chunk().bytecode.len()
|
||||
}
|
||||
|
||||
fn handle_msg(&mut self, args: Vec<Value>) {
|
||||
println!("message received! {}", args[0]);
|
||||
let Value::Keyword(msg) = args.first().unwrap() else {
|
||||
return self.panic("malformed message to Process");
|
||||
};
|
||||
match *msg {
|
||||
"self" => self.push(Value::Keyword(self.id)),
|
||||
"msgs" => {
|
||||
let msgs = self.mbx.iter().cloned().collect::<Vec<_>>();
|
||||
let msgs = Vector::from(msgs);
|
||||
self.push(Value::List(Box::new(msgs)));
|
||||
}
|
||||
"send" => {
|
||||
let Value::Keyword(pid) = args[1] else {
|
||||
return self.panic("malformed pid");
|
||||
};
|
||||
if self.id == pid {
|
||||
self.mbx.push_back(args[2].clone());
|
||||
} else {
|
||||
self.zoo
|
||||
.as_ref()
|
||||
.borrow_mut()
|
||||
.send_msg(pid, args[2].clone());
|
||||
}
|
||||
self.push(Value::Nil);
|
||||
}
|
||||
"spawn" => {
|
||||
println!("spawning new process!");
|
||||
let f = args[1].clone();
|
||||
let proc = Creature::spawn(f, self.zoo.clone(), self.debug);
|
||||
let id = self.zoo.as_ref().borrow_mut().put(proc);
|
||||
self.push(Value::Keyword(id));
|
||||
}
|
||||
"yield" => {
|
||||
self.r#yield = true;
|
||||
self.push(Value::Nil);
|
||||
}
|
||||
msg => panic!("Process does not understand message: {msg}"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn interpret(&mut self) {
|
||||
loop {
|
||||
if self.at_end() {
|
||||
self.result = Some(Ok(self.stack.pop().unwrap()));
|
||||
return;
|
||||
}
|
||||
if self.reductions >= MAX_REDUCTIONS {
|
||||
if self.reductions >= MAX_REDUCTIONS || self.r#yield {
|
||||
return;
|
||||
}
|
||||
let code = self.read();
|
||||
|
@ -321,27 +390,27 @@ impl Creature {
|
|||
self.push(value.clone());
|
||||
}
|
||||
Store => {
|
||||
self.return_register[0] = self.pop();
|
||||
self.register[0] = self.pop();
|
||||
}
|
||||
StoreN => {
|
||||
let n = self.read() as usize;
|
||||
for i in (0..n).rev() {
|
||||
self.return_register[i] = self.pop();
|
||||
self.register[i] = self.pop();
|
||||
}
|
||||
}
|
||||
Stash => {
|
||||
self.return_register[0] = self.peek().clone();
|
||||
self.register[0] = self.peek().clone();
|
||||
}
|
||||
Load => {
|
||||
let mut value = Value::Nothing;
|
||||
swap(&mut self.return_register[0], &mut value);
|
||||
swap(&mut self.register[0], &mut value);
|
||||
self.push(value);
|
||||
}
|
||||
LoadN => {
|
||||
let n = self.read() as usize;
|
||||
for i in 0..n {
|
||||
let mut value = Value::Nothing;
|
||||
swap(&mut self.return_register[i], &mut value);
|
||||
swap(&mut self.register[i], &mut value);
|
||||
self.push(value);
|
||||
}
|
||||
}
|
||||
|
@ -814,6 +883,7 @@ impl Creature {
|
|||
self.push(Value::Partial(Rc::new(partial)));
|
||||
}
|
||||
TailCall => {
|
||||
self.reduce();
|
||||
let arity = self.read();
|
||||
|
||||
let called = self.pop();
|
||||
|
@ -826,6 +896,10 @@ impl Creature {
|
|||
}
|
||||
|
||||
match called {
|
||||
Value::Process => {
|
||||
let args = self.stack.split_off(self.stack.len() - arity as usize);
|
||||
self.handle_msg(args);
|
||||
}
|
||||
Value::Fn(_) => {
|
||||
if !called.as_fn().accepts(arity) {
|
||||
return self.panic_with(format!(
|
||||
|
@ -835,7 +909,7 @@ impl Creature {
|
|||
}
|
||||
// first put the arguments in the register
|
||||
for i in 0..arity as usize {
|
||||
self.return_register[arity as usize - i - 1] = self.pop();
|
||||
self.register[arity as usize - i - 1] = self.pop();
|
||||
}
|
||||
// self.print_stack();
|
||||
|
||||
|
@ -843,9 +917,9 @@ impl Creature {
|
|||
self.stack.truncate(self.frame.stack_base);
|
||||
// then push the arguments back on the stack
|
||||
let mut i = 0;
|
||||
while i < 8 && self.return_register[i] != Value::Nothing {
|
||||
while i < 8 && self.register[i] != Value::Nothing {
|
||||
let mut value = Value::Nothing;
|
||||
swap(&mut self.return_register[i], &mut value);
|
||||
swap(&mut self.register[i], &mut value);
|
||||
self.push(value);
|
||||
i += 1;
|
||||
}
|
||||
|
@ -936,6 +1010,7 @@ impl Creature {
|
|||
}
|
||||
}
|
||||
Call => {
|
||||
self.reduce();
|
||||
let arity = self.read();
|
||||
|
||||
let called = self.pop();
|
||||
|
@ -945,6 +1020,10 @@ impl Creature {
|
|||
}
|
||||
|
||||
match called {
|
||||
Value::Process => {
|
||||
let args = self.stack.split_off(self.stack.len() - arity as usize);
|
||||
self.handle_msg(args);
|
||||
}
|
||||
Value::Fn(_) => {
|
||||
if !called.as_fn().accepts(arity) {
|
||||
return self.panic_with(format!(
|
||||
|
@ -1030,12 +1109,20 @@ impl Creature {
|
|||
if self.debug {
|
||||
println!("== returning from {} ==", self.frame.function.show())
|
||||
}
|
||||
self.frame = self.call_stack.pop().unwrap();
|
||||
self.ip = self.frame.ip;
|
||||
let mut value = Value::Nothing;
|
||||
swap(&mut self.return_register[0], &mut value);
|
||||
swap(&mut self.register[0], &mut value);
|
||||
match self.call_stack.pop() {
|
||||
Some(frame) => {
|
||||
self.ip = frame.ip;
|
||||
self.frame = frame;
|
||||
self.push(value);
|
||||
}
|
||||
None => {
|
||||
self.result = Some(Ok(value));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Print => {
|
||||
println!("{}", self.pop().show());
|
||||
self.push(Value::Keyword("ok"));
|
||||
|
|
154
src/world.rs
154
src/world.rs
|
@ -1,3 +1,4 @@
|
|||
use crate::chunk::Chunk;
|
||||
use crate::value::Value;
|
||||
use crate::vm::{Creature, Panic};
|
||||
use ran::ran_u8;
|
||||
|
@ -39,12 +40,33 @@ enum Status {
|
|||
Nested(Creature),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Status {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Status::Empty => write!(f, "empty"),
|
||||
Status::Borrowed => write!(f, "borrowed"),
|
||||
Status::Nested(creature) => write!(f, "nested {creature}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Status {
|
||||
pub fn receive(&mut self, msg: Value) {
|
||||
match self {
|
||||
Status::Nested(creature) => creature.receive(msg),
|
||||
Status::Borrowed => println!("sending a message to a borrowed process"),
|
||||
Status::Empty => println!("sending a message to a dead process"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
struct Zoo {
|
||||
pub struct Zoo {
|
||||
procs: Vec<Status>,
|
||||
empty: Vec<usize>,
|
||||
ids: HashMap<&'static str, usize>,
|
||||
dead: Vec<&'static str>,
|
||||
kill_list: Vec<&'static str>,
|
||||
active: usize,
|
||||
}
|
||||
|
||||
|
@ -54,6 +76,7 @@ impl Zoo {
|
|||
procs: vec![],
|
||||
empty: vec![],
|
||||
ids: HashMap::new(),
|
||||
kill_list: vec![],
|
||||
dead: vec![],
|
||||
active: 0,
|
||||
}
|
||||
|
@ -93,13 +116,19 @@ impl Zoo {
|
|||
}
|
||||
|
||||
pub fn kill(&mut self, id: &'static str) {
|
||||
self.kill_list.push(id);
|
||||
}
|
||||
|
||||
pub fn clean_up(&mut self) {
|
||||
while let Some(id) = self.kill_list.pop() {
|
||||
if let Some(idx) = self.ids.get(id) {
|
||||
self.procs[*idx] = Status::Empty;
|
||||
self.empty.push(*idx);
|
||||
self.ids.remove(&id);
|
||||
self.ids.remove(id);
|
||||
self.dead.push(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn catch(&mut self, id: &'static str) -> Creature {
|
||||
if let Some(idx) = self.ids.get(id) {
|
||||
|
@ -125,7 +154,18 @@ impl Zoo {
|
|||
}
|
||||
|
||||
pub fn next(&mut self, curr_id: &'static str) -> &'static str {
|
||||
println!("getting next process from {curr_id}");
|
||||
println!(
|
||||
"current procs in zoo:\n{}",
|
||||
self.procs
|
||||
.iter()
|
||||
.map(|proc| proc.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join("//")
|
||||
);
|
||||
println!("ids: {:?}", self.ids);
|
||||
let idx = self.ids.get(curr_id).unwrap();
|
||||
println!("current idx: {idx}");
|
||||
if *idx != self.active {
|
||||
panic!(
|
||||
"tried to get next creature after {curr_id} while {} is active",
|
||||
|
@ -133,9 +173,14 @@ impl Zoo {
|
|||
);
|
||||
}
|
||||
self.active = (self.active + 1) % self.procs.len();
|
||||
while self.procs[self.active] != Status::Empty {
|
||||
println!("active idx is now: {}", self.active);
|
||||
while self.procs[self.active] == Status::Empty {
|
||||
let new_active_idx = (self.active + 1) % self.procs.len();
|
||||
println!("new active idx: {new_active_idx}");
|
||||
println!("new active process is: {}", self.procs[new_active_idx]);
|
||||
self.active = (self.active + 1) % self.procs.len();
|
||||
}
|
||||
println!("found next proc: {}", &self.procs[self.active]);
|
||||
match &self.procs[self.active] {
|
||||
Status::Empty => unreachable!(),
|
||||
Status::Borrowed => panic!(
|
||||
|
@ -145,61 +190,63 @@ impl Zoo {
|
|||
Status::Nested(proc) => proc.id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type Grasp = Option<Rc<RefCell<World>>>;
|
||||
pub fn send_msg(&mut self, id: &'static str, msg: Value) {
|
||||
let Some(idx) = self.ids.get(id) else {
|
||||
return;
|
||||
};
|
||||
self.procs[*idx].receive(msg);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct World {
|
||||
zoo: Zoo,
|
||||
zoo: Rc<RefCell<Zoo>>,
|
||||
active: Option<Creature>,
|
||||
main: &'static str,
|
||||
handle: Grasp,
|
||||
pub result: Option<Result<Value, Panic>>,
|
||||
}
|
||||
|
||||
impl World {
|
||||
pub fn new(proc: Creature) -> Rc<RefCell<World>> {
|
||||
let mut zoo = Zoo::new();
|
||||
let id = zoo.put(proc);
|
||||
let world = World {
|
||||
pub fn new(chunk: Chunk, debug: bool) -> World {
|
||||
let zoo = Rc::new(RefCell::new(Zoo::new()));
|
||||
let main = Creature::new(chunk, zoo.clone(), debug);
|
||||
let id = zoo.as_ref().borrow_mut().put(main);
|
||||
|
||||
World {
|
||||
zoo,
|
||||
active: None,
|
||||
main: id,
|
||||
handle: None,
|
||||
result: None,
|
||||
};
|
||||
let handle = Rc::new(RefCell::new(world));
|
||||
let grasped = handle.clone();
|
||||
let mut world = grasped.as_ref().borrow_mut();
|
||||
world.handle = Some(grasped.clone());
|
||||
|
||||
let mut caught = world.zoo.catch(id);
|
||||
caught.world = world.handle.clone();
|
||||
world.zoo.release(caught);
|
||||
|
||||
handle
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawn(&mut self, proc: Creature) -> Value {
|
||||
let id = self.zoo.put(proc);
|
||||
Value::Keyword(id)
|
||||
}
|
||||
// pub fn spawn(&mut self, proc: Creature) -> Value {
|
||||
// let id = self.zoo.put(proc);
|
||||
// Value::Keyword(id)
|
||||
// }
|
||||
|
||||
pub fn send_msg(&mut self, id: &'static str, msg: Value) {
|
||||
let mut proc = self.zoo.catch(id);
|
||||
proc.receive(msg);
|
||||
self.zoo.release(proc);
|
||||
}
|
||||
// pub fn send_msg(&mut self, id: &'static str, msg: Value) {
|
||||
// let mut proc = self.zoo.catch(id);
|
||||
// proc.receive(msg);
|
||||
// self.zoo.release(proc);
|
||||
// }
|
||||
|
||||
fn next(&mut self) {
|
||||
let id = self.zoo.next(self.active.as_ref().unwrap().id);
|
||||
let id = self
|
||||
.zoo
|
||||
.as_ref()
|
||||
.borrow_mut()
|
||||
.next(self.active.as_ref().unwrap().id);
|
||||
println!("next id is {id}");
|
||||
let mut active = None;
|
||||
std::mem::swap(&mut active, &mut self.active);
|
||||
let mut holding_pen = self.zoo.catch(id);
|
||||
let mut holding_pen = self.zoo.as_ref().borrow_mut().catch(id);
|
||||
let mut active = active.unwrap();
|
||||
std::mem::swap(&mut active, &mut holding_pen);
|
||||
self.zoo.release(holding_pen);
|
||||
println!("now in the holding pen: {}", holding_pen.id);
|
||||
holding_pen.reset_reductions();
|
||||
self.zoo.as_ref().borrow_mut().release(holding_pen);
|
||||
let mut active = Some(active);
|
||||
std::mem::swap(&mut active, &mut self.active);
|
||||
}
|
||||
|
@ -234,22 +281,47 @@ impl World {
|
|||
// self.next(id);
|
||||
// }
|
||||
|
||||
pub fn run(&mut self) {
|
||||
let main = self.zoo.catch(self.main);
|
||||
pub fn activate_main(&mut self) {
|
||||
let main = self.zoo.as_ref().borrow_mut().catch(self.main);
|
||||
self.active = Some(main);
|
||||
}
|
||||
|
||||
pub fn active_id(&mut self) -> &'static str {
|
||||
self.active.as_ref().unwrap().id
|
||||
}
|
||||
|
||||
pub fn kill_active(&mut self) {
|
||||
let id = self.active_id();
|
||||
self.zoo.as_ref().borrow_mut().kill(id);
|
||||
}
|
||||
|
||||
pub fn active_result(&mut self) -> &Option<Result<Value, Panic>> {
|
||||
&self.active.as_ref().unwrap().result
|
||||
}
|
||||
|
||||
pub fn clean_up(&mut self) {
|
||||
self.zoo.as_ref().borrow_mut().clean_up()
|
||||
}
|
||||
|
||||
pub fn run(&mut self) {
|
||||
self.activate_main();
|
||||
loop {
|
||||
println!("entering world loop");
|
||||
self.active.as_mut().unwrap().interpret();
|
||||
match self.active.as_ref().unwrap().result {
|
||||
println!("interpreted loop");
|
||||
match self.active_result() {
|
||||
None => (),
|
||||
Some(_) => {
|
||||
if self.active.as_ref().unwrap().id == self.main {
|
||||
self.result = self.active.as_ref().unwrap().result.clone();
|
||||
if self.active_id() == self.main {
|
||||
self.result = self.active_result().clone();
|
||||
return;
|
||||
}
|
||||
self.zoo.kill(self.active.as_ref().unwrap().id);
|
||||
self.kill_active();
|
||||
}
|
||||
}
|
||||
println!("getting next process");
|
||||
self.next();
|
||||
self.clean_up();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user