mirror of
https://github.com/urbit/ares.git
synced 2024-12-24 13:55:23 +03:00
Add +zing jet
This commit is contained in:
parent
15e0b5339f
commit
463cd31eaf
@ -8,14 +8,24 @@ use crate::noun::{Noun, D};
|
|||||||
crate::gdb!();
|
crate::gdb!();
|
||||||
|
|
||||||
pub fn jet_lent(_context: &mut Context, subject: Noun) -> Result {
|
pub fn jet_lent(_context: &mut Context, subject: Noun) -> Result {
|
||||||
let tape = slot(subject, 6)?;
|
let list = slot(subject, 6)?;
|
||||||
util::lent(tape).map(|x| D(x as u64))
|
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 {
|
pub mod util {
|
||||||
use crate::interpreter::Error;
|
use crate::interpreter::Error;
|
||||||
|
use crate::jets;
|
||||||
use crate::jets::JetErr;
|
use crate::jets::JetErr;
|
||||||
use crate::noun::{Noun, D};
|
use crate::mem::NockStack;
|
||||||
|
use crate::noun::{Noun, Cell, D};
|
||||||
|
use std::result::Result;
|
||||||
|
|
||||||
pub fn lent(tape: Noun) -> Result<usize, JetErr> {
|
pub fn lent(tape: Noun) -> Result<usize, JetErr> {
|
||||||
let mut len = 0usize;
|
let mut len = 0usize;
|
||||||
@ -35,6 +45,54 @@ pub mod util {
|
|||||||
}
|
}
|
||||||
Ok(len)
|
Ok(len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn zing(stack: &mut NockStack, mut list: Noun) -> jets::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 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
list = pair.tail();
|
||||||
|
}
|
||||||
|
|
||||||
|
if flag {
|
||||||
|
(*new_memory).tail = D(0);
|
||||||
|
}
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -58,4 +116,21 @@ mod tests {
|
|||||||
let sam = T(&mut c.stack, &[D(3), D(2), D(1)]);
|
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))));
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user