WIP - 09/10

This commit is contained in:
Alex Shelkovnykov 2023-09-10 23:05:01 -06:00
parent 96a8915cc3
commit 54f982bf4d
6 changed files with 152 additions and 128 deletions

View File

@ -1,10 +1,11 @@
use self::NockWork::*;
use crate::hamt::Hamt;
use crate::jets;
use crate::jets::nock::util::mook;
use crate::mem::unifying_equality;
use crate::mem::NockStack;
use crate::newt::Newt;
use crate::noun::{Atom, Cell, DirectAtom, IndirectAtom, Noun, Slots, D};
use crate::noun::{Atom, Cell, DirectAtom, IndirectAtom, Noun, Slots, D, T};
use ares_macros::tas;
use assert_no_alloc::assert_no_alloc;
use bitvec::prelude::{BitSlice, Lsb0};
@ -741,9 +742,6 @@ fn match_hint_pre_nock(
let trace = Cell::new(stack, tag.as_noun(), res).as_noun();
stack.trace_push(trace);
}
tas!(b"hela") => {
// Joe: "to render to a tank call mook in Arvo with u3v_wish in Vere"
// need to make tank from stack trace; need mook equivalent
//
// u3_serf_writ -> u3_serf_work -> _serf_work -> _serf_poke -> u3m_soft -> u3dc -> u3v_do -> u3v_wish -> +wish in Arvo
// |
@ -760,14 +758,40 @@ fn match_hint_pre_nock(
// - call u3t_slog_trace on combined stack
// u3t_slog_nara = print home road stack trace = call u3t_slog_trace on home road stack
//
if let Some(not) = newt {
// flop the trace_stack XX: u3m_soft doesn't do this!!!
// call mook on [%2 trace_stack]
// slog each item in the trace
// if priority given: use priority
// if priority not given: priority = 0
// delete data structure
tas!(b"hela") => {
// XX: should this be virtualized?
// pretty sure we should be bailing on error
// might need to switch return type to Result<Option<Noun>, NockErr>
let stak = stack.get_mean_stack();
let tone = T(stack, &[D(2), stak]);
if let Ok(Ok(toon)) = mook(stack, newt, tone, true).map(|t| t.as_cell()) {
if unsafe { !toon.head().raw_equals(D(2)) } {
// Print jet errors and punt to Nock
eprintln!("\r%hela failed: toon not %2");
return None;
}
let mut list = toon.tail();
loop {
if unsafe { list.raw_equals(D(0)) } {
break;
}
let cell = list.as_cell().unwrap();
if let Some(not) = newt {
// XX: %hela priority is configurable, but I'm not sure how
not.slog(stack, 0, cell.head());
} else {
println!("raw slog: {} {}", 0, cell.head());
}
list = cell.tail();
}
} else {
// Print jet errors and punt to Nock
eprintln!("\r%hela failed: mook error");
return None;
}
}
_ => {}

View File

@ -1,13 +1,13 @@
pub mod bits;
pub mod hash;
pub mod math;
pub mod mock;
pub mod nock;
pub mod tree;
use crate::jets::bits::*;
use crate::jets::hash::*;
use crate::jets::math::*;
use crate::jets::mink::*;
use crate::jets::nock::*;
use crate::jets::tree::*;
use crate::mem::NockStack;
use crate::newt::Newt;
@ -99,7 +99,7 @@ pub fn get_jet_test_mode(_jet_name: Noun) -> bool {
pub mod util {
use super::*;
use crate::noun::Error::NotRepresentable;
use crate::noun::{Atom, DirectAtom, IndirectAtom, Noun, D};
use crate::noun::{Noun, Atom, DirectAtom, IndirectAtom, Cell, D};
use bitvec::prelude::{BitSlice, Lsb0};
use ibig::UBig;
use std::result;
@ -249,7 +249,12 @@ pub mod util {
}
}
pub fn rip(bloq: usize, step: usize, atom: Atom) -> Noun {
pub fn rip(
stack: &mut NockStack,
bloq: usize,
step: usize,
atom: Atom
) -> Result {
let len = (met(bloq, atom) + step - 1) / step;
let mut list = D(0);
for i in (0..len).rev() {
@ -261,7 +266,8 @@ pub mod util {
};
list = Cell::new(stack, new_atom.as_noun(), list).as_noun();
}
list
Ok(list)
}
/// Binary OR

View File

@ -5,7 +5,7 @@ use crate::jets::util::*;
use crate::jets::JetErr::*;
use crate::mem::NockStack;
use crate::newt::Newt;
use crate::noun::{Cell, DirectAtom, IndirectAtom, Noun, D};
use crate::noun::{DirectAtom, IndirectAtom, Noun, D};
use std::cmp;
crate::gdb!();
@ -321,7 +321,7 @@ pub fn jet_rip(
let arg = slot(subject, 6)?;
let (bloq, step) = bite(slot(arg, 2)?)?;
let atom = slot(arg, 3)?.as_atom()?;
Ok(rip(bloq, step, atom))
rip(stack, bloq, step, atom)
}
pub fn jet_rsh(

View File

@ -31,87 +31,21 @@ pub fn jet_mink(
}
}
mod util {
// +$ tone $% [%0 product=*]
// [%1 block=*]
// [%2 trace=(list [@ta *])]
// ==
// +$ toon $% [%0 p=*]
// [%1 p=*]
// [%2 p=(list tank)]
// ==
// ++ mook
// |= ton=tone
// ^- toon
// ?. ?=([%2 *] ton)
// ton
// |^ [%2 (turn skip rend)]
// ::
// ++ skip
// ^+ trace.ton
// =/ yel (lent trace.ton) :: get length of the trace
// ?. (gth yel 1.024) trace.ton :: return early if the length of the trace is less than 1024
// %+ weld
// (scag 512 trace.ton)
// ^+ trace.ton
// :_ (slag (sub yel 512) trace.ton)
// :- %lose
// (crip "[skipped {(scow %ud (sub yel 1.024))} frames]")
// ::
// :: +rend: raw stack frame to tank
// ::
// :: $% [%hunk ref=* path] :: failed scry ([~ ~])
// :: [%lose cord] :: skipped frames
// :: [%hand *] :: mug any
// :: [%mean $@(cord (trap tank))] :: ~_ et al
// :: [%spot spot] :: source location
// :: ==
// ::
// ++ rend
// |= [tag=@ta dat=*]
// ^- tank
// ?+ tag
// ::
// leaf+"mook.{(rip 3 tag)}"
// ::
// %hunk
// ?@ dat leaf+"mook.hunk"
// =/ sof=(unit path) ((soft path) +.dat)
// ?~ sof leaf+"mook.hunk"
// (smyt u.sof)
// ::
// %lose
// ?^ dat leaf+"mook.lose"
// leaf+(rip 3 dat)
// ::
// %hand
// leaf+(scow %p (mug dat))
// ::
// %mean
// ?@ dat leaf+(rip 3 dat)
// =/ mac (mack dat -.dat)
// ?~ mac leaf+"####"
// =/ sof ((soft tank) u.mac)
// ?~ sof leaf+"mook.mean"
// u.sof
// ::
// %spot
// =/ sof=(unit spot) ((soft spot) dat)
// ?~ sof leaf+"mook.spot"
// :+ %rose [":" ~ ~]
// :~ (smyt p.u.sof)
// =* l p.q.u.sof
// =* r q.q.u.sof
// =/ ud |=(a=@u (scow %ud a))
// leaf+"<[{(ud p.l)} {(ud q.l)}].[{(ud p.r)} {(ud q.r)}]>"
// ==
// ==
// --
pub mod util {
use crate::jets::{JetErr, Result, jet_mink};
use crate::jets::util::rip;
use crate::mem::NockStack;
use crate::newt::Newt;
use crate::noun::{Noun, D, T, tape};
use ares_macros::tas;
const LEAF: Noun = D(tas!(b"leaf"));
const ROSE: Noun = D(tas!(b"rose"));
/** Consume $tone, produce $toon
*/
pub fn mook(
stack: NockStack,
stack: &mut NockStack,
newt: &mut Option<&mut Newt>,
tone: Noun,
flop: bool
@ -127,7 +61,6 @@ mod util {
}
// XX: trim traces longer than 1024 frames
let leaf = D(tas!(b"leaf"));
if flop {
let mut list = original_list;
@ -142,46 +75,104 @@ mod util {
let tag = trace.head().as_direct()?;
let dat = trace.tail();
// XX: implement
let tank: Noun = match tag.data() {
// *[a [9 2 [0 1]]]
// *[*[a [0 1]] [2 [0 1] [0 2]]]
// *[\[1 a] [2 [0 1] [0 2]]]
// *[a [2 [0 1] [0 2]]]
// *[*[a [0 1]] *[a [0 2]]]
// *[\[1 a] \[2 a]]
// *[a \[2 a]]
tas!(b"mean") => {
if let Ok(atom) = dat.as_atom() {
let tape = rip(stack, 3, 1, atom)?;
T(stack, &[LEAF, tape])
} else {
let virt = T(stack, &[dat, dat.as_cell()?.head()]);
let load = T(stack, &[virt, D(0)]);
let subj = T(stack, &[D(0), load, D(0)]);
let tone = jet_mink(stack, newt, subj)?.as_cell()?;
if unsafe { !tone.head().raw_equals(D(0)) } {
let tape = tape(stack, "####");
T(stack, &[LEAF, tape])
} else {
// XX: need to check that this is actually a tank
// return leaf+"mean.mook" if not
tone.tail()
}
}
},
tas!(b"spot") => {
let subj = T(stack, &[D(0), dat, D(0)]);
let spot = jet_mink(stack, newt, subj)?;
if spot.as_cell()?.head().as_direct().data() != 0 {
let tone = jet_mink(stack, newt, subj)?.as_cell()?;
if unsafe { !tone.head().raw_equals(D(0)) } {
// XX test this in Vere
// if the formula in dat crashes, we produce leaf+"mook.spot"
let msg = tape(stack, "mook.spot");
T(stack, &[leaf, msg])
T(stack, &[LEAF, msg])
} else {
let spot = tone.tail().as_cell()?;
let pint = spot.tail().as_cell()?;
let pstr = pint.head().as_cell()?;
let pend = pint.tail().as_cell()?;
let colo = T(stack, &[D(tas!(b":")), D(0)]);
let trel = T(stack, &[colo, D(0), D(0)]);
let smyt = smyt(stack, spot.head())?;
// XX: numbers not +scow-ed
let text = format!(
"<[{} {}.{} {}]>",
pstr.head().as_atom()?.as_either().either(|l| l.data().to_string(), |r| r.as_ubig(stack).to_string()),
pstr.tail().as_atom()?.as_either().either(|l| l.data().to_string(), |r| r.as_ubig(stack).to_string()),
pend.head().as_atom()?.as_either().either(|l| l.data().to_string(), |r| r.as_ubig(stack).to_string()),
pend.tail().as_atom()?.as_either().either(|l| l.data().to_string(), |r| r.as_ubig(stack).to_string())
);
let tape = tape(stack, &text);
let finn = T(stack, &[LEAF, tape]);
T(stack, &[ROSE, trel, smyt, finn])
}
},
_ => {
let tape = rip(stack, 3, 1, tag.as_atom())?;
T(stack, &[D(tas!(b"m")), D(tas!(b"o")), D(tas!(b"o")), D(tas!(b"k")), D(tas!(b".")), tape])
}
// XX: TODO
// %hand
// %hunk
// %lose
// %mean
// default
};
res = T(stack, &[tank, res]);
list = cell.tail();
}
Ok(Res)
Ok(res)
} else {
// XX: need non-tail recursive helper to build +mook without +flop, because no helper in noun.rs to allocate Cell and set tail later (like u3i_defcons in Vere)
Ok(D(0))
}
}
pub fn smyt(stack: &mut NockStack, path: Noun) -> Result {
let lash = D(tas!(b"/"));
let zero = D(0);
let sep = T(stack, &[lash, zero]);
let trel = T(stack, &[sep, sep, zero]);
let tank = smyt_help(stack, path)?;
Ok(T(stack, &[ROSE, trel, tank]))
}
fn smyt_help(stack: &mut NockStack, path: Noun) -> Result {
// XX: Need deferred Cell allocation, like u3i_defcons in Vere
if unsafe { path.raw_equals(D(0)) } {
return Ok(D(0));
}
let cell = path.as_cell()?;
let tail = smyt_help(stack, cell.tail())?;
let trip = rip(stack, 3, 1, cell.head().as_atom()?)?;
let head = T(stack, &[LEAF, trip]);
Ok(T(stack, &[head, tail]))
}
}
#[cfg(test)]

View File

@ -19,8 +19,11 @@ fn main() -> io::Result<()> {
if filename == "see gdb! definition in lib.rs about this" {
ares::interpreter::use_gdb();
ares::jets::use_gdb();
ares::jets::bits::use_gdb();
ares::jets::hash::use_gdb();
ares::jets::math::use_gdb();
ares::jets::mink::use_gdb();
ares::jets::nock::use_gdb();
ares::jets::tree::use_gdb();
ares::mem::use_gdb();
ares::mug::use_gdb();
ares::newt::use_gdb();

View File

@ -231,7 +231,7 @@ pub fn T<A: NounAllocator>(allocator: &mut A, tup: &[Noun]) -> Noun {
pub fn tape<A: NounAllocator>(allocator: &mut A, text: &str) -> Noun {
let mut res = D(0);
// XX: Need deferred Cell allocation, like u3i_defcons in Vere
for c in str.bytes().rev() {
for c in text.bytes().rev() {
res = T(allocator, &[D(c as u64), res])
}
res