mirror of
https://github.com/urbit/ares.git
synced 2024-11-22 15:08:54 +03:00
sha: various fixes
- make variable names consistent w/ their Hoon counterparts - fix slice copy bugs - add tests for cases that weren't caught until live testing - btree.c change to boot w/ slim.pill
This commit is contained in:
parent
dc657deb0b
commit
593e386bc4
@ -94,6 +94,11 @@ pub const URBIT_HOT_STATE: &[HotEntry] = &[
|
||||
1,
|
||||
jet_lent,
|
||||
),
|
||||
(
|
||||
&[K_139, Left(b"one"), Left(b"two"), Left(b"turn")],
|
||||
1,
|
||||
jet_turn,
|
||||
),
|
||||
(
|
||||
&[K_139, Left(b"one"), Left(b"two"), Left(b"zing")],
|
||||
1,
|
||||
@ -344,6 +349,19 @@ pub const URBIT_HOT_STATE: &[HotEntry] = &[
|
||||
jet_pfix,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"plug"),
|
||||
],
|
||||
1,
|
||||
jet_plug,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
@ -370,6 +388,34 @@ pub const URBIT_HOT_STATE: &[HotEntry] = &[
|
||||
jet_sfix,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"cold"),
|
||||
Left(b"fun"),
|
||||
],
|
||||
1,
|
||||
jet_cold,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"cook"),
|
||||
Left(b"fun"),
|
||||
],
|
||||
1,
|
||||
jet_cook,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
@ -426,6 +472,20 @@ pub const URBIT_HOT_STATE: &[HotEntry] = &[
|
||||
jet_mask,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"shim"),
|
||||
Left(b"fun"),
|
||||
],
|
||||
1,
|
||||
jet_shim,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
@ -440,6 +500,34 @@ pub const URBIT_HOT_STATE: &[HotEntry] = &[
|
||||
jet_stag,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"stew"),
|
||||
Left(b"fun"),
|
||||
],
|
||||
1,
|
||||
jet_stew,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"stir"),
|
||||
Left(b"fun"),
|
||||
],
|
||||
1,
|
||||
jet_stir,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
|
@ -1,9 +1,11 @@
|
||||
/** Text processing jets
|
||||
*/
|
||||
use crate::interpreter::Context;
|
||||
use crate::interpreter::{interpret, Context, Error};
|
||||
use crate::jets::util::slot;
|
||||
use crate::jets::Result;
|
||||
use crate::noun::{Noun, D};
|
||||
use crate::jets::{JetErr, Result};
|
||||
use crate::noun::{Cell, Noun, D, T};
|
||||
use bitvec::order::Lsb0;
|
||||
use bitvec::slice::BitSlice;
|
||||
|
||||
crate::gdb!();
|
||||
|
||||
@ -24,6 +26,97 @@ pub fn jet_zing(context: &mut Context, subject: Noun) -> Result {
|
||||
util::zing(stack, list)
|
||||
}
|
||||
|
||||
pub fn jet_turn(context: &mut Context, subject: Noun) -> Result {
|
||||
let sample = slot(subject, 6)?;
|
||||
let mut list = slot(sample, 2)?;
|
||||
let mut gate = slot(sample, 3)?;
|
||||
let mut gate_battery = slot(gate, 2)?;
|
||||
let gate_context = slot(gate, 7)?;
|
||||
let mut res = D(0);
|
||||
let mut dest: *mut Noun = &mut res; // Mutable pointer because we cannot guarantee initialized
|
||||
|
||||
// Since the gate doesn't change, we can do a single jet check and use that through the whole
|
||||
// loop
|
||||
if let Some((jet, _path)) = context
|
||||
.warm
|
||||
.find_jet(&mut context.stack, &mut gate, &mut gate_battery)
|
||||
.filter(|(_jet, mut path)| {
|
||||
// check that 7 is a prefix of the parent battery axis,
|
||||
// to ensure that the sample (axis 6) is not part of the jet match.
|
||||
//
|
||||
// XX TODO this check is pessimized since there could be multiple ways to match the
|
||||
// jet and we only actually match one of them, but we check all of them and run
|
||||
// unjetted if any have an axis outside 7.
|
||||
let axis_7_bits: &BitSlice<u64, Lsb0> = BitSlice::from_element(&7u64);
|
||||
let batteries_list = context.cold.find(&mut context.stack, &mut path);
|
||||
let mut ret = true;
|
||||
for mut batteries in batteries_list {
|
||||
if let Some((_battery, parent_axis)) = batteries.next() {
|
||||
let parent_axis_prefix_bits = &parent_axis.as_bitslice()[0..3];
|
||||
if parent_axis_prefix_bits == axis_7_bits {
|
||||
continue;
|
||||
} else {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret
|
||||
})
|
||||
{
|
||||
loop {
|
||||
if let Ok(list_cell) = list.as_cell() {
|
||||
list = list_cell.tail();
|
||||
let element_subject = T(
|
||||
&mut context.stack,
|
||||
&[gate_battery, list_cell.head(), gate_context],
|
||||
);
|
||||
unsafe {
|
||||
let (new_cell, new_mem) = Cell::new_raw_mut(&mut context.stack);
|
||||
(*new_mem).head = jet(context, element_subject)?;
|
||||
*dest = new_cell.as_noun();
|
||||
dest = &mut (*new_mem).tail;
|
||||
}
|
||||
} else {
|
||||
if unsafe { !list.raw_equals(D(0)) } {
|
||||
return Err(JetErr::Fail(Error::Deterministic(D(0))));
|
||||
}
|
||||
unsafe {
|
||||
*dest = D(0);
|
||||
};
|
||||
return Ok(res);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
loop {
|
||||
if let Ok(list_cell) = list.as_cell() {
|
||||
list = list_cell.tail();
|
||||
let element_subject = T(
|
||||
&mut context.stack,
|
||||
&[gate_battery, list_cell.head(), gate_context],
|
||||
);
|
||||
unsafe {
|
||||
let (new_cell, new_mem) = Cell::new_raw_mut(&mut context.stack);
|
||||
(*new_mem).head = interpret(context, element_subject, gate_battery)?;
|
||||
*dest = new_cell.as_noun();
|
||||
dest = &mut (*new_mem).tail;
|
||||
}
|
||||
} else {
|
||||
if unsafe { !list.raw_equals(D(0)) } {
|
||||
return Err(JetErr::Fail(Error::Deterministic(D(0))));
|
||||
}
|
||||
unsafe {
|
||||
*dest = D(0);
|
||||
};
|
||||
return Ok(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod util {
|
||||
use crate::interpreter::Error;
|
||||
use crate::jets::{JetErr, Result};
|
||||
|
@ -13,43 +13,42 @@ pub fn jet_shas(context: &mut Context, subject: Noun) -> Result {
|
||||
let sal = slot(sam, 2)?.as_atom()?;
|
||||
let ruz = slot(sam, 3)?.as_atom()?;
|
||||
|
||||
let sal_bytes = &(sal.as_bytes())[0..met(3, sal)]; // drop trailing zeros
|
||||
let (mut _salt_ida, salt) = unsafe { IndirectAtom::new_raw_mut_bytes(stack, sal_bytes.len()) };
|
||||
salt.copy_from_slice(sal_bytes);
|
||||
|
||||
unsafe {
|
||||
let (mut out_ida, out) = IndirectAtom::new_raw_mut_bytes(stack, 32);
|
||||
|
||||
let sal_bytes = &(sal.as_bytes())[0..met(3, sal)]; // drop trailing zeros
|
||||
let (mut _salt_ida, salt) = IndirectAtom::new_raw_mut_bytes(stack, sal_bytes.len());
|
||||
salt.copy_from_slice(sal_bytes);
|
||||
|
||||
let msg_len = met(3, ruz);
|
||||
if msg_len > 0 {
|
||||
let (_msg_ida, message) = IndirectAtom::new_raw_mut_bytes(stack, msg_len);
|
||||
message.copy_from_slice(&ruz.as_bytes()[0..msg_len]);
|
||||
ac_shas(message, salt, out);
|
||||
}
|
||||
else {
|
||||
let msg_bytes = &(ruz.as_bytes())[0..msg_len];
|
||||
let (_msg_ida, msg) = IndirectAtom::new_raw_mut_bytes(stack, msg_bytes.len());
|
||||
msg.copy_from_slice(&msg_bytes);
|
||||
ac_shas(msg, salt, out);
|
||||
} else {
|
||||
ac_shas(&mut [], salt, out);
|
||||
}
|
||||
|
||||
Ok(out_ida.normalize_as_atom().as_noun())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn jet_shax(context: &mut Context, subject: Noun) -> Result {
|
||||
let stack = &mut context.stack;
|
||||
let sam = slot(subject, 6)?;
|
||||
let msg = sam.as_atom()?;
|
||||
let len = met(3, msg);
|
||||
let ruz = sam.as_atom()?;
|
||||
let msg_len = met(3, ruz);
|
||||
|
||||
unsafe {
|
||||
let (mut ida, out) = IndirectAtom::new_raw_mut_bytes(stack, 32);
|
||||
|
||||
if len > 0 {
|
||||
let (mut _msg_ida, msg_copy) = IndirectAtom::new_raw_mut_bytes(stack, len);
|
||||
msg_copy.copy_from_slice(&msg.as_bytes()[0..len]);
|
||||
ac_shay(&mut (msg_copy)[0..len], out);
|
||||
}
|
||||
else {
|
||||
if msg_len > 0 {
|
||||
let msg_bytes = &(ruz.as_bytes())[0..msg_len];
|
||||
let (_msg_ida, msg) = IndirectAtom::new_raw_mut_bytes(stack, msg_bytes.len());
|
||||
msg.copy_from_slice(&msg_bytes);
|
||||
ac_shay(msg, out);
|
||||
} else {
|
||||
ac_shay(&mut [], out);
|
||||
}
|
||||
|
||||
@ -60,24 +59,30 @@ pub fn jet_shax(context: &mut Context, subject: Noun) -> Result {
|
||||
pub fn jet_shay(context: &mut Context, subject: Noun) -> Result {
|
||||
let stack = &mut context.stack;
|
||||
let sam = slot(subject, 6)?;
|
||||
let wid = slot(sam, 2)?.as_atom()?;
|
||||
let dat = slot(sam, 3)?.as_atom()?;
|
||||
let len = slot(sam, 2)?.as_atom()?;
|
||||
let ruz = slot(sam, 3)?.as_atom()?;
|
||||
|
||||
let width = match wid.as_direct() {
|
||||
let length = match len.as_direct() {
|
||||
Ok(direct) => direct.data() as usize,
|
||||
Err(_) => return Err(JetErr::Fail(Error::NonDeterministic(D(0)))),
|
||||
};
|
||||
let msg_len = met(3, ruz);
|
||||
|
||||
unsafe {
|
||||
let (mut out_ida, out) = IndirectAtom::new_raw_mut_bytes(stack, 32);
|
||||
if width > 0 {
|
||||
let (mut _msg_ida, msg) = IndirectAtom::new_raw_mut_bytes(stack, width);
|
||||
msg.copy_from_slice(&dat.as_bytes()[0..width]);
|
||||
if length == 0 {
|
||||
ac_shay(&mut [], out);
|
||||
} else if msg_len >= length {
|
||||
let (mut _msg_ida, msg) = IndirectAtom::new_raw_mut_bytes(stack, length);
|
||||
msg.copy_from_slice(&(ruz.as_bytes())[0..length]);
|
||||
ac_shay(msg, out);
|
||||
} else {
|
||||
let msg_bytes = &(ruz.as_bytes())[0..msg_len];
|
||||
let (mut _msg_ida, msg) = IndirectAtom::new_raw_mut_bytes(stack, length);
|
||||
msg[0..msg_len].copy_from_slice(&msg_bytes);
|
||||
ac_shay(msg, out);
|
||||
}
|
||||
else {
|
||||
ac_shay(&mut [], out);
|
||||
}
|
||||
|
||||
Ok(out_ida.normalize_as_atom().as_noun())
|
||||
}
|
||||
}
|
||||
@ -85,51 +90,61 @@ pub fn jet_shay(context: &mut Context, subject: Noun) -> Result {
|
||||
pub fn jet_shal(context: &mut Context, subject: Noun) -> Result {
|
||||
let stack = &mut context.stack;
|
||||
let sam = slot(subject, 6)?;
|
||||
let wid = slot(sam, 2)?.as_atom()?;
|
||||
let dat = slot(sam, 3)?.as_atom()?;
|
||||
let len = slot(sam, 2)?.as_atom()?;
|
||||
let ruz = slot(sam, 3)?.as_atom()?;
|
||||
|
||||
let width = match wid.as_direct() {
|
||||
let length = match len.as_direct() {
|
||||
Ok(direct) => direct.data() as usize,
|
||||
Err(_) => return Err(JetErr::Fail(Error::NonDeterministic(D(0)))),
|
||||
};
|
||||
|
||||
// let msg_len = met(3, dat);
|
||||
let msg_len = met(3, ruz);
|
||||
|
||||
unsafe {
|
||||
let msg_bytes = &(dat.as_bytes())[0..width];
|
||||
let (mut ida, out) = IndirectAtom::new_raw_mut_bytes(stack, 64);
|
||||
|
||||
if width > 0 {
|
||||
let (mut _msg_ida, msg) = IndirectAtom::new_raw_mut_bytes(stack, msg_bytes.len());
|
||||
msg.copy_from_slice(msg_bytes);
|
||||
let (mut out_ida, out) = IndirectAtom::new_raw_mut_bytes(stack, 64);
|
||||
if length == 0 {
|
||||
ac_shal(&mut [], out);
|
||||
} else if msg_len >= length {
|
||||
let (mut _msg_ida, msg) = IndirectAtom::new_raw_mut_bytes(stack, length);
|
||||
msg.copy_from_slice(&(ruz.as_bytes())[0..length]);
|
||||
ac_shal(msg, out);
|
||||
} else {
|
||||
let msg_bytes = &(ruz.as_bytes())[0..msg_len];
|
||||
let (mut _msg_ida, msg) = IndirectAtom::new_raw_mut_bytes(stack, length);
|
||||
msg[0..msg_len].copy_from_slice(&msg_bytes);
|
||||
ac_shal(msg, out);
|
||||
}
|
||||
else {
|
||||
ac_shal(&mut [], out);
|
||||
}
|
||||
|
||||
Ok(ida.normalize_as_atom().as_noun())
|
||||
Ok(out_ida.normalize_as_atom().as_noun())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jet_sha1(context: &mut Context, subject: Noun) -> Result {
|
||||
let stack = &mut context.stack;
|
||||
let sam = slot(subject, 6)?;
|
||||
let wid = slot(sam, 2)?.as_atom()?;
|
||||
let dat = slot(sam, 3)?.as_atom()?;
|
||||
let len = slot(sam, 2)?.as_atom()?;
|
||||
let ruz = slot(sam, 3)?.as_atom()?;
|
||||
|
||||
let width = match wid.as_direct() {
|
||||
let length = match len.as_direct() {
|
||||
Ok(direct) => direct.data() as usize,
|
||||
Err(_) => return Err(JetErr::Fail(Error::NonDeterministic(D(0)))),
|
||||
};
|
||||
let msg_len = met(3, ruz);
|
||||
|
||||
unsafe {
|
||||
let msg_bytes = &(dat.as_bytes())[0..width];
|
||||
let (mut _msg_ida, msg) = IndirectAtom::new_raw_mut_bytes(stack, msg_bytes.len());
|
||||
msg.copy_from_slice(msg_bytes);
|
||||
|
||||
let (mut out_ida, out) = IndirectAtom::new_raw_mut_bytes(stack, 20);
|
||||
ac_sha1(msg, out);
|
||||
if length == 0 {
|
||||
ac_sha1(&mut [], out);
|
||||
} else if msg_len >= length {
|
||||
let (mut _msg_ida, msg) = IndirectAtom::new_raw_mut_bytes(stack, length);
|
||||
msg.copy_from_slice(&(ruz.as_bytes())[0..length]);
|
||||
ac_sha1(msg, out);
|
||||
} else {
|
||||
let msg_bytes = &(ruz.as_bytes())[0..msg_len];
|
||||
let (mut _msg_ida, msg) = IndirectAtom::new_raw_mut_bytes(stack, length);
|
||||
msg[0..msg_len].copy_from_slice(&msg_bytes);
|
||||
ac_sha1(msg, out);
|
||||
}
|
||||
|
||||
Ok(out_ida.normalize_as_atom().as_noun())
|
||||
}
|
||||
}
|
||||
@ -311,20 +326,20 @@ mod tests {
|
||||
ubig!(_0x3eda27f97a3238a5817a4147bd31b9632fec7e87d21883ffb0f2855d3cd1d047cee96cd321a9f483dc15570b05e420d607806dd6502854f1bdb8ef7e35e183cf)
|
||||
);
|
||||
|
||||
let sam = T(&mut c.stack, &[D(1), D(1)]);
|
||||
let sam = T(&mut c.stack, &[D(1), D(0)]);
|
||||
assert_jet_ubig(
|
||||
c,
|
||||
jet_shal,
|
||||
sam,
|
||||
ubig!(_0x39e3d936c6e31eaac08fcfcfe7bb443460c61c0bd5b74408c8bcc35a6b8d6f5700bdcddeaa4b466ae65f8fb67f67ca62dc34149e1d44d213ddfbc13668b6547b)
|
||||
ubig!(_0xee1069e3f03884c3e5d457253423844a323c29eb4cde70630b58c3712a804a70221d35d9506e242c9414ff192e283dd6caa4eff86a457baf93d68189024d24b8)
|
||||
);
|
||||
|
||||
let sam = T(&mut c.stack, &[D(1), D(2)]);
|
||||
let sam = T(&mut c.stack, &[D(0), D(1)]);
|
||||
assert_jet_ubig(
|
||||
c,
|
||||
jet_shal,
|
||||
sam,
|
||||
ubig!(_0xcadc698fca01cf2935f760278554b4e61f35453975a5bb45389003159bc8485b7018dd8152d9cc23b6e9dd91b107380b9d14ddbf9cc037ee53a857b6c948b8fa)
|
||||
ubig!(_0x3eda27f97a3238a5817a4147bd31b9632fec7e87d21883ffb0f2855d3cd1d047cee96cd321a9f483dc15570b05e420d607806dd6502854f1bdb8ef7e35e183cf)
|
||||
);
|
||||
|
||||
let wid = A(
|
||||
@ -360,20 +375,28 @@ mod tests {
|
||||
fn test_sha1() {
|
||||
let c = &mut init_context();
|
||||
|
||||
let sam = T(&mut c.stack, &[D(1), D(1)]);
|
||||
let sam = T(&mut c.stack, &[D(0), D(0)]);
|
||||
assert_jet_ubig(
|
||||
c,
|
||||
jet_sha1,
|
||||
sam,
|
||||
ubig!(_0xbf8b4530d8d246dd74ac53a13471bba17941dff7),
|
||||
ubig!(_0xda39a3ee5e6b4b0d3255bfef95601890afd80709),
|
||||
);
|
||||
|
||||
let sam = T(&mut c.stack, &[D(1), D(2)]);
|
||||
let sam = T(&mut c.stack, &[D(1), D(0)]);
|
||||
assert_jet_ubig(
|
||||
c,
|
||||
jet_sha1,
|
||||
sam,
|
||||
ubig!(_0xc4ea21bb365bbeeaf5f2c654883e56d11e43c44e),
|
||||
ubig!(_0x5ba93c9db0cff93f52b521d7420e43f6eda2784f),
|
||||
);
|
||||
|
||||
let sam = T(&mut c.stack, &[D(0), D(1)]);
|
||||
assert_jet_ubig(
|
||||
c,
|
||||
jet_sha1,
|
||||
sam,
|
||||
ubig!(_0xda39a3ee5e6b4b0d3255bfef95601890afd80709),
|
||||
);
|
||||
|
||||
let wid = A(
|
||||
|
@ -15,7 +15,7 @@
|
||||
use crate::interpreter::{Context, Error};
|
||||
use crate::jets::util::*;
|
||||
use crate::jets::{JetErr, Result};
|
||||
use crate::noun::{Atom, DirectAtom, IndirectAtom, Noun, D, DIRECT_MAX, NO, T, YES};
|
||||
use crate::noun::{Atom, DirectAtom, IndirectAtom, Noun, D, DIRECT_MAX, T};
|
||||
use either::{Left, Right};
|
||||
use ibig::ops::DivRem;
|
||||
use ibig::UBig;
|
||||
@ -120,21 +120,7 @@ pub fn jet_gte(context: &mut Context, subject: Noun) -> Result {
|
||||
let a = slot(arg, 2)?.as_atom()?;
|
||||
let b = slot(arg, 3)?.as_atom()?;
|
||||
|
||||
Ok(if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
|
||||
if a.data() >= b.data() {
|
||||
YES
|
||||
} else {
|
||||
NO
|
||||
}
|
||||
} else if a.bit_size() > b.bit_size() {
|
||||
YES
|
||||
} else if a.bit_size() < b.bit_size() {
|
||||
NO
|
||||
} else if a.as_ubig(stack) >= b.as_ubig(stack) {
|
||||
YES
|
||||
} else {
|
||||
NO
|
||||
})
|
||||
Ok(util::gte(stack, a, b))
|
||||
}
|
||||
|
||||
pub fn jet_gth(context: &mut Context, subject: Noun) -> Result {
|
||||
@ -143,21 +129,7 @@ pub fn jet_gth(context: &mut Context, subject: Noun) -> Result {
|
||||
let a = slot(arg, 2)?.as_atom()?;
|
||||
let b = slot(arg, 3)?.as_atom()?;
|
||||
|
||||
Ok(if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
|
||||
if a.data() > b.data() {
|
||||
YES
|
||||
} else {
|
||||
NO
|
||||
}
|
||||
} else if a.bit_size() > b.bit_size() {
|
||||
YES
|
||||
} else if a.bit_size() < b.bit_size() {
|
||||
NO
|
||||
} else if a.as_ubig(stack) > b.as_ubig(stack) {
|
||||
YES
|
||||
} else {
|
||||
NO
|
||||
})
|
||||
Ok(util::gth(stack, a, b))
|
||||
}
|
||||
|
||||
pub fn jet_lte(context: &mut Context, subject: Noun) -> Result {
|
||||
@ -166,21 +138,7 @@ pub fn jet_lte(context: &mut Context, subject: Noun) -> Result {
|
||||
let a = slot(arg, 2)?.as_atom()?;
|
||||
let b = slot(arg, 3)?.as_atom()?;
|
||||
|
||||
Ok(if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
|
||||
if a.data() <= b.data() {
|
||||
YES
|
||||
} else {
|
||||
NO
|
||||
}
|
||||
} else if a.bit_size() < b.bit_size() {
|
||||
YES
|
||||
} else if a.bit_size() > b.bit_size() {
|
||||
NO
|
||||
} else if a.as_ubig(stack) <= b.as_ubig(stack) {
|
||||
YES
|
||||
} else {
|
||||
NO
|
||||
})
|
||||
Ok(util::lte(stack, a, b))
|
||||
}
|
||||
|
||||
pub fn jet_lth(context: &mut Context, subject: Noun) -> Result {
|
||||
@ -307,19 +265,88 @@ pub mod util {
|
||||
}
|
||||
}
|
||||
|
||||
/// Greater than or equal to (boolean)
|
||||
pub fn gte_b(stack: &mut NockStack, a: Atom, b: Atom) -> bool {
|
||||
if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
|
||||
a.data() >= b.data()
|
||||
} else if a.bit_size() > b.bit_size() {
|
||||
true
|
||||
} else if a.bit_size() < b.bit_size() {
|
||||
false
|
||||
} else {
|
||||
a.as_ubig(stack) >= b.as_ubig(stack)
|
||||
}
|
||||
}
|
||||
|
||||
/// Greater than or equal to
|
||||
pub fn gte(stack: &mut NockStack, a: Atom, b: Atom) -> Noun {
|
||||
if gte_b(stack, a, b) {
|
||||
YES
|
||||
} else {
|
||||
NO
|
||||
}
|
||||
}
|
||||
|
||||
/// Greater than (boolean)
|
||||
pub fn gth_b(stack: &mut NockStack, a: Atom, b: Atom) -> bool {
|
||||
if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
|
||||
a.data() > b.data()
|
||||
} else if a.bit_size() > b.bit_size() {
|
||||
true
|
||||
} else if a.bit_size() < b.bit_size() {
|
||||
false
|
||||
} else {
|
||||
a.as_ubig(stack) > b.as_ubig(stack)
|
||||
}
|
||||
}
|
||||
|
||||
/// Greater than
|
||||
pub fn gth(stack: &mut NockStack, a: Atom, b: Atom) -> Noun {
|
||||
if gth_b(stack, a, b) {
|
||||
YES
|
||||
} else {
|
||||
NO
|
||||
}
|
||||
}
|
||||
|
||||
/// Less than or equal to (boolean)
|
||||
pub fn lte_b(stack: &mut NockStack, a: Atom, b: Atom) -> bool {
|
||||
if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
|
||||
a.data() <= b.data()
|
||||
} else if a.bit_size() < b.bit_size() {
|
||||
true
|
||||
} else if a.bit_size() > b.bit_size() {
|
||||
false
|
||||
} else {
|
||||
a.as_ubig(stack) <= b.as_ubig(stack)
|
||||
}
|
||||
}
|
||||
|
||||
/// Less than or equal to
|
||||
pub fn lte(stack: &mut NockStack, a: Atom, b: Atom) -> Noun {
|
||||
if lte_b(stack, a, b) {
|
||||
YES
|
||||
} else {
|
||||
NO
|
||||
}
|
||||
}
|
||||
|
||||
/// Less than (boolean)
|
||||
pub fn lth_b(stack: &mut NockStack, a: Atom, b: Atom) -> bool {
|
||||
if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
|
||||
a.data() < b.data()
|
||||
} else if a.bit_size() > b.bit_size() {
|
||||
false
|
||||
} else if a.bit_size() < b.bit_size() {
|
||||
true
|
||||
} else {
|
||||
a.as_ubig(stack) < b.as_ubig(stack)
|
||||
}
|
||||
}
|
||||
|
||||
/// 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() {
|
||||
YES
|
||||
} else {
|
||||
NO
|
||||
}
|
||||
} else if a.bit_size() < b.bit_size() {
|
||||
YES
|
||||
} else if a.bit_size() > b.bit_size() {
|
||||
NO
|
||||
} else if a.as_ubig(stack) < b.as_ubig(stack) {
|
||||
if lth_b(stack, a, b) {
|
||||
YES
|
||||
} else {
|
||||
NO
|
||||
|
@ -1,9 +1,11 @@
|
||||
/** Parsing jets
|
||||
*/
|
||||
use crate::interpreter::Context;
|
||||
use crate::interpreter::{Context, Error};
|
||||
use crate::jets::math::util::{gte_b, lte_b, lth_b};
|
||||
use crate::jets::util::{kick, slam, slot};
|
||||
use crate::jets::Result;
|
||||
use crate::jets::{JetErr, Result};
|
||||
use crate::noun::{Noun, D, T};
|
||||
use either::{Left, Right};
|
||||
|
||||
crate::gdb!();
|
||||
|
||||
@ -177,6 +179,38 @@ pub fn jet_pfix(context: &mut Context, subject: Noun) -> Result {
|
||||
Ok(T(&mut context.stack, &[arg, q_yit]))
|
||||
}
|
||||
|
||||
pub fn jet_plug(context: &mut Context, subject: Noun) -> Result {
|
||||
let vex = slot(subject, 12)?.as_cell()?;
|
||||
let sab = slot(subject, 13)?;
|
||||
let p_vex = vex.head();
|
||||
let q_vex = vex.tail();
|
||||
|
||||
if unsafe { q_vex.raw_equals(D(0)) } {
|
||||
Ok(vex.as_noun())
|
||||
} else {
|
||||
let uq_vex = q_vex.as_cell()?.tail().as_cell()?;
|
||||
let puq_vex = uq_vex.head();
|
||||
let quq_vex = uq_vex.tail();
|
||||
|
||||
let yit = slam(context, sab, quq_vex)?.as_cell()?;
|
||||
let p_yit = yit.head();
|
||||
let q_yit = yit.tail();
|
||||
|
||||
let yur = util::last(p_vex, p_yit)?;
|
||||
|
||||
if unsafe { q_yit.raw_equals(D(0)) } {
|
||||
Ok(T(&mut context.stack, &[yur, D(0)]))
|
||||
} else {
|
||||
let uq_yit = q_yit.as_cell()?.tail().as_cell()?;
|
||||
let puq_yit = uq_yit.head();
|
||||
let quq_yit = uq_yit.tail();
|
||||
|
||||
let inner = T(&mut context.stack, &[puq_vex, puq_yit]);
|
||||
Ok(T(&mut context.stack, &[yur, D(0), inner, quq_yit]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jet_pose(context: &mut Context, subject: Noun) -> Result {
|
||||
let vex = slot(subject, 12)?.as_cell()?;
|
||||
let sab = slot(subject, 13)?;
|
||||
@ -229,6 +263,47 @@ pub fn jet_sfix(context: &mut Context, subject: Noun) -> Result {
|
||||
// Rule Builders
|
||||
//
|
||||
|
||||
pub fn jet_cold(context: &mut Context, subject: Noun) -> Result {
|
||||
let tub = slot(subject, 6)?;
|
||||
let van = slot(subject, 7)?;
|
||||
let cus = slot(van, 12)?;
|
||||
let sef = slot(van, 13)?;
|
||||
|
||||
let vex = slam(context, sef, tub)?.as_cell()?;
|
||||
let p_vex = vex.head();
|
||||
let q_vex = vex.tail();
|
||||
|
||||
if unsafe { q_vex.raw_equals(D(0)) } {
|
||||
Ok(vex.as_noun())
|
||||
} else {
|
||||
let quq_vex = q_vex.as_cell()?.tail().as_cell()?.tail();
|
||||
|
||||
Ok(T(&mut context.stack, &[p_vex, D(0), cus, quq_vex]))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jet_cook(context: &mut Context, subject: Noun) -> Result {
|
||||
let tub = slot(subject, 6)?;
|
||||
let van = slot(subject, 7)?;
|
||||
let poq = slot(van, 12)?;
|
||||
let sef = slot(van, 13)?;
|
||||
|
||||
let vex = slam(context, sef, tub)?.as_cell()?;
|
||||
let p_vex = vex.head();
|
||||
let q_vex = vex.tail();
|
||||
|
||||
if unsafe { q_vex.raw_equals(D(0)) } {
|
||||
Ok(vex.as_noun())
|
||||
} else {
|
||||
let uq_vex = q_vex.as_cell()?.tail().as_cell()?;
|
||||
let puq_vex = uq_vex.head();
|
||||
let quq_vex = uq_vex.tail();
|
||||
|
||||
let wag = slam(context, poq, puq_vex)?;
|
||||
Ok(T(&mut context.stack, &[p_vex, D(0), wag, quq_vex]))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jet_easy(context: &mut Context, subject: Noun) -> Result {
|
||||
let tub = slot(subject, 6)?;
|
||||
let van = slot(subject, 7)?;
|
||||
@ -307,6 +382,35 @@ pub fn jet_mask(context: &mut Context, subject: Noun) -> Result {
|
||||
util::fail(context, p_tub)
|
||||
}
|
||||
|
||||
pub fn jet_shim(context: &mut Context, subject: Noun) -> Result {
|
||||
let tub = slot(subject, 6)?.as_cell()?;
|
||||
let van = slot(subject, 7)?;
|
||||
let zep = slot(van, 6)?.as_cell()?;
|
||||
|
||||
let p_tub = tub.head();
|
||||
let q_tub = tub.tail();
|
||||
|
||||
if unsafe { q_tub.raw_equals(D(0)) } {
|
||||
util::fail(context, p_tub)
|
||||
} else {
|
||||
let p_zep = zep.head();
|
||||
let q_zep = zep.tail();
|
||||
let iq_tub = q_tub.as_cell()?.head();
|
||||
|
||||
if let (Some(p_zep_d), Some(q_zep_d), Some(iq_tub_d)) =
|
||||
(p_zep.direct(), q_zep.direct(), iq_tub.direct())
|
||||
{
|
||||
if (iq_tub_d.data() >= p_zep_d.data()) && (iq_tub_d.data() <= q_zep_d.data()) {
|
||||
util::next(context, tub.as_noun())
|
||||
} else {
|
||||
util::fail(context, p_tub)
|
||||
}
|
||||
} else {
|
||||
Err(JetErr::Fail(Error::NonDeterministic(D(0))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jet_stag(context: &mut Context, subject: Noun) -> Result {
|
||||
let tub = slot(subject, 6)?;
|
||||
let van = slot(subject, 7)?;
|
||||
@ -329,6 +433,139 @@ pub fn jet_stag(context: &mut Context, subject: Noun) -> Result {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jet_stew(context: &mut Context, subject: Noun) -> Result {
|
||||
let tub = slot(subject, 6)?.as_cell()?;
|
||||
let con = slot(subject, 7)?;
|
||||
let mut hel = slot(con, 2)?;
|
||||
|
||||
let p_tub = tub.head();
|
||||
let q_tub = tub.tail();
|
||||
if unsafe { q_tub.raw_equals(D(0)) } {
|
||||
return util::fail(context, p_tub);
|
||||
}
|
||||
|
||||
let iq_tub = q_tub.as_cell()?.head().as_atom()?;
|
||||
if !iq_tub.is_direct() {
|
||||
// Character cannot be encoded using 8 bytes = computibilty error
|
||||
return Err(JetErr::Fail(Error::NonDeterministic(D(0))));
|
||||
}
|
||||
|
||||
loop {
|
||||
if unsafe { hel.raw_equals(D(0)) } {
|
||||
return util::fail(context, p_tub);
|
||||
} else {
|
||||
let n_hel = slot(hel, 2)?.as_cell()?;
|
||||
let l_hel = slot(hel, 6)?;
|
||||
let r_hel = slot(hel, 7)?;
|
||||
let pn_hel = n_hel.head();
|
||||
let qn_hel = n_hel.tail();
|
||||
|
||||
let bit = match pn_hel.as_either_atom_cell() {
|
||||
Left(atom) => match atom.as_either() {
|
||||
Left(direct) => iq_tub.as_direct()?.data() == direct.data(),
|
||||
Right(_) => {
|
||||
// Character cannot be encoded using 8 bytes = computibilty error
|
||||
return Err(JetErr::Fail(Error::NonDeterministic(D(0))));
|
||||
}
|
||||
},
|
||||
Right(cell) => {
|
||||
let hpn_hel = cell.head().as_atom()?;
|
||||
let tpn_hel = cell.tail().as_atom()?;
|
||||
|
||||
match (hpn_hel.as_either(), tpn_hel.as_either()) {
|
||||
(Left(_), Left(_)) => {
|
||||
gte_b(&mut context.stack, iq_tub, hpn_hel)
|
||||
&& lte_b(&mut context.stack, iq_tub, tpn_hel)
|
||||
}
|
||||
_ => {
|
||||
// XX: Fixes jet mismatch in Vere
|
||||
// Character cannot be encoded using 8 bytes = computibilty error
|
||||
return Err(JetErr::Fail(Error::NonDeterministic(D(0))));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if bit {
|
||||
return slam(context, qn_hel, tub.as_noun());
|
||||
} else {
|
||||
let wor = match pn_hel.as_either_atom_cell() {
|
||||
Left(atom) => atom,
|
||||
Right(cell) => cell.head().as_atom()?,
|
||||
};
|
||||
|
||||
if lth_b(&mut context.stack, iq_tub, wor) {
|
||||
hel = l_hel;
|
||||
} else {
|
||||
hel = r_hel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// +$ edge [p=hair q=(unit [p=* q=nail])]
|
||||
#[derive(Copy, Clone)]
|
||||
struct StirPair {
|
||||
pub har: Noun, // p.edge
|
||||
pub res: Noun, // p.u.q.edge
|
||||
}
|
||||
|
||||
pub fn jet_stir(context: &mut Context, subject: Noun) -> Result {
|
||||
unsafe {
|
||||
context.with_stack_frame(0, |context| {
|
||||
let mut tub = slot(subject, 6)?;
|
||||
let van = slot(subject, 7)?;
|
||||
let rud = slot(van, 12)?;
|
||||
let raq = slot(van, 26)?;
|
||||
let fel = slot(van, 27)?;
|
||||
|
||||
// initial accumulator (deconstructed)
|
||||
let mut p_wag: Noun;
|
||||
let mut puq_wag: Noun;
|
||||
let quq_wag: Noun;
|
||||
|
||||
// push incremental, succesful [fel] parse results onto stack
|
||||
{
|
||||
let vex = slam(context, fel, tub)?.as_cell()?;
|
||||
let mut p_vex = vex.head();
|
||||
let mut q_vex = vex.tail();
|
||||
while !q_vex.raw_equals(D(0)) {
|
||||
let puq_vex = slot(q_vex, 6)?;
|
||||
let quq_vex = slot(q_vex, 7)?;
|
||||
|
||||
*(context.stack.push::<StirPair>()) = StirPair {
|
||||
har: p_vex,
|
||||
res: puq_vex,
|
||||
};
|
||||
|
||||
tub = quq_vex;
|
||||
|
||||
let vex = slam(context, fel, tub)?.as_cell()?;
|
||||
p_vex = vex.head();
|
||||
q_vex = vex.tail();
|
||||
}
|
||||
|
||||
p_wag = p_vex;
|
||||
puq_wag = rud;
|
||||
quq_wag = tub;
|
||||
}
|
||||
|
||||
// unwind the stack, folding parse results into [wag] by way of [raq]
|
||||
while !context.stack.stack_is_empty() {
|
||||
let par_u = *(context.stack.top::<StirPair>());
|
||||
p_wag = util::last(par_u.har, p_wag)?;
|
||||
let sam = T(&mut context.stack, &[par_u.res, puq_wag]);
|
||||
puq_wag = slam(context, raq, sam)?;
|
||||
context.stack.pop::<StirPair>();
|
||||
}
|
||||
|
||||
let res = T(&mut context.stack, &[p_wag, D(0), puq_wag, quq_wag]);
|
||||
Ok(res)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub mod util {
|
||||
use crate::interpreter::{inc, Context};
|
||||
use crate::jets::Result;
|
||||
@ -339,14 +576,14 @@ pub mod util {
|
||||
let zyl = zyc.as_cell()?;
|
||||
let nal = naz.as_cell()?;
|
||||
|
||||
let zyll = zyl.head().as_direct()?.data();
|
||||
let zylc = zyl.tail().as_direct()?.data();
|
||||
let nall = nal.head().as_direct()?.data();
|
||||
let nalc = nal.tail().as_direct()?.data();
|
||||
let p_zyc = zyl.head().as_direct()?.data();
|
||||
let q_zyc = zyl.tail().as_direct()?.data();
|
||||
let p_naz = nal.head().as_direct()?.data();
|
||||
let q_naz = nal.tail().as_direct()?.data();
|
||||
|
||||
match zyll.cmp(&nall) {
|
||||
match p_zyc.cmp(&p_naz) {
|
||||
Ordering::Equal => {
|
||||
if zylc > nalc {
|
||||
if q_zyc > q_naz {
|
||||
Ok(zyc)
|
||||
} else {
|
||||
Ok(naz)
|
||||
|
@ -143,7 +143,7 @@ impl Context {
|
||||
snapshot: Option<Snapshot>,
|
||||
constant_hot_state: &[HotEntry],
|
||||
) -> Self {
|
||||
let mut stack = NockStack::new(1024 << 10 << 10, 0);
|
||||
let mut stack = NockStack::new(4096 << 10 << 10, 0);
|
||||
let newt = Newt::new();
|
||||
let cache = Hamt::<Noun>::new(&mut stack);
|
||||
|
||||
@ -419,7 +419,7 @@ fn peek(context: &mut Context, ovo: Noun) -> Noun {
|
||||
}
|
||||
|
||||
fn goof(context: &mut Context, traces: Noun) -> Noun {
|
||||
let trace = zing(&mut context.nock_context.stack, traces).unwrap();
|
||||
let trace = zing(&mut context.nock_context.stack, traces).expect("serf: goof: zing failed");
|
||||
let tone = Cell::new(&mut context.nock_context.stack, D(2), trace);
|
||||
let tang = mook(&mut context.nock_context, tone, false)
|
||||
.expect("serf: goof: +mook crashed on bail")
|
||||
|
@ -122,7 +122,7 @@ off2addr(vaof_t off)
|
||||
#define BT_NUMMETAS 2 /* 2 metapages */
|
||||
#define BT_META_SECTION_WIDTH (BT_NUMMETAS * BT_PAGESIZE)
|
||||
#define BT_ADDRSIZE (BT_PAGESIZE << BT_PAGEWORD)
|
||||
#define PMA_GROW_SIZE_p (1024)
|
||||
#define PMA_GROW_SIZE_p (10000000)
|
||||
#define PMA_GROW_SIZE_b (BT_PAGESIZE * PMA_GROW_SIZE_p)
|
||||
|
||||
#define BT_NOPAGE 0
|
||||
|
Loading…
Reference in New Issue
Block a user