mirror of
https://github.com/urbit/ares.git
synced 2024-11-22 06:32:47 +03:00
jets: mink jet compiles and passes trivial tests
This commit is contained in:
parent
fbb24d170c
commit
ad357352ac
@ -4,7 +4,7 @@ use crate::jets;
|
|||||||
use crate::mem::unifying_equality;
|
use crate::mem::unifying_equality;
|
||||||
use crate::mem::NockStack;
|
use crate::mem::NockStack;
|
||||||
use crate::newt::Newt;
|
use crate::newt::Newt;
|
||||||
use crate::noun::{Atom, Cell, DirectAtom, IndirectAtom, Noun};
|
use crate::noun::{Atom, Cell, DirectAtom, IndirectAtom, Noun, D};
|
||||||
use ares_macros::tas;
|
use ares_macros::tas;
|
||||||
use assert_no_alloc::assert_no_alloc;
|
use assert_no_alloc::assert_no_alloc;
|
||||||
use bitvec::prelude::{BitSlice, Lsb0};
|
use bitvec::prelude::{BitSlice, Lsb0};
|
||||||
@ -69,16 +69,25 @@ fn noun_to_work(noun: Noun) -> NockWork {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum NockErr {
|
pub enum NockErr {
|
||||||
Blocked(Noun),
|
Blocked(Noun),
|
||||||
Error(Noun),
|
Error(Noun),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn early_exit(stack: &mut NockStack, virtual_frame: *u64, cache: &mut Hamt::<Noun>::new()) {
|
impl From<NockErr> for () {
|
||||||
while stack.frame_pointer() != virtual_frame {
|
fn from(_: NockErr) -> Self {
|
||||||
// TODO: also preserve trace
|
()
|
||||||
stack.preserve(&mut cache);
|
}
|
||||||
stack.pop();
|
}
|
||||||
|
|
||||||
|
pub fn early_exit(stack: &mut NockStack, virtual_frame: *const u64, cache: &mut Hamt<Noun>) {
|
||||||
|
unsafe {
|
||||||
|
while stack.frame_pointer() != virtual_frame {
|
||||||
|
// TODO: also preserve trace
|
||||||
|
stack.preserve(cache);
|
||||||
|
stack.pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +98,7 @@ pub fn interpret(
|
|||||||
mut subject: Noun,
|
mut subject: Noun,
|
||||||
formula: Noun,
|
formula: Noun,
|
||||||
) -> Result<Noun, NockErr> {
|
) -> Result<Noun, NockErr> {
|
||||||
let mut res = unsafe { D(0) };
|
let mut res = D(0);
|
||||||
let virtual_frame = stack.frame_pointer(); // before or after the push?
|
let virtual_frame = stack.frame_pointer(); // before or after the push?
|
||||||
stack.push(1);
|
stack.push(1);
|
||||||
let mut cache = Hamt::<Noun>::new();
|
let mut cache = Hamt::<Noun>::new();
|
||||||
@ -97,15 +106,14 @@ pub fn interpret(
|
|||||||
*(stack.local_noun_pointer(0)) = work_to_noun(Done);
|
*(stack.local_noun_pointer(0)) = work_to_noun(Done);
|
||||||
}
|
}
|
||||||
push_formula(stack, formula)?;
|
push_formula(stack, formula)?;
|
||||||
let tone =
|
let tone = assert_no_alloc(|| unsafe {
|
||||||
assert_no_alloc(|| unsafe {
|
|
||||||
loop {
|
loop {
|
||||||
match noun_to_work(*(stack.local_noun_pointer(0))) {
|
match noun_to_work(*(stack.local_noun_pointer(0))) {
|
||||||
Done => {
|
Done => {
|
||||||
stack.preserve(&mut cache);
|
stack.preserve(&mut cache);
|
||||||
stack.preserve(&mut res);
|
stack.preserve(&mut res);
|
||||||
stack.pop();
|
stack.pop();
|
||||||
break;
|
break Ok(res);
|
||||||
}
|
}
|
||||||
NockCellComputeHead => {
|
NockCellComputeHead => {
|
||||||
*stack.local_noun_pointer(0) = work_to_noun(NockCellComputeTail);
|
*stack.local_noun_pointer(0) = work_to_noun(NockCellComputeTail);
|
||||||
@ -127,15 +135,16 @@ pub fn interpret(
|
|||||||
}
|
}
|
||||||
Nock0Axis => {
|
Nock0Axis => {
|
||||||
if let Ok(atom) = (*(stack.local_noun_pointer(1))).as_atom() {
|
if let Ok(atom) = (*(stack.local_noun_pointer(1))).as_atom() {
|
||||||
if let Ok(res) = slot(subject, atom.as_bitslice()) {
|
if let Ok(x) = slot(subject, atom.as_bitslice()) {
|
||||||
|
res = x;
|
||||||
stack.preserve(&mut cache);
|
stack.preserve(&mut cache);
|
||||||
stack.preserve(&mut res);
|
stack.preserve(&mut res);
|
||||||
stack.pop();
|
stack.pop();
|
||||||
} else {
|
} else {
|
||||||
return Err(Error(D(1));
|
break Err(NockErr::Error(D(1)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(Error(D(0))); // Axis must be atom
|
break Err(NockErr::Error(D(0))); // Axis must be atom
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Nock1Constant => {
|
Nock1Constant => {
|
||||||
@ -194,7 +203,7 @@ pub fn interpret(
|
|||||||
stack.preserve(&mut res);
|
stack.preserve(&mut res);
|
||||||
stack.pop();
|
stack.pop();
|
||||||
} else {
|
} else {
|
||||||
return Err(Error(D(2))); // Cannot increment (Nock 4) a cell
|
break Err(NockErr::Error(D(2))); // Cannot increment (Nock 4) a cell
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Nock5ComputeLeftChild => {
|
Nock5ComputeLeftChild => {
|
||||||
@ -234,10 +243,10 @@ pub fn interpret(
|
|||||||
let formula = *stack.local_noun_pointer(3);
|
let formula = *stack.local_noun_pointer(3);
|
||||||
push_formula(stack, formula)?;
|
push_formula(stack, formula)?;
|
||||||
} else {
|
} else {
|
||||||
return Err(Error(D(3))); // Test branch of Nock 6 must return 0 or 1
|
break Err(NockErr::Error(D(3))); // Test branch of Nock 6 must return 0 or 1
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return Err(Error(D(4))); // Test branch of Nock 6 must return a direct atom
|
break Err(NockErr::Error(D(4))); // Test branch of Nock 6 must return a direct atom
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Nock6Done => {
|
Nock6Done => {
|
||||||
@ -291,9 +300,14 @@ pub fn interpret(
|
|||||||
*(stack.local_noun_pointer(0)) = work_to_noun(Nock9RestoreSubject);
|
*(stack.local_noun_pointer(0)) = work_to_noun(Nock9RestoreSubject);
|
||||||
*(stack.local_noun_pointer(2)) = subject;
|
*(stack.local_noun_pointer(2)) = subject;
|
||||||
subject = res;
|
subject = res;
|
||||||
push_formula(stack, slot(subject, formula_axis.as_bitslice()))?;
|
let axis = if let Ok(x) = slot(subject, formula_axis.as_bitslice()) {
|
||||||
|
x
|
||||||
|
} else {
|
||||||
|
break Err(NockErr::Error(D(55))); // Axis must be in subject
|
||||||
|
};
|
||||||
|
push_formula(stack, axis)?;
|
||||||
} else {
|
} else {
|
||||||
return Err(Error(D(5))); // Axis into core must be atom
|
break Err(NockErr::Error(D(5))); // Axis into core must be atom
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Nock9RestoreSubject => {
|
Nock9RestoreSubject => {
|
||||||
@ -321,7 +335,7 @@ pub fn interpret(
|
|||||||
stack.preserve(&mut res);
|
stack.preserve(&mut res);
|
||||||
stack.pop();
|
stack.pop();
|
||||||
} else {
|
} else {
|
||||||
return Err(Error(D(6))); // Axis into tree must be atom
|
break Err(NockErr::Error(D(6))); // Axis into tree must be atom
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Nock11ComputeHint => {
|
Nock11ComputeHint => {
|
||||||
@ -371,12 +385,12 @@ pub fn interpret(
|
|||||||
Ok(res) => Ok(res),
|
Ok(res) => Ok(res),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
early_exit(stack, virtual_frame, &mut cache);
|
early_exit(stack, virtual_frame, &mut cache);
|
||||||
Err(err);
|
Err(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_formula(stack: &mut NockStack, formula: Noun) -> Result((), NockErr) {
|
fn push_formula(stack: &mut NockStack, formula: Noun) -> Result<(), NockErr> {
|
||||||
if let Ok(formula_cell) = formula.as_cell() {
|
if let Ok(formula_cell) = formula.as_cell() {
|
||||||
// Formula
|
// Formula
|
||||||
match formula_cell.head().as_either_atom_cell() {
|
match formula_cell.head().as_either_atom_cell() {
|
||||||
@ -546,7 +560,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun) -> Result((), NockErr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(Error(D(10))); // Bad formula: atoms are not formulas: {}
|
return Err(NockErr::Error(D(10))); // Bad formula: atoms are not formulas: {}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -558,9 +572,9 @@ pub fn raw_slot(noun: Noun, axis: u64) -> Noun {
|
|||||||
|
|
||||||
pub fn slot(mut noun: Noun, axis: &BitSlice<u64, Lsb0>) -> Result<Noun, ()> {
|
pub fn slot(mut noun: Noun, axis: &BitSlice<u64, Lsb0>) -> Result<Noun, ()> {
|
||||||
let mut cursor = if let Some(x) = axis.last_one() {
|
let mut cursor = if let Some(x) = axis.last_one() {
|
||||||
Ok(x)
|
x
|
||||||
} else {
|
} else {
|
||||||
Err(()) // 0 is not allowed as an axis
|
return Err(()); // 0 is not allowed as an axis
|
||||||
};
|
};
|
||||||
loop {
|
loop {
|
||||||
if cursor == 0 {
|
if cursor == 0 {
|
||||||
@ -574,7 +588,7 @@ pub fn slot(mut noun: Noun, axis: &BitSlice<u64, Lsb0>) -> Result<Noun, ()> {
|
|||||||
noun = cell.head();
|
noun = cell.head();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(()) // Axis tried to descend through atom: {}
|
return Err(()); // Axis tried to descend through atom: {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Ok(noun)
|
Ok(noun)
|
||||||
@ -667,10 +681,12 @@ fn match_pre_hint(
|
|||||||
let jet_name = jet_formula.tail();
|
let jet_name = jet_formula.tail();
|
||||||
|
|
||||||
let jet = jets::get_jet(jet_name).ok_or(())?;
|
let jet = jets::get_jet(jet_name).ok_or(())?;
|
||||||
if let Ok(mut jet_res) = jet(stack, subject) {
|
if let Ok(mut jet_res) = jet(stack, newt, subject) {
|
||||||
// if in test mode, check that the jet returns the same result as the raw nock
|
// if in test mode, check that the jet returns the same result as the raw nock
|
||||||
if jets::get_jet_test_mode(jet_name) {
|
if jets::get_jet_test_mode(jet_name) {
|
||||||
let mut nock_res = interpret(stack, newt, subject, formula);
|
// Throw away trace because we'll regenerate it later, and this is in test mode
|
||||||
|
// so it's okay if it runs twice
|
||||||
|
let mut nock_res = interpret(stack, newt, subject, formula)?;
|
||||||
if unsafe { !unifying_equality(stack, &mut nock_res, &mut jet_res) } {
|
if unsafe { !unifying_equality(stack, &mut nock_res, &mut jet_res) } {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"\rJet {} failed, raw: {}, jetted: {}",
|
"\rJet {} failed, raw: {}, jetted: {}",
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
pub mod math;
|
pub mod math;
|
||||||
|
pub mod mink;
|
||||||
|
|
||||||
use crate::jets::math::*;
|
use crate::jets::math::*;
|
||||||
use crate::jets::virtual::*;
|
use crate::jets::mink::*;
|
||||||
use crate::mem::NockStack;
|
use crate::mem::NockStack;
|
||||||
|
use crate::newt::Newt;
|
||||||
use crate::noun::{self, Noun};
|
use crate::noun::{self, Noun};
|
||||||
use ares_macros::tas;
|
use ares_macros::tas;
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ use crate::interpreter::raw_slot;
|
|||||||
use crate::jets::{JetErr, JetErr::*};
|
use crate::jets::{JetErr, JetErr::*};
|
||||||
use crate::mem::NockStack;
|
use crate::mem::NockStack;
|
||||||
use crate::mug::mug;
|
use crate::mug::mug;
|
||||||
|
use crate::newt::Newt;
|
||||||
use crate::noun::{Atom, Cell, DirectAtom, IndirectAtom, Noun, D, DIRECT_MAX, NO, T, YES};
|
use crate::noun::{Atom, Cell, DirectAtom, IndirectAtom, Noun, D, DIRECT_MAX, NO, T, YES};
|
||||||
use bitvec::prelude::{BitSlice, Lsb0};
|
use bitvec::prelude::{BitSlice, Lsb0};
|
||||||
use either::Either::*;
|
use either::Either::*;
|
||||||
@ -25,7 +26,11 @@ use std::{cmp, convert::TryFrom};
|
|||||||
|
|
||||||
crate::gdb!();
|
crate::gdb!();
|
||||||
|
|
||||||
pub fn jet_dec(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_dec(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
if let Ok(atom) = arg.as_atom() {
|
if let Ok(atom) = arg.as_atom() {
|
||||||
match atom.as_either() {
|
match atom.as_either() {
|
||||||
@ -62,7 +67,11 @@ pub fn jet_dec(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_add(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_add(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let a = raw_slot(arg, 2).as_atom()?;
|
let a = raw_slot(arg, 2).as_atom()?;
|
||||||
let b = raw_slot(arg, 3).as_atom()?;
|
let b = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -77,7 +86,11 @@ pub fn jet_add(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_sub(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_sub(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let a = raw_slot(arg, 2).as_atom()?;
|
let a = raw_slot(arg, 2).as_atom()?;
|
||||||
let b = raw_slot(arg, 3).as_atom()?;
|
let b = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -102,7 +115,11 @@ pub fn jet_sub(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_mul(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_mul(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let a = raw_slot(arg, 2).as_atom()?;
|
let a = raw_slot(arg, 2).as_atom()?;
|
||||||
let b = raw_slot(arg, 3).as_atom()?;
|
let b = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -129,7 +146,11 @@ pub fn jet_mul(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_div(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_div(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let a = raw_slot(arg, 2).as_atom()?;
|
let a = raw_slot(arg, 2).as_atom()?;
|
||||||
let b = raw_slot(arg, 3).as_atom()?;
|
let b = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -146,7 +167,11 @@ pub fn jet_div(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_mod(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_mod(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let a = raw_slot(arg, 2).as_atom()?;
|
let a = raw_slot(arg, 2).as_atom()?;
|
||||||
let b = raw_slot(arg, 3).as_atom()?;
|
let b = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -161,7 +186,11 @@ pub fn jet_mod(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_dvr(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_dvr(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let a = raw_slot(arg, 2).as_atom()?;
|
let a = raw_slot(arg, 2).as_atom()?;
|
||||||
let b = raw_slot(arg, 3).as_atom()?;
|
let b = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -189,7 +218,11 @@ pub fn jet_dvr(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_lth(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_lth(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let a = raw_slot(arg, 2).as_atom()?;
|
let a = raw_slot(arg, 2).as_atom()?;
|
||||||
let b = raw_slot(arg, 3).as_atom()?;
|
let b = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -211,7 +244,11 @@ pub fn jet_lth(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_lte(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_lte(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let a = raw_slot(arg, 2).as_atom()?;
|
let a = raw_slot(arg, 2).as_atom()?;
|
||||||
let b = raw_slot(arg, 3).as_atom()?;
|
let b = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -233,7 +270,11 @@ pub fn jet_lte(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_gth(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_gth(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let a = raw_slot(arg, 2).as_atom()?;
|
let a = raw_slot(arg, 2).as_atom()?;
|
||||||
let b = raw_slot(arg, 3).as_atom()?;
|
let b = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -255,7 +296,11 @@ pub fn jet_gth(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_gte(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_gte(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let a = raw_slot(arg, 2).as_atom()?;
|
let a = raw_slot(arg, 2).as_atom()?;
|
||||||
let b = raw_slot(arg, 3).as_atom()?;
|
let b = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -277,7 +322,11 @@ pub fn jet_gte(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_bex(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_bex(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6).as_direct()?.data() as usize;
|
let arg = raw_slot(subject, 6).as_direct()?.data() as usize;
|
||||||
|
|
||||||
if arg < 63 {
|
if arg < 63 {
|
||||||
@ -291,7 +340,11 @@ pub fn jet_bex(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_lsh(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_lsh(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let (bloq, step) = bite(raw_slot(arg, 2))?;
|
let (bloq, step) = bite(raw_slot(arg, 2))?;
|
||||||
let a = raw_slot(arg, 3).as_atom()?;
|
let a = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -317,7 +370,11 @@ pub fn jet_lsh(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_rsh(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_rsh(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let (bloq, step) = bite(raw_slot(arg, 2))?;
|
let (bloq, step) = bite(raw_slot(arg, 2))?;
|
||||||
let a = raw_slot(arg, 3).as_atom()?;
|
let a = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -343,7 +400,11 @@ pub fn jet_rsh(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_con(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_con(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let a = raw_slot(arg, 2).as_atom()?;
|
let a = raw_slot(arg, 2).as_atom()?;
|
||||||
let b = raw_slot(arg, 3).as_atom()?;
|
let b = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -359,7 +420,11 @@ pub fn jet_con(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_dis(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_dis(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let a = raw_slot(arg, 2).as_atom()?;
|
let a = raw_slot(arg, 2).as_atom()?;
|
||||||
let b = raw_slot(arg, 3).as_atom()?;
|
let b = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -375,7 +440,11 @@ pub fn jet_dis(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_mix(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_mix(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let a = raw_slot(arg, 2).as_atom()?;
|
let a = raw_slot(arg, 2).as_atom()?;
|
||||||
let b = raw_slot(arg, 3).as_atom()?;
|
let b = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -391,7 +460,11 @@ pub fn jet_mix(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_end(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_end(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let (bloq, step) = bite(raw_slot(arg, 2))?;
|
let (bloq, step) = bite(raw_slot(arg, 2))?;
|
||||||
let a = raw_slot(arg, 3).as_atom()?;
|
let a = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -416,7 +489,11 @@ pub fn jet_end(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_cat(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_cat(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let bloq = raw_slot(arg, 2).as_direct()?.data() as usize;
|
let bloq = raw_slot(arg, 2).as_direct()?.data() as usize;
|
||||||
if bloq >= 64 {
|
if bloq >= 64 {
|
||||||
@ -440,7 +517,11 @@ pub fn jet_cat(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_can(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_can(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let bloq = raw_slot(arg, 2).as_direct()?.data() as usize;
|
let bloq = raw_slot(arg, 2).as_direct()?.data() as usize;
|
||||||
if bloq >= 64 {
|
if bloq >= 64 {
|
||||||
@ -490,7 +571,11 @@ pub fn jet_can(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_rep(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_rep(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let (bloq, step) = bite(raw_slot(arg, 2))?;
|
let (bloq, step) = bite(raw_slot(arg, 2))?;
|
||||||
let original_list = raw_slot(arg, 3);
|
let original_list = raw_slot(arg, 3);
|
||||||
@ -533,7 +618,11 @@ pub fn jet_rep(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_cut(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_cut(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let bloq = raw_slot(arg, 2).as_direct()?.data() as usize;
|
let bloq = raw_slot(arg, 2).as_direct()?.data() as usize;
|
||||||
if bloq >= 64 {
|
if bloq >= 64 {
|
||||||
@ -552,7 +641,11 @@ pub fn jet_cut(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
Ok(new_indirect.as_noun())
|
Ok(new_indirect.as_noun())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_rip(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_rip(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let (bloq, step) = bite(raw_slot(arg, 2))?;
|
let (bloq, step) = bite(raw_slot(arg, 2))?;
|
||||||
let atom = raw_slot(arg, 3).as_atom()?;
|
let atom = raw_slot(arg, 3).as_atom()?;
|
||||||
@ -571,7 +664,11 @@ pub fn jet_rip(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
Ok(list)
|
Ok(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_met(_stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_met(
|
||||||
|
_stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let bloq = raw_slot(arg, 2).as_direct()?.data() as usize;
|
let bloq = raw_slot(arg, 2).as_direct()?.data() as usize;
|
||||||
if bloq >= 64 {
|
if bloq >= 64 {
|
||||||
@ -582,7 +679,11 @@ pub fn jet_met(_stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
|||||||
Ok(D(met(bloq, a) as u64))
|
Ok(D(met(bloq, a) as u64))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_mug(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_mug(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
Ok(mug(stack, arg).as_noun())
|
Ok(mug(stack, arg).as_noun())
|
||||||
}
|
}
|
||||||
@ -651,7 +752,11 @@ pub fn met(bloq: usize, a: Atom) -> usize {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jet_rev(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
pub fn jet_rev(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
_newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
let arg = raw_slot(subject, 6);
|
let arg = raw_slot(subject, 6);
|
||||||
let boz = raw_slot(arg, 2).as_atom()?.as_direct()?.data();
|
let boz = raw_slot(arg, 2).as_atom()?.as_direct()?.data();
|
||||||
|
|
||||||
@ -751,7 +856,7 @@ mod tests {
|
|||||||
|
|
||||||
fn assert_jet(stack: &mut NockStack, jet: Jet, sam: Noun, res: Noun) {
|
fn assert_jet(stack: &mut NockStack, jet: Jet, sam: Noun, res: Noun) {
|
||||||
let sam = T(stack, &[D(0), sam, D(0)]);
|
let sam = T(stack, &[D(0), sam, D(0)]);
|
||||||
let jet_res = assert_no_alloc(|| jet(stack, sam).unwrap());
|
let jet_res = assert_no_alloc(|| jet(stack, &mut None, sam).unwrap());
|
||||||
assert_noun_eq(stack, jet_res, res);
|
assert_noun_eq(stack, jet_res, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -788,7 +893,7 @@ mod tests {
|
|||||||
|
|
||||||
fn assert_jet_err(stack: &mut NockStack, jet: Jet, sam: Noun, err: JetErr) {
|
fn assert_jet_err(stack: &mut NockStack, jet: Jet, sam: Noun, err: JetErr) {
|
||||||
let sam = T(stack, &[D(0), sam, D(0)]);
|
let sam = T(stack, &[D(0), sam, D(0)]);
|
||||||
let jet_res = jet(stack, sam);
|
let jet_res = jet(stack, &mut None, sam);
|
||||||
assert!(
|
assert!(
|
||||||
jet_res.is_err(),
|
jet_res.is_err(),
|
||||||
"with sample: {}, expected err: {:?}, got: {:?}",
|
"with sample: {}, expected err: {:?}, got: {:?}",
|
||||||
|
71
rust/ares/src/jets/mink.rs
Normal file
71
rust/ares/src/jets/mink.rs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/** Virtualization jets
|
||||||
|
*/
|
||||||
|
use crate::interpreter::{interpret, raw_slot, NockErr};
|
||||||
|
use crate::jets::JetErr;
|
||||||
|
use crate::mem::NockStack;
|
||||||
|
use crate::newt::Newt;
|
||||||
|
use crate::noun::{Noun, D, T};
|
||||||
|
|
||||||
|
crate::gdb!();
|
||||||
|
|
||||||
|
// TODO: interpret should accept optional scry function and potentially produce blocked
|
||||||
|
// TODO: what do we do with the trace, if it's on the stack?
|
||||||
|
pub fn jet_mink(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
newt: &mut Option<&mut Newt>,
|
||||||
|
subject: Noun,
|
||||||
|
) -> Result<Noun, JetErr> {
|
||||||
|
let arg = raw_slot(subject, 6);
|
||||||
|
let v_subject = raw_slot(arg, 4);
|
||||||
|
let v_formula = raw_slot(arg, 5);
|
||||||
|
let _scry = raw_slot(arg, 3);
|
||||||
|
|
||||||
|
match interpret(stack, newt, v_subject, v_formula) {
|
||||||
|
Ok(res) => Ok(T(stack, &[D(0), res])),
|
||||||
|
Err(err) => match err {
|
||||||
|
NockErr::Blocked(block) => Ok(T(stack, &[D(1), block])),
|
||||||
|
NockErr::Error(error) => Ok(T(stack, &[D(2), error])),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::jets::Jet;
|
||||||
|
use crate::mem::unifying_equality;
|
||||||
|
use assert_no_alloc::assert_no_alloc;
|
||||||
|
|
||||||
|
fn init() -> NockStack {
|
||||||
|
NockStack::new(8 << 10 << 10, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_noun_eq(stack: &mut NockStack, mut a: Noun, mut b: Noun) {
|
||||||
|
let eq = unsafe { unifying_equality(stack, &mut a, &mut b) };
|
||||||
|
assert!(eq, "got: {}, need: {}", a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_jet(stack: &mut NockStack, jet: Jet, sam: Noun, res: Noun) {
|
||||||
|
let sam = T(stack, &[D(0), sam, D(0)]);
|
||||||
|
let jet_res = assert_no_alloc(|| jet(stack, &mut None, sam).unwrap());
|
||||||
|
assert_noun_eq(stack, jet_res, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mink_success() {
|
||||||
|
let s = &mut init();
|
||||||
|
let n = T(s, &[D(0), D(1), D(53)]);
|
||||||
|
let sam = T(s, &[n, D(0)]);
|
||||||
|
let res = T(s, &[D(0), D(53)]);
|
||||||
|
assert_jet(s, jet_mink, sam, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mink_zapzap() {
|
||||||
|
let s = &mut init();
|
||||||
|
let n = T(s, &[D(0), D(0), D(0)]);
|
||||||
|
let sam = T(s, &[n, D(0)]);
|
||||||
|
let res = T(s, &[D(2), D(1)]);
|
||||||
|
assert_jet(s, jet_mink, sam, res);
|
||||||
|
}
|
||||||
|
}
|
@ -1,30 +0,0 @@
|
|||||||
/** Virtualization jets
|
|
||||||
*/
|
|
||||||
use crate::interpreter::raw_slot;
|
|
||||||
use crate::jets::{JetErr, JetErr::*};
|
|
||||||
use crate::mem::NockStack;
|
|
||||||
use crate::mug::mug;
|
|
||||||
use crate::noun::{Atom, Cell, DirectAtom, IndirectAtom, Noun, D, DIRECT_MAX, NO, T, YES};
|
|
||||||
use bitvec::prelude::{BitSlice, Lsb0};
|
|
||||||
use either::Either::*;
|
|
||||||
use std::{cmp, convert::TryFrom};
|
|
||||||
|
|
||||||
crate::gdb!();
|
|
||||||
|
|
||||||
// can we reuse stack like this?
|
|
||||||
// interpret should accept optional scry function and potentially produce blocked
|
|
||||||
// what do we do with the trace, if it's on the stack?
|
|
||||||
pub fn jet_mink(stack: &mut NockStack, newt: &mut Option<&mut Newt>, subject: Noun) -> Result<Noun, JetErr> {
|
|
||||||
let arg = raw_slot(subject, 6);
|
|
||||||
let v_subject = raw_slot(arg, 4);
|
|
||||||
let v_formula = raw_slot(arg, 5);
|
|
||||||
let scry = raw_slot(arg, 3);
|
|
||||||
|
|
||||||
match interpret(stack, newt, v_subject, v_formula) {
|
|
||||||
Ok(res) => Ok(T(stack, &[D(0), res])),
|
|
||||||
Err(err) => match err {
|
|
||||||
Blocked(block) => Ok(T(stack, &[D(1), block])),
|
|
||||||
Error(error) => Ok(T(stack, &[D(2), error])),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -20,7 +20,7 @@ fn main() -> io::Result<()> {
|
|||||||
ares::interpreter::use_gdb();
|
ares::interpreter::use_gdb();
|
||||||
ares::jets::use_gdb();
|
ares::jets::use_gdb();
|
||||||
ares::jets::math::use_gdb();
|
ares::jets::math::use_gdb();
|
||||||
ares::jets::virtual::use_gdb();
|
ares::jets::mink::use_gdb();
|
||||||
ares::mem::use_gdb();
|
ares::mem::use_gdb();
|
||||||
ares::mug::use_gdb();
|
ares::mug::use_gdb();
|
||||||
ares::newt::use_gdb();
|
ares::newt::use_gdb();
|
||||||
@ -53,7 +53,8 @@ fn main() -> io::Result<()> {
|
|||||||
let input_cell = input
|
let input_cell = input
|
||||||
.as_cell()
|
.as_cell()
|
||||||
.expect("Input must be jam of subject/formula pair");
|
.expect("Input must be jam of subject/formula pair");
|
||||||
let result = interpret(&mut stack, &mut None, input_cell.head(), input_cell.tail());
|
let result = interpret(&mut stack, &mut None, input_cell.head(), input_cell.tail())
|
||||||
|
.expect("nock failed");
|
||||||
if let Ok(atom) = result.as_atom() {
|
if let Ok(atom) = result.as_atom() {
|
||||||
println!("Result: {}", atom);
|
println!("Result: {}", atom);
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ impl NockStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Current frame pointer of this NockStack */
|
/** Current frame pointer of this NockStack */
|
||||||
pub fn frame_pointer(&self) -> *u64 {
|
pub fn frame_pointer(&self) -> *const u64 {
|
||||||
self.frame_pointer
|
self.frame_pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::interpreter::{interpret, raw_slot};
|
use crate::interpreter::{interpret, raw_slot, NockErr};
|
||||||
use crate::mem::NockStack;
|
use crate::mem::NockStack;
|
||||||
use crate::mug::mug_u32;
|
use crate::mug::mug_u32;
|
||||||
use crate::newt::Newt;
|
use crate::newt::Newt;
|
||||||
@ -67,7 +67,8 @@ pub fn serf() -> io::Result<()> {
|
|||||||
}
|
}
|
||||||
tas!(b"peek") => {
|
tas!(b"peek") => {
|
||||||
let sam = raw_slot(writ, 7);
|
let sam = raw_slot(writ, 7);
|
||||||
let res = slam(stack, newt, arvo, PEEK_AXIS, sam);
|
let res = slam(stack, newt, arvo, PEEK_AXIS, sam)
|
||||||
|
.expect("peek error handling unimplemented");
|
||||||
newt.peek_done(stack, res);
|
newt.peek_done(stack, res);
|
||||||
}
|
}
|
||||||
tas!(b"play") => {
|
tas!(b"play") => {
|
||||||
@ -76,7 +77,8 @@ pub fn serf() -> io::Result<()> {
|
|||||||
let lit = raw_slot(writ, 7);
|
let lit = raw_slot(writ, 7);
|
||||||
let sub = T(stack, &[D(0), D(3)]);
|
let sub = T(stack, &[D(0), D(3)]);
|
||||||
let lyf = T(stack, &[D(2), sub, D(0), D(2)]);
|
let lyf = T(stack, &[D(2), sub, D(0), D(2)]);
|
||||||
let gat = interpret(stack, &mut Some(newt), lit, lyf);
|
let gat = interpret(stack, &mut Some(newt), lit, lyf)
|
||||||
|
.expect("play error handling unimplemented");
|
||||||
arvo = raw_slot(gat, 7);
|
arvo = raw_slot(gat, 7);
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
@ -90,7 +92,10 @@ pub fn serf() -> io::Result<()> {
|
|||||||
while let Ok(cell) = lit.as_cell() {
|
while let Ok(cell) = lit.as_cell() {
|
||||||
if run {
|
if run {
|
||||||
let ovo = cell.head();
|
let ovo = cell.head();
|
||||||
let res = slam(stack, newt, arvo, POKE_AXIS, ovo).as_cell().unwrap();
|
let res = slam(stack, newt, arvo, POKE_AXIS, ovo)
|
||||||
|
.expect("play error handling unimplemented")
|
||||||
|
.as_cell()
|
||||||
|
.unwrap();
|
||||||
arvo = res.tail();
|
arvo = res.tail();
|
||||||
}
|
}
|
||||||
event_number += 1;
|
event_number += 1;
|
||||||
@ -102,7 +107,10 @@ pub fn serf() -> io::Result<()> {
|
|||||||
}
|
}
|
||||||
tas!(b"work") => {
|
tas!(b"work") => {
|
||||||
let ovo = raw_slot(writ, 7);
|
let ovo = raw_slot(writ, 7);
|
||||||
let res = slam(stack, newt, arvo, POKE_AXIS, ovo).as_cell().unwrap();
|
let res = slam(stack, newt, arvo, POKE_AXIS, ovo)
|
||||||
|
.expect("work error handling unimplemented")
|
||||||
|
.as_cell()
|
||||||
|
.unwrap();
|
||||||
let fec = res.head();
|
let fec = res.head();
|
||||||
arvo = res.tail();
|
arvo = res.tail();
|
||||||
snap.save(stack, &mut arvo);
|
snap.save(stack, &mut arvo);
|
||||||
@ -118,7 +126,13 @@ pub fn serf() -> io::Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn slam(stack: &mut NockStack, newt: &mut Newt, core: Noun, axis: u64, ovo: Noun) -> Noun {
|
pub fn slam(
|
||||||
|
stack: &mut NockStack,
|
||||||
|
newt: &mut Newt,
|
||||||
|
core: Noun,
|
||||||
|
axis: u64,
|
||||||
|
ovo: Noun,
|
||||||
|
) -> Result<Noun, NockErr> {
|
||||||
let pul = T(stack, &[D(9), D(axis), D(0), D(2)]);
|
let pul = T(stack, &[D(9), D(axis), D(0), D(2)]);
|
||||||
let sam = T(stack, &[D(6), D(0), D(7)]);
|
let sam = T(stack, &[D(6), D(0), D(7)]);
|
||||||
let fol = T(stack, &[D(8), pul, D(9), D(2), D(10), sam, D(0), D(2)]);
|
let fol = T(stack, &[D(8), pul, D(9), D(2), D(10), sam, D(0), D(2)]);
|
||||||
|
Loading…
Reference in New Issue
Block a user