[jets] add mul jet

This commit is contained in:
Philip Monk 2023-02-13 21:40:36 -07:00
parent 511370d592
commit f6e5b3898d
3 changed files with 37 additions and 5 deletions

View File

@ -30,6 +30,7 @@ pub fn get_jet(jet_name: Noun) -> Result<Jet, ()> {
tas!(b"dec") => Ok(jet_dec),
tas!(b"add") => Ok(jet_add),
tas!(b"sub") => Ok(jet_sub),
tas!(b"mul") => Ok(jet_mul),
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};
use crate::noun::{Atom, DirectAtom, IndirectAtom, Noun, DIRECT_MAX};
use either::Either::*;
pub fn jet_dec(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
@ -114,3 +114,33 @@ pub fn jet_sub(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
}
}
}
pub fn jet_mul(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)) => {
let res = a.data() as u128 * b.data() as u128;
if res < DIRECT_MAX as u128 {
Ok(Atom::new(stack, res as u64).as_noun())
} else {
Ok(unsafe {
IndirectAtom::new_raw_bytes(
stack,
if res < u64::MAX as u128 { 8 } else { 16 },
&res.to_le_bytes() as *const u8,
)
}
.as_noun())
}
}
(_, _) => {
let a_int = a.as_ubig();
let b_int = b.as_ubig();
let res = a_int * b_int;
Ok(Atom::from_ubig(stack, &res).as_noun())
}
}
}

View File

@ -1,10 +1,10 @@
use bitvec::prelude::{BitSlice, Lsb0};
use either::Either;
use ibig::UBig;
use intmap::IntMap;
use std::fmt;
use std::ptr;
use std::slice::{from_raw_parts, from_raw_parts_mut};
use ibig::UBig;
/** Tag for a direct atom. */
const DIRECT_TAG: u64 = 0x0;
@ -527,9 +527,10 @@ impl Atom {
let bit_size = big.bit_len();
let buffer = big.to_le_bytes();
if bit_size < 64 {
let value: u64 = if bit_size == 0 { 0 } else {
buffer[0] as u64
| if bit_size <= 8 { 0 } else { (buffer[1] as u64) << 8
#[rustfmt::skip]
let value: u64 =
if bit_size == 0 { 0 } else { (buffer[0] as u64)
| if bit_size <= 8 { 0 } else { (buffer[1] as u64) << 8
| if bit_size <= 16 { 0 } else { (buffer[2] as u64) << 16
| if bit_size <= 24 { 0 } else { (buffer[3] as u64) << 24
| if bit_size <= 32 { 0 } else { (buffer[4] as u64) << 32