[jets] add lth jet

This commit is contained in:
Philip Monk 2023-02-13 22:36:34 -07:00
parent 8c1f2b668f
commit 3e7df76174
3 changed files with 53 additions and 1 deletions

View File

@ -34,6 +34,7 @@ pub fn get_jet(jet_name: Noun) -> Result<Jet, ()> {
tas!(b"div") => Ok(jet_div),
tas!(b"dvr") => Ok(jet_dvr),
tas!(b"mod") => Ok(jet_mod),
tas!(b"lth") => Ok(jet_lth),
tas!(b"cut") => Ok(jet_cut),
tas!(b"mug") => Ok(jet_mug),
_ => {

View File

@ -15,7 +15,7 @@
use crate::interpreter::raw_slot;
use crate::jets::{JetErr, JetErr::*};
use crate::mem::NockStack;
use crate::noun::{Atom, DirectAtom, IndirectAtom, Noun, D, DIRECT_MAX, T};
use crate::noun::{Atom, DirectAtom, IndirectAtom, Noun, D, DIRECT_MAX, NO, T, YES};
use either::Either::*;
use ibig::ops::DivRem;
@ -222,3 +222,32 @@ pub fn jet_mod(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
}
}
}
pub fn jet_lth(_stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
let arg = raw_slot(subject, 6);
let a = raw_slot(arg, 2).as_atom()?;
let b = raw_slot(arg, 3).as_atom()?;
Ok(match (a.as_direct(), b.as_direct()) {
(Ok(a), Ok(b)) => {
if a.data() < b.data() {
YES
} else {
NO
}
}
(_, _) => {
if a.bit_size() < b.bit_size() {
YES
} else if a.bit_size() > b.bit_size() {
NO
} else {
if a.as_ubig() < b.as_ubig() {
YES
} else {
NO
}
}
}
})
}

View File

@ -33,6 +33,10 @@ const FORWARDING_TAG: u64 = u64::MAX & CELL_MASK;
/** Tag mask for a forwarding pointer */
const FORWARDING_MASK: u64 = CELL_MASK;
/** Loobeans */
pub const YES: Noun = D(0);
pub const NO: Noun = D(1);
#[cfg(feature = "check_acyclic")]
#[macro_export]
macro_rules! assert_acyclic {
@ -128,6 +132,10 @@ impl DirectAtom {
DirectAtom(value)
}
pub fn bit_size(self) -> usize {
(64 - self.0.leading_zeros()) as usize
}
pub fn as_atom(self) -> Atom {
Atom { direct: self }
}
@ -299,6 +307,13 @@ impl IndirectAtom {
unsafe { *(self.to_raw_pointer().add(1)) as usize }
}
pub fn bit_size(&self) -> usize {
unsafe {
((self.size() - 1) << 6)
+ (*(self.to_raw_pointer().add(2 + self.size() - 1))).leading_zeros() as usize
}
}
/** Pointer to data for indirect atom */
pub fn data_pointer(&self) -> *const u64 {
unsafe { self.to_raw_pointer().add(2) as *const u64 }
@ -599,6 +614,13 @@ impl Atom {
}
}
pub fn bit_size(&self) -> usize {
match self.as_either() {
Either::Left(direct) => direct.bit_size(),
Either::Right(indirect) => indirect.bit_size(),
}
}
pub fn data_pointer(&self) -> *const u64 {
match self.as_either() {
Either::Left(_direct) => (self as *const Atom) as *const u64,