mirror of
https://github.com/urbit/ares.git
synced 2024-11-26 09:57:56 +03:00
Forward non-deterministic errors to the senior frame
This commit is contained in:
parent
95083f7b78
commit
0072e09a85
@ -1,10 +1,12 @@
|
|||||||
use crate::hamt::Hamt;
|
use crate::hamt::Hamt;
|
||||||
use crate::jets;
|
use crate::jets;
|
||||||
use crate::jets::nock::util::mook;
|
use crate::jets::nock::util::mook;
|
||||||
|
use crate::jets::JetErr;
|
||||||
use crate::mem::unifying_equality;
|
use crate::mem::unifying_equality;
|
||||||
use crate::mem::NockStack;
|
use crate::mem::NockStack;
|
||||||
use crate::newt::Newt;
|
use crate::newt::Newt;
|
||||||
use crate::noun::{Atom, Cell, IndirectAtom, Noun, Slots, D, T};
|
use crate::noun;
|
||||||
|
use crate::noun::{tape, Atom, Cell, IndirectAtom, Noun, Slots, D, T};
|
||||||
use ares_macros::tas;
|
use ares_macros::tas;
|
||||||
use assert_no_alloc::assert_no_alloc;
|
use assert_no_alloc::assert_no_alloc;
|
||||||
use bitvec::prelude::{BitSlice, Lsb0};
|
use bitvec::prelude::{BitSlice, Lsb0};
|
||||||
@ -226,14 +228,33 @@ enum NockWork {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum NockErr {
|
pub enum NockErr {
|
||||||
|
Deterministic,
|
||||||
|
NonDeterministic,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Tone {
|
||||||
Blocked(Noun),
|
Blocked(Noun),
|
||||||
DeterministicError(Noun),
|
Error(NockErr, Noun),
|
||||||
NonDeterministicError(Noun),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<NockErr> for () {
|
impl From<NockErr> for () {
|
||||||
fn from(_: NockErr) -> Self {
|
fn from(_: NockErr) -> Self {}
|
||||||
()
|
}
|
||||||
|
|
||||||
|
impl From<noun::Error> for NockErr {
|
||||||
|
fn from(_: noun::Error) -> Self {
|
||||||
|
NockErr::Deterministic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<JetErr> for NockErr {
|
||||||
|
fn from(e: JetErr) -> Self {
|
||||||
|
match e {
|
||||||
|
JetErr::Deterministic => NockErr::Deterministic,
|
||||||
|
JetErr::NonDeterministic => NockErr::NonDeterministic,
|
||||||
|
JetErr::Punt => panic!("unhandled JetErr::Punt"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,9 +264,8 @@ pub fn interpret(
|
|||||||
newt: &mut Option<&mut Newt>, // For printing slogs; if None, print to stdout
|
newt: &mut Option<&mut Newt>, // For printing slogs; if None, print to stdout
|
||||||
mut subject: Noun,
|
mut subject: Noun,
|
||||||
formula: Noun,
|
formula: Noun,
|
||||||
) -> Result<Noun, NockErr> {
|
) -> Result<Noun, Tone> {
|
||||||
let mut res: Noun = D(0);
|
let mut res: Noun = D(0);
|
||||||
let mut trace: Noun;
|
|
||||||
let mut cache = Hamt::<Noun>::new();
|
let mut cache = Hamt::<Noun>::new();
|
||||||
// XX: Should this come after initial frame_push()?
|
// XX: Should this come after initial frame_push()?
|
||||||
let virtual_frame = stack.get_frame_pointer();
|
let virtual_frame = stack.get_frame_pointer();
|
||||||
@ -254,7 +274,6 @@ pub fn interpret(
|
|||||||
unsafe {
|
unsafe {
|
||||||
*stack.push() = NockWork::Done;
|
*stack.push() = NockWork::Done;
|
||||||
};
|
};
|
||||||
push_formula(stack, formula, true)?;
|
|
||||||
// DO NOT REMOVE THIS ASSERTION
|
// DO NOT REMOVE THIS ASSERTION
|
||||||
//
|
//
|
||||||
// If you need to allocate for debugging, wrap the debugging code in
|
// If you need to allocate for debugging, wrap the debugging code in
|
||||||
@ -266,7 +285,8 @@ pub fn interpret(
|
|||||||
// ```
|
// ```
|
||||||
//
|
//
|
||||||
// (See https://docs.rs/assert_no_alloc/latest/assert_no_alloc/#advanced-use)
|
// (See https://docs.rs/assert_no_alloc/latest/assert_no_alloc/#advanced-use)
|
||||||
let tone = assert_no_alloc(|| unsafe {
|
let nock = assert_no_alloc(|| unsafe {
|
||||||
|
push_formula(stack, formula, true)?;
|
||||||
loop {
|
loop {
|
||||||
let work: NockWork = *stack.top();
|
let work: NockWork = *stack.top();
|
||||||
match work {
|
match work {
|
||||||
@ -303,7 +323,7 @@ pub fn interpret(
|
|||||||
res = noun;
|
res = noun;
|
||||||
stack.pop::<NockWork>();
|
stack.pop::<NockWork>();
|
||||||
} else {
|
} else {
|
||||||
break Err(NockErr::Error(D(1)));
|
break Err(NockErr::Deterministic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NockWork::Work1(once) => {
|
NockWork::Work1(once) => {
|
||||||
@ -364,7 +384,7 @@ pub fn interpret(
|
|||||||
stack.pop::<NockWork>();
|
stack.pop::<NockWork>();
|
||||||
} else {
|
} else {
|
||||||
// Cannot increment (Nock 4) a cell
|
// Cannot increment (Nock 4) a cell
|
||||||
break Err(NockErr::Error(D(2)));
|
break Err(NockErr::Deterministic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -405,11 +425,11 @@ pub fn interpret(
|
|||||||
push_formula(stack, cond.once, cond.tail)?;
|
push_formula(stack, cond.once, cond.tail)?;
|
||||||
} else {
|
} else {
|
||||||
// Test branch of Nock 6 must return 0 or 1
|
// Test branch of Nock 6 must return 0 or 1
|
||||||
break Err(NockErr::Error(D(3)));
|
break Err(NockErr::Deterministic);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Test branch of Nock 6 must return a direct atom
|
// Test branch of Nock 6 must return a direct atom
|
||||||
break Err(NockErr::Error(D(4)));
|
break Err(NockErr::Deterministic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -484,7 +504,7 @@ pub fn interpret(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Axis into core must be atom
|
// Axis into core must be atom
|
||||||
break Err(NockErr::Error(D(5)));
|
break Err(NockErr::Deterministic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Todo9::RestoreSubject => {
|
Todo9::RestoreSubject => {
|
||||||
@ -513,20 +533,25 @@ pub fn interpret(
|
|||||||
}
|
}
|
||||||
NockWork::Work11D(mut dint) => match dint.todo {
|
NockWork::Work11D(mut dint) => match dint.todo {
|
||||||
Todo11D::ComputeHint => {
|
Todo11D::ComputeHint => {
|
||||||
if let Some(found) = match_hint_pre_hint(
|
match match_hint_pre_hint(
|
||||||
stack, newt, &cache, subject, dint.tag, dint.hint, dint.body,
|
stack, newt, &cache, subject, dint.tag, dint.hint, dint.body,
|
||||||
) {
|
) {
|
||||||
res = found;
|
Ok(Some(found)) => {
|
||||||
stack.pop::<NockWork>();
|
res = found;
|
||||||
} else {
|
stack.pop::<NockWork>();
|
||||||
dint.todo = Todo11D::ComputeResult;
|
}
|
||||||
*stack.top() = NockWork::Work11D(dint);
|
Ok(None) => {
|
||||||
push_formula(stack, dint.hint, false)?;
|
dint.todo = Todo11D::ComputeResult;
|
||||||
|
*stack.top() = NockWork::Work11D(dint);
|
||||||
|
push_formula(stack, dint.hint, false)?;
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
break Err(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Todo11D::ComputeResult => {
|
Todo11D::ComputeResult => {
|
||||||
dint.todo = Todo11D::Done;
|
match match_hint_pre_nock(
|
||||||
if let Some(found) = match_hint_pre_nock(
|
|
||||||
stack,
|
stack,
|
||||||
newt,
|
newt,
|
||||||
subject,
|
subject,
|
||||||
@ -535,12 +560,18 @@ pub fn interpret(
|
|||||||
dint.body,
|
dint.body,
|
||||||
Some(res),
|
Some(res),
|
||||||
) {
|
) {
|
||||||
res = found;
|
Ok(Some(found)) => {
|
||||||
stack.pop::<NockWork>();
|
res = found;
|
||||||
} else {
|
stack.pop::<NockWork>();
|
||||||
dint.todo = Todo11D::Done;
|
}
|
||||||
*stack.top() = NockWork::Work11D(dint);
|
Ok(None) => {
|
||||||
push_formula(stack, dint.body, false)?;
|
dint.todo = Todo11D::Done;
|
||||||
|
*stack.top() = NockWork::Work11D(dint);
|
||||||
|
push_formula(stack, dint.body, false)?;
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
break Err(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Todo11D::Done => {
|
Todo11D::Done => {
|
||||||
@ -560,16 +591,21 @@ pub fn interpret(
|
|||||||
},
|
},
|
||||||
NockWork::Work11S(mut sint) => match sint.todo {
|
NockWork::Work11S(mut sint) => match sint.todo {
|
||||||
Todo11S::ComputeResult => {
|
Todo11S::ComputeResult => {
|
||||||
sint.todo = Todo11S::Done;
|
match match_hint_pre_nock(
|
||||||
if let Some(found) = match_hint_pre_nock(
|
|
||||||
stack, newt, subject, sint.tag, None, sint.body, None,
|
stack, newt, subject, sint.tag, None, sint.body, None,
|
||||||
) {
|
) {
|
||||||
res = found;
|
Ok(Some(found)) => {
|
||||||
stack.pop::<NockWork>();
|
res = found;
|
||||||
} else {
|
stack.pop::<NockWork>();
|
||||||
sint.todo = Todo11S::Done;
|
}
|
||||||
*stack.top() = NockWork::Work11S(sint);
|
Ok(None) => {
|
||||||
push_formula(stack, sint.body, false)?;
|
sint.todo = Todo11S::Done;
|
||||||
|
*stack.top() = NockWork::Work11S(sint);
|
||||||
|
push_formula(stack, sint.body, false)?;
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
break Err(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Todo11S::Done => {
|
Todo11S::Done => {
|
||||||
@ -585,13 +621,9 @@ pub fn interpret(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
match tone {
|
match nock {
|
||||||
Ok(res) => Ok(res),
|
Ok(res) => Ok(res),
|
||||||
Err(_err) => {
|
Err(err) => Err(exit_early(stack, &mut cache, virtual_frame, err)),
|
||||||
trace = stack.get_mean_stack();
|
|
||||||
exit_early(stack, virtual_frame, &mut trace, &mut cache);
|
|
||||||
Err(NockErr::Error(trace))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,7 +647,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> Result<(),
|
|||||||
*stack.push() = NockWork::Work0(Nock0 { axis: axis_atom });
|
*stack.push() = NockWork::Work0(Nock0 { axis: axis_atom });
|
||||||
} else {
|
} else {
|
||||||
// Axis for Nock 0 must be an atom
|
// Axis for Nock 0 must be an atom
|
||||||
return Err(NockErr::Error(D(1)));
|
return Err(NockErr::Deterministic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
1 => {
|
1 => {
|
||||||
@ -633,7 +665,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> Result<(),
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Argument to Nock 2 must be cell
|
// Argument to Nock 2 must be cell
|
||||||
return Err(NockErr::Error(D(21)));
|
return Err(NockErr::Deterministic);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
3 => {
|
3 => {
|
||||||
@ -657,7 +689,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> Result<(),
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Argument to Nock 5 must be cell
|
// Argument to Nock 5 must be cell
|
||||||
return Err(NockErr::Error(D(51)));
|
return Err(NockErr::Deterministic);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
6 => {
|
6 => {
|
||||||
@ -672,11 +704,11 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> Result<(),
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Argument tail to Nock 6 must be cell
|
// Argument tail to Nock 6 must be cell
|
||||||
return Err(NockErr::Error(D(62)));
|
return Err(NockErr::Deterministic);
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// Argument to Nock 6 must be cell
|
// Argument to Nock 6 must be cell
|
||||||
return Err(NockErr::Error(D(61)));
|
return Err(NockErr::Deterministic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
7 => {
|
7 => {
|
||||||
@ -689,7 +721,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> Result<(),
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Argument to Nock 7 must be cell
|
// Argument to Nock 7 must be cell
|
||||||
return Err(NockErr::Error(D(71)));
|
return Err(NockErr::Deterministic);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
8 => {
|
8 => {
|
||||||
@ -702,7 +734,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> Result<(),
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Argument to Nock 8 must be cell
|
// Argument to Nock 8 must be cell
|
||||||
return Err(NockErr::Error(D(81)));
|
return Err(NockErr::Deterministic);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
9 => {
|
9 => {
|
||||||
@ -716,11 +748,11 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> Result<(),
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Axis for Nock 9 must be an atom
|
// Axis for Nock 9 must be an atom
|
||||||
return Err(NockErr::Error(D(92)));
|
return Err(NockErr::Deterministic);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Argument to Nock 9 must be cell
|
// Argument to Nock 9 must be cell
|
||||||
return Err(NockErr::Error(D(91)));
|
return Err(NockErr::Deterministic);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
10 => {
|
10 => {
|
||||||
@ -735,15 +767,15 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> Result<(),
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Axis for Nock 10 must be an atom
|
// Axis for Nock 10 must be an atom
|
||||||
return Err(NockErr::Error(D(103)));
|
return Err(NockErr::Deterministic);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Heah of argument to Nock 10 must be a cell
|
// Heah of argument to Nock 10 must be a cell
|
||||||
return Err(NockErr::Error(D(102)));
|
return Err(NockErr::Deterministic);
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// Argument to Nock 10 must be a cell
|
// Argument to Nock 10 must be a cell
|
||||||
return Err(NockErr::Error(D(101)));
|
return Err(NockErr::Deterministic);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
11 => {
|
11 => {
|
||||||
@ -766,29 +798,29 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> Result<(),
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Hint tag must be an atom
|
// Hint tag must be an atom
|
||||||
return Err(NockErr::Error(D(112)));
|
return Err(NockErr::Deterministic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// Argument for Nock 11 must be cell
|
// Argument for Nock 11 must be cell
|
||||||
return Err(NockErr::Error(D(111)));
|
return Err(NockErr::Deterministic);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Invalid formula opcode
|
// Invalid formula opcode
|
||||||
return Err(NockErr::Error(D(0)));
|
return Err(NockErr::Deterministic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Formula opcode must be direct atom
|
// Formula opcode must be direct atom
|
||||||
return Err(NockErr::Error(D(0)));
|
return Err(NockErr::Deterministic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Bad formula: atoms are not formulas
|
// Bad formula: atoms are not formulas
|
||||||
return Err(NockErr::Error(D(0)));
|
return Err(NockErr::Deterministic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -796,17 +828,19 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> Result<(),
|
|||||||
|
|
||||||
pub fn exit_early(
|
pub fn exit_early(
|
||||||
stack: &mut NockStack,
|
stack: &mut NockStack,
|
||||||
virtual_frame: *const u64,
|
|
||||||
trace: &mut Noun,
|
|
||||||
cache: &mut Hamt<Noun>,
|
cache: &mut Hamt<Noun>,
|
||||||
) {
|
virtual_frame: *const u64,
|
||||||
|
error: NockErr,
|
||||||
|
) -> Tone {
|
||||||
|
let mut trace = stack.get_mean_stack();
|
||||||
unsafe {
|
unsafe {
|
||||||
while stack.get_frame_pointer() != virtual_frame {
|
while stack.get_frame_pointer() != virtual_frame {
|
||||||
stack.preserve(trace);
|
stack.preserve(&mut trace);
|
||||||
stack.preserve(cache);
|
stack.preserve(cache);
|
||||||
stack.frame_pop();
|
stack.frame_pop();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
Tone::Error(error, trace)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn edit(
|
fn edit(
|
||||||
@ -888,23 +922,9 @@ fn match_hint_pre_hint(
|
|||||||
tag: Atom,
|
tag: Atom,
|
||||||
hint: Noun,
|
hint: Noun,
|
||||||
body: Noun,
|
body: Noun,
|
||||||
// ) -> Result<Option<Noun>, JetErr> {
|
|
||||||
// possible cases:
|
|
||||||
// 1. Deterministic error, no trace
|
|
||||||
// jet - nock mismatch
|
|
||||||
// need to add a mean hint, then fail
|
|
||||||
// 2. Deterministic error, trace
|
|
||||||
// Deterministic error in jet or nock
|
|
||||||
// 3. Nondeterministic error, trace
|
|
||||||
// Nondeterministic error in jet or nock
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// 4. Nondeterministic error, no trace
|
|
||||||
// ??? does this exist?
|
|
||||||
//
|
|
||||||
) -> Result<Option<Noun>, NockErr> {
|
) -> Result<Option<Noun>, NockErr> {
|
||||||
// XX: handle IndirectAtom tags
|
// XX: handle IndirectAtom tags
|
||||||
match tag.direct()?.data() {
|
match tag.as_direct()?.data() {
|
||||||
// %sham hints are scaffolding until we have a real jet dashboard
|
// %sham hints are scaffolding until we have a real jet dashboard
|
||||||
tas!(b"sham") => {
|
tas!(b"sham") => {
|
||||||
let jet_formula = hint.as_cell()?;
|
let jet_formula = hint.as_cell()?;
|
||||||
@ -914,71 +934,69 @@ fn match_hint_pre_hint(
|
|||||||
if let Some(jet) = jets::get_jet(jet_name) {
|
if let Some(jet) = jets::get_jet(jet_name) {
|
||||||
match jet(stack, newt, subject) {
|
match jet(stack, newt, subject) {
|
||||||
Ok(mut jet_res) => {
|
Ok(mut jet_res) => {
|
||||||
|
// XX: simplify this by moving jet test mode into the 11 code in interpret, or into its own function?
|
||||||
// if in test mode, check that the jet returns the same result as the raw nock
|
// if in test mode, check that the jet returns the same result as the raw nock
|
||||||
if jets::get_jet_test_mode(jet_name) {
|
if jets::get_jet_test_mode(jet_name) {
|
||||||
// Throw away trace because we'll regenerate it later, and this is in test mode
|
// XX: we throw away trace, which might matter for non-deterministic errors
|
||||||
// so it's okay if it runs twice
|
// maybe mook and slog it?
|
||||||
match interpret(stack, newt, subject, body) {
|
match interpret(stack, newt, subject, body) {
|
||||||
Ok(mut nock_res) => {
|
Ok(mut nock_res) => {
|
||||||
if unsafe { !unifying_equality(stack, &mut nock_res, &mut jet_res) } {
|
if unsafe {
|
||||||
|
!unifying_equality(stack, &mut nock_res, &mut jet_res)
|
||||||
|
} {
|
||||||
|
// XX: need string interpolation without allocation, then delete eprintln
|
||||||
|
// let tape = tape(stack, "jet mismatch in {}, raw: {}, jetted: {}", jet_name, nock_res, jet_res);
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"\rJet {} failed, raw: {}, jetted: {}",
|
"\rjet {} failed, raw: {:?}, jetted: {}",
|
||||||
jet_name, nock_res, jet_res
|
jet_name, nock_res, jet_res
|
||||||
);
|
);
|
||||||
Err(Deterministic)
|
let tape = tape(stack, "jet mismatch");
|
||||||
|
let mean = T(stack, &[D(tas!(b"mean")), tape]);
|
||||||
|
stack.trace_push(mean);
|
||||||
|
Err(NockErr::Deterministic)
|
||||||
} else {
|
} else {
|
||||||
Ok(Some(jet_res))
|
Ok(Some(nock_res))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(NockErr::DeterministicError(trace)) => {
|
Err(Tone::Error(err, _)) => {
|
||||||
|
// XX: need string interpolation without allocation, then delete eprintln
|
||||||
|
// let tape = tape(stack, "jet mismatch in {}, raw: {}, jetted: {}", jet_name, err, jet_res);
|
||||||
|
eprintln!(
|
||||||
|
"\rjet {} failed, raw: {:?}, jetted: {}",
|
||||||
|
jet_name, err, jet_res
|
||||||
|
);
|
||||||
|
let tape = tape(stack, "jet mismatch");
|
||||||
|
let mean = T(stack, &[D(tas!(b"mean")), tape]);
|
||||||
|
stack.trace_push(mean);
|
||||||
|
Err(err)
|
||||||
|
}
|
||||||
|
Err(Tone::Blocked(_)) => {
|
||||||
|
panic!("jet test mode: no scry handling")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interpret(stack, newt, subject, body)
|
|
||||||
.ok()
|
|
||||||
.map(|mut nock_res| {
|
|
||||||
if unsafe { !unifying_equality(stack, &mut nock_res, &mut jet_res) } {
|
|
||||||
eprintln!(
|
|
||||||
"\rJet {} failed, raw: {}, jetted: {}",
|
|
||||||
jet_name, nock_res, jet_res
|
|
||||||
);
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(jet_res)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.unwrap()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Some(jet_res))
|
Ok(Some(jet_res))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Err(JetErr::Punt) => Ok(None),
|
||||||
|
Err(err) => {
|
||||||
|
// XX: need string interpolation without allocation
|
||||||
if let Ok(mut jet_res) = jet(stack, newt, subject) {
|
// let tape = tape(stack, "{} jet error in {}", err, jet_name);
|
||||||
|
let tape = tape(stack, "jet error");
|
||||||
} else {
|
let mean = T(stack, &[D(tas!(b"mean")), tape]);
|
||||||
// Print jet errors and punt to Nock
|
stack.trace_push(mean);
|
||||||
eprintln!("\rJet {} failed: ", jet_name);
|
Err(err.into())
|
||||||
None
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
tas!(b"memo") => {
|
tas!(b"memo") => {
|
||||||
let mut key = Cell::new(stack, subject, body).as_noun();
|
let mut key = Cell::new(stack, subject, body).as_noun();
|
||||||
cache.lookup(stack, &mut key)
|
Ok(cache.lookup(stack, &mut key))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => Ok(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -991,41 +1009,27 @@ fn match_hint_pre_nock(
|
|||||||
_hint: Option<Noun>,
|
_hint: Option<Noun>,
|
||||||
_body: Noun,
|
_body: Noun,
|
||||||
res: Option<Noun>,
|
res: Option<Noun>,
|
||||||
) -> Result<Option<Noun>, JetErr> {
|
) -> Result<Option<Noun>, NockErr> {
|
||||||
// XX: assert Some(res) <=> Some(hint)
|
// XX: assert Some(res) <=> Some(hint)
|
||||||
|
|
||||||
// XX: handle IndirectAtom tags
|
// XX: handle IndirectAtom tags
|
||||||
match tag.direct()?.data() {
|
match tag.as_direct()?.data() {
|
||||||
tas!(b"slog") => {
|
tas!(b"slog") => {
|
||||||
let slog_cell = res?.cell()?;
|
let slog_cell = res.ok_or(NockErr::Deterministic)?.as_cell()?;
|
||||||
let pri = slog_cell.head().direct()?.data();
|
let pri = slog_cell.head().as_direct()?.data();
|
||||||
let tank = slog_cell.tail();
|
let tank = slog_cell.tail();
|
||||||
if let Some(not) = newt {
|
if let Some(not) = newt {
|
||||||
not.slog(stack, pri, tank);
|
not.slog(stack, pri, tank);
|
||||||
} else {
|
} else {
|
||||||
eprintln!("raw slog: {} {}", pri, tank);
|
eprintln!("raw slog: {} {}", pri, tank);
|
||||||
}
|
}
|
||||||
|
Ok(None)
|
||||||
}
|
}
|
||||||
tas!(b"hand") | tas!(b"hunk") | tas!(b"lose") | tas!(b"mean") | tas!(b"spot") => {
|
tas!(b"hand") | tas!(b"hunk") | tas!(b"lose") | tas!(b"mean") | tas!(b"spot") => {
|
||||||
let trace = Cell::new(stack, tag.as_noun(), res?).as_noun();
|
let trace = T(stack, &[tag.as_noun(), res.ok_or(NockErr::Deterministic)?]);
|
||||||
stack.trace_push(trace);
|
stack.trace_push(trace);
|
||||||
|
Ok(None)
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// u3_serf_writ -> u3_serf_work -> _serf_work -> _serf_poke -> u3m_soft -> u3dc -> u3v_do -> u3v_wish -> +wish in Arvo
|
|
||||||
// |
|
|
||||||
// V
|
|
||||||
// mook
|
|
||||||
//
|
|
||||||
// No +wish in toy Arvo; missing +slap and a ton of parsing functions needed by +ream
|
|
||||||
//
|
|
||||||
// u3t_slog = print on thing directly
|
|
||||||
// u3t_slog_trace = print stack trace = - convert tone to toon
|
|
||||||
// - presume toon is [%2 tang]
|
|
||||||
// - print each tank in tang one at at time using u3t_slog
|
|
||||||
// u3t_slog_hela = print entire stack trace = - weld stacks from all roads together
|
|
||||||
// - call u3t_slog_trace on combined stack
|
|
||||||
// u3t_slog_nara = print home road stack trace = call u3t_slog_trace on home road stack
|
|
||||||
//
|
|
||||||
tas!(b"hela") => {
|
tas!(b"hela") => {
|
||||||
// XX: should this be virtualized?
|
// XX: should this be virtualized?
|
||||||
// pretty sure we should be bailing on error
|
// pretty sure we should be bailing on error
|
||||||
@ -1033,39 +1037,44 @@ fn match_hint_pre_nock(
|
|||||||
let stak = stack.get_mean_stack();
|
let stak = stack.get_mean_stack();
|
||||||
let tone = Cell::new(stack, D(2), stak);
|
let tone = Cell::new(stack, D(2), stak);
|
||||||
|
|
||||||
if let Ok(toon) = mook(stack, newt, tone, true) {
|
match mook(stack, newt, tone, true) {
|
||||||
if unsafe { !toon.head().raw_equals(D(2)) } {
|
Ok(toon) => {
|
||||||
// Print jet error and punt to Nock
|
if unsafe { !toon.head().raw_equals(D(2)) } {
|
||||||
eprintln!("\r%hela failed: toon not %2");
|
let tape = tape(stack, "%hela failed: toon not %2");
|
||||||
return None;
|
let mean = T(stack, &[D(tas!(b"mean")), tape]);
|
||||||
}
|
stack.trace_push(mean);
|
||||||
|
return Err(NockErr::Deterministic);
|
||||||
let mut list = toon.tail();
|
|
||||||
loop {
|
|
||||||
if unsafe { list.raw_equals(D(0)) } {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let cell = list.as_cell().unwrap();
|
let mut list = toon.tail();
|
||||||
if let Some(not) = newt {
|
loop {
|
||||||
// XX: %hela priority is configurable, but I'm not sure how
|
if unsafe { list.raw_equals(D(0)) } {
|
||||||
not.slog(stack, 0, cell.head());
|
break;
|
||||||
} else {
|
}
|
||||||
eprintln!("raw slog: {} {}", 0, cell.head());
|
|
||||||
|
let cell = list.as_cell().unwrap();
|
||||||
|
if let Some(not) = newt {
|
||||||
|
// XX: %hela priority is configurable, but I'm not sure how
|
||||||
|
not.slog(stack, 0, cell.head());
|
||||||
|
} else {
|
||||||
|
eprintln!("raw slog: {} {}", 0, cell.head());
|
||||||
|
}
|
||||||
|
|
||||||
|
list = cell.tail();
|
||||||
}
|
}
|
||||||
|
|
||||||
list = cell.tail();
|
Ok(None)
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
let tape = tape(stack, "%hela failed: mook error");
|
||||||
|
let mean = T(stack, &[D(tas!(b"mean")), tape]);
|
||||||
|
stack.trace_push(mean);
|
||||||
|
Err(err.into())
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Print jet errors and punt to Nock
|
|
||||||
eprintln!("\r%hela failed: mook error");
|
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => Ok(None),
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Match static and dynamic hints after the nock formula is evaluated */
|
/** Match static and dynamic hints after the nock formula is evaluated */
|
||||||
@ -1077,7 +1086,7 @@ fn match_hint_post_nock(
|
|||||||
_hint: Option<Noun>,
|
_hint: Option<Noun>,
|
||||||
body: Noun,
|
body: Noun,
|
||||||
res: Noun,
|
res: Noun,
|
||||||
) -> Result<Option<Noun>, JetErr> {
|
) -> Option<Noun> {
|
||||||
// XX: handle IndirectAtom tags
|
// XX: handle IndirectAtom tags
|
||||||
match tag.direct()?.data() {
|
match tag.direct()?.data() {
|
||||||
tas!(b"memo") => {
|
tas!(b"memo") => {
|
||||||
@ -1085,7 +1094,7 @@ fn match_hint_post_nock(
|
|||||||
*cache = cache.insert(stack, &mut key, res);
|
*cache = cache.insert(stack, &mut key, res);
|
||||||
}
|
}
|
||||||
tas!(b"hand") | tas!(b"hunk") | tas!(b"lose") | tas!(b"mean") | tas!(b"spot") => {
|
tas!(b"hand") | tas!(b"hunk") | tas!(b"lose") | tas!(b"mean") | tas!(b"spot") => {
|
||||||
// In the future, we should only do this if 11 is not in tail position
|
// XX: we should only do this if 11 is not in tail position
|
||||||
stack.trace_pop();
|
stack.trace_pop();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -172,7 +172,7 @@ pub mod util {
|
|||||||
let step = cell.tail().as_direct()?.data() as usize;
|
let step = cell.tail().as_direct()?.data() as usize;
|
||||||
Ok((bloq, step))
|
Ok((bloq, step))
|
||||||
} else {
|
} else {
|
||||||
bloq(a).map(|x| (x, 1 as usize))
|
bloq(a).map(|x| (x, 1_usize))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,13 +29,13 @@ pub mod util {
|
|||||||
) -> jets::Result {
|
) -> jets::Result {
|
||||||
match aura.data() {
|
match aura.data() {
|
||||||
tas!(b"ud") => {
|
tas!(b"ud") => {
|
||||||
if let None = atom.as_bitslice().first_one() {
|
if atom.as_bitslice().first_one().is_none() {
|
||||||
return Ok(T(stack, &[D(b'0' as u64), D(0)]));
|
return Ok(T(stack, &[D(b'0' as u64), D(0)]));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut root = D(0);
|
let mut root = D(0);
|
||||||
let mut lent = 0;
|
let mut lent = 0;
|
||||||
if let Some(_) = atom.direct() {
|
if atom.direct().is_some() {
|
||||||
let mut n = atom.as_direct()?.data();
|
let mut n = atom.as_direct()?.data();
|
||||||
|
|
||||||
while n != 0 {
|
while n != 0 {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
/** Virtualization jets
|
/** Virtualization jets
|
||||||
*/
|
*/
|
||||||
use crate::interpreter::{interpret, NockErr};
|
use crate::interpreter::{interpret, NockErr, Tone};
|
||||||
use crate::jets;
|
use crate::jets;
|
||||||
use crate::jets::util::slot;
|
use crate::jets::util::slot;
|
||||||
|
use crate::jets::JetErr;
|
||||||
use crate::mem::NockStack;
|
use crate::mem::NockStack;
|
||||||
use crate::newt::Newt;
|
use crate::newt::Newt;
|
||||||
use crate::noun::{Noun, D, T};
|
use crate::noun::{Noun, D, T};
|
||||||
@ -22,12 +23,14 @@ pub fn jet_mink(
|
|||||||
let v_formula = slot(arg, 5)?;
|
let v_formula = slot(arg, 5)?;
|
||||||
let _scry = slot(arg, 3)?;
|
let _scry = slot(arg, 3)?;
|
||||||
|
|
||||||
// XX: NonDeterministic errors need to bail here, too
|
|
||||||
match interpret(stack, newt, v_subject, v_formula) {
|
match interpret(stack, newt, v_subject, v_formula) {
|
||||||
Ok(res) => Ok(T(stack, &[D(0), res])),
|
Ok(res) => Ok(T(stack, &[D(0), res])),
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
NockErr::Blocked(block) => Ok(T(stack, &[D(1), block])),
|
Tone::Blocked(block) => Ok(T(stack, &[D(1), block])),
|
||||||
NockErr::Error(error) => Ok(T(stack, &[D(2), error])),
|
Tone::Error(err, trace) => match err {
|
||||||
|
NockErr::Deterministic => Ok(T(stack, &[D(2), trace])),
|
||||||
|
NockErr::NonDeterministic => Err(JetErr::NonDeterministic),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,15 +61,20 @@ pub mod util {
|
|||||||
let tag = tone.head().as_direct()?;
|
let tag = tone.head().as_direct()?;
|
||||||
let original_list = tone.tail();
|
let original_list = tone.tail();
|
||||||
|
|
||||||
if tag.data() < 2 {
|
// if tag.data() < 2 {
|
||||||
return Ok(tone);
|
// return Ok(tone);
|
||||||
} else if tag.data() > 2 {
|
// } else if tag.data() > 2 {
|
||||||
return Err(JetErr::Deterministic);
|
// return Err(JetErr::Deterministic);
|
||||||
}
|
// }
|
||||||
|
match tag.data() {
|
||||||
|
x if x < 2 => return Ok(tone),
|
||||||
|
x if x > 2 => return Err(JetErr::Deterministic),
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
|
||||||
if unsafe { original_list.raw_equals(D(0)) } {
|
if unsafe { original_list.raw_equals(D(0)) } {
|
||||||
return Ok(tone);
|
return Ok(tone);
|
||||||
} else if let Some(_) = original_list.atom() {
|
} else if original_list.atom().is_some() {
|
||||||
return Err(JetErr::Deterministic);
|
return Err(JetErr::Deterministic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +143,7 @@ pub mod util {
|
|||||||
|
|
||||||
let mut list = end_col.as_cell()?;
|
let mut list = end_col.as_cell()?;
|
||||||
loop {
|
loop {
|
||||||
if let Some(_) = list.tail().atom() {
|
if list.tail().atom().is_some() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
list = list.tail().as_cell()?;
|
list = list.tail().as_cell()?;
|
||||||
@ -146,7 +154,7 @@ pub mod util {
|
|||||||
|
|
||||||
list = end_lin.as_cell()?;
|
list = end_lin.as_cell()?;
|
||||||
loop {
|
loop {
|
||||||
if let Some(_) = list.tail().atom() {
|
if list.tail().atom().is_some() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
list = list.tail().as_cell()?;
|
list = list.tail().as_cell()?;
|
||||||
@ -157,7 +165,7 @@ pub mod util {
|
|||||||
|
|
||||||
list = str_col.as_cell()?;
|
list = str_col.as_cell()?;
|
||||||
loop {
|
loop {
|
||||||
if let Some(_) = list.tail().atom() {
|
if list.tail().atom().is_some() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
list = list.tail().as_cell()?;
|
list = list.tail().as_cell()?;
|
||||||
@ -171,7 +179,7 @@ pub mod util {
|
|||||||
|
|
||||||
list = str_lin.as_cell()?;
|
list = str_lin.as_cell()?;
|
||||||
loop {
|
loop {
|
||||||
if let Some(_) = list.tail().atom() {
|
if list.tail().atom().is_some() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
list = list.tail().as_cell()?;
|
list = list.tail().as_cell()?;
|
||||||
|
@ -22,7 +22,7 @@ pub mod util {
|
|||||||
let mut list = tape;
|
let mut list = tape;
|
||||||
loop {
|
loop {
|
||||||
if let Some(atom) = list.atom() {
|
if let Some(atom) = list.atom() {
|
||||||
if let None = atom.as_bitslice().first_one() {
|
if atom.as_bitslice().first_one().is_none() {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
return Err(JetErr::Deterministic);
|
return Err(JetErr::Deterministic);
|
||||||
|
@ -107,11 +107,11 @@ impl Newt {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
self.output.write_all(&buf).unwrap();
|
self.output.write_all(buf).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send %ripe, the first event.
|
/** Send %ripe, the first event.
|
||||||
*
|
*
|
||||||
* eve = event number
|
* eve = event number
|
||||||
* mug = mug of Arvo after above event
|
* mug = mug of Arvo after above event
|
||||||
*/
|
*/
|
||||||
@ -135,7 +135,7 @@ impl Newt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Send %slog, pretty-printed debug output.
|
/** Send %slog, pretty-printed debug output.
|
||||||
*
|
*
|
||||||
* pri = debug priority
|
* pri = debug priority
|
||||||
* tank = output as tank
|
* tank = output as tank
|
||||||
*/
|
*/
|
||||||
@ -157,7 +157,7 @@ impl Newt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Send %peek %bail, unsuccessfully scried.
|
/** Send %peek %bail, unsuccessfully scried.
|
||||||
*
|
*
|
||||||
* dud = goof
|
* dud = goof
|
||||||
*/
|
*/
|
||||||
pub fn peek_bail(&mut self, stack: &mut NockStack, dud: Noun) {
|
pub fn peek_bail(&mut self, stack: &mut NockStack, dud: Noun) {
|
||||||
@ -166,7 +166,7 @@ impl Newt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Send %play %done, successfully replayed events.
|
/** Send %play %done, successfully replayed events.
|
||||||
*
|
*
|
||||||
* mug = mug of Arvo after full replay
|
* mug = mug of Arvo after full replay
|
||||||
*/
|
*/
|
||||||
pub fn play_done(&mut self, stack: &mut NockStack, mug: u64) {
|
pub fn play_done(&mut self, stack: &mut NockStack, mug: u64) {
|
||||||
@ -175,7 +175,7 @@ impl Newt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Send %play %bail, failed to replay events.
|
/** Send %play %bail, failed to replay events.
|
||||||
*
|
*
|
||||||
* eve = last good event number
|
* eve = last good event number
|
||||||
* mug = mug of Arvo after above event
|
* mug = mug of Arvo after above event
|
||||||
* dud = goof when trying next event
|
* dud = goof when trying next event
|
||||||
@ -189,7 +189,7 @@ impl Newt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Send %work %done, successfully ran event.
|
/** Send %work %done, successfully ran event.
|
||||||
*
|
*
|
||||||
* eve = new event number
|
* eve = new event number
|
||||||
* mug = mug of Arvo after above event
|
* mug = mug of Arvo after above event
|
||||||
* fec = list of effects
|
* fec = list of effects
|
||||||
@ -203,7 +203,7 @@ impl Newt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Send %work %swap, successfully replaced failed event.
|
/** Send %work %swap, successfully replaced failed event.
|
||||||
*
|
*
|
||||||
* eve = new event number
|
* eve = new event number
|
||||||
* mug = mug of Arvo after above event
|
* mug = mug of Arvo after above event
|
||||||
* job = event performed instead of the one given to serf by king
|
* job = event performed instead of the one given to serf by king
|
||||||
@ -218,7 +218,7 @@ impl Newt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Send %work %bail, failed to run event.
|
/** Send %work %bail, failed to run event.
|
||||||
*
|
*
|
||||||
* lud = list of goof
|
* lud = list of goof
|
||||||
*/
|
*/
|
||||||
pub fn work_bail(&mut self, stack: &mut NockStack, lud: Noun) {
|
pub fn work_bail(&mut self, stack: &mut NockStack, lud: Noun) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::interpreter::{interpret, NockErr, inc};
|
use crate::interpreter::{inc, interpret, Tone};
|
||||||
use crate::jets::nock::util::mook;
|
use crate::jets::nock::util::mook;
|
||||||
use crate::jets::text::util::lent;
|
use crate::jets::text::util::lent;
|
||||||
use crate::mem::NockStack;
|
use crate::mem::NockStack;
|
||||||
@ -82,7 +82,6 @@ pub fn serf() -> io::Result<()> {
|
|||||||
let eve = slot(writ, 7)?;
|
let eve = slot(writ, 7)?;
|
||||||
let sub = T(stack, &[D(0), D(3)]);
|
let sub = T(stack, &[D(0), D(3)]);
|
||||||
let lyf = T(stack, &[D(2), sub, D(0), D(2)]);
|
let lyf = T(stack, &[D(2), sub, D(0), D(2)]);
|
||||||
// XX: TODO
|
|
||||||
match interpret(stack, &mut Some(newt), eve, lyf) {
|
match interpret(stack, &mut Some(newt), eve, lyf) {
|
||||||
Ok(gat) => {
|
Ok(gat) => {
|
||||||
arvo = slot(gat, 7)
|
arvo = slot(gat, 7)
|
||||||
@ -91,7 +90,7 @@ pub fn serf() -> io::Result<()> {
|
|||||||
lent(eve).expect("serf: play: boot event number failure") as u64;
|
lent(eve).expect("serf: play: boot event number failure") as u64;
|
||||||
current_mug = mug_u32(stack, arvo);
|
current_mug = mug_u32(stack, arvo);
|
||||||
}
|
}
|
||||||
Err(NockErr::Error(trace)) => {
|
Err(Tone::Error(_, trace)) => {
|
||||||
let tone = Cell::new(stack, D(2), trace);
|
let tone = Cell::new(stack, D(2), trace);
|
||||||
let tang = mook(stack, &mut Some(newt), tone, false)
|
let tang = mook(stack, &mut Some(newt), tone, false)
|
||||||
.expect("serf: play: +mook crashed on bail")
|
.expect("serf: play: +mook crashed on bail")
|
||||||
@ -99,7 +98,7 @@ pub fn serf() -> io::Result<()> {
|
|||||||
let goof = T(stack, &[D(tas!(b"exit")), tang]);
|
let goof = T(stack, &[D(tas!(b"exit")), tang]);
|
||||||
newt.play_bail(stack, 0, 0, goof);
|
newt.play_bail(stack, 0, 0, goof);
|
||||||
}
|
}
|
||||||
Err(NockErr::Blocked(_)) => {
|
Err(Tone::Blocked(_)) => {
|
||||||
panic!("play: blocked err handling unimplemented")
|
panic!("play: blocked err handling unimplemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,7 +117,7 @@ pub fn serf() -> io::Result<()> {
|
|||||||
current_mug = mug_u32(stack, arvo);
|
current_mug = mug_u32(stack, arvo);
|
||||||
current_event_num += 1;
|
current_event_num += 1;
|
||||||
}
|
}
|
||||||
Err(NockErr::Error(trace)) => {
|
Err(Tone::Error(_, trace)) => {
|
||||||
let tone = Cell::new(stack, D(2), trace);
|
let tone = Cell::new(stack, D(2), trace);
|
||||||
let tang = mook(stack, &mut Some(newt), tone, false)
|
let tang = mook(stack, &mut Some(newt), tone, false)
|
||||||
.expect("serf: play: +mook crashed on bail")
|
.expect("serf: play: +mook crashed on bail")
|
||||||
@ -126,7 +125,7 @@ pub fn serf() -> io::Result<()> {
|
|||||||
let goof = T(stack, &[D(tas!(b"exit")), tang]);
|
let goof = T(stack, &[D(tas!(b"exit")), tang]);
|
||||||
newt.play_bail(stack, current_event_num, current_mug as u64, goof);
|
newt.play_bail(stack, current_event_num, current_mug as u64, goof);
|
||||||
}
|
}
|
||||||
Err(NockErr::Blocked(_)) => {
|
Err(Tone::Blocked(_)) => {
|
||||||
panic!("play: blocked err handling unimplemented")
|
panic!("play: blocked err handling unimplemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,13 +160,18 @@ pub fn serf() -> io::Result<()> {
|
|||||||
//
|
//
|
||||||
// crud = [+(now) [%$ %arvo ~] [%crud goof ovo]]
|
// crud = [+(now) [%$ %arvo ~] [%crud goof ovo]]
|
||||||
let job_cell = job.as_cell().expect("serf: work: job not a cell");
|
let job_cell = job.as_cell().expect("serf: work: job not a cell");
|
||||||
let now = inc(stack, job_cell.head().as_atom().expect("serf: work: now not atom")).as_noun();
|
let now = inc(
|
||||||
|
stack,
|
||||||
|
job_cell.head().as_atom().expect("serf: work: now not atom"),
|
||||||
|
)
|
||||||
|
.as_noun();
|
||||||
let wire = T(stack, &[D(0), D(tas!(b"arvo")), D(0)]);
|
let wire = T(stack, &[D(0), D(tas!(b"arvo")), D(0)]);
|
||||||
let crud = T(stack, &[now, wire, D(tas!(b"crud")), goof, job_cell.tail()]);
|
let crud = T(stack, &[now, wire, D(tas!(b"crud")), goof, job_cell.tail()]);
|
||||||
|
|
||||||
match soft(stack, newt, arvo, POKE_AXIS, crud) {
|
match soft(stack, newt, arvo, POKE_AXIS, crud) {
|
||||||
Ok(res) => {
|
Ok(res) => {
|
||||||
let cell = res.as_cell().expect("serf: work: crud +slam returned atom");
|
let cell =
|
||||||
|
res.as_cell().expect("serf: work: crud +slam returned atom");
|
||||||
let fec = cell.head();
|
let fec = cell.head();
|
||||||
arvo = cell.tail();
|
arvo = cell.tail();
|
||||||
snap.save(stack, &mut arvo);
|
snap.save(stack, &mut arvo);
|
||||||
@ -175,7 +179,13 @@ pub fn serf() -> io::Result<()> {
|
|||||||
current_mug = mug_u32(stack, arvo);
|
current_mug = mug_u32(stack, arvo);
|
||||||
current_event_num += 1;
|
current_event_num += 1;
|
||||||
|
|
||||||
newt.work_swap(stack, current_event_num, current_mug as u64, crud, fec);
|
newt.work_swap(
|
||||||
|
stack,
|
||||||
|
current_event_num,
|
||||||
|
current_mug as u64,
|
||||||
|
crud,
|
||||||
|
fec,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Err(goof_crud) => {
|
Err(goof_crud) => {
|
||||||
let lud = T(stack, &[goof_crud, goof, D(0)]);
|
let lud = T(stack, &[goof_crud, goof, D(0)]);
|
||||||
@ -198,7 +208,7 @@ pub fn slam(
|
|||||||
core: Noun,
|
core: Noun,
|
||||||
axis: u64,
|
axis: u64,
|
||||||
ovo: Noun,
|
ovo: Noun,
|
||||||
) -> Result<Noun, NockErr> {
|
) -> Result<Noun, Tone> {
|
||||||
let pul = T(stack, &[D(9), D(axis), D(0), D(2)]);
|
let pul = T(stack, &[D(9), D(axis), D(0), D(2)]);
|
||||||
let sam = T(stack, &[D(6), D(0), D(7)]);
|
let sam = T(stack, &[D(6), D(0), D(7)]);
|
||||||
let fol = T(stack, &[D(8), pul, D(9), D(2), D(10), sam, D(0), D(2)]);
|
let fol = T(stack, &[D(8), pul, D(9), D(2), D(10), sam, D(0), D(2)]);
|
||||||
@ -216,7 +226,7 @@ pub fn soft(
|
|||||||
) -> Result<Noun, Noun> {
|
) -> Result<Noun, Noun> {
|
||||||
match slam(stack, newt, core, axis, ovo) {
|
match slam(stack, newt, core, axis, ovo) {
|
||||||
Ok(res) => Ok(res),
|
Ok(res) => Ok(res),
|
||||||
Err(NockErr::Error(trace)) => {
|
Err(Tone::Error(_, trace)) => {
|
||||||
let tone = Cell::new(stack, D(2), trace);
|
let tone = Cell::new(stack, D(2), trace);
|
||||||
let tang = mook(stack, &mut Some(newt), tone, false)
|
let tang = mook(stack, &mut Some(newt), tone, false)
|
||||||
.expect("serf: soft: +mook crashed on bail")
|
.expect("serf: soft: +mook crashed on bail")
|
||||||
@ -226,11 +236,10 @@ pub fn soft(
|
|||||||
let goof = T(stack, &[D(tas!(b"exit")), tang]);
|
let goof = T(stack, &[D(tas!(b"exit")), tang]);
|
||||||
Err(goof)
|
Err(goof)
|
||||||
}
|
}
|
||||||
Err(NockErr::Blocked(_)) => panic!("soft: blocked err handling unimplemented"),
|
Err(Tone::Blocked(_)) => panic!("soft: blocked err handling unimplemented"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn slot(noun: Noun, axis: u64) -> io::Result<Noun> {
|
fn slot(noun: Noun, axis: u64) -> io::Result<Noun> {
|
||||||
noun.slot(axis)
|
noun.slot(axis)
|
||||||
.map_err(|_e| io::Error::new(io::ErrorKind::InvalidInput, "Bad axis"))
|
.map_err(|_e| io::Error::new(io::ErrorKind::InvalidInput, "Bad axis"))
|
||||||
|
Loading…
Reference in New Issue
Block a user