From 2aabf2e8a77daad07a567e81de0d5f2b4a9e6cf4 Mon Sep 17 00:00:00 2001 From: Sigilante Date: Wed, 6 Sep 2023 13:02:33 -0500 Subject: [PATCH 01/11] Add min/max jets. --- rust/ares/src/jets/math.rs | 82 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/rust/ares/src/jets/math.rs b/rust/ares/src/jets/math.rs index 64cf6ca6..ec61483b 100644 --- a/rust/ares/src/jets/math.rs +++ b/rust/ares/src/jets/math.rs @@ -241,6 +241,58 @@ pub fn jet_lth( }) } +pub fn jet_max( + _stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> jets::Result { + let arg = slot(subject, 6)?; + let a = slot(arg, 2)?.as_atom()?; + let b = slot(arg, 3)?.as_atom()?; + + Ok(if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { + if a.data() >= b.data() { + a.as_noun() + } else { + b.as_noun() + } + } else if a.bit_size() > b.bit_size() { + a.as_noun() + } else if a.bit_size() < b.bit_size() { + b.as_noun() + } else if a.as_ubig(_stack) >= b.as_ubig(_stack) { + a.as_noun() + } else { + b.as_noun() + }) +} + +pub fn jet_min( + _stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun, +) -> jets::Result { + let arg = slot(subject, 6)?; + let a = slot(arg, 2)?.as_atom()?; + let b = slot(arg, 3)?.as_atom()?; + + Ok(if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { + if a.data() <= b.data() { + a.as_noun() + } else { + b.as_noun() + } + } else if a.bit_size() < b.bit_size() { + a.as_noun() + } else if a.bit_size() > b.bit_size() { + b.as_noun() + } else if a.as_ubig(_stack) <= b.as_ubig(_stack) { + a.as_noun() + } else { + b.as_noun() + }) +} + pub fn jet_mod( stack: &mut NockStack, _newt: &mut Option<&mut Newt>, @@ -529,6 +581,36 @@ mod tests { assert_math_jet_noun(s, jet_lth, &[atom_128_b, atom_128], YES); } + #[test] + fn test_max() { + let s = &mut init_stack(); + assert_math_jet(s, jet_max, &[atom_128, atom_96], ubig!(0xdeadbeef12345678fedcba9876543210)); + assert_math_jet(s, jet_max, &[atom_96, atom_63], ubig!(0xfaceb00c15deadbeef123456)); + assert_math_jet(s, jet_max, &[atom_63, atom_96], ubig!(0xfaceb00c15deadbeef123456)); + assert_math_jet(s, jet_max, &[atom_63, atom_63], ubig!(0x7fffffffffffffff)); + assert_math_jet(s, jet_max, &[atom_63, atom_24], ubig!(0x7fffffffffffffff)); + assert_math_jet(s, jet_max, &[atom_128, atom_24], ubig!(0xdeadbeef12345678fedcba9876543210)); + assert_math_jet(s, jet_max, &[atom_128, atom_128_b], ubig!(0xdeadbeef12345678fedcba9876543210)); + assert_math_jet(s, jet_max, &[atom_128_b, atom_128], ubig!(0xdeadbeef12345678fedcba9876543210)); + assert_math_jet(s, jet_max, &[atom_528, atom_264], ubig!(_0xdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540000ffdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540001ff)); + assert_math_jet(s, jet_max, &[atom_264, atom_528], ubig!(_0xdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540000ffdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540001ff)); + } + + #[test] + fn test_min() { + let s = &mut init_stack(); + assert_math_jet(s, jet_min, &[atom_128, atom_96], ubig!(0xfaceb00c15deadbeef123456)); + assert_math_jet(s, jet_min, &[atom_96, atom_63], ubig!(0x7fffffffffffffff)); + assert_math_jet(s, jet_min, &[atom_63, atom_96], ubig!(0x7fffffffffffffff)); + assert_math_jet(s, jet_min, &[atom_63, atom_63], ubig!(0x7fffffffffffffff)); + assert_math_jet(s, jet_min, &[atom_63, atom_24], ubig!(0x876543)); + assert_math_jet(s, jet_min, &[atom_128, atom_24], ubig!(0x876543)); + assert_math_jet(s, jet_min, &[atom_128, atom_128_b], ubig!(0xdeadbeef12345678fedcba9876540000)); + assert_math_jet(s, jet_min, &[atom_128_b, atom_128], ubig!(0xdeadbeef12345678fedcba9876540000)); + assert_math_jet(s, jet_min, &[atom_528, atom_264], ubig!(_0xdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540000ff)); + assert_math_jet(s, jet_min, &[atom_264, atom_528], ubig!(_0xdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540000ff)); + } + #[test] fn test_mod() { let s = &mut init_stack(); From 39cfd709bc368d96cc66c650d0ccba57984e85b0 Mon Sep 17 00:00:00 2001 From: Sigilante Date: Fri, 8 Sep 2023 22:00:19 -0500 Subject: [PATCH 02/11] WIP jets --- rust/ares/src/jets.rs | 124 ++++++++++++++++++++++++++++++++++++- rust/ares/src/jets/math.rs | 4 +- rust/ares/src/jets/tree.rs | 72 ++++++++++++++++++++- rust/ares/src/noun.rs | 3 + 4 files changed, 199 insertions(+), 4 deletions(-) diff --git a/rust/ares/src/jets.rs b/rust/ares/src/jets.rs index 74591df4..892264b1 100644 --- a/rust/ares/src/jets.rs +++ b/rust/ares/src/jets.rs @@ -105,6 +105,7 @@ pub mod util { use std::result; /** + * Address-based size checks. * Currently, only addresses indexable by the first 48 bits are reachable by * modern 64-bit CPUs. */ @@ -115,7 +116,7 @@ pub mod util { a.checked_add(b).filter(|x| x <= &MAX_BIT_LENGTH).ok_or(JetErr::NonDeterministic) } - /// Performs addition that returns None on Noun size overflow + /// Performs subtraction that returns None on Noun size overflow pub fn checked_sub(a: usize, b: usize) -> result::Result { a.checked_sub(b).ok_or(JetErr::NonDeterministic) } @@ -131,6 +132,51 @@ pub mod util { } } + /** + * Value-based size operations. + * Up to 64 bits are allowed, then it's a UBig. + */ + const MAX_BIT_LENGTH: u64 = (1 << 63) - 1; + + /// Performs addition that returns UBig on Noun size overflow + pub fn safe_add(a: u64, b: u64) -> result::Either { + if a <= (crate::noun::DIRECT_MAX - b) { + a + b + } else { + ubig!(a) + ubig!(b) + } + } + + /// Performs multiplication that returns UBig on Noun size overflow + pub fn safe_mul(a: u64, b: u64) -> result::Either { + if a == 0 || b == 0 { + return 0; + } + if a == 1 { + return b; + } + if b == 1 { + return a; + } + + if a <= (crate::noun::DIRECT_MAX / b) { + a * b + } else { + ubig!(a) * ubig!(b) + } + } + + /// Performs left-shift that returns UBig on Noun size overflow + /// Must be smaller than crate::noun::DIRECT_BITS, which is 62 + /// bits (not 63), thus the decrement + pub fn safe_shl(a: u64, b: u64) -> result::Either { + if b <= (a.leading_zeros() - 1) { + a << b + } else { + ubig!(a) << ubig!(b) + } + } + /// Convert length in bits to length in 64-bit words pub fn bits_to_word(a: usize) -> result::Result { checked_add(a, 63).map(|x| x >> 6) @@ -196,6 +242,25 @@ pub mod util { Ok(()) } + /// Addition + pub fn add(stack: &mut NockStack, a: Atom, b: Atom) -> noun::Result { + if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { + let a_small: u64 = a.data(); + let b_small: u64 = b.data(); + + if a_small > MAX_BIT_LENGTH as u64 - 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); + let res = UBig::add_stack(stack, a_big, b_big); + Ok(Atom::from_ubig(stack, &res)) + } + } + /// Subtraction pub fn sub(stack: &mut NockStack, a: Atom, b: Atom) -> noun::Result { if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { @@ -222,6 +287,63 @@ pub mod util { } } + /// Multiplication + pub fn mul(stack: &mut NockStack, a: Atom, b: Atom) -> noun::Result { + 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 > MAX_BIT_LENGTH as u64 / 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); + let res = UBig::mul_stack(stack, a_big, b_big); + Ok(Atom::from_ubig(stack, &res)) + } + } + + /// Division + pub fn div(stack: &mut NockStack, a: Atom, b: Atom) -> noun::Result { + if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { + let a_small = a.data(); + let b_small = b.data(); + + if b_small == 0 { + 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); + let res = UBig::div_stack(stack, a_big, b_big); + Ok(Atom::from_ubig(stack, &res)) + } + } + + /// Modulus + pub fn mod_(stack: &mut NockStack, a: Atom, b: Atom) -> noun::Result { + if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { + let a_small = a.data(); + let b_small = b.data(); + + if b_small == 0 { + 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); + let res = UBig::rem_stack(stack, a_big, b_big); + Ok(Atom::from_ubig(stack, &res)) + } + } + /// Binary exponent pub fn bex(stack: &mut NockStack, arg: usize) -> Atom { unsafe { diff --git a/rust/ares/src/jets/math.rs b/rust/ares/src/jets/math.rs index ec61483b..bfb5d132 100644 --- a/rust/ares/src/jets/math.rs +++ b/rust/ares/src/jets/math.rs @@ -242,7 +242,7 @@ pub fn jet_lth( } pub fn jet_max( - _stack: &mut NockStack, + stack: &mut NockStack, _newt: &mut Option<&mut Newt>, subject: Noun, ) -> jets::Result { @@ -260,7 +260,7 @@ pub fn jet_max( a.as_noun() } else if a.bit_size() < b.bit_size() { b.as_noun() - } else if a.as_ubig(_stack) >= b.as_ubig(_stack) { + } else if a.as_ubig(stack) >= b.as_ubig(stack) { a.as_noun() } else { b.as_noun() diff --git a/rust/ares/src/jets/tree.rs b/rust/ares/src/jets/tree.rs index 75863cb6..9f4b3c44 100644 --- a/rust/ares/src/jets/tree.rs +++ b/rust/ares/src/jets/tree.rs @@ -3,9 +3,12 @@ use crate::jets; use crate::jets::JetErr::*; use crate::jets::util::*; +use crate::jets::util::test::{assert_jet, assert_jet_err, assert_jet_ubig, assert_nary_jet_ubig, init_stack, A}; use crate::mem::NockStack; use crate::newt::Newt; -use crate::noun::{Noun, D}; +use crate::noun::{Atom, Noun, D}; +//use crate::noun::{Atom, DirectAtom, IndirectAtom, Noun, D, DIRECT_MAX, NO, T, YES}; +use ibig::{UBig, ubig}; crate::gdb!(); @@ -49,6 +52,73 @@ pub fn jet_mas( } } +/* +++ peg + ~/ %peg + |= [a=@ b=@] + ?< =(0 a) + ^- @ + ?- b + %1 a + %2 (mul a 2) + %3 +((mul a 2)) + * (add (mod b 2) (mul $(b (div b 2)) 2)) + == +*/ +pub fn jet_peg( + stack: &mut NockStack, + _newt: &mut Option<&mut Newt>, + subject: Noun +) -> jets::Result { + let arg = slot(subject, 6)?; + let a = slot(arg, 2)?.as_atom()?; + let b = slot(arg, 3)?.as_atom()?; + + if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { + if a.as_direct()?.data() == 0 { + return Err(Deterministic); + } + // XX JET MISMATCH IMPORTED FROM VERE + if b.as_direct()?.data() == 0 { + return Err(Deterministic); + } + + let c = met(0, b); + let d = c - 1; + let e = d << 1; + let f = b.as_direct()?.data() - e; // left or right child + let g = d << a; // can overflow in which case use ubig + // checked_left_shift, checked_add only good for usize 2^{47} max size but for values okay to 2^{64} + // wrappers on checked_add, checked_sub native to numbers + // no native ch_lsh in Rust---should have version for values, other for addresses + // so you could rewrite to just use other jets + let h = checked_add(f, g); + + // XX MAY RETURN INDIRECT ATOM + D(h) + } else { + let a_big = a.as_ubig(stack)?; + let b_big = b.as_ubig(stack)?; + + if a_big == 0 { + return Err(Deterministic); + } + // XX JET MISMATCH IMPORTED FROM VERE + if b_big == 0 { + return Err(Deterministic); + } + + let c = met(0, b); + let d = c - 1; + let e = checked_left_shift(d, 1); + let f = b_big - e; // left or right child + let g = checked_left_shift(d, a); + let h = checked_add(f, g); + + Ok(Atom::from_ubig(stack, &h).as_noun()) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/rust/ares/src/noun.rs b/rust/ares/src/noun.rs index cfec55fc..629645d5 100644 --- a/rust/ares/src/noun.rs +++ b/rust/ares/src/noun.rs @@ -18,6 +18,9 @@ const DIRECT_MASK: u64 = !(u64::MAX >> 1); /** Maximum value of a direct atom. Values higher than this must be represented by indirect atoms. */ pub const DIRECT_MAX: u64 = u64::MAX >> 1; +/** Highest direct bit (since leading 0 marks directness) */ +const DIRECT_BITS: u64 = 62; + /** Tag for an indirect atom. */ const INDIRECT_TAG: u64 = u64::MAX & DIRECT_MASK; From 1b667672915e09d980a21e839c865db375627b36 Mon Sep 17 00:00:00 2001 From: Sigilante Date: Fri, 15 Sep 2023 09:48:48 -0500 Subject: [PATCH 03/11] Clean up peg jet. --- rust/ares/src/jets/tree.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/rust/ares/src/jets/tree.rs b/rust/ares/src/jets/tree.rs index 9f4b3c44..89cc2618 100644 --- a/rust/ares/src/jets/tree.rs +++ b/rust/ares/src/jets/tree.rs @@ -87,13 +87,9 @@ pub fn jet_peg( let d = c - 1; let e = d << 1; let f = b.as_direct()?.data() - e; // left or right child - let g = d << a; // can overflow in which case use ubig - // checked_left_shift, checked_add only good for usize 2^{47} max size but for values okay to 2^{64} - // wrappers on checked_add, checked_sub native to numbers - // no native ch_lsh in Rust---should have version for values, other for addresses - // so you could rewrite to just use other jets - let h = checked_add(f, g); - + let g = safe_shl(d, a); + let h = safe_add(f, g); + // XX MAY RETURN INDIRECT ATOM D(h) } else { @@ -110,10 +106,10 @@ pub fn jet_peg( let c = met(0, b); let d = c - 1; - let e = checked_left_shift(d, 1); + let e = safe_shl(d, 1); let f = b_big - e; // left or right child - let g = checked_left_shift(d, a); - let h = checked_add(f, g); + let g = safe_shl(d, a); + let h = safe_add(f, g); Ok(Atom::from_ubig(stack, &h).as_noun()) } From 7fd9f41cad8eb13f12edce4e99ad440f0b283759 Mon Sep 17 00:00:00 2001 From: Sigilante Date: Fri, 15 Sep 2023 15:33:09 -0500 Subject: [PATCH 04/11] Post jet_peg and tests. --- rust/ares/src/jets.rs | 48 +------------ rust/ares/src/jets/tree.rs | 135 ++++++++++++++++++++++++++++++++----- 2 files changed, 120 insertions(+), 63 deletions(-) diff --git a/rust/ares/src/jets.rs b/rust/ares/src/jets.rs index 892264b1..90835985 100644 --- a/rust/ares/src/jets.rs +++ b/rust/ares/src/jets.rs @@ -14,6 +14,7 @@ use crate::newt::Newt; use crate::noun::{self, Noun, Slots}; use ares_macros::tas; use std::cmp; +use ibig::{UBig, ubig}; crate::gdb!(); @@ -132,51 +133,6 @@ pub mod util { } } - /** - * Value-based size operations. - * Up to 64 bits are allowed, then it's a UBig. - */ - const MAX_BIT_LENGTH: u64 = (1 << 63) - 1; - - /// Performs addition that returns UBig on Noun size overflow - pub fn safe_add(a: u64, b: u64) -> result::Either { - if a <= (crate::noun::DIRECT_MAX - b) { - a + b - } else { - ubig!(a) + ubig!(b) - } - } - - /// Performs multiplication that returns UBig on Noun size overflow - pub fn safe_mul(a: u64, b: u64) -> result::Either { - if a == 0 || b == 0 { - return 0; - } - if a == 1 { - return b; - } - if b == 1 { - return a; - } - - if a <= (crate::noun::DIRECT_MAX / b) { - a * b - } else { - ubig!(a) * ubig!(b) - } - } - - /// Performs left-shift that returns UBig on Noun size overflow - /// Must be smaller than crate::noun::DIRECT_BITS, which is 62 - /// bits (not 63), thus the decrement - pub fn safe_shl(a: u64, b: u64) -> result::Either { - if b <= (a.leading_zeros() - 1) { - a << b - } else { - ubig!(a) << ubig!(b) - } - } - /// Convert length in bits to length in 64-bit words pub fn bits_to_word(a: usize) -> result::Result { checked_add(a, 63).map(|x| x >> 6) @@ -260,7 +216,7 @@ pub mod util { Ok(Atom::from_ubig(stack, &res)) } } - + /// Subtraction pub fn sub(stack: &mut NockStack, a: Atom, b: Atom) -> noun::Result { if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { diff --git a/rust/ares/src/jets/tree.rs b/rust/ares/src/jets/tree.rs index 89cc2618..9ba12a91 100644 --- a/rust/ares/src/jets/tree.rs +++ b/rust/ares/src/jets/tree.rs @@ -6,7 +6,7 @@ use crate::jets::util::*; use crate::jets::util::test::{assert_jet, assert_jet_err, assert_jet_ubig, assert_nary_jet_ubig, init_stack, A}; use crate::mem::NockStack; use crate::newt::Newt; -use crate::noun::{Atom, Noun, D}; +use crate::noun::{Atom, Noun, D, T}; //use crate::noun::{Atom, DirectAtom, IndirectAtom, Noun, D, DIRECT_MAX, NO, T, YES}; use ibig::{UBig, ubig}; @@ -75,43 +75,48 @@ pub fn jet_peg( let b = slot(arg, 3)?.as_atom()?; if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { - if a.as_direct()?.data() == 0 { + if a.data() == 0 { return Err(Deterministic); } // XX JET MISMATCH IMPORTED FROM VERE - if b.as_direct()?.data() == 0 { + if b.data() == 0 { return Err(Deterministic); } - let c = met(0, b); + let c = met(0, b.as_atom()) as u8; let d = c - 1; let e = d << 1; - let f = b.as_direct()?.data() - e; // left or right child - let g = safe_shl(d, a); - let h = safe_add(f, g); + let f = b.data() - e as u64; // left or right child + let g = ubig!(d) << a.data() as usize; + let _h = f + g; - // XX MAY RETURN INDIRECT ATOM - D(h) + Ok(A(stack, &ubig!(h))) } else { - let a_big = a.as_ubig(stack)?; - let b_big = b.as_ubig(stack)?; + let a_big = a.as_ubig(stack); + let b_big = b.as_ubig(stack); - if a_big == 0 { + if a_big == ubig!(0) { return Err(Deterministic); } // XX JET MISMATCH IMPORTED FROM VERE - if b_big == 0 { + if b_big == ubig!(0) { return Err(Deterministic); } let c = met(0, b); let d = c - 1; - let e = safe_shl(d, 1); + let e = d << 1; let f = b_big - e; // left or right child - let g = safe_shl(d, a); - let h = safe_add(f, g); + // shl on ubig not defined, so crash if a_big is too big + if a_big.bit_len() > 64 { + return Err(Deterministic); + } else { + // downcast a_big to u64 + let g = d << a.as_direct()?.data(); + let h = f + g; - Ok(Atom::from_ubig(stack, &h).as_noun()) + Ok(Atom::from_ubig(stack, &h).as_noun()) + } } } @@ -153,4 +158,100 @@ mod tests { assert_jet(s, jet_mas, D(7), D(3)); assert_jet(s, jet_mas, D(8), D(4)); } + + fn assert_math_jet( + stack: &mut NockStack, + jet: jets::Jet, + sam: &[fn(&mut NockStack) -> Noun], + res: UBig, + ) { + let sam: Vec = sam.iter().map(|f| f(stack)).collect(); + assert_nary_jet_ubig(stack, jet, &sam, res); + } + + fn assert_math_jet_err( + stack: &mut NockStack, + jet: jets::Jet, + sam: &[fn(&mut NockStack) -> Noun], + err: JetErr, + ) { + let sam: Vec = sam.iter().map(|f| f(stack)).collect(); + let sam = T(stack, &sam); + assert_jet_err(stack, jet, sam, err); + } + + fn atom_0(_stack: &mut NockStack) -> Noun { + print!("{:x}", 0); + D(0x0) + } + + fn atom_1(_stack: &mut NockStack) -> Noun { + print!("{:x}", 1); + D(0x1) + } + + fn atom_2(_stack: &mut NockStack) -> Noun { + print!("{:x}", 2); + D(0x2) + } + + fn atom_3(_stack: &mut NockStack) -> Noun { + print!("{:x}", 3); + D(0x3) + } + + fn atom_4(_stack: &mut NockStack) -> Noun { + D(0x4) + } + + fn atom_5(_stack: &mut NockStack) -> Noun { + D(0x5) + } + + fn atom_10(_stack: &mut NockStack) -> Noun { + D(0x10) + } + + fn atom_7f(_stack: &mut NockStack) -> Noun { + D(0x7fffffffffffffff) + } + + fn atom_100(stack: &mut NockStack) -> Noun { + let shl1_6 = UBig::from_str_radix("10000000000000000", 16); + A(stack, &ubig!(shl1_6)) + } + + fn atom_1000(stack: &mut NockStack) -> Noun { + let shl1_7 = UBig::from_str_radix("100000000000000000000000000000000", 16); + A(stack, &ubig!(shl1_7)) + } + + fn atom_2000(stack: &mut NockStack) -> Noun { + let shl2_7 = UBig::from_str_radix("200000000000000000000000000000000", 16); + A(stack, &ubig!(shl2_7)) + } + + #[test] + fn test_peg() { + let s = &mut init_stack(); + + assert_math_jet_err(s, jet_peg, &[atom_0, atom_1], JetErr::Deterministic); + + // Test direct + assert_math_jet(s, jet_peg, &[atom_2, atom_3], ubig!(5)); + assert_math_jet(s, jet_peg, &[atom_10,atom_10], ubig!(82)); + assert_math_jet(s, jet_peg, &[atom_7f, atom_2], ubig!(0xfffffffffffffffe)); + assert_math_jet(s, jet_peg, &[atom_7f, atom_3], ubig!(0xffffffffffffffff)); + + // Test direct with overflow. + assert_math_jet(s, jet_peg, &[atom_7f, atom_4], ubig!(0x1fffffffffffffffc)); + assert_math_jet(s, jet_peg, &[atom_7f, atom_5], ubig!(0x1fffffffffffffffd)); + + // Test indirect. + let val_1000 = UBig::from_str_radix("100000000000000000000000000000000", 16); + let val_2000 = UBig::from_str_radix("200000000000000000000000000000000", 16); + assert_math_jet(s, jet_peg, &[atom_1000, atom_2], ubig!(val_2000)); + assert_math_jet(s, jet_peg, &[atom_2, atom_1000], ubig!(val_2000)); + assert_math_jet(s, jet_peg, &[atom_100, atom_100], ubig!(val_1000)); + } } From 517c20bafbf7be0fab1afe68c65bb261c384f1e7 Mon Sep 17 00:00:00 2001 From: Sigilante Date: Fri, 15 Sep 2023 16:06:42 -0500 Subject: [PATCH 05/11] Start crypto shax/shay. --- rust/ares/Cargo.lock | 224 +++++++++++++++++++++++++++++++++++++++--- rust/ares/Cargo.toml | 1 + rust/ares/src/jets.rs | 2 + 3 files changed, 216 insertions(+), 11 deletions(-) diff --git a/rust/ares/Cargo.lock b/rust/ares/Cargo.lock index ccabf993..cb3ebb9b 100644 --- a/rust/ares/Cargo.lock +++ b/rust/ares/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "anes" version = "0.1.6" @@ -25,6 +40,7 @@ dependencies = [ "murmur3", "num-derive", "num-traits", + "sha256", "static_assertions", ] @@ -33,7 +49,7 @@ name = "ares_macros" version = "0.1.0" dependencies = [ "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -42,6 +58,17 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55ca83137a482d61d916ceb1eba52a684f98004f18e0cafea230fe5579c178a3" +[[package]] +name = "async-trait" +version = "0.1.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.34", +] + [[package]] name = "atty" version = "0.2.14" @@ -59,6 +86,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -77,12 +119,27 @@ dependencies = [ "wyz", ] +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + [[package]] name = "cast" version = "0.3.0" @@ -149,6 +206,15 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + [[package]] name = "criterion" version = "0.4.0" @@ -228,6 +294,26 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "either" version = "1.9.0" @@ -240,6 +326,22 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + [[package]] name = "half" version = "1.8.2" @@ -270,6 +372,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "ibig" version = "0.3.6" @@ -328,9 +436,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.126" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "log" @@ -341,6 +449,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "memchr" +version = "2.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" + [[package]] name = "memmap" version = "0.7.0" @@ -360,6 +474,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + [[package]] name = "murmur3" version = "0.5.2" @@ -373,7 +496,7 @@ checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -395,6 +518,15 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.17.0" @@ -413,6 +545,12 @@ version = "6.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + [[package]] name = "plotters" version = "0.3.4" @@ -443,18 +581,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.40" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.20" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -517,6 +655,12 @@ version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "ryu" version = "1.0.12" @@ -555,7 +699,7 @@ checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -569,6 +713,30 @@ dependencies = [ "serde", ] +[[package]] +name = "sha2" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha256" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7895c8ae88588ccead14ff438b939b0c569cd619116f14b4d13fdff7b8333386" +dependencies = [ + "async-trait", + "bytes", + "hex", + "sha2", + "tokio", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -586,6 +754,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ec6cdb6a4c16306eccf52ccd8d492e4ab64705a15a5016acb205251001bf72" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tap" version = "1.0.1" @@ -608,12 +787,35 @@ dependencies = [ "serde_json", ] +[[package]] +name = "tokio" +version = "1.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +dependencies = [ + "backtrace", + "bytes", + "pin-project-lite", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unicode-ident" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "walkdir" version = "2.3.2" @@ -646,7 +848,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.98", "wasm-bindgen-shared", ] @@ -668,7 +870,7 @@ checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/rust/ares/Cargo.toml b/rust/ares/Cargo.toml index ab76fb93..36ce2e49 100644 --- a/rust/ares/Cargo.toml +++ b/rust/ares/Cargo.toml @@ -23,6 +23,7 @@ criterion = "0.4" static_assertions = "1.1.0" ibig = "0.3.6" assert_no_alloc = "1.1.2" +sha256 = "1.4.0" [build-dependencies] cc = "1.0.79" diff --git a/rust/ares/src/jets.rs b/rust/ares/src/jets.rs index 90835985..70d0e795 100644 --- a/rust/ares/src/jets.rs +++ b/rust/ares/src/jets.rs @@ -1,11 +1,13 @@ pub mod math; pub mod tree; +pub mod crypto; pub mod bits; pub mod hash; pub mod mink; use crate::jets::math::*; use crate::jets::tree::*; +use crate::jets::crypto::*; use crate::jets::bits::*; use crate::jets::hash::*; use crate::jets::mink::*; From f0377d7d7a40c3a5153509691283ae4d74693217 Mon Sep 17 00:00:00 2001 From: Alex Shelkovnykov Date: Tue, 24 Oct 2023 20:09:59 -0600 Subject: [PATCH 06/11] Fix up logic & tests --- rust/ares/src/jets.rs | 102 +++++--------- rust/ares/src/jets/bits.rs | 91 ++++++------ rust/ares/src/jets/math.rs | 274 +++++++++++++++++++------------------ rust/ares/src/jets/tree.rs | 223 +++++++++++------------------- 4 files changed, 309 insertions(+), 381 deletions(-) diff --git a/rust/ares/src/jets.rs b/rust/ares/src/jets.rs index 20cc21cc..9e57b4d8 100644 --- a/rust/ares/src/jets.rs +++ b/rust/ares/src/jets.rs @@ -232,21 +232,14 @@ pub mod util { } /// Addition - pub fn add(stack: &mut NockStack, a: Atom, b: Atom) -> noun::Result { + pub fn add(stack: &mut NockStack, a: Atom, b: Atom) -> Atom { if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { - let a_small: u64 = a.data(); - let b_small: u64 = b.data(); - - if a_small > MAX_BIT_LENGTH as u64 - b_small { - Err(NotRepresentable) - } else { - Ok(Atom::new(stack, a_small + b_small)) - } + 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); - Ok(Atom::from_ubig(stack, &res)) + Atom::from_ubig(stack, &res) } } @@ -276,63 +269,6 @@ pub mod util { } } - /// Multiplication - pub fn mul(stack: &mut NockStack, a: Atom, b: Atom) -> noun::Result { - 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 > MAX_BIT_LENGTH as u64 / 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); - let res = UBig::mul_stack(stack, a_big, b_big); - Ok(Atom::from_ubig(stack, &res)) - } - } - - /// Division - pub fn div(stack: &mut NockStack, a: Atom, b: Atom) -> noun::Result { - if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { - let a_small = a.data(); - let b_small = b.data(); - - if b_small == 0 { - 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); - let res = UBig::div_stack(stack, a_big, b_big); - Ok(Atom::from_ubig(stack, &res)) - } - } - - /// Modulus - pub fn mod_(stack: &mut NockStack, a: Atom, b: Atom) -> noun::Result { - if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { - let a_small = a.data(); - let b_small = b.data(); - - if b_small == 0 { - 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); - let res = UBig::rem_stack(stack, a_big, b_big); - Ok(Atom::from_ubig(stack, &res)) - } - } - /// Binary exponent pub fn bex(stack: &mut NockStack, arg: usize) -> Atom { unsafe { @@ -484,6 +420,38 @@ pub mod util { } } } + + pub fn assert_common_jet( + context: &mut Context, + jet: Jet, + sam: &[fn(&mut NockStack) -> Noun], + res: UBig, + ) { + let sam: Vec = sam.iter().map(|f| f(&mut context.stack)).collect(); + assert_nary_jet_ubig(context, jet, &sam, res); + } + + pub fn assert_common_jet_noun( + context: &mut Context, + jet: Jet, + sam: &[fn(&mut NockStack) -> Noun], + res: Noun, + ) { + let sam: Vec = sam.iter().map(|f| f(&mut context.stack)).collect(); + let sam = T(&mut context.stack, &sam); + assert_jet(context, jet, sam, res); + } + + pub fn assert_common_jet_err( + context: &mut Context, + jet: Jet, + sam: &[fn(&mut NockStack) -> Noun], + err: JetErr, + ) { + let sam: Vec = sam.iter().map(|f| f(&mut context.stack)).collect(); + let sam = T(&mut context.stack, &sam); + assert_jet_err(context, jet, sam, err); + } } #[cfg(test)] diff --git a/rust/ares/src/jets/bits.rs b/rust/ares/src/jets/bits.rs index 1bb0c464..6230dccd 100644 --- a/rust/ares/src/jets/bits.rs +++ b/rust/ares/src/jets/bits.rs @@ -130,17 +130,7 @@ pub fn jet_lsh(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); - if len == 0 { - return Ok(D(0)); - } - - let new_size = bits_to_word(checked_add(a.bit_size(), checked_left_shift(bloq, step)?)?)?; - unsafe { - let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(&mut context.stack, new_size); - chop(bloq, 0, len, step, dest, a.as_bitslice())?; - Ok(atom.normalize_as_atom().as_noun()) - } + util::lsh(&mut context.stack, bloq, step, a).map(|a| a.as_noun()) } pub fn jet_met(_context: &mut Context, subject: Noun) -> Result { @@ -347,10 +337,32 @@ pub fn jet_mix(context: &mut Context, subject: Noun) -> Result { } } +pub mod util { + use crate::jets::util::*; + use crate::jets::JetErr; + use crate::mem::NockStack; + use crate::noun::{Atom, IndirectAtom, D}; + use std::result::Result; + + pub fn lsh(stack: &mut NockStack, bloq: usize, step: usize, a: Atom) -> Result { + let len = met(bloq, a); + if len == 0 { + return Ok(D(0).as_atom()?); + } + + let new_size = bits_to_word(checked_add(a.bit_size(), checked_left_shift(bloq, step)?)?)?; + unsafe { + let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(stack, new_size); + chop(bloq, 0, len, step, dest, a.as_bitslice())?; + Ok(atom.normalize_as_atom()) + } + } +} + #[cfg(test)] mod tests { use super::*; - use crate::jets::util::test::{assert_jet, assert_jet_ubig, init_context, A}; + use crate::jets::util::test::*; use crate::mem::NockStack; use crate::noun::{Noun, D, T}; use ibig::ubig; @@ -525,34 +537,33 @@ mod tests { fn test_lsh() { let c = &mut init_context(); - let (a0, a24, _a63, a96, a128) = atoms(&mut c.stack); - let sam = T(&mut c.stack, &[a0, a24]); - assert_jet(c, jet_lsh, sam, D(0x10eca86)); - let sam = T(&mut c.stack, &[D(3), a24]); - assert_jet(c, jet_lsh, sam, D(0x87654300)); - let sam = T(&mut c.stack, &[D(7), a24]); - let res = A( - &mut c.stack, - &ubig!(_0x87654300000000000000000000000000000000), - ); - assert_jet(c, jet_lsh, sam, res); - let sam = T(&mut c.stack, &[D(6), a128]); - let res = A( - &mut c.stack, - &ubig!(_0xdeadbeef12345678fedcba98765432100000000000000000), - ); - assert_jet(c, jet_lsh, sam, res); - - let bit = T(&mut c.stack, &[D(0), D(5)]); - let sam = T(&mut c.stack, &[bit, a24]); - assert_jet(c, jet_lsh, sam, D(0x10eca860)); - let bit = T(&mut c.stack, &[D(4), D(6)]); - let sam = T(&mut c.stack, &[bit, a96]); - let res = A( - &mut c.stack, - &ubig!(_0xfaceb00c15deadbeef123456000000000000000000000000), - ); - assert_jet(c, jet_lsh, sam, res); + // let (a0, a24, _a63, a96, a128) = atoms(&mut c.stack); + assert_common_jet_noun(c, jet_lsh, &[atom_0, atom_24], D(0x10eca86)); + // let sam = T(&mut c.stack, &[D(3), a24]); + // assert_jet(c, jet_lsh, sam, D(0x87654300)); + // let sam = T(&mut c.stack, &[D(7), a24]); + // let res = A( + // &mut c.stack, + // &ubig!(_0x87654300000000000000000000000000000000), + // ); + // assert_jet(c, jet_lsh, sam, res); + // let sam = T(&mut c.stack, &[D(6), a128]); + // let res = A( + // &mut c.stack, + // &ubig!(_0xdeadbeef12345678fedcba98765432100000000000000000), + // ); + // assert_jet(c, jet_lsh, sam, res); + + // let bit = T(&mut c.stack, &[D(0), D(5)]); + // let sam = T(&mut c.stack, &[bit, a24]); + // assert_jet(c, jet_lsh, sam, D(0x10eca860)); + // let bit = T(&mut c.stack, &[D(4), D(6)]); + // let sam = T(&mut c.stack, &[bit, a96]); + // let res = A( + // &mut c.stack, + // &ubig!(_0xfaceb00c15deadbeef123456000000000000000000000000), + // ); + // assert_jet(c, jet_lsh, sam, res); } #[test] diff --git a/rust/ares/src/jets/math.rs b/rust/ares/src/jets/math.rs index e67103ca..69722fe9 100644 --- a/rust/ares/src/jets/math.rs +++ b/rust/ares/src/jets/math.rs @@ -23,19 +23,10 @@ use ibig::UBig; crate::gdb!(); pub fn jet_add(context: &mut Context, subject: Noun) -> Result { - let stack = &mut context.stack; let arg = slot(subject, 6)?; let a = slot(arg, 2)?.as_atom()?; let b = slot(arg, 3)?.as_atom()?; - - if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { - Ok(Atom::new(stack, a.data() + b.data()).as_noun()) - } 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); - Ok(Atom::from_ubig(stack, &res).as_noun()) - } + Ok(add(&mut context.stack, a, b).as_noun()) } pub fn jet_dec(context: &mut Context, subject: Noun) -> Result { @@ -326,13 +317,11 @@ pub mod util { mod tests { use super::*; use crate::interpreter::Error; - use crate::jets::util::test::{ - assert_jet, assert_jet_err, assert_jet_ubig, assert_nary_jet_ubig, init_context, A, - }; - use crate::jets::{Jet, JetErr}; + use crate::jets::util::test::*; + use crate::jets::JetErr; use crate::mem::NockStack; use crate::noun::{Noun, D, NO, T, YES}; - use ibig::{ubig, UBig}; + use ibig::ubig; fn atoms(s: &mut NockStack) -> (Noun, Noun, Noun, Noun, Noun) { (atom_0(s), atom_24(s), atom_63(s), atom_96(s), atom_128(s)) @@ -373,55 +362,23 @@ mod tests { A(stack, &ubig!(_0xdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540000ffdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540001ff)) } - fn assert_math_jet( - context: &mut Context, - jet: Jet, - sam: &[fn(&mut NockStack) -> Noun], - res: UBig, - ) { - let sam: Vec = sam.iter().map(|f| f(&mut context.stack)).collect(); - assert_nary_jet_ubig(context, jet, &sam, res); - } - - fn assert_math_jet_noun( - context: &mut Context, - jet: Jet, - sam: &[fn(&mut NockStack) -> Noun], - res: Noun, - ) { - let sam: Vec = sam.iter().map(|f| f(&mut context.stack)).collect(); - let sam = T(&mut context.stack, &sam); - assert_jet(context, jet, sam, res); - } - - fn assert_math_jet_err( - context: &mut Context, - jet: Jet, - sam: &[fn(&mut NockStack) -> Noun], - err: JetErr, - ) { - let sam: Vec = sam.iter().map(|f| f(&mut context.stack)).collect(); - let sam = T(&mut context.stack, &sam); - assert_jet_err(context, jet, sam, err); - } - #[test] fn test_add() { let c = &mut init_context(); - assert_math_jet( + assert_common_jet( c, jet_add, &[atom_128, atom_96], ubig!(0xdeadbef00d03068514bb685765666666), ); - assert_math_jet( + assert_common_jet( c, jet_add, &[atom_63, atom_96], ubig!(0xfaceb00c95deadbeef123455), ); - assert_math_jet(c, jet_add, &[atom_63, atom_63], ubig!(0xfffffffffffffffe)); + assert_common_jet(c, jet_add, &[atom_63, atom_63], ubig!(0xfffffffffffffffe)); } #[test] @@ -439,12 +396,12 @@ mod tests { fn test_div() { let c = &mut init_context(); - assert_math_jet(c, jet_div, &[atom_128, atom_96], ubig!(0xe349f8f0)); - assert_math_jet(c, jet_div, &[atom_96, atom_63], ubig!(0x1f59d6018)); - assert_math_jet(c, jet_div, &[atom_63, atom_96], ubig!(0)); - assert_math_jet(c, jet_div, &[atom_63, atom_63], ubig!(1)); - assert_math_jet(c, jet_div, &[atom_63, atom_24], ubig!(0xf2044dacfe)); - assert_math_jet( + assert_common_jet(c, jet_div, &[atom_128, atom_96], ubig!(0xe349f8f0)); + assert_common_jet(c, jet_div, &[atom_96, atom_63], ubig!(0x1f59d6018)); + assert_common_jet(c, jet_div, &[atom_63, atom_96], ubig!(0)); + assert_common_jet(c, jet_div, &[atom_63, atom_63], ubig!(1)); + assert_common_jet(c, jet_div, &[atom_63, atom_24], ubig!(0xf2044dacfe)); + assert_common_jet( c, jet_div, &[atom_128, atom_24], @@ -453,14 +410,14 @@ mod tests { let res = ubig!( _0x00000000000001000000000000000000000000000000000000000000000000000000000000000001 ); - assert_math_jet(c, jet_div, &[atom_528, atom_264], res); - assert_math_jet_err( + assert_common_jet(c, jet_div, &[atom_528, atom_264], res); + assert_common_jet_err( c, jet_div, &[atom_63, atom_0], JetErr::Fail(Error::Deterministic(D(0))), ); - assert_math_jet_err( + assert_common_jet_err( c, jet_div, &[atom_0, atom_0], @@ -511,7 +468,7 @@ mod tests { let res = T(&mut c.stack, &[res_a, res_b]); assert_jet(c, jet_dvr, sam, res); - assert_math_jet_err( + assert_common_jet_err( c, jet_dvr, &[atom_63, atom_0], @@ -523,113 +480,168 @@ mod tests { fn test_gte() { let c = &mut init_context(); - assert_math_jet_noun(c, jet_gte, &[atom_128, atom_96], YES); - assert_math_jet_noun(c, jet_gte, &[atom_96, atom_63], YES); - assert_math_jet_noun(c, jet_gte, &[atom_63, atom_96], NO); - assert_math_jet_noun(c, jet_gte, &[atom_63, atom_63], YES); - assert_math_jet_noun(c, jet_gte, &[atom_63, atom_24], YES); - assert_math_jet_noun(c, jet_gte, &[atom_128, atom_24], YES); - assert_math_jet_noun(c, jet_gte, &[atom_128, atom_128_b], YES); - assert_math_jet_noun(c, jet_gte, &[atom_128_b, atom_128], NO); + assert_common_jet_noun(c, jet_gte, &[atom_128, atom_96], YES); + assert_common_jet_noun(c, jet_gte, &[atom_96, atom_63], YES); + assert_common_jet_noun(c, jet_gte, &[atom_63, atom_96], NO); + assert_common_jet_noun(c, jet_gte, &[atom_63, atom_63], YES); + assert_common_jet_noun(c, jet_gte, &[atom_63, atom_24], YES); + assert_common_jet_noun(c, jet_gte, &[atom_128, atom_24], YES); + assert_common_jet_noun(c, jet_gte, &[atom_128, atom_128_b], YES); + assert_common_jet_noun(c, jet_gte, &[atom_128_b, atom_128], NO); } #[test] fn test_gth() { let c = &mut init_context(); - assert_math_jet_noun(c, jet_gth, &[atom_128, atom_96], YES); - assert_math_jet_noun(c, jet_gth, &[atom_96, atom_63], YES); - assert_math_jet_noun(c, jet_gth, &[atom_63, atom_96], NO); - assert_math_jet_noun(c, jet_gth, &[atom_63, atom_63], NO); - assert_math_jet_noun(c, jet_gth, &[atom_63, atom_24], YES); - assert_math_jet_noun(c, jet_gth, &[atom_128, atom_24], YES); - assert_math_jet_noun(c, jet_gth, &[atom_128, atom_128_b], YES); - assert_math_jet_noun(c, jet_gth, &[atom_128_b, atom_128], NO); + assert_common_jet_noun(c, jet_gth, &[atom_128, atom_96], YES); + assert_common_jet_noun(c, jet_gth, &[atom_96, atom_63], YES); + assert_common_jet_noun(c, jet_gth, &[atom_63, atom_96], NO); + assert_common_jet_noun(c, jet_gth, &[atom_63, atom_63], NO); + assert_common_jet_noun(c, jet_gth, &[atom_63, atom_24], YES); + assert_common_jet_noun(c, jet_gth, &[atom_128, atom_24], YES); + assert_common_jet_noun(c, jet_gth, &[atom_128, atom_128_b], YES); + assert_common_jet_noun(c, jet_gth, &[atom_128_b, atom_128], NO); } #[test] fn test_lte() { let c = &mut init_context(); - assert_math_jet_noun(c, jet_lte, &[atom_128, atom_96], NO); - assert_math_jet_noun(c, jet_lte, &[atom_96, atom_63], NO); - assert_math_jet_noun(c, jet_lte, &[atom_63, atom_96], YES); - assert_math_jet_noun(c, jet_lte, &[atom_63, atom_63], YES); - assert_math_jet_noun(c, jet_lte, &[atom_63, atom_24], NO); - assert_math_jet_noun(c, jet_lte, &[atom_128, atom_24], NO); - assert_math_jet_noun(c, jet_lte, &[atom_128, atom_128_b], NO); - assert_math_jet_noun(c, jet_lte, &[atom_128_b, atom_128], YES); + assert_common_jet_noun(c, jet_lte, &[atom_128, atom_96], NO); + assert_common_jet_noun(c, jet_lte, &[atom_96, atom_63], NO); + assert_common_jet_noun(c, jet_lte, &[atom_63, atom_96], YES); + assert_common_jet_noun(c, jet_lte, &[atom_63, atom_63], YES); + assert_common_jet_noun(c, jet_lte, &[atom_63, atom_24], NO); + assert_common_jet_noun(c, jet_lte, &[atom_128, atom_24], NO); + assert_common_jet_noun(c, jet_lte, &[atom_128, atom_128_b], NO); + assert_common_jet_noun(c, jet_lte, &[atom_128_b, atom_128], YES); } #[test] fn test_lth() { let c = &mut init_context(); - assert_math_jet_noun(c, jet_lth, &[atom_128, atom_96], NO); - assert_math_jet_noun(c, jet_lth, &[atom_96, atom_63], NO); - assert_math_jet_noun(c, jet_lth, &[atom_63, atom_96], YES); - assert_math_jet_noun(c, jet_lth, &[atom_63, atom_63], NO); - assert_math_jet_noun(c, jet_lth, &[atom_63, atom_24], NO); - assert_math_jet_noun(c, jet_lth, &[atom_128, atom_24], NO); - assert_math_jet_noun(c, jet_lth, &[atom_128, atom_128_b], NO); - assert_math_jet_noun(c, jet_lth, &[atom_128_b, atom_128], YES); + assert_common_jet_noun(c, jet_lth, &[atom_128, atom_96], NO); + assert_common_jet_noun(c, jet_lth, &[atom_96, atom_63], NO); + assert_common_jet_noun(c, jet_lth, &[atom_63, atom_96], YES); + assert_common_jet_noun(c, jet_lth, &[atom_63, atom_63], NO); + assert_common_jet_noun(c, jet_lth, &[atom_63, atom_24], NO); + assert_common_jet_noun(c, jet_lth, &[atom_128, atom_24], NO); + assert_common_jet_noun(c, jet_lth, &[atom_128, atom_128_b], NO); + assert_common_jet_noun(c, jet_lth, &[atom_128_b, atom_128], YES); } #[test] fn test_max() { let c = &mut init_context(); - assert_math_jet(c, jet_max, &[atom_128, atom_96], ubig!(0xdeadbeef12345678fedcba9876543210)); - assert_math_jet(c, jet_max, &[atom_96, atom_63], ubig!(0xfaceb00c15deadbeef123456)); - assert_math_jet(c, jet_max, &[atom_63, atom_96], ubig!(0xfaceb00c15deadbeef123456)); - assert_math_jet(c, jet_max, &[atom_63, atom_63], ubig!(0x7fffffffffffffff)); - assert_math_jet(c, jet_max, &[atom_63, atom_24], ubig!(0x7fffffffffffffff)); - assert_math_jet(c, jet_max, &[atom_128, atom_24], ubig!(0xdeadbeef12345678fedcba9876543210)); - assert_math_jet(c, jet_max, &[atom_128, atom_128_b], ubig!(0xdeadbeef12345678fedcba9876543210)); - assert_math_jet(c, jet_max, &[atom_128_b, atom_128], ubig!(0xdeadbeef12345678fedcba9876543210)); - assert_math_jet(c, jet_max, &[atom_528, atom_264], ubig!(_0xdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540000ffdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540001ff)); - assert_math_jet(c, jet_max, &[atom_264, atom_528], ubig!(_0xdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540000ffdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540001ff)); + assert_common_jet( + c, + jet_max, + &[atom_128, atom_96], + ubig!(0xdeadbeef12345678fedcba9876543210), + ); + assert_common_jet( + c, + jet_max, + &[atom_96, atom_63], + ubig!(0xfaceb00c15deadbeef123456), + ); + assert_common_jet( + c, + jet_max, + &[atom_63, atom_96], + ubig!(0xfaceb00c15deadbeef123456), + ); + assert_common_jet(c, jet_max, &[atom_63, atom_63], ubig!(0x7fffffffffffffff)); + assert_common_jet(c, jet_max, &[atom_63, atom_24], ubig!(0x7fffffffffffffff)); + assert_common_jet( + c, + jet_max, + &[atom_128, atom_24], + ubig!(0xdeadbeef12345678fedcba9876543210), + ); + assert_common_jet( + c, + jet_max, + &[atom_128, atom_128_b], + ubig!(0xdeadbeef12345678fedcba9876543210), + ); + assert_common_jet( + c, + jet_max, + &[atom_128_b, atom_128], + ubig!(0xdeadbeef12345678fedcba9876543210), + ); + assert_common_jet(c, jet_max, &[atom_528, atom_264], ubig!(_0xdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540000ffdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540001ff)); + assert_common_jet(c, jet_max, &[atom_264, atom_528], ubig!(_0xdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540000ffdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540001ff)); } #[test] fn test_min() { let c = &mut init_context(); - - assert_math_jet(c, jet_min, &[atom_128, atom_96], ubig!(0xfaceb00c15deadbeef123456)); - assert_math_jet(c, jet_min, &[atom_96, atom_63], ubig!(0x7fffffffffffffff)); - assert_math_jet(c, jet_min, &[atom_63, atom_96], ubig!(0x7fffffffffffffff)); - assert_math_jet(c, jet_min, &[atom_63, atom_63], ubig!(0x7fffffffffffffff)); - assert_math_jet(c, jet_min, &[atom_63, atom_24], ubig!(0x876543)); - assert_math_jet(c, jet_min, &[atom_128, atom_24], ubig!(0x876543)); - assert_math_jet(c, jet_min, &[atom_128, atom_128_b], ubig!(0xdeadbeef12345678fedcba9876540000)); - assert_math_jet(c, jet_min, &[atom_128_b, atom_128], ubig!(0xdeadbeef12345678fedcba9876540000)); - assert_math_jet(c, jet_min, &[atom_528, atom_264], ubig!(_0xdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540000ff)); - assert_math_jet(c, jet_min, &[atom_264, atom_528], ubig!(_0xdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540000ff)); + + assert_common_jet( + c, + jet_min, + &[atom_128, atom_96], + ubig!(0xfaceb00c15deadbeef123456), + ); + assert_common_jet(c, jet_min, &[atom_96, atom_63], ubig!(0x7fffffffffffffff)); + assert_common_jet(c, jet_min, &[atom_63, atom_96], ubig!(0x7fffffffffffffff)); + assert_common_jet(c, jet_min, &[atom_63, atom_63], ubig!(0x7fffffffffffffff)); + assert_common_jet(c, jet_min, &[atom_63, atom_24], ubig!(0x876543)); + assert_common_jet(c, jet_min, &[atom_128, atom_24], ubig!(0x876543)); + assert_common_jet( + c, + jet_min, + &[atom_128, atom_128_b], + ubig!(0xdeadbeef12345678fedcba9876540000), + ); + assert_common_jet( + c, + jet_min, + &[atom_128_b, atom_128], + ubig!(0xdeadbeef12345678fedcba9876540000), + ); + assert_common_jet( + c, + jet_min, + &[atom_528, atom_264], + ubig!(_0xdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540000ff), + ); + assert_common_jet( + c, + jet_min, + &[atom_264, atom_528], + ubig!(_0xdeadbeef12345678fedcba9876540000deadbeef12345678fedcba9876540000ff), + ); } #[test] fn test_mod() { let c = &mut init_context(); - assert_math_jet( + assert_common_jet( c, jet_mod, &[atom_128, atom_96], ubig!(0xcb0ce564ec598f658409d170), ); - assert_math_jet(c, jet_mod, &[atom_96, atom_63], ubig!(0x15deadc0e4af946e)); - assert_math_jet(c, jet_mod, &[atom_63, atom_96], ubig!(0x7fffffffffffffff)); - assert_math_jet(c, jet_mod, &[atom_63, atom_63], ubig!(0)); - assert_math_jet(c, jet_mod, &[atom_63, atom_24], ubig!(0x798385)); - assert_math_jet(c, jet_mod, &[atom_128, atom_24], ubig!(0x3b2013)); - assert_math_jet(c, jet_mod, &[atom_528, atom_264], ubig!(0x100)); - assert_math_jet_err( + assert_common_jet(c, jet_mod, &[atom_96, atom_63], ubig!(0x15deadc0e4af946e)); + assert_common_jet(c, jet_mod, &[atom_63, atom_96], ubig!(0x7fffffffffffffff)); + assert_common_jet(c, jet_mod, &[atom_63, atom_63], ubig!(0)); + assert_common_jet(c, jet_mod, &[atom_63, atom_24], ubig!(0x798385)); + assert_common_jet(c, jet_mod, &[atom_128, atom_24], ubig!(0x3b2013)); + assert_common_jet(c, jet_mod, &[atom_528, atom_264], ubig!(0x100)); + assert_common_jet_err( c, jet_mod, &[atom_63, atom_0], JetErr::Fail(Error::Deterministic(D(0))), ); - assert_math_jet_err( + assert_common_jet_err( c, jet_mod, &[atom_0, atom_0], @@ -641,46 +653,46 @@ mod tests { fn test_mul() { let c = &mut init_context(); - assert_math_jet( + assert_common_jet( c, jet_mul, &[atom_128, atom_96], ubig!(_0xda297567129704bf42e744f13ff0ea4fc4ac01215b708bc94f941160), ); - assert_math_jet( + assert_common_jet( c, jet_mul, &[atom_63, atom_96], ubig!(_0x7d6758060aef56de7cba6a1eea21524110edcbaa), ); - assert_math_jet( + assert_common_jet( c, jet_mul, &[atom_63, atom_63], ubig!(0x3fffffffffffffff0000000000000001), ); - assert_math_jet(c, jet_mul, &[atom_24, atom_24], ubig!(0x479bf4b7ef89)); + assert_common_jet(c, jet_mul, &[atom_24, atom_24], ubig!(0x479bf4b7ef89)); } #[test] fn test_sub() { let c = &mut init_context(); - assert_math_jet( + assert_common_jet( c, jet_sub, &[atom_128, atom_96], ubig!(0xdeadbeee1765a66ce8fe0cd98741fdba), ); - assert_math_jet( + assert_common_jet( c, jet_sub, &[atom_96, atom_63], ubig!(0xfaceb00b95deadbeef123457), ); - assert_math_jet(c, jet_sub, &[atom_63, atom_63], ubig!(0)); - assert_math_jet(c, jet_sub, &[atom_128, atom_128], ubig!(0)); - assert_math_jet_err( + assert_common_jet(c, jet_sub, &[atom_63, atom_63], ubig!(0)); + assert_common_jet(c, jet_sub, &[atom_128, atom_128], ubig!(0)); + assert_common_jet_err( c, jet_sub, &[atom_63, atom_96], diff --git a/rust/ares/src/jets/tree.rs b/rust/ares/src/jets/tree.rs index b6b881a0..eadf78ec 100644 --- a/rust/ares/src/jets/tree.rs +++ b/rust/ares/src/jets/tree.rs @@ -1,9 +1,11 @@ /** Tree jets */ use crate::interpreter::{Context, Error}; +use crate::jets; +use crate::jets::bits; use crate::jets::util::*; use crate::jets::{JetErr, Result}; -use crate::noun::{Noun, Atom, D}; +use crate::noun::{Noun, D}; crate::gdb!(); @@ -40,77 +42,72 @@ pub fn jet_mas(context: &mut Context, subject: Noun) -> Result { } } -/* -++ peg - ~/ %peg - |= [a=@ b=@] - ?< =(0 a) - ^- @ - ?- b - %1 a - %2 (mul a 2) - %3 +((mul a 2)) - * (add (mod b 2) (mul $(b (div b 2)) 2)) - == -*/ pub fn jet_peg(context: &mut Context, subject: Noun) -> Result { let stack = &mut context.stack; let arg = slot(subject, 6)?; - let a = slot(arg, 2)?.as_atom()?; - let b = slot(arg, 3)?.as_atom()?; + let a = slot(arg, 2)?; + let b = slot(arg, 3)?; - if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { - if a.data() == 0 { - return Err(JetErr::Fail(Error::Deterministic(D(0)))); - } - // XX JET MISMATCH IMPORTED FROM VERE - if b.data() == 0 { + unsafe { + if a.raw_equals(D(0)) { return Err(JetErr::Fail(Error::Deterministic(D(0)))); } - - let c = met(0, b.as_atom()) as u8; - let d = c - 1; - let e = d << 1; - let f = b.data() - e as u64; // left or right child - let g = d << a.data(); - let h = f + g as u64; - - Ok(Atom::new(stack, h).as_noun()) - } else { - // Don't need 0 checks here since it's presumed that any UBig is - // greater than or equal to 2^63 (i.e. that indirect atoms are - // normalized before being returned). - let a_big = a.as_ubig(stack); - let b_big = b.as_ubig(stack); - - let c = met(0, b); - let d = c - 1; - let e = d << 1; - let f = b_big - e; // left or right child - // shl on ubig not defined, so crash if a_big is too big - if a_big.bit_len() > 64 { + // XX: Import jet mistmatch from Vere + if b.raw_equals(D(0)) { return Err(JetErr::Fail(Error::Deterministic(D(0)))); - } else { - // downcast a_big to u64 - let g = d << a.as_direct()?.data(); - let h = f + g; - - Ok(Atom::from_ubig(stack, &h).as_noun()) } - } + }; + + let c = met(0, b.as_atom()?); + let d = c - 1; + let e = bits::util::lsh(stack, 0, d, D(1).as_atom()?)?; + let f = jets::util::sub(stack, b.as_atom()?, e)?; + let g = bits::util::lsh(stack, 0, d, a.as_atom()?)?; + Ok(jets::util::add(stack, f, g).as_noun()) } #[cfg(test)] mod tests { use super::*; - use crate::interpreter::{Context, Error}; + use crate::interpreter::Error; use crate::jets::util::test::*; - use crate::jets::{Jet, JetErr}; + use crate::jets::JetErr; use crate::mem::NockStack; - use crate::noun::{Noun, D, T}; - use ibig::UBig; + use crate::noun::{Noun, D, DIRECT_MAX}; use ibig::ubig; + fn atom_0(_stack: &mut NockStack) -> Noun { + D(0x0) + } + + fn atom_1(_stack: &mut NockStack) -> Noun { + D(0x1) + } + + fn atom_62(_stack: &mut NockStack) -> Noun { + D(0x3fffffffffffffff) + } + + fn atom_63(_stack: &mut NockStack) -> Noun { + D(0x4000000000000000) + } + + fn atom_65(stack: &mut NockStack) -> Noun { + A(stack, &ubig!(_0x10000000000000000)) + } + + fn pos_2(_stack: &mut NockStack) -> Noun { + D(2) + } + + fn pos_3(_stack: &mut NockStack) -> Noun { + D(3) + } + + fn pos_4(_stack: &mut NockStack) -> Noun { + D(4) + } + #[test] fn test_cap() { let c = &mut init_context(); @@ -143,99 +140,39 @@ mod tests { assert_jet(c, jet_mas, D(8), D(4)); } - fn assert_math_jet( - context: &mut Context, - jet: Jet, - sam: &[fn(&mut NockStack) -> Noun], - res: UBig, - ) { - let sam: Vec = sam.iter().map(|f| f(&mut context.stack)).collect(); - assert_nary_jet_ubig(context, jet, &sam, res); - } - - fn assert_math_jet_noun( - context: &mut Context, - jet: Jet, - sam: &[fn(&mut NockStack) -> Noun], - res: Noun, - ) { - let sam: Vec = sam.iter().map(|f| f(&mut context.stack)).collect(); - let sam = T(&mut context.stack, &sam); - assert_jet(context, jet, sam, res); - } - - fn assert_math_jet_err( - context: &mut Context, - jet: Jet, - sam: &[fn(&mut NockStack) -> Noun], - err: JetErr, - ) { - let sam: Vec = sam.iter().map(|f| f(&mut context.stack)).collect(); - let sam = T(&mut context.stack, &sam); - assert_jet_err(context, jet, sam, err); - } - - fn atom_0(_stack: &mut NockStack) -> Noun { - D(0x0) - } - - fn atom_1(_stack: &mut NockStack) -> Noun { - D(0x1) - } - - fn atom_2(_stack: &mut NockStack) -> Noun { - D(0x2) - } - - fn atom_3(_stack: &mut NockStack) -> Noun { - D(0x3) - } - - fn atom_4(_stack: &mut NockStack) -> Noun { - D(0x4) - } - - fn atom_5(_stack: &mut NockStack) -> Noun { - D(0x5) - } - - fn atom_10(_stack: &mut NockStack) -> Noun { - D(0x10) - } - - fn atom_7f(_stack: &mut NockStack) -> Noun { - D(0x7fffffffffffffff) - } - - fn atom_100(stack: &mut NockStack) -> Noun { - A(stack, &ubig!(_0x10000000000000000)) - } - - fn atom_1000(stack: &mut NockStack) -> Noun { - A(stack, &ubig!(_0x100000000000000000000000000000000)) - } - #[test] fn test_peg() { let c = &mut init_context(); - assert_math_jet_err(c, jet_peg, &[atom_0, atom_1], JetErr::Fail(Error::Deterministic(D(0)))); + assert_common_jet_err( + c, + jet_peg, + &[atom_0, atom_1], + JetErr::Fail(Error::Deterministic(D(0))), + ); + assert_common_jet_err( + c, + jet_peg, + &[atom_1, atom_0], + JetErr::Fail(Error::Deterministic(D(0))), + ); // Test direct - assert_math_jet_noun(c, jet_peg, &[atom_2, atom_3], D(5)); - assert_math_jet_noun(c, jet_peg, &[atom_10, atom_10], D(82)); - // assert_math_jet_noun(c, jet_peg, &[atom_7f, atom_2], D(0xfffffffffffffffe)); - // assert_math_jet(c, jet_peg, &[atom_7f, atom_3], ubig!(0xffffffffffffffff)); - - // // Test direct with overflow. - // assert_math_jet(c, jet_peg, &[atom_7f, atom_4], ubig!(0x1fffffffffffffffc)); - // assert_math_jet(c, jet_peg, &[atom_7f, atom_5], ubig!(0x1fffffffffffffffd)); - - // // Test indirect. - // let val_1000 = A(&mut c.stack, &ubig!(_0x100000000000000000000000000000000)); - // let val_2000 = A(&mut c.stack, &ubig!(_0x200000000000000000000000000000000)); - // assert_math_jet_noun(c, jet_peg, &[atom_1000, atom_2], val_2000); - // assert_math_jet_noun(c, jet_peg, &[atom_2, atom_1000], val_2000); - // assert_math_jet_noun(c, jet_peg, &[atom_100, atom_100], val_1000); + assert_common_jet_noun(c, jet_peg, &[pos_2, pos_3], D(5)); + assert_common_jet_noun(c, jet_peg, &[pos_4, pos_4], D(16)); + + // Test direct with overflow. + assert_common_jet_noun(c, jet_peg, &[atom_62, pos_3], D(DIRECT_MAX)); + assert_common_jet(c, jet_peg, &[pos_2, atom_63], ubig!(0x8000000000000000)); + + // Test indirect. + assert_common_jet(c, jet_peg, &[atom_65, atom_1], ubig!(_0x10000000000000000)); + assert_common_jet(c, jet_peg, &[atom_1, atom_65], ubig!(_0x10000000000000000)); + assert_common_jet( + c, + jet_peg, + &[atom_65, atom_65], + ubig!(_0x100000000000000000000000000000000), + ); } } From 25a7b09ddd1865912b95ec9bf0f5af79512cf8f5 Mon Sep 17 00:00:00 2001 From: Alex Shelkovnykov Date: Tue, 24 Oct 2023 20:18:59 -0600 Subject: [PATCH 07/11] Undo Cargo changes --- rust/ares/Cargo.lock | 230 +++---------------------------------------- rust/ares/Cargo.toml | 3 +- 2 files changed, 15 insertions(+), 218 deletions(-) diff --git a/rust/ares/Cargo.lock b/rust/ares/Cargo.lock index 1e4dc7dd..950e6fcf 100644 --- a/rust/ares/Cargo.lock +++ b/rust/ares/Cargo.lock @@ -2,21 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "anes" version = "0.1.6" @@ -41,7 +26,6 @@ dependencies = [ "murmur3", "num-derive", "num-traits", - "sha256", "signal-hook", "static_assertions", ] @@ -51,7 +35,7 @@ name = "ares_macros" version = "0.1.0" dependencies = [ "quote", - "syn 1.0.98", + "syn", ] [[package]] @@ -60,17 +44,6 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55ca83137a482d61d916ceb1eba52a684f98004f18e0cafea230fe5579c178a3" -[[package]] -name = "async-trait" -version = "0.1.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.34", -] - [[package]] name = "atty" version = "0.2.14" @@ -88,21 +61,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "backtrace" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -121,27 +79,12 @@ dependencies = [ "wyz", ] -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - [[package]] name = "bumpalo" version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" -[[package]] -name = "bytes" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" - [[package]] name = "cast" version = "0.3.0" @@ -208,15 +151,6 @@ dependencies = [ "os_str_bytes", ] -[[package]] -name = "cpufeatures" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" -dependencies = [ - "libc", -] - [[package]] name = "criterion" version = "0.4.0" @@ -296,26 +230,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - [[package]] name = "either" version = "1.9.0" @@ -328,22 +242,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "gimli" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" - [[package]] name = "half" version = "1.8.2" @@ -374,12 +272,6 @@ dependencies = [ "libc", ] -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - [[package]] name = "ibig" version = "0.3.6" @@ -438,9 +330,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] name = "log" @@ -451,12 +343,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "memchr" -version = "2.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" - [[package]] name = "memmap" version = "0.7.0" @@ -476,15 +362,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - [[package]] name = "murmur3" version = "0.5.2" @@ -498,14 +375,14 @@ checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ "proc-macro2", "quote", - "syn 1.0.98", + "syn", ] [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] @@ -520,15 +397,6 @@ dependencies = [ "libc", ] -[[package]] -name = "object" -version = "0.32.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.17.0" @@ -547,12 +415,6 @@ version = "6.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" -[[package]] -name = "pin-project-lite" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" - [[package]] name = "plotters" version = "0.3.4" @@ -583,18 +445,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" dependencies = [ "proc-macro2", ] @@ -657,12 +519,6 @@ version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - [[package]] name = "ryu" version = "1.0.12" @@ -701,7 +557,7 @@ checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" dependencies = [ "proc-macro2", "quote", - "syn 1.0.98", + "syn", ] [[package]] @@ -715,30 +571,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sha2" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha256" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7895c8ae88588ccead14ff438b939b0c569cd619116f14b4d13fdff7b8333386" -dependencies = [ - "async-trait", - "bytes", - "hex", - "sha2", - "tokio", -] - [[package]] name = "signal-hook" version = "0.3.17" @@ -775,17 +607,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "syn" -version = "2.0.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ec6cdb6a4c16306eccf52ccd8d492e4ab64705a15a5016acb205251001bf72" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "tap" version = "1.0.1" @@ -808,35 +629,12 @@ dependencies = [ "serde_json", ] -[[package]] -name = "tokio" -version = "1.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" -dependencies = [ - "backtrace", - "bytes", - "pin-project-lite", -] - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - [[package]] name = "unicode-ident" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - [[package]] name = "walkdir" version = "2.3.2" @@ -869,7 +667,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 1.0.98", + "syn", "wasm-bindgen-shared", ] @@ -891,7 +689,7 @@ checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", - "syn 1.0.98", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -950,4 +748,4 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e" dependencies = [ "tap", -] +] \ No newline at end of file diff --git a/rust/ares/Cargo.toml b/rust/ares/Cargo.toml index 8c75e580..14b00fc7 100644 --- a/rust/ares/Cargo.toml +++ b/rust/ares/Cargo.toml @@ -26,7 +26,6 @@ memmap = "0.7.0" murmur3 = { git = "https://github.com/tloncorp/murmur3", rev = "7878a0f" } num-derive = "0.3" num-traits = "0.2" -sha256 = "1.4.0" signal-hook = "0.3" static_assertions = "1.1.0" @@ -49,4 +48,4 @@ check_all = [ "check_acyclic", "check_forwarding", "check_junior" ] check_acyclic = [] check_forwarding = [] check_junior = [] -sham_hints = [] +sham_hints = [] \ No newline at end of file From 5aed65c969a2ddce0b71597958076d13433639af Mon Sep 17 00:00:00 2001 From: Alex Shelkovnykov Date: Fri, 27 Oct 2023 13:08:48 +0100 Subject: [PATCH 08/11] Minor fixes --- rust/ares/Cargo.toml | 2 +- rust/ares/src/jets/bits.rs | 52 +++++++++++++++++++------------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/rust/ares/Cargo.toml b/rust/ares/Cargo.toml index 14b00fc7..96ffd8b1 100644 --- a/rust/ares/Cargo.toml +++ b/rust/ares/Cargo.toml @@ -48,4 +48,4 @@ check_all = [ "check_acyclic", "check_forwarding", "check_junior" ] check_acyclic = [] check_forwarding = [] check_junior = [] -sham_hints = [] \ No newline at end of file +sham_hints = [] diff --git a/rust/ares/src/jets/bits.rs b/rust/ares/src/jets/bits.rs index 6230dccd..387f8866 100644 --- a/rust/ares/src/jets/bits.rs +++ b/rust/ares/src/jets/bits.rs @@ -537,33 +537,33 @@ mod tests { fn test_lsh() { let c = &mut init_context(); - // let (a0, a24, _a63, a96, a128) = atoms(&mut c.stack); + let (_, a24, _a63, a96, a128) = atoms(&mut c.stack); assert_common_jet_noun(c, jet_lsh, &[atom_0, atom_24], D(0x10eca86)); - // let sam = T(&mut c.stack, &[D(3), a24]); - // assert_jet(c, jet_lsh, sam, D(0x87654300)); - // let sam = T(&mut c.stack, &[D(7), a24]); - // let res = A( - // &mut c.stack, - // &ubig!(_0x87654300000000000000000000000000000000), - // ); - // assert_jet(c, jet_lsh, sam, res); - // let sam = T(&mut c.stack, &[D(6), a128]); - // let res = A( - // &mut c.stack, - // &ubig!(_0xdeadbeef12345678fedcba98765432100000000000000000), - // ); - // assert_jet(c, jet_lsh, sam, res); - - // let bit = T(&mut c.stack, &[D(0), D(5)]); - // let sam = T(&mut c.stack, &[bit, a24]); - // assert_jet(c, jet_lsh, sam, D(0x10eca860)); - // let bit = T(&mut c.stack, &[D(4), D(6)]); - // let sam = T(&mut c.stack, &[bit, a96]); - // let res = A( - // &mut c.stack, - // &ubig!(_0xfaceb00c15deadbeef123456000000000000000000000000), - // ); - // assert_jet(c, jet_lsh, sam, res); + let sam = T(&mut c.stack, &[D(3), a24]); + assert_jet(c, jet_lsh, sam, D(0x87654300)); + let sam = T(&mut c.stack, &[D(7), a24]); + let res = A( + &mut c.stack, + &ubig!(_0x87654300000000000000000000000000000000), + ); + assert_jet(c, jet_lsh, sam, res); + let sam = T(&mut c.stack, &[D(6), a128]); + let res = A( + &mut c.stack, + &ubig!(_0xdeadbeef12345678fedcba98765432100000000000000000), + ); + assert_jet(c, jet_lsh, sam, res); + + let bit = T(&mut c.stack, &[D(0), D(5)]); + let sam = T(&mut c.stack, &[bit, a24]); + assert_jet(c, jet_lsh, sam, D(0x10eca860)); + let bit = T(&mut c.stack, &[D(4), D(6)]); + let sam = T(&mut c.stack, &[bit, a96]); + let res = A( + &mut c.stack, + &ubig!(_0xfaceb00c15deadbeef123456000000000000000000000000), + ); + assert_jet(c, jet_lsh, sam, res); } #[test] From 4177ae6fa3a6f02a797559623f0cf8458d46ea2f Mon Sep 17 00:00:00 2001 From: Edward Amsden Date: Fri, 10 Nov 2023 10:39:55 -0600 Subject: [PATCH 09/11] jets: peg and mas implemented using bitslices --- rust/ares/src/jets/tree.rs | 60 ++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/rust/ares/src/jets/tree.rs b/rust/ares/src/jets/tree.rs index eadf78ec..55842284 100644 --- a/rust/ares/src/jets/tree.rs +++ b/rust/ares/src/jets/tree.rs @@ -1,11 +1,9 @@ /** Tree jets */ use crate::interpreter::{Context, Error}; -use crate::jets; -use crate::jets::bits; use crate::jets::util::*; use crate::jets::{JetErr, Result}; -use crate::noun::{Noun, D}; +use crate::noun::{IndirectAtom, Noun, D}; crate::gdb!(); @@ -27,43 +25,55 @@ pub fn jet_cap(_context: &mut Context, subject: Noun) -> Result { pub fn jet_mas(context: &mut Context, subject: Noun) -> Result { let stack = &mut context.stack; - let arg = slot(subject, 6)?; - let tom = arg.as_atom()?; + let tom = slot(subject, 6)?.as_atom()?; let met = met(0, tom); if met < 2 { Err(JetErr::Fail(Error::Deterministic(D(0)))) } else { - let c = bex(stack, met - 1); - let d = bex(stack, met - 2); - let e = sub(stack, tom, c)?; - - Ok(con(stack, e, d).as_noun()) + let out_bits = met - 1; + let out_words = (out_bits + 63) << 6; + let (mut indirect_out, out_bs) = unsafe { IndirectAtom::new_raw_mut_bitslice(stack, out_words) }; + out_bs.set(met - 2, true); // Set MSB + if met > 2 { + out_bs[0..met - 2].copy_from_bitslice(&tom.as_bitslice()[0..met - 2]); + }; + unsafe { + Ok(indirect_out.normalize_as_atom().as_noun()) + } } } pub fn jet_peg(context: &mut Context, subject: Noun) -> Result { let stack = &mut context.stack; let arg = slot(subject, 6)?; - let a = slot(arg, 2)?; - let b = slot(arg, 3)?; + let a = slot(arg, 2)?.as_atom()?; + let b = slot(arg, 3)?.as_atom()?; unsafe { - if a.raw_equals(D(0)) { + if a.as_noun().raw_equals(D(0)) { return Err(JetErr::Fail(Error::Deterministic(D(0)))); - } - // XX: Import jet mistmatch from Vere - if b.raw_equals(D(0)) { + }; + + if b.as_noun().raw_equals(D(0)) { return Err(JetErr::Fail(Error::Deterministic(D(0)))); - } - }; - - let c = met(0, b.as_atom()?); - let d = c - 1; - let e = bits::util::lsh(stack, 0, d, D(1).as_atom()?)?; - let f = jets::util::sub(stack, b.as_atom()?, e)?; - let g = bits::util::lsh(stack, 0, d, a.as_atom()?)?; - Ok(jets::util::add(stack, f, g).as_noun()) + }; + } + + let a_bits = met(0, a); + let b_bits = met(0, b); + let out_bits = a_bits + b_bits - 1; + + let out_words = (out_bits + 63) << 6; // bits to 8-byte words + + let (mut indirect_out, out_bs) = unsafe { IndirectAtom::new_raw_mut_bitslice(stack, out_words) }; + + out_bs[0..b_bits - 1].copy_from_bitslice(&b.as_bitslice()[0..b_bits - 1]); + out_bs[b_bits - 1..out_bits].copy_from_bitslice(&a.as_bitslice()[0..a_bits]); + + unsafe { + Ok(indirect_out.normalize_as_atom().as_noun()) + } } #[cfg(test)] From 214b745a435fd25743b866ce6e76f35035293207 Mon Sep 17 00:00:00 2001 From: Alex Shelkovnykov Date: Wed, 15 Nov 2023 11:08:48 +0100 Subject: [PATCH 10/11] jets: fix allocation bug and add tests for it --- rust/ares/Cargo.toml | 4 ++-- rust/ares/src/jets.rs | 19 +++++++++++++++ rust/ares/src/jets/tree.rs | 49 +++++++++++++++++++++++++++++--------- 3 files changed, 59 insertions(+), 13 deletions(-) diff --git a/rust/ares/Cargo.toml b/rust/ares/Cargo.toml index 96ffd8b1..22c28c3b 100644 --- a/rust/ares/Cargo.toml +++ b/rust/ares/Cargo.toml @@ -12,9 +12,9 @@ edition = "2018" # Please keep these alphabetized [dependencies] ares_macros = { path = "../ares_macros" } -assert_no_alloc = "1.1.2" +# assert_no_alloc = "1.1.2" # use this when debugging requires allocation (e.g. eprintln) -# assert_no_alloc = {version="1.1.2", features=["warn_debug"]} +assert_no_alloc = {version="1.1.2", features=["warn_debug"]} bitvec = "1.0.0" criterion = "0.4" either = "1.9.0" diff --git a/rust/ares/src/jets.rs b/rust/ares/src/jets.rs index 9e57b4d8..2137a8f8 100644 --- a/rust/ares/src/jets.rs +++ b/rust/ares/src/jets.rs @@ -421,6 +421,14 @@ pub mod util { } } + pub fn assert_jet_size(context: &mut Context, jet: Jet, sam: Noun, siz: usize) { + let sam = T(&mut context.stack, &[D(0), sam, D(0)]); + let res = assert_no_alloc(|| jet(context, sam).unwrap()); + assert!(res.is_atom(), "jet result not atom"); + let res_siz = res.atom().unwrap().size(); + assert!(siz == res_siz, "got: {}, need: {}", res_siz, siz); + } + pub fn assert_common_jet( context: &mut Context, jet: Jet, @@ -452,6 +460,17 @@ pub mod util { let sam = T(&mut context.stack, &sam); assert_jet_err(context, jet, sam, err); } + + pub fn assert_common_jet_size( + context: &mut Context, + jet: Jet, + sam: &[fn(&mut NockStack) -> Noun], + siz: usize, + ) { + let sam: Vec = sam.iter().map(|f| f(&mut context.stack)).collect(); + let sam = T(&mut context.stack, &sam); + assert_jet_size(context, jet, sam, siz) + } } #[cfg(test)] diff --git a/rust/ares/src/jets/tree.rs b/rust/ares/src/jets/tree.rs index 55842284..d69be466 100644 --- a/rust/ares/src/jets/tree.rs +++ b/rust/ares/src/jets/tree.rs @@ -32,15 +32,14 @@ pub fn jet_mas(context: &mut Context, subject: Noun) -> Result { Err(JetErr::Fail(Error::Deterministic(D(0)))) } else { let out_bits = met - 1; - let out_words = (out_bits + 63) << 6; - let (mut indirect_out, out_bs) = unsafe { IndirectAtom::new_raw_mut_bitslice(stack, out_words) }; + let out_words = (out_bits + 63) >> 6; + let (mut indirect_out, out_bs) = + unsafe { IndirectAtom::new_raw_mut_bitslice(stack, out_words) }; out_bs.set(met - 2, true); // Set MSB if met > 2 { - out_bs[0..met - 2].copy_from_bitslice(&tom.as_bitslice()[0..met - 2]); + out_bs[0..(met - 2)].copy_from_bitslice(&tom.as_bitslice()[0..(met - 2)]); }; - unsafe { - Ok(indirect_out.normalize_as_atom().as_noun()) - } + unsafe { Ok(indirect_out.normalize_as_atom().as_noun()) } } } @@ -64,16 +63,15 @@ pub fn jet_peg(context: &mut Context, subject: Noun) -> Result { let b_bits = met(0, b); let out_bits = a_bits + b_bits - 1; - let out_words = (out_bits + 63) << 6; // bits to 8-byte words + let out_words = (out_bits + 63) >> 6; // bits to 8-byte words - let (mut indirect_out, out_bs) = unsafe { IndirectAtom::new_raw_mut_bitslice(stack, out_words) }; + let (mut indirect_out, out_bs) = + unsafe { IndirectAtom::new_raw_mut_bitslice(stack, out_words) }; out_bs[0..b_bits - 1].copy_from_bitslice(&b.as_bitslice()[0..b_bits - 1]); out_bs[b_bits - 1..out_bits].copy_from_bitslice(&a.as_bitslice()[0..a_bits]); - unsafe { - Ok(indirect_out.normalize_as_atom().as_noun()) - } + unsafe { Ok(indirect_out.normalize_as_atom().as_noun()) } } #[cfg(test)] @@ -102,10 +100,18 @@ mod tests { D(0x4000000000000000) } + fn atom_64(stack: &mut NockStack) -> Noun { + A(stack, &ubig!(_0x8000000000000000)) + } + fn atom_65(stack: &mut NockStack) -> Noun { A(stack, &ubig!(_0x10000000000000000)) } + fn atom_66(stack: &mut NockStack) -> Noun { + A(stack, &ubig!(_0x20000000000000000)) + } + fn pos_2(_stack: &mut NockStack) -> Noun { D(2) } @@ -137,10 +143,16 @@ mod tests { #[test] fn test_mas() { let c = &mut init_context(); + let a63 = atom_63(&mut c.stack); + let a64 = atom_64(&mut c.stack); + let a65 = atom_65(&mut c.stack); + let a66 = atom_66(&mut c.stack); + // Test invalid input assert_jet_err(c, jet_mas, D(0), JetErr::Fail(Error::Deterministic(D(0)))); assert_jet_err(c, jet_mas, D(1), JetErr::Fail(Error::Deterministic(D(0)))); + // Test direct assert_jet(c, jet_mas, D(2), D(1)); assert_jet(c, jet_mas, D(3), D(1)); assert_jet(c, jet_mas, D(4), D(2)); @@ -148,6 +160,16 @@ mod tests { assert_jet(c, jet_mas, D(6), D(2)); assert_jet(c, jet_mas, D(7), D(3)); assert_jet(c, jet_mas, D(8), D(4)); + + // Test indirect + assert_jet(c, jet_mas, a64, a63); + assert_jet(c, jet_mas, a65, a64); + assert_jet(c, jet_mas, a66, a65); + + // Test allocation + assert_jet_size(c, jet_mas, D(2), 1_usize); + assert_jet_size(c, jet_mas, a65, 1_usize); + assert_jet_size(c, jet_mas, a66, 2_usize); } #[test] @@ -184,5 +206,10 @@ mod tests { &[atom_65, atom_65], ubig!(_0x100000000000000000000000000000000), ); + + // Test allocation + assert_common_jet_size(c, jet_peg, &[atom_65, atom_1], 2_usize); + assert_common_jet_size(c, jet_peg, &[atom_1, atom_65], 2_usize); + assert_common_jet_size(c, jet_peg, &[atom_65, atom_65], 3_usize); } } From 3d65516be68e4e5432b718cd9b86a9c8b824ea9b Mon Sep 17 00:00:00 2001 From: Alex Shelkovnykov Date: Wed, 15 Nov 2023 11:41:06 +0100 Subject: [PATCH 11/11] jets: re-enable assert_no_alloc --- rust/ares/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/ares/Cargo.toml b/rust/ares/Cargo.toml index 22c28c3b..96ffd8b1 100644 --- a/rust/ares/Cargo.toml +++ b/rust/ares/Cargo.toml @@ -12,9 +12,9 @@ edition = "2018" # Please keep these alphabetized [dependencies] ares_macros = { path = "../ares_macros" } -# assert_no_alloc = "1.1.2" +assert_no_alloc = "1.1.2" # use this when debugging requires allocation (e.g. eprintln) -assert_no_alloc = {version="1.1.2", features=["warn_debug"]} +# assert_no_alloc = {version="1.1.2", features=["warn_debug"]} bitvec = "1.0.0" criterion = "0.4" either = "1.9.0"