Merge branch 'xeb' into fake

This commit is contained in:
Alex Shelkovnykov 2023-10-27 18:59:41 +01:00
commit 59db570ce6
10 changed files with 314 additions and 212 deletions

View File

@ -209,6 +209,7 @@
++ flop :: reverse
~/ %flop
|* a=(list)
~> %sham.%flop
=> .(a (homo a))
^+ a
=+ b=`_a`~
@ -413,6 +414,13 @@
|= [a=bloq b=@]
(rep a (flop (rip a b)))
::
++ xeb :: binary logarithm
~/ %xeb
|= a=@
~> %sham.%xeb
^- @
(met 0 a)
::
:: Modular arithmetic
::
++ fe :: modulo bloq

View File

@ -5,12 +5,12 @@ pub mod warm;
pub mod bits;
pub mod form;
pub mod hash;
pub mod list;
pub mod lute;
pub mod math;
pub mod nock;
pub mod serial;
pub mod sort;
pub mod text;
pub mod tree;
use crate::interpreter::{Context, Error};
@ -19,18 +19,18 @@ use crate::jets::cold::Cold;
use crate::jets::form::*;
use crate::jets::hash::*;
use crate::jets::hot::Hot;
use crate::jets::list::*;
use crate::jets::math::*;
use crate::jets::nock::*;
use crate::jets::serial::*;
use crate::jets::sort::*;
use crate::jets::text::*;
use crate::jets::tree::*;
use crate::jets::warm::Warm;
use crate::mem::NockStack;
use crate::newt::Newt;
use crate::noun::{self, Noun, Slots, D};
use ares_macros::tas;
use std::cmp;
crate::gdb!();
@ -48,6 +48,12 @@ pub enum JetErr {
Fail(Error), // Error; do not retry
}
impl From<Error> for JetErr {
fn from(err: Error) -> Self {
Self::Fail(err)
}
}
impl From<noun::Error> for JetErr {
fn from(_err: noun::Error) -> Self {
Self::Fail(Error::Deterministic(D(0)))
@ -90,6 +96,7 @@ pub fn get_jet(jet_name: Noun) -> Option<Jet> {
tas!(b"cap") => Some(jet_cap),
tas!(b"mas") => Some(jet_mas),
//
tas!(b"flop") => Some(jet_flop),
tas!(b"lent") => Some(jet_lent),
//
tas!(b"bex") => Some(jet_bex),
@ -104,6 +111,7 @@ pub fn get_jet(jet_name: Noun) -> Option<Jet> {
tas!(b"rev") => Some(jet_rev),
tas!(b"rip") => Some(jet_rip),
tas!(b"rsh") => Some(jet_rsh),
tas!(b"xeb") => Some(jet_xeb),
//
tas!(b"con") => Some(jet_con),
tas!(b"dis") => Some(jet_dis),
@ -140,10 +148,8 @@ pub fn get_jet_test_mode(_jet_name: Noun) -> bool {
pub mod util {
use super::*;
use crate::noun::Error::NotRepresentable;
use crate::noun::{Atom, Cell, DirectAtom, IndirectAtom, Noun, D};
use crate::noun::{Noun, D};
use bitvec::prelude::{BitSlice, Lsb0};
use ibig::UBig;
use std::result;
/**
@ -243,98 +249,6 @@ pub mod util {
Ok(())
}
/// Addition
pub fn add(stack: &mut NockStack, a: Atom, b: Atom) -> Atom {
if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
Atom::new(stack, a.data() + b.data())
} else {
let a_big = a.as_ubig(stack);
let b_big = b.as_ubig(stack);
let res = UBig::add_stack(stack, a_big, b_big);
Atom::from_ubig(stack, &res)
}
}
/// Subtraction
pub fn sub(stack: &mut NockStack, a: Atom, b: Atom) -> noun::Result<Atom> {
if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
let a_small = a.data();
let b_small = b.data();
if a_small < b_small {
Err(NotRepresentable)
} else {
Ok(Atom::new(stack, a_small - b_small))
}
} else {
let a_big = a.as_ubig(stack);
let b_big = b.as_ubig(stack);
if a_big < b_big {
Err(NotRepresentable)
} else {
let a_big = a.as_ubig(stack);
let b_big = b.as_ubig(stack);
let res = UBig::sub_stack(stack, a_big, b_big);
Ok(Atom::from_ubig(stack, &res))
}
}
}
/// Binary exponent
pub fn bex(stack: &mut NockStack, arg: usize) -> Atom {
unsafe {
if arg < 63 {
DirectAtom::new_unchecked(1 << arg).as_atom()
} else {
let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(stack, (arg + 7) >> 3);
dest.set(arg, true);
atom.normalize_as_atom()
}
}
}
/// Measure the number of bloqs in an atom
pub fn met(bloq: usize, a: Atom) -> usize {
if unsafe { a.as_noun().raw_equals(D(0)) } {
0
} else if bloq < 6 {
(a.bit_size() + ((1 << bloq) - 1)) >> bloq
} else {
let bloq_word = bloq - 6;
(a.size() + ((1 << bloq_word) - 1)) >> bloq_word
}
}
pub fn rip(stack: &mut NockStack, bloq: usize, step: usize, atom: Atom) -> Result {
let len = (met(bloq, atom) + step - 1) / step;
let mut list = D(0);
for i in (0..len).rev() {
let new_atom = unsafe {
let (mut new_indirect, new_slice) =
IndirectAtom::new_raw_mut_bitslice(stack, step << bloq);
chop(bloq, i * step, step, 0, new_slice, atom.as_bitslice())?;
new_indirect.normalize_as_atom()
};
list = Cell::new(stack, new_atom.as_noun(), list).as_noun();
}
Ok(list)
}
/// Binary OR
pub fn con(stack: &mut NockStack, a: Atom, b: Atom) -> Atom {
let new_size = cmp::max(a.size(), b.size());
unsafe {
let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(stack, new_size);
let a_bit = a.as_bitslice();
dest[..a_bit.len()].copy_from_bitslice(a_bit);
*dest |= b.as_bitslice();
atom.normalize_as_atom()
}
}
pub mod test {
use super::*;
use crate::hamt::Hamt;
@ -465,40 +379,4 @@ pub mod util {
assert_jet_err(context, jet, sam, err);
}
}
#[cfg(test)]
mod tests {
use super::test::{init_context, A};
use super::*;
use ibig::ubig;
#[test]
fn test_met() {
let c = &mut init_context();
let s = &mut c.stack;
let a = A(s, &ubig!(0xdeadbeef12345678fedcba9876543210))
.as_atom()
.unwrap();
assert_eq!(met(0, a), 128);
assert_eq!(met(1, a), 64);
assert_eq!(met(2, a), 32);
assert_eq!(met(3, a), 16);
assert_eq!(met(4, a), 8);
assert_eq!(met(5, a), 4);
assert_eq!(met(6, a), 2);
assert_eq!(met(7, a), 1);
assert_eq!(met(8, a), 1);
let a = D(0x7fffffffffffffff).as_atom().unwrap();
assert_eq!(met(0, a), 63);
assert_eq!(met(1, a), 32);
assert_eq!(met(2, a), 16);
assert_eq!(met(3, a), 8);
assert_eq!(met(4, a), 4);
assert_eq!(met(5, a), 2);
assert_eq!(met(6, a), 1);
assert_eq!(met(7, a), 1);
}
}
}

View File

@ -14,7 +14,7 @@ crate::gdb!();
pub fn jet_bex(context: &mut Context, subject: Noun) -> Result {
let arg = slot(subject, 6)?.as_direct()?.data() as usize;
Ok(bex(&mut context.stack, arg).as_noun())
Ok(util::bex(&mut context.stack, arg).as_noun())
}
pub fn jet_can(context: &mut Context, subject: Noun) -> Result {
@ -70,8 +70,8 @@ pub fn jet_cat(context: &mut Context, subject: Noun) -> Result {
let a = slot(arg, 6)?.as_atom()?;
let b = slot(arg, 7)?.as_atom()?;
let len_a = met(bloq, a);
let len_b = met(bloq, b);
let len_a = util::met(bloq, a);
let len_b = util::met(bloq, b);
let new_len = bite_to_word(bloq, checked_add(len_a, len_b)?)?;
if new_len == 0 {
Ok(a.as_noun())
@ -113,7 +113,7 @@ pub fn jet_end(context: &mut Context, subject: Noun) -> Result {
if step == 0 {
Ok(D(0))
} else if step >= met(bloq, a) {
} else if step >= util::met(bloq, a) {
Ok(a.as_noun())
} else {
unsafe {
@ -138,7 +138,7 @@ pub fn jet_met(_context: &mut Context, subject: Noun) -> Result {
let bloq = bloq(slot(arg, 2)?)?;
let a = slot(arg, 3)?.as_atom()?;
Ok(D(met(bloq, a) as u64))
Ok(D(util::met(bloq, a) as u64))
}
pub fn jet_rap(context: &mut Context, subject: Noun) -> Result {
@ -155,7 +155,7 @@ pub fn jet_rap(context: &mut Context, subject: Noun) -> Result {
let cell = list.as_cell()?;
len = checked_add(len, met(bloq, cell.head().as_atom()?))?;
len = checked_add(len, util::met(bloq, cell.head().as_atom()?))?;
list = cell.tail();
}
@ -175,7 +175,7 @@ pub fn jet_rap(context: &mut Context, subject: Noun) -> Result {
let cell = list.as_cell()?;
let atom = cell.head().as_atom()?;
let step = met(bloq, atom);
let step = util::met(bloq, atom);
chop(bloq, 0, step, pos, new_slice, atom.as_bitslice())?;
pos += step;
@ -272,7 +272,7 @@ pub fn jet_rip(context: &mut Context, subject: Noun) -> Result {
let arg = slot(subject, 6)?;
let (bloq, step) = bite(slot(arg, 2)?)?;
let atom = slot(arg, 3)?.as_atom()?;
rip(&mut context.stack, bloq, step, atom)
util::rip(&mut context.stack, bloq, step, atom)
}
pub fn jet_rsh(context: &mut Context, subject: Noun) -> Result {
@ -280,7 +280,7 @@ pub fn jet_rsh(context: &mut Context, subject: Noun) -> Result {
let (bloq, step) = bite(slot(arg, 2)?)?;
let a = slot(arg, 3)?.as_atom()?;
let len = met(bloq, a);
let len = util::met(bloq, a);
if step >= len {
return Ok(D(0));
}
@ -302,7 +302,7 @@ pub fn jet_con(context: &mut Context, subject: Noun) -> Result {
let a = slot(arg, 2)?.as_atom()?;
let b = slot(arg, 3)?.as_atom()?;
Ok(con(&mut context.stack, a, b).as_noun())
Ok(util::con(&mut context.stack, a, b).as_noun())
}
pub fn jet_dis(context: &mut Context, subject: Noun) -> Result {
@ -337,12 +337,31 @@ pub fn jet_mix(context: &mut Context, subject: Noun) -> Result {
}
}
pub fn jet_xeb(_context: &mut Context, subject: Noun) -> Result {
let sam = slot(subject, 6)?;
let a = slot(sam, 1)?.as_atom()?;
Ok(D(util::met(0, a) as u64))
}
pub mod util {
use crate::jets::util::*;
use crate::jets::JetErr;
use crate::jets::Result;
use crate::mem::NockStack;
use crate::noun::{Atom, IndirectAtom, D};
use std::result::Result;
use crate::noun::{Atom, Cell, DirectAtom, IndirectAtom, D};
use std::cmp;
/// Binary exponent
pub fn bex(stack: &mut NockStack, arg: usize) -> Atom {
unsafe {
if arg < 63 {
DirectAtom::new_unchecked(1 << arg).as_atom()
} else {
let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(stack, (arg + 7) >> 3);
dest.set(arg, true);
atom.normalize_as_atom()
}
}
}
pub fn lsh(stack: &mut NockStack, bloq: usize, step: usize, a: Atom) -> Result<Atom, JetErr> {
let len = met(bloq, a);
@ -357,6 +376,87 @@ pub mod util {
Ok(atom.normalize_as_atom())
}
}
/// Measure the number of bloqs in an atom
pub fn met(bloq: usize, a: Atom) -> usize {
if unsafe { a.as_noun().raw_equals(D(0)) } {
0
} else if bloq < 6 {
(a.bit_size() + ((1 << bloq) - 1)) >> bloq
} else {
let bloq_word = bloq - 6;
(a.size() + ((1 << bloq_word) - 1)) >> bloq_word
}
}
pub fn rip(stack: &mut NockStack, bloq: usize, step: usize, atom: Atom) -> Result {
let len = (met(bloq, atom) + step - 1) / step;
let mut list = D(0);
for i in (0..len).rev() {
let new_atom = unsafe {
let (mut new_indirect, new_slice) =
IndirectAtom::new_raw_mut_bitslice(stack, step << bloq);
chop(bloq, i * step, step, 0, new_slice, atom.as_bitslice())?;
new_indirect.normalize_as_atom()
};
list = Cell::new(stack, new_atom.as_noun(), list).as_noun();
}
Ok(list)
}
/// Binary OR
pub fn con(stack: &mut NockStack, a: Atom, b: Atom) -> Atom {
let new_size = cmp::max(a.size(), b.size());
unsafe {
let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(stack, new_size);
let a_bit = a.as_bitslice();
dest[..a_bit.len()].copy_from_bitslice(a_bit);
*dest |= b.as_bitslice();
atom.normalize_as_atom()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::jets::util::test::A;
use crate::noun::D;
use ibig::ubig;
fn init_stack() -> NockStack {
NockStack::new(8 << 10 << 10, 0)
}
#[test]
fn test_met() {
let s = &mut init_stack();
let a = A(s, &ubig!(0xdeadbeef12345678fedcba9876543210))
.as_atom()
.unwrap();
assert_eq!(met(0, a), 128);
assert_eq!(met(1, a), 64);
assert_eq!(met(2, a), 32);
assert_eq!(met(3, a), 16);
assert_eq!(met(4, a), 8);
assert_eq!(met(5, a), 4);
assert_eq!(met(6, a), 2);
assert_eq!(met(7, a), 1);
assert_eq!(met(8, a), 1);
let a = D(0x7fffffffffffffff).as_atom().unwrap();
assert_eq!(met(0, a), 63);
assert_eq!(met(1, a), 32);
assert_eq!(met(2, a), 16);
assert_eq!(met(3, a), 8);
assert_eq!(met(4, a), 4);
assert_eq!(met(5, a), 2);
assert_eq!(met(6, a), 1);
assert_eq!(met(7, a), 1);
}
}
}
#[cfg(test)]
@ -751,4 +851,16 @@ mod tests {
let sam = T(&mut c.stack, &[a128, a0]);
assert_jet(c, jet_mix, sam, a128);
}
#[test]
fn test_xeb() {
let c = &mut init_context();
let (a0, a24, a63, a96, a128) = atoms(&mut c.stack);
assert_jet(c, jet_xeb, a0, D(0));
assert_jet(c, jet_xeb, a24, D(24));
assert_jet(c, jet_xeb, a63, D(63));
assert_jet(c, jet_xeb, a96, D(96));
assert_jet(c, jet_xeb, a128, D(128));
}
}

View File

@ -25,6 +25,7 @@ const HOT_STATE: &[(&[Either<u64, (u64, u64)>], u64, Jet)] = &[
(&[A_50, Left(tas!(b"mas"))], 1, jet_mas),
//
(&[A_50, Left(tas!(b"lent"))], 1, jet_lent),
(&[A_50, Left(tas!(b"flop"))], 1, jet_flop),
//
(&[A_50, Left(tas!(b"bex"))], 1, jet_bex),
(&[A_50, Left(tas!(b"can"))], 1, jet_can),
@ -38,6 +39,7 @@ const HOT_STATE: &[(&[Either<u64, (u64, u64)>], u64, Jet)] = &[
(&[A_50, Left(tas!(b"rev"))], 1, jet_rev),
(&[A_50, Left(tas!(b"rip"))], 1, jet_rip),
(&[A_50, Left(tas!(b"rsh"))], 1, jet_rsh),
(&[A_50, Left(tas!(b"xeb"))], 1, jet_xeb),
//
(&[A_50, Left(tas!(b"con"))], 1, jet_con),
(&[A_50, Left(tas!(b"dis"))], 1, jet_dis),

122
rust/ares/src/jets/list.rs Normal file
View File

@ -0,0 +1,122 @@
/** Text processing jets
*/
use crate::interpreter::Context;
use crate::jets::util::slot;
use crate::jets::Result;
use crate::noun::{Noun, D};
crate::gdb!();
pub fn jet_flop(context: &mut Context, subject: Noun) -> Result {
let sam = slot(subject, 6)?;
Ok(util::flop(&mut context.stack, sam)?)
}
pub fn jet_lent(_context: &mut Context, subject: Noun) -> Result {
let tape = slot(subject, 6)?;
util::lent(tape).map(|x| D(x as u64))
}
pub mod util {
use crate::interpreter::Error;
use crate::jets::JetErr;
use crate::mem::NockStack;
use crate::noun::{Noun, D, T};
use std::result::Result;
/// Reverse order of list
pub fn flop(stack: &mut NockStack, noun: Noun) -> Result<Noun, Error> {
let mut list = noun;
let mut tsil = D(0);
loop {
if unsafe { list.raw_equals(D(0)) } {
break;
}
let cell = list.as_cell()?;
tsil = T(stack, &[cell.head(), tsil]);
list = cell.tail();
}
Ok(tsil)
}
pub fn lent(tape: Noun) -> Result<usize, JetErr> {
let mut len = 0usize;
let mut list = tape;
loop {
if let Some(atom) = list.atom() {
if atom.as_bitslice().first_one().is_none() {
break;
} else {
return Err(JetErr::Fail(Error::Deterministic(D(0))));
}
}
let cell = list.as_cell()?;
// don't need checked_add or indirect atom result: 2^63-1 atoms would be 64 ebibytes
len += 1;
list = cell.tail();
}
Ok(len)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::interpreter::Error;
use crate::jets::util::test::{assert_jet, assert_jet_err, init_context};
use crate::jets::JetErr;
use crate::noun::{D, T};
#[test]
fn test_flop() {
let c = &mut init_context();
let sam = T(&mut c.stack, &[D(1), D(2), D(3), D(0)]);
let res = T(&mut c.stack, &[D(3), D(2), D(1), D(0)]);
assert_jet(c, jet_flop, sam, res);
#[rustfmt::skip]
let sam = T(
&mut c.stack,
&[
D(0xd), D(0xe), D(0xa), D(0xd), D(0xb), D(0xe), D(0xe), D(0xf),
D(0x1), D(0x2), D(0x3), D(0x4), D(0x5), D(0x6), D(0x7), D(0x8),
D(0xf), D(0xe), D(0xd), D(0xc), D(0xb), D(0xa), D(0x9), D(0x8),
D(0x7), D(0x6), D(0x5), D(0x4), D(0x3), D(0x2), D(0x1), D(0x0),
D(0x0),
],
);
#[rustfmt::skip]
let res = T(
&mut c.stack,
&[
D(0x0), D(0x1), D(0x2), D(0x3), D(0x4), D(0x5), D(0x6), D(0x7),
D(0x8), D(0x9), D(0xa), D(0xb), D(0xc), D(0xd), D(0xe), D(0xf),
D(0x8), D(0x7), D(0x6), D(0x5), D(0x4), D(0x3), D(0x2), D(0x1),
D(0xf), D(0xe), D(0xe), D(0xb), D(0xd), D(0xa), D(0xe), D(0xd),
D(0x0),
],
);
assert_jet(c, jet_flop, sam, res);
assert_jet_err(c, jet_flop, D(1), JetErr::Fail(Error::Deterministic(D(0))));
let sam = T(&mut c.stack, &[D(1), D(2), D(3)]);
assert_jet_err(c, jet_flop, sam, JetErr::Fail(Error::Deterministic(D(0))));
}
#[test]
fn test_lent() {
let c = &mut init_context();
assert_jet(c, jet_lent, D(0), D(0));
let sam = T(&mut c.stack, &[D(1), D(2), D(3), D(0)]);
assert_jet(c, jet_lent, sam, D(3));
let sam = T(&mut c.stack, &[D(3), D(2), D(1), D(0)]);
assert_jet(c, jet_lent, sam, D(3));
assert_jet_err(c, jet_lent, D(1), JetErr::Fail(Error::Deterministic(D(0))));
let sam = T(&mut c.stack, &[D(3), D(2), D(1)]);
assert_jet_err(c, jet_lent, sam, JetErr::Fail(Error::Deterministic(D(0))));
}
}

View File

@ -287,12 +287,25 @@ pub fn jet_sub(context: &mut Context, subject: Noun) -> Result {
let a = slot(arg, 2)?.as_atom()?;
let b = slot(arg, 3)?.as_atom()?;
Ok(sub(&mut context.stack, a, b)?.as_noun())
Ok(util::sub(&mut context.stack, a, b)?.as_noun())
}
pub mod util {
use crate::mem::NockStack;
use crate::noun::{Atom, Noun, NO, YES};
use crate::noun::{Atom, Error, Noun, Result, NO, YES};
use ibig::UBig;
/// Addition
pub fn add(stack: &mut NockStack, a: Atom, b: Atom) -> Atom {
if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
Atom::new(stack, a.data() + b.data())
} else {
let a_big = a.as_ubig(stack);
let b_big = b.as_ubig(stack);
let res = UBig::add_stack(stack, a_big, b_big);
Atom::from_ubig(stack, &res)
}
}
pub fn lth(stack: &mut NockStack, a: Atom, b: Atom) -> Noun {
if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
@ -311,6 +324,32 @@ pub mod util {
NO
}
}
/// Subtraction
pub fn sub(stack: &mut NockStack, a: Atom, b: Atom) -> Result<Atom> {
if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
let a_small = a.data();
let b_small = b.data();
if a_small < b_small {
Err(Error::NotRepresentable)
} else {
Ok(Atom::new(stack, a_small - b_small))
}
} else {
let a_big = a.as_ubig(stack);
let b_big = b.as_ubig(stack);
if a_big < b_big {
Err(Error::NotRepresentable)
} else {
let a_big = a.as_ubig(stack);
let b_big = b.as_ubig(stack);
let res = UBig::sub_stack(stack, a_big, b_big);
Ok(Atom::from_ubig(stack, &res))
}
}
}
}
#[cfg(test)]

View File

@ -138,8 +138,8 @@ pub fn jet_mute(context: &mut Context, subject: Noun) -> Result {
pub mod util {
use crate::interpreter::{interpret, Context, Error};
use crate::jets;
use crate::jets::bits::util::rip;
use crate::jets::form::util::scow;
use crate::jets::util::rip;
use crate::jets::JetErr;
use crate::mem::NockStack;
use crate::noun::{tape, Cell, Noun, D, T};

View File

@ -1,61 +0,0 @@
/** Text processing jets
*/
use crate::interpreter::Context;
use crate::jets::util::slot;
use crate::jets::Result;
use crate::noun::{Noun, D};
crate::gdb!();
pub fn jet_lent(_context: &mut Context, subject: Noun) -> Result {
let tape = slot(subject, 6)?;
util::lent(tape).map(|x| D(x as u64))
}
pub mod util {
use crate::interpreter::Error;
use crate::jets::JetErr;
use crate::noun::{Noun, D};
pub fn lent(tape: Noun) -> Result<usize, JetErr> {
let mut len = 0usize;
let mut list = tape;
loop {
if let Some(atom) = list.atom() {
if atom.as_bitslice().first_one().is_none() {
break;
} else {
return Err(JetErr::Fail(Error::Deterministic(D(0))));
}
}
let cell = list.as_cell()?;
// don't need checked_add or indirect atom result: 2^63-1 atoms would be 64 ebibytes
len += 1;
list = cell.tail();
}
Ok(len)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::interpreter::Error;
use crate::jets::util::test::{assert_jet, assert_jet_err, init_context};
use crate::jets::JetErr;
use crate::noun::{D, T};
#[test]
fn test_lent() {
let c = &mut init_context();
assert_jet(c, jet_lent, D(0), D(0));
let sam = T(&mut c.stack, &[D(1), D(2), D(3), D(0)]);
assert_jet(c, jet_lent, sam, D(3));
let sam = T(&mut c.stack, &[D(3), D(2), D(1), D(0)]);
assert_jet(c, jet_lent, sam, D(3));
assert_jet_err(c, jet_lent, D(1), JetErr::Fail(Error::Deterministic(D(0))));
let sam = T(&mut c.stack, &[D(3), D(2), D(1)]);
assert_jet_err(c, jet_lent, sam, JetErr::Fail(Error::Deterministic(D(0))));
}
}

View File

@ -1,6 +1,8 @@
/** Tree jets
*/
use crate::interpreter::{Context, Error};
use crate::jets::bits::util::*;
use crate::jets::math::util::*;
use crate::jets;
use crate::jets::bits;
use crate::jets::util::*;

View File

@ -3,8 +3,8 @@ use crate::interpreter;
use crate::interpreter::{inc, interpret, Error};
use crate::jets::cold::Cold;
use crate::jets::hot::Hot;
use crate::jets::list::util::lent;
use crate::jets::nock::util::mook;
use crate::jets::text::util::lent;
use crate::jets::warm::Warm;
use crate::mem::NockStack;
use crate::mug::mug_u32;