Merge pull request #119 from urbit/as/zing

Add jet for `+zing`
This commit is contained in:
Edward Amsden 2023-11-15 06:52:09 -06:00 committed by GitHub
commit c5ea3f04dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 63 additions and 14 deletions

View File

@ -9,23 +9,30 @@ 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 {
let list = slot(subject, 6)?;
let stack = &mut context.stack;
util::zing(stack, list)
}
pub mod util {
use crate::interpreter::Error;
use crate::jets::JetErr;
use crate::jets::{JetErr, Result};
use crate::mem::NockStack;
use crate::noun::{Noun, D, T};
use std::result::Result;
use crate::noun::{Cell, Noun, D, T};
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 {
@ -41,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 {
@ -59,6 +66,33 @@ pub mod util {
}
Ok(len)
}
pub fn zing(stack: &mut NockStack, mut list: Noun) -> Result {
unsafe {
let mut res: Noun = D(0);
let mut dest = &mut res as *mut Noun;
while !list.raw_equals(D(0)) {
let pair = list.as_cell()?;
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;
}
}
*dest = D(0);
Ok(res)
}
}
}
#[cfg(test)]
@ -119,4 +153,21 @@ mod tests {
let sam = T(&mut c.stack, &[D(3), D(2), D(1)]);
assert_jet_err(c, jet_lent, sam, JetErr::Fail(Error::Deterministic(D(0))));
}
#[test]
fn test_zing() {
let c = &mut init_context();
let list_0 = T(&mut c.stack, &[D(0), D(0), D(0), D(0)]);
let list_1 = T(&mut c.stack, &[D(1), D(2), D(3), D(0)]);
let list_2 = T(&mut c.stack, &[D(4), D(5), D(6), D(0)]);
let list_3 = T(&mut c.stack, &[D(1), D(2), D(3), D(4), D(5), D(6), D(0)]);
assert_jet(c, jet_zing, D(0), D(0));
assert_jet(c, jet_zing, list_0, D(0));
let sam = T(&mut c.stack, &[list_0, D(0)]);
assert_jet(c, jet_zing, sam, list_0);
let sam = T(&mut c.stack, &[list_1, list_2, D(0)]);
assert_jet(c, jet_zing, sam, list_3);
}
}

View File

@ -3,7 +3,7 @@ use crate::interpreter;
use crate::interpreter::{inc, interpret, Error};
use crate::jets::cold::Cold;
use crate::jets::hot::Hot;
use crate::jets::list::util::lent;
use crate::jets::list::util::*;
use crate::jets::nock::util::mook;
use crate::jets::warm::Warm;
use crate::mem::NockStack;
@ -263,11 +263,9 @@ fn slam(context: &mut Context, axis: u64, ovo: Noun) -> Result<Noun, Error> {
interpret(&mut context.nock_context, sub, fol)
}
fn goof(context: &mut Context, trace: Noun) -> Noun {
// XX: trace is a $tang with at least one $tank, which we pick off the top.
// Actual input to +mook should be (roll trace weld) ( or (zing trace)).
let head = trace.cell().unwrap().head();
let tone = Cell::new(&mut context.nock_context.stack, D(2), head);
fn goof(context: &mut Context, traces: Noun) -> Noun {
let trace = zing(&mut context.nock_context.stack, traces).unwrap();
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")
.tail();