[jets] add rsh jet

This commit is contained in:
Philip Monk 2023-02-14 01:53:41 -07:00
parent 89e7d612f8
commit dec93b9ed8
2 changed files with 34 additions and 0 deletions

View File

@ -40,6 +40,7 @@ pub fn get_jet(jet_name: Noun) -> Result<Jet, ()> {
tas!(b"gte") => Ok(jet_gte), tas!(b"gte") => Ok(jet_gte),
tas!(b"bex") => Ok(jet_bex), tas!(b"bex") => Ok(jet_bex),
tas!(b"lsh") => Ok(jet_lsh), tas!(b"lsh") => Ok(jet_lsh),
tas!(b"rsh") => Ok(jet_rsh),
tas!(b"cut") => Ok(jet_cut), tas!(b"cut") => Ok(jet_cut),
tas!(b"mug") => Ok(jet_mug), tas!(b"mug") => Ok(jet_mug),
_ => { _ => {
@ -52,6 +53,7 @@ pub fn get_jet(jet_name: Noun) -> Result<Jet, ()> {
pub fn get_jet_test_mode(jet_name: Noun) -> bool { pub fn get_jet_test_mode(jet_name: Noun) -> bool {
match jet_name.as_direct().unwrap().data() { match jet_name.as_direct().unwrap().data() {
tas!(b"cut") => true, tas!(b"cut") => true,
tas!(b"rsh") => true,
_ => false, _ => false,
} }
} }

View File

@ -327,6 +327,7 @@ pub fn jet_lsh(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
let step = step.as_direct()?.data() as usize; let step = step.as_direct()?.data() as usize;
let a = raw_slot(arg, 3).as_atom()?; let a = raw_slot(arg, 3).as_atom()?;
// TODO: need to assert step << bloq doesn't overflow?
let len = met(bloq, a); let len = met(bloq, a);
let new_size = (a let new_size = (a
.bit_size() .bit_size()
@ -347,6 +348,37 @@ pub fn jet_lsh(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
} }
} }
pub fn jet_rsh(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
let arg = raw_slot(subject, 6);
let (bloq, step) = bite(raw_slot(arg, 2))?;
let bloq = bloq.as_direct()?.data() as usize;
if bloq >= 64 {
return Err(Deterministic);
}
let step = step.as_direct()?.data() as usize;
let a = raw_slot(arg, 3).as_atom()?;
let len = met(bloq, a);
if step >= len {
return Ok(D(0));
}
// TODO: need to assert step << bloq doesn't overflow?
let new_size = (a
.bit_size()
.checked_sub(step << bloq)
.ok_or(NonDeterministic)?
.checked_add(63)
.ok_or(NonDeterministic)?)
>> 6;
unsafe {
let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(stack, new_size);
chop(bloq, step, len - step, 0, dest, a.as_bitslice())?;
Ok(atom.normalize_as_atom().as_noun())
}
}
/** Extract the bloq and step from a bite */ /** Extract the bloq and step from a bite */
fn bite(a: Noun) -> Result<(Atom, Atom), ()> { fn bite(a: Noun) -> Result<(Atom, Atom), ()> {
if let Ok(cell) = a.as_cell() { if let Ok(cell) = a.as_cell() {