[ares] add sub jet

This commit is contained in:
Philip Monk 2023-02-13 21:11:29 -07:00
parent 4c1e742044
commit 511370d592
2 changed files with 33 additions and 11 deletions

View File

@ -2,7 +2,7 @@ use crate::interpreter::raw_slot;
use crate::jets_math::*;
use crate::mem::NockStack;
use crate::mug::mug;
use crate::noun::{Noun};
use crate::noun::Noun;
use ares_macros::tas;
/// Return Err if the computation crashed or should punt to Nock
@ -29,12 +29,13 @@ pub fn get_jet(jet_name: Noun) -> Result<Jet, ()> {
match jet_name.as_direct()?.data() {
tas!(b"dec") => Ok(jet_dec),
tas!(b"add") => Ok(jet_add),
tas!(b"sub") => Ok(jet_sub),
tas!(b"cut") => Ok(jet_cut),
tas!(b"mug") => Ok(jet_mug),
_ => {
// eprintln!("Unknown jet: {:?}", jet_name);
Err(())
},
}
}
}

View File

@ -12,7 +12,6 @@
* Another approach is use a global custom allocator. This is fairly involved, but it would allow
* us to use any library without worrying whether it allocates.
*/
use crate::interpreter::raw_slot;
use crate::jets::{JetErr, JetErr::*};
use crate::mem::NockStack;
@ -75,21 +74,43 @@ pub fn jet_cut(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
}
pub fn jet_add(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
eprintln!("\radd");
let arg = raw_slot(subject, 6);
let a = raw_slot(arg, 2).as_atom()?;
let b = raw_slot(arg, 3).as_atom()?;
let res = match (a.as_direct(), b.as_direct()) {
(Ok(a), Ok(b)) => {
Atom::new(stack, a.data() + b.data())
}
match (a.as_direct(), b.as_direct()) {
(Ok(a), Ok(b)) => Ok(Atom::new(stack, a.data() + b.data()).as_noun()),
(_, _) => {
let a_int = a.as_ubig();
let b_int = b.as_ubig();
let res = a_int + b_int;
Atom::from_ubig(stack, &res)
Ok(Atom::from_ubig(stack, &res).as_noun())
}
};
Ok(res.as_noun())
}
}
pub fn jet_sub(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()?;
match (a.as_direct(), b.as_direct()) {
(Ok(a), Ok(b)) => {
if a.data() < b.data() {
Err(Deterministic)
} else {
Ok(unsafe { DirectAtom::new_unchecked(a.data() - b.data()) }.as_noun())
}
}
(_, _) => {
let a_int = a.as_ubig();
let b_int = b.as_ubig();
if a_int < b_int {
Err(Deterministic)
} else {
let res = a_int - b_int;
Ok(Atom::from_ubig(stack, &res).as_noun())
}
}
}
}