mirror of
https://github.com/urbit/ares.git
synced 2024-11-26 09:57:56 +03:00
Merge branch 'status' into profile
This commit is contained in:
commit
33186d5789
@ -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"
|
||||
|
@ -49,15 +49,15 @@ pub enum JetErr {
|
||||
Fail(Error), // Error; do not retry
|
||||
}
|
||||
|
||||
impl From<noun::Error> for JetErr {
|
||||
fn from(_err: noun::Error) -> Self {
|
||||
Self::Fail(Error::Deterministic(D(0)))
|
||||
impl From<Error> for JetErr {
|
||||
fn from(err: Error) -> Self {
|
||||
Self::Fail(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Error> for JetErr {
|
||||
fn from(e: Error) -> Self {
|
||||
Self::Fail(e)
|
||||
impl From<noun::Error> for JetErr {
|
||||
fn from(_err: noun::Error) -> Self {
|
||||
Self::Fail(Error::Deterministic(D(0)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -343,6 +343,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,
|
||||
@ -374,5 +382,16 @@ 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<Noun> = sam.iter().map(|f| f(&mut context.stack)).collect();
|
||||
let sam = T(&mut context.stack, &sam);
|
||||
assert_jet_size(context, jet, sam, siz)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +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()?;
|
||||
|
||||
util::lsh(&mut context.stack, bloq, step, a).map(|a| a.as_noun())
|
||||
util::lsh(&mut context.stack, bloq, step, a)
|
||||
}
|
||||
|
||||
pub fn jet_met(_context: &mut Context, subject: Noun) -> Result {
|
||||
@ -306,13 +306,11 @@ pub fn jet_mix(context: &mut Context, subject: Noun) -> Result {
|
||||
}
|
||||
|
||||
pub mod util {
|
||||
use crate::jets;
|
||||
use crate::jets::util::*;
|
||||
use crate::jets::JetErr;
|
||||
use crate::jets::Result;
|
||||
use crate::mem::NockStack;
|
||||
use crate::noun::{Atom, Cell, DirectAtom, IndirectAtom, D, Noun};
|
||||
use std::cmp;
|
||||
use std::result;
|
||||
|
||||
/// Binary exponent
|
||||
pub fn bex(stack: &mut NockStack, arg: usize) -> Atom {
|
||||
@ -327,22 +325,17 @@ pub mod util {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lsh(
|
||||
stack: &mut NockStack,
|
||||
bloq: usize,
|
||||
step: usize,
|
||||
a: Atom,
|
||||
) -> result::Result<Atom, JetErr> {
|
||||
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()?);
|
||||
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(stack, new_size);
|
||||
chop(bloq, 0, len, step, dest, a.as_bitslice())?;
|
||||
Ok(atom.normalize_as_atom())
|
||||
Ok(atom.normalize_as_atom().as_noun())
|
||||
}
|
||||
}
|
||||
|
||||
@ -358,7 +351,7 @@ pub mod util {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rip(stack: &mut NockStack, bloq: usize, step: usize, atom: Atom) -> jets::Result {
|
||||
pub fn rip(stack: &mut NockStack, bloq: usize, step: usize, atom: Atom) -> Result {
|
||||
let len = (met(bloq, atom) + step - 1) / step;
|
||||
let mut list = D(0);
|
||||
for i in (0..len).rev() {
|
||||
|
@ -9,12 +9,12 @@ crate::gdb!();
|
||||
|
||||
pub fn jet_flop(context: &mut Context, subject: Noun) -> Result {
|
||||
let sam = slot(subject, 6)?;
|
||||
Ok(util::flop(&mut context.stack, sam)?)
|
||||
util::flop(&mut context.stack, sam)
|
||||
}
|
||||
|
||||
pub fn jet_lent(_context: &mut Context, subject: Noun) -> Result {
|
||||
let tape = slot(subject, 6)?;
|
||||
util::lent(tape).map(|x| D(x as u64))
|
||||
let list = slot(subject, 6)?;
|
||||
util::lent(list).map(|x| D(x as u64))
|
||||
}
|
||||
|
||||
pub fn jet_zing(context: &mut Context, subject: Noun) -> Result {
|
||||
@ -26,14 +26,13 @@ pub fn jet_zing(context: &mut Context, subject: Noun) -> Result {
|
||||
|
||||
pub mod util {
|
||||
use crate::interpreter::Error;
|
||||
use crate::jets;
|
||||
use crate::jets::JetErr;
|
||||
use crate::jets::{JetErr, Result};
|
||||
use crate::mem::NockStack;
|
||||
use crate::noun::{Cell, Noun, D, T};
|
||||
use std::result::Result;
|
||||
use std::result;
|
||||
|
||||
/// Reverse order of list
|
||||
pub fn flop(stack: &mut NockStack, noun: Noun) -> Result<Noun, Error> {
|
||||
pub fn flop(stack: &mut NockStack, noun: Noun) -> Result {
|
||||
let mut list = noun;
|
||||
let mut tsil = D(0);
|
||||
loop {
|
||||
@ -49,7 +48,7 @@ pub mod util {
|
||||
Ok(tsil)
|
||||
}
|
||||
|
||||
pub fn lent(tape: Noun) -> Result<usize, JetErr> {
|
||||
pub fn lent(tape: Noun) -> result::Result<usize, JetErr> {
|
||||
let mut len = 0usize;
|
||||
let mut list = tape;
|
||||
loop {
|
||||
@ -68,50 +67,29 @@ pub mod util {
|
||||
Ok(len)
|
||||
}
|
||||
|
||||
pub fn zing(stack: &mut NockStack, mut list: Noun) -> jets::Result {
|
||||
pub fn zing(stack: &mut NockStack, mut list: Noun) -> Result {
|
||||
unsafe {
|
||||
let (mut new_cell, mut new_memory) = Cell::new_raw_mut(stack);
|
||||
#[allow(unused_assignments)]
|
||||
let (mut cell, mut memory) = (new_cell, new_memory);
|
||||
let mut res: Noun = D(0);
|
||||
let mut flag = false;
|
||||
|
||||
loop {
|
||||
if list.raw_equals(D(0)) {
|
||||
break;
|
||||
}
|
||||
let mut dest = &mut res as *mut Noun;
|
||||
|
||||
while !list.raw_equals(D(0)) {
|
||||
let pair = list.as_cell()?;
|
||||
let mut sub_list = pair.head();
|
||||
|
||||
loop {
|
||||
if sub_list.raw_equals(D(0)) {
|
||||
break;
|
||||
}
|
||||
|
||||
let elem = sub_list.as_cell()?;
|
||||
let head = elem.head();
|
||||
|
||||
if flag {
|
||||
(new_cell, new_memory) = Cell::new_raw_mut(stack);
|
||||
(*memory).tail = new_cell.as_noun();
|
||||
memory = new_memory;
|
||||
} else {
|
||||
(cell, memory) = Cell::new_raw_mut(stack);
|
||||
res = cell.as_noun();
|
||||
flag = true;
|
||||
}
|
||||
(*memory).head = head;
|
||||
|
||||
sub_list = elem.tail();
|
||||
}
|
||||
|
||||
let mut sublist = pair.head();
|
||||
list = pair.tail();
|
||||
|
||||
while !sublist.raw_equals(D(0)) {
|
||||
let it = sublist.as_cell()?;
|
||||
let i = it.head();
|
||||
sublist = it.tail();
|
||||
|
||||
let (new_cell, new_memory) = Cell::new_raw_mut(stack);
|
||||
(*new_memory).head = i;
|
||||
*dest = new_cell.as_noun();
|
||||
dest = &mut (*new_memory).tail;
|
||||
}
|
||||
}
|
||||
|
||||
if flag {
|
||||
(*memory).tail = D(0);
|
||||
}
|
||||
*dest = D(0);
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
@ -307,6 +307,7 @@ pub mod util {
|
||||
}
|
||||
}
|
||||
|
||||
/// Less than
|
||||
pub fn lth(stack: &mut NockStack, a: Atom, b: Atom) -> Noun {
|
||||
if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
|
||||
if a.data() < b.data() {
|
||||
|
@ -1,18 +1,17 @@
|
||||
/** Tree jets
|
||||
*/
|
||||
use crate::interpreter::{Context, Error};
|
||||
use crate::jets::bits;
|
||||
use crate::jets::math;
|
||||
use crate::jets::util::slot;
|
||||
use crate::jets::bits::util::*;
|
||||
use crate::jets::util::*;
|
||||
use crate::jets::{JetErr, Result};
|
||||
use crate::noun::{Noun, D};
|
||||
use crate::noun::{IndirectAtom, Noun, D};
|
||||
|
||||
crate::gdb!();
|
||||
|
||||
pub fn jet_cap(_context: &mut Context, subject: Noun) -> Result {
|
||||
let arg = slot(subject, 6)?;
|
||||
let tom = arg.as_atom()?;
|
||||
let met = bits::util::met(0, tom);
|
||||
let met = met(0, tom);
|
||||
|
||||
unsafe {
|
||||
if met < 2 {
|
||||
@ -27,43 +26,53 @@ 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 met = bits::util::met(0, tom);
|
||||
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 = bits::util::bex(stack, met - 1);
|
||||
let d = bits::util::bex(stack, met - 2);
|
||||
let e = math::util::sub(stack, tom, c)?;
|
||||
|
||||
Ok(bits::util::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)) {
|
||||
return Err(JetErr::Fail(Error::Deterministic(D(0))));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
let c = bits::util::met(0, b.as_atom()?);
|
||||
let d = c - 1;
|
||||
let e = bits::util::lsh(stack, 0, d, D(1).as_atom()?)?;
|
||||
let f = math::util::sub(stack, b.as_atom()?, e)?;
|
||||
let g = bits::util::lsh(stack, 0, d, a.as_atom()?)?;
|
||||
Ok(math::util::add(stack, f, g).as_noun())
|
||||
if b.as_noun().raw_equals(D(0)) {
|
||||
return Err(JetErr::Fail(Error::Deterministic(D(0))));
|
||||
};
|
||||
}
|
||||
|
||||
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)]
|
||||
@ -92,10 +101,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)
|
||||
}
|
||||
@ -127,10 +144,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));
|
||||
@ -138,6 +161,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]
|
||||
@ -174,5 +207,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);
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ const FORWARDING_MASK: u64 = CELL_MASK;
|
||||
/** Loobeans */
|
||||
pub const YES: Noun = D(0);
|
||||
pub const NO: Noun = D(1);
|
||||
pub const NONE: Noun = unsafe { DirectAtom::new_unchecked(tas!(b"mormagic")).as_noun() };
|
||||
pub const NONE: Noun = unsafe { DirectAtom::new_unchecked(tas!(b"MORMAGIC")).as_noun() };
|
||||
|
||||
#[cfg(feature = "check_acyclic")]
|
||||
#[macro_export]
|
||||
|
Loading…
Reference in New Issue
Block a user