From 593e386bc4b77d68798c64aaa06cf0babd502c60 Mon Sep 17 00:00:00 2001 From: Alex Shelkovnykov Date: Wed, 7 Feb 2024 22:56:38 +0900 Subject: [PATCH] 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 --- rust/ares/src/jets/hot.rs | 88 ++++++++++++ rust/ares/src/jets/list.rs | 99 ++++++++++++- rust/ares/src/jets/lock/sha.rs | 139 ++++++++++-------- rust/ares/src/jets/math.rs | 141 ++++++++++-------- rust/ares/src/jets/parse.rs | 253 +++++++++++++++++++++++++++++++-- rust/ares/src/serf.rs | 4 +- rust/ares_pma/c-src/btree.c | 2 +- 7 files changed, 597 insertions(+), 129 deletions(-) diff --git a/rust/ares/src/jets/hot.rs b/rust/ares/src/jets/hot.rs index 2cd5387..97bf5c7 100644 --- a/rust/ares/src/jets/hot.rs +++ b/rust/ares/src/jets/hot.rs @@ -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, diff --git a/rust/ares/src/jets/list.rs b/rust/ares/src/jets/list.rs index c281d35..bca2402 100644 --- a/rust/ares/src/jets/list.rs +++ b/rust/ares/src/jets/list.rs @@ -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 = 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}; diff --git a/rust/ares/src/jets/lock/sha.rs b/rust/ares/src/jets/lock/sha.rs index 60b057a..6133a89 100644 --- a/rust/ares/src/jets/lock/sha.rs +++ b/rust/ares/src/jets/lock/sha.rs @@ -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( diff --git a/rust/ares/src/jets/math.rs b/rust/ares/src/jets/math.rs index f7b03be..ba7a45b 100644 --- a/rust/ares/src/jets/math.rs +++ b/rust/ares/src/jets/math.rs @@ -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 diff --git a/rust/ares/src/jets/parse.rs b/rust/ares/src/jets/parse.rs index 0eb3c9b..a5a8da4 100644 --- a/rust/ares/src/jets/parse.rs +++ b/rust/ares/src/jets/parse.rs @@ -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 { + 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::()); + 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::(); + } + + 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) diff --git a/rust/ares/src/serf.rs b/rust/ares/src/serf.rs index b553771..ce942d3 100644 --- a/rust/ares/src/serf.rs +++ b/rust/ares/src/serf.rs @@ -143,7 +143,7 @@ impl Context { snapshot: Option, 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::::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") diff --git a/rust/ares_pma/c-src/btree.c b/rust/ares_pma/c-src/btree.c index eb15dd3..e8726da 100644 --- a/rust/ares_pma/c-src/btree.c +++ b/rust/ares_pma/c-src/btree.c @@ -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