From ad357352acdad88e647baa2f7e1799f204d55d14 Mon Sep 17 00:00:00 2001 From: Philip Monk Date: Tue, 8 Aug 2023 12:34:50 -0700 Subject: [PATCH] jets: mink jet compiles and passes trivial tests --- rust/ares/src/interpreter.rs | 70 +++++++++------ rust/ares/src/jets.rs | 4 +- rust/ares/src/jets/math.rs | 161 ++++++++++++++++++++++++++++------ rust/ares/src/jets/mink.rs | 71 +++++++++++++++ rust/ares/src/jets/virtual.rs | 30 ------- rust/ares/src/main.rs | 5 +- rust/ares/src/mem.rs | 2 +- rust/ares/src/serf.rs | 26 ++++-- 8 files changed, 274 insertions(+), 95 deletions(-) create mode 100644 rust/ares/src/jets/mink.rs delete mode 100644 rust/ares/src/jets/virtual.rs diff --git a/rust/ares/src/interpreter.rs b/rust/ares/src/interpreter.rs index 3c1c26f..609b037 100644 --- a/rust/ares/src/interpreter.rs +++ b/rust/ares/src/interpreter.rs @@ -4,7 +4,7 @@ use crate::jets; use crate::mem::unifying_equality; use crate::mem::NockStack; use crate::newt::Newt; -use crate::noun::{Atom, Cell, DirectAtom, IndirectAtom, Noun}; +use crate::noun::{Atom, Cell, DirectAtom, IndirectAtom, Noun, D}; use ares_macros::tas; use assert_no_alloc::assert_no_alloc; use bitvec::prelude::{BitSlice, Lsb0}; @@ -69,16 +69,25 @@ fn noun_to_work(noun: Noun) -> NockWork { } } +#[derive(Debug)] pub enum NockErr { Blocked(Noun), Error(Noun), } -pub fn early_exit(stack: &mut NockStack, virtual_frame: *u64, cache: &mut Hamt::::new()) { - while stack.frame_pointer() != virtual_frame { - // TODO: also preserve trace - stack.preserve(&mut cache); - stack.pop(); +impl From for () { + fn from(_: NockErr) -> Self { + () + } +} + +pub fn early_exit(stack: &mut NockStack, virtual_frame: *const u64, cache: &mut Hamt) { + unsafe { + while stack.frame_pointer() != virtual_frame { + // TODO: also preserve trace + stack.preserve(cache); + stack.pop(); + } } } @@ -89,7 +98,7 @@ pub fn interpret( mut subject: Noun, formula: Noun, ) -> Result { - let mut res = unsafe { D(0) }; + let mut res = D(0); let virtual_frame = stack.frame_pointer(); // before or after the push? stack.push(1); let mut cache = Hamt::::new(); @@ -97,15 +106,14 @@ pub fn interpret( *(stack.local_noun_pointer(0)) = work_to_noun(Done); } push_formula(stack, formula)?; - let tone = - assert_no_alloc(|| unsafe { + let tone = assert_no_alloc(|| unsafe { loop { match noun_to_work(*(stack.local_noun_pointer(0))) { Done => { stack.preserve(&mut cache); stack.preserve(&mut res); stack.pop(); - break; + break Ok(res); } NockCellComputeHead => { *stack.local_noun_pointer(0) = work_to_noun(NockCellComputeTail); @@ -127,15 +135,16 @@ pub fn interpret( } Nock0Axis => { if let Ok(atom) = (*(stack.local_noun_pointer(1))).as_atom() { - if let Ok(res) = slot(subject, atom.as_bitslice()) { + if let Ok(x) = slot(subject, atom.as_bitslice()) { + res = x; stack.preserve(&mut cache); stack.preserve(&mut res); stack.pop(); } else { - return Err(Error(D(1)); + break Err(NockErr::Error(D(1))); } } else { - return Err(Error(D(0))); // Axis must be atom + break Err(NockErr::Error(D(0))); // Axis must be atom }; } Nock1Constant => { @@ -194,7 +203,7 @@ pub fn interpret( stack.preserve(&mut res); stack.pop(); } else { - return Err(Error(D(2))); // Cannot increment (Nock 4) a cell + break Err(NockErr::Error(D(2))); // Cannot increment (Nock 4) a cell }; } Nock5ComputeLeftChild => { @@ -234,10 +243,10 @@ pub fn interpret( let formula = *stack.local_noun_pointer(3); push_formula(stack, formula)?; } else { - return Err(Error(D(3))); // Test branch of Nock 6 must return 0 or 1 + break Err(NockErr::Error(D(3))); // Test branch of Nock 6 must return 0 or 1 }; } else { - return Err(Error(D(4))); // Test branch of Nock 6 must return a direct atom + break Err(NockErr::Error(D(4))); // Test branch of Nock 6 must return a direct atom } } Nock6Done => { @@ -291,9 +300,14 @@ pub fn interpret( *(stack.local_noun_pointer(0)) = work_to_noun(Nock9RestoreSubject); *(stack.local_noun_pointer(2)) = subject; subject = res; - push_formula(stack, slot(subject, formula_axis.as_bitslice()))?; + let axis = if let Ok(x) = slot(subject, formula_axis.as_bitslice()) { + x + } else { + break Err(NockErr::Error(D(55))); // Axis must be in subject + }; + push_formula(stack, axis)?; } else { - return Err(Error(D(5))); // Axis into core must be atom + break Err(NockErr::Error(D(5))); // Axis into core must be atom } } Nock9RestoreSubject => { @@ -321,7 +335,7 @@ pub fn interpret( stack.preserve(&mut res); stack.pop(); } else { - return Err(Error(D(6))); // Axis into tree must be atom + break Err(NockErr::Error(D(6))); // Axis into tree must be atom } } Nock11ComputeHint => { @@ -371,12 +385,12 @@ pub fn interpret( Ok(res) => Ok(res), Err(err) => { early_exit(stack, virtual_frame, &mut cache); - Err(err); + Err(err) } } } -fn push_formula(stack: &mut NockStack, formula: Noun) -> Result((), NockErr) { +fn push_formula(stack: &mut NockStack, formula: Noun) -> Result<(), NockErr> { if let Ok(formula_cell) = formula.as_cell() { // Formula match formula_cell.head().as_either_atom_cell() { @@ -546,7 +560,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun) -> Result((), NockErr) { } } } else { - return Err(Error(D(10))); // Bad formula: atoms are not formulas: {} + return Err(NockErr::Error(D(10))); // Bad formula: atoms are not formulas: {} } Ok(()) } @@ -558,9 +572,9 @@ pub fn raw_slot(noun: Noun, axis: u64) -> Noun { pub fn slot(mut noun: Noun, axis: &BitSlice) -> Result { let mut cursor = if let Some(x) = axis.last_one() { - Ok(x) + x } else { - Err(()) // 0 is not allowed as an axis + return Err(()); // 0 is not allowed as an axis }; loop { if cursor == 0 { @@ -574,7 +588,7 @@ pub fn slot(mut noun: Noun, axis: &BitSlice) -> Result { noun = cell.head(); } } else { - Err(()) // Axis tried to descend through atom: {} + return Err(()); // Axis tried to descend through atom: {} }; } Ok(noun) @@ -667,10 +681,12 @@ fn match_pre_hint( let jet_name = jet_formula.tail(); let jet = jets::get_jet(jet_name).ok_or(())?; - if let Ok(mut jet_res) = jet(stack, subject) { + if let Ok(mut jet_res) = jet(stack, newt, subject) { // if in test mode, check that the jet returns the same result as the raw nock if jets::get_jet_test_mode(jet_name) { - let mut nock_res = interpret(stack, newt, subject, formula); + // Throw away trace because we'll regenerate it later, and this is in test mode + // so it's okay if it runs twice + let mut nock_res = interpret(stack, newt, subject, formula)?; if unsafe { !unifying_equality(stack, &mut nock_res, &mut jet_res) } { eprintln!( "\rJet {} failed, raw: {}, jetted: {}", diff --git a/rust/ares/src/jets.rs b/rust/ares/src/jets.rs index 723798d..47b9633 100644 --- a/rust/ares/src/jets.rs +++ b/rust/ares/src/jets.rs @@ -1,8 +1,10 @@ pub mod math; +pub mod mink; use crate::jets::math::*; -use crate::jets::virtual::*; +use crate::jets::mink::*; use crate::mem::NockStack; +use crate::newt::Newt; use crate::noun::{self, Noun}; use ares_macros::tas; diff --git a/rust/ares/src/jets/math.rs b/rust/ares/src/jets/math.rs index c0960e2..b4a1919 100644 --- a/rust/ares/src/jets/math.rs +++ b/rust/ares/src/jets/math.rs @@ -16,6 +16,7 @@ use crate::interpreter::raw_slot; use crate::jets::{JetErr, JetErr::*}; use crate::mem::NockStack; use crate::mug::mug; +use crate::newt::Newt; use crate::noun::{Atom, Cell, DirectAtom, IndirectAtom, Noun, D, DIRECT_MAX, NO, T, YES}; use bitvec::prelude::{BitSlice, Lsb0}; use either::Either::*; @@ -25,7 +26,11 @@ use std::{cmp, convert::TryFrom}; crate::gdb!(); -pub fn jet_dec(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_dec( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); if let Ok(atom) = arg.as_atom() { match atom.as_either() { @@ -62,7 +67,11 @@ pub fn jet_dec(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_add(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_add( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let a = raw_slot(arg, 2).as_atom()?; let b = raw_slot(arg, 3).as_atom()?; @@ -77,7 +86,11 @@ pub fn jet_add(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_sub(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_sub( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let a = raw_slot(arg, 2).as_atom()?; let b = raw_slot(arg, 3).as_atom()?; @@ -102,7 +115,11 @@ pub fn jet_sub(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_mul(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_mul( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let a = raw_slot(arg, 2).as_atom()?; let b = raw_slot(arg, 3).as_atom()?; @@ -129,7 +146,11 @@ pub fn jet_mul(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_div(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_div( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let a = raw_slot(arg, 2).as_atom()?; let b = raw_slot(arg, 3).as_atom()?; @@ -146,7 +167,11 @@ pub fn jet_div(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_mod(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_mod( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let a = raw_slot(arg, 2).as_atom()?; let b = raw_slot(arg, 3).as_atom()?; @@ -161,7 +186,11 @@ pub fn jet_mod(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_dvr(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_dvr( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let a = raw_slot(arg, 2).as_atom()?; let b = raw_slot(arg, 3).as_atom()?; @@ -189,7 +218,11 @@ pub fn jet_dvr(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_lth(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_lth( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let a = raw_slot(arg, 2).as_atom()?; let b = raw_slot(arg, 3).as_atom()?; @@ -211,7 +244,11 @@ pub fn jet_lth(stack: &mut NockStack, subject: Noun) -> Result { }) } -pub fn jet_lte(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_lte( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let a = raw_slot(arg, 2).as_atom()?; let b = raw_slot(arg, 3).as_atom()?; @@ -233,7 +270,11 @@ pub fn jet_lte(stack: &mut NockStack, subject: Noun) -> Result { }) } -pub fn jet_gth(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_gth( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let a = raw_slot(arg, 2).as_atom()?; let b = raw_slot(arg, 3).as_atom()?; @@ -255,7 +296,11 @@ pub fn jet_gth(stack: &mut NockStack, subject: Noun) -> Result { }) } -pub fn jet_gte(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_gte( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let a = raw_slot(arg, 2).as_atom()?; let b = raw_slot(arg, 3).as_atom()?; @@ -277,7 +322,11 @@ pub fn jet_gte(stack: &mut NockStack, subject: Noun) -> Result { }) } -pub fn jet_bex(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_bex( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6).as_direct()?.data() as usize; if arg < 63 { @@ -291,7 +340,11 @@ pub fn jet_bex(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_lsh(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_lsh( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let (bloq, step) = bite(raw_slot(arg, 2))?; let a = raw_slot(arg, 3).as_atom()?; @@ -317,7 +370,11 @@ pub fn jet_lsh(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_rsh(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_rsh( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let (bloq, step) = bite(raw_slot(arg, 2))?; let a = raw_slot(arg, 3).as_atom()?; @@ -343,7 +400,11 @@ pub fn jet_rsh(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_con(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_con( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let a = raw_slot(arg, 2).as_atom()?; let b = raw_slot(arg, 3).as_atom()?; @@ -359,7 +420,11 @@ pub fn jet_con(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_dis(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_dis( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let a = raw_slot(arg, 2).as_atom()?; let b = raw_slot(arg, 3).as_atom()?; @@ -375,7 +440,11 @@ pub fn jet_dis(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_mix(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_mix( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let a = raw_slot(arg, 2).as_atom()?; let b = raw_slot(arg, 3).as_atom()?; @@ -391,7 +460,11 @@ pub fn jet_mix(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_end(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_end( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let (bloq, step) = bite(raw_slot(arg, 2))?; let a = raw_slot(arg, 3).as_atom()?; @@ -416,7 +489,11 @@ pub fn jet_end(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_cat(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_cat( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let bloq = raw_slot(arg, 2).as_direct()?.data() as usize; if bloq >= 64 { @@ -440,7 +517,11 @@ pub fn jet_cat(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_can(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_can( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let bloq = raw_slot(arg, 2).as_direct()?.data() as usize; if bloq >= 64 { @@ -490,7 +571,11 @@ pub fn jet_can(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_rep(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_rep( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let (bloq, step) = bite(raw_slot(arg, 2))?; let original_list = raw_slot(arg, 3); @@ -533,7 +618,11 @@ pub fn jet_rep(stack: &mut NockStack, subject: Noun) -> Result { } } -pub fn jet_cut(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_cut( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let bloq = raw_slot(arg, 2).as_direct()?.data() as usize; if bloq >= 64 { @@ -552,7 +641,11 @@ pub fn jet_cut(stack: &mut NockStack, subject: Noun) -> Result { Ok(new_indirect.as_noun()) } -pub fn jet_rip(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_rip( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let (bloq, step) = bite(raw_slot(arg, 2))?; let atom = raw_slot(arg, 3).as_atom()?; @@ -571,7 +664,11 @@ pub fn jet_rip(stack: &mut NockStack, subject: Noun) -> Result { Ok(list) } -pub fn jet_met(_stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_met( + _stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let bloq = raw_slot(arg, 2).as_direct()?.data() as usize; if bloq >= 64 { @@ -582,7 +679,11 @@ pub fn jet_met(_stack: &mut NockStack, subject: Noun) -> Result { Ok(D(met(bloq, a) as u64)) } -pub fn jet_mug(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_mug( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); Ok(mug(stack, arg).as_noun()) } @@ -651,7 +752,11 @@ pub fn met(bloq: usize, a: Atom) -> usize { } } -pub fn jet_rev(stack: &mut NockStack, subject: Noun) -> Result { +pub fn jet_rev( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { let arg = raw_slot(subject, 6); let boz = raw_slot(arg, 2).as_atom()?.as_direct()?.data(); @@ -751,7 +856,7 @@ mod tests { fn assert_jet(stack: &mut NockStack, jet: Jet, sam: Noun, res: Noun) { let sam = T(stack, &[D(0), sam, D(0)]); - let jet_res = assert_no_alloc(|| jet(stack, sam).unwrap()); + let jet_res = assert_no_alloc(|| jet(stack, &mut None, sam).unwrap()); assert_noun_eq(stack, jet_res, res); } @@ -788,7 +893,7 @@ mod tests { fn assert_jet_err(stack: &mut NockStack, jet: Jet, sam: Noun, err: JetErr) { let sam = T(stack, &[D(0), sam, D(0)]); - let jet_res = jet(stack, sam); + let jet_res = jet(stack, &mut None, sam); assert!( jet_res.is_err(), "with sample: {}, expected err: {:?}, got: {:?}", diff --git a/rust/ares/src/jets/mink.rs b/rust/ares/src/jets/mink.rs new file mode 100644 index 0000000..fc78b21 --- /dev/null +++ b/rust/ares/src/jets/mink.rs @@ -0,0 +1,71 @@ +/** Virtualization jets + */ +use crate::interpreter::{interpret, raw_slot, NockErr}; +use crate::jets::JetErr; +use crate::mem::NockStack; +use crate::newt::Newt; +use crate::noun::{Noun, D, T}; + +crate::gdb!(); + +// TODO: interpret should accept optional scry function and potentially produce blocked +// TODO: what do we do with the trace, if it's on the stack? +pub fn jet_mink( + stack: &mut NockStack, + newt: &mut Option<&mut Newt>, + subject: Noun, +) -> Result { + let arg = raw_slot(subject, 6); + let v_subject = raw_slot(arg, 4); + let v_formula = raw_slot(arg, 5); + let _scry = raw_slot(arg, 3); + + match interpret(stack, newt, v_subject, v_formula) { + Ok(res) => Ok(T(stack, &[D(0), res])), + Err(err) => match err { + NockErr::Blocked(block) => Ok(T(stack, &[D(1), block])), + NockErr::Error(error) => Ok(T(stack, &[D(2), error])), + }, + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::jets::Jet; + use crate::mem::unifying_equality; + use assert_no_alloc::assert_no_alloc; + + fn init() -> NockStack { + NockStack::new(8 << 10 << 10, 0) + } + + fn assert_noun_eq(stack: &mut NockStack, mut a: Noun, mut b: Noun) { + let eq = unsafe { unifying_equality(stack, &mut a, &mut b) }; + assert!(eq, "got: {}, need: {}", a, b); + } + + fn assert_jet(stack: &mut NockStack, jet: Jet, sam: Noun, res: Noun) { + let sam = T(stack, &[D(0), sam, D(0)]); + let jet_res = assert_no_alloc(|| jet(stack, &mut None, sam).unwrap()); + assert_noun_eq(stack, jet_res, res); + } + + #[test] + fn test_mink_success() { + let s = &mut init(); + let n = T(s, &[D(0), D(1), D(53)]); + let sam = T(s, &[n, D(0)]); + let res = T(s, &[D(0), D(53)]); + assert_jet(s, jet_mink, sam, res); + } + + #[test] + fn test_mink_zapzap() { + let s = &mut init(); + let n = T(s, &[D(0), D(0), D(0)]); + let sam = T(s, &[n, D(0)]); + let res = T(s, &[D(2), D(1)]); + assert_jet(s, jet_mink, sam, res); + } +} diff --git a/rust/ares/src/jets/virtual.rs b/rust/ares/src/jets/virtual.rs deleted file mode 100644 index 4591c54..0000000 --- a/rust/ares/src/jets/virtual.rs +++ /dev/null @@ -1,30 +0,0 @@ -/** Virtualization jets - */ -use crate::interpreter::raw_slot; -use crate::jets::{JetErr, JetErr::*}; -use crate::mem::NockStack; -use crate::mug::mug; -use crate::noun::{Atom, Cell, DirectAtom, IndirectAtom, Noun, D, DIRECT_MAX, NO, T, YES}; -use bitvec::prelude::{BitSlice, Lsb0}; -use either::Either::*; -use std::{cmp, convert::TryFrom}; - -crate::gdb!(); - -// can we reuse stack like this? -// interpret should accept optional scry function and potentially produce blocked -// what do we do with the trace, if it's on the stack? -pub fn jet_mink(stack: &mut NockStack, newt: &mut Option<&mut Newt>, subject: Noun) -> Result { - let arg = raw_slot(subject, 6); - let v_subject = raw_slot(arg, 4); - let v_formula = raw_slot(arg, 5); - let scry = raw_slot(arg, 3); - - match interpret(stack, newt, v_subject, v_formula) { - Ok(res) => Ok(T(stack, &[D(0), res])), - Err(err) => match err { - Blocked(block) => Ok(T(stack, &[D(1), block])), - Error(error) => Ok(T(stack, &[D(2), error])), - } - } -} diff --git a/rust/ares/src/main.rs b/rust/ares/src/main.rs index 3e3ac07..6c6d87d 100644 --- a/rust/ares/src/main.rs +++ b/rust/ares/src/main.rs @@ -20,7 +20,7 @@ fn main() -> io::Result<()> { ares::interpreter::use_gdb(); ares::jets::use_gdb(); ares::jets::math::use_gdb(); - ares::jets::virtual::use_gdb(); + ares::jets::mink::use_gdb(); ares::mem::use_gdb(); ares::mug::use_gdb(); ares::newt::use_gdb(); @@ -53,7 +53,8 @@ fn main() -> io::Result<()> { let input_cell = input .as_cell() .expect("Input must be jam of subject/formula pair"); - let result = interpret(&mut stack, &mut None, input_cell.head(), input_cell.tail()); + let result = interpret(&mut stack, &mut None, input_cell.head(), input_cell.tail()) + .expect("nock failed"); if let Ok(atom) = result.as_atom() { println!("Result: {}", atom); } diff --git a/rust/ares/src/mem.rs b/rust/ares/src/mem.rs index 8318aa0..5cb3db6 100644 --- a/rust/ares/src/mem.rs +++ b/rust/ares/src/mem.rs @@ -114,7 +114,7 @@ impl NockStack { } /** Current frame pointer of this NockStack */ - pub fn frame_pointer(&self) -> *u64 { + pub fn frame_pointer(&self) -> *const u64 { self.frame_pointer } diff --git a/rust/ares/src/serf.rs b/rust/ares/src/serf.rs index 7660050..321c68c 100644 --- a/rust/ares/src/serf.rs +++ b/rust/ares/src/serf.rs @@ -1,4 +1,4 @@ -use crate::interpreter::{interpret, raw_slot}; +use crate::interpreter::{interpret, raw_slot, NockErr}; use crate::mem::NockStack; use crate::mug::mug_u32; use crate::newt::Newt; @@ -67,7 +67,8 @@ pub fn serf() -> io::Result<()> { } tas!(b"peek") => { let sam = raw_slot(writ, 7); - let res = slam(stack, newt, arvo, PEEK_AXIS, sam); + let res = slam(stack, newt, arvo, PEEK_AXIS, sam) + .expect("peek error handling unimplemented"); newt.peek_done(stack, res); } tas!(b"play") => { @@ -76,7 +77,8 @@ pub fn serf() -> io::Result<()> { let lit = raw_slot(writ, 7); let sub = T(stack, &[D(0), D(3)]); let lyf = T(stack, &[D(2), sub, D(0), D(2)]); - let gat = interpret(stack, &mut Some(newt), lit, lyf); + let gat = interpret(stack, &mut Some(newt), lit, lyf) + .expect("play error handling unimplemented"); arvo = raw_slot(gat, 7); false } else { @@ -90,7 +92,10 @@ pub fn serf() -> io::Result<()> { while let Ok(cell) = lit.as_cell() { if run { let ovo = cell.head(); - let res = slam(stack, newt, arvo, POKE_AXIS, ovo).as_cell().unwrap(); + let res = slam(stack, newt, arvo, POKE_AXIS, ovo) + .expect("play error handling unimplemented") + .as_cell() + .unwrap(); arvo = res.tail(); } event_number += 1; @@ -102,7 +107,10 @@ pub fn serf() -> io::Result<()> { } tas!(b"work") => { let ovo = raw_slot(writ, 7); - let res = slam(stack, newt, arvo, POKE_AXIS, ovo).as_cell().unwrap(); + let res = slam(stack, newt, arvo, POKE_AXIS, ovo) + .expect("work error handling unimplemented") + .as_cell() + .unwrap(); let fec = res.head(); arvo = res.tail(); snap.save(stack, &mut arvo); @@ -118,7 +126,13 @@ pub fn serf() -> io::Result<()> { Ok(()) } -pub fn slam(stack: &mut NockStack, newt: &mut Newt, core: Noun, axis: u64, ovo: Noun) -> Noun { +pub fn slam( + stack: &mut NockStack, + newt: &mut Newt, + core: Noun, + axis: u64, + ovo: Noun, +) -> Result { let pul = T(stack, &[D(9), D(axis), D(0), D(2)]); 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)]);