mirror of
https://github.com/urbit/ares.git
synced 2024-12-24 13:55:23 +03:00
WIP - 09/10
This commit is contained in:
parent
96a8915cc3
commit
54f982bf4d
@ -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,33 +742,56 @@ fn match_hint_pre_nock(
|
||||
let trace = Cell::new(stack, tag.as_noun(), res).as_noun();
|
||||
stack.trace_push(trace);
|
||||
}
|
||||
//
|
||||
// u3_serf_writ -> u3_serf_work -> _serf_work -> _serf_poke -> u3m_soft -> u3dc -> u3v_do -> u3v_wish -> +wish in Arvo
|
||||
// |
|
||||
// V
|
||||
// mook
|
||||
//
|
||||
// No +wish in toy Arvo; missing +slap and a ton of parsing functions needed by +ream
|
||||
//
|
||||
// u3t_slog = print on thing directly
|
||||
// u3t_slog_trace = print stack trace = - convert tone to toon
|
||||
// - presume toon is [%2 tang]
|
||||
// - print each tank in tang one at at time using u3t_slog
|
||||
// u3t_slog_hela = print entire stack trace = - weld stacks from all roads together
|
||||
// - call u3t_slog_trace on combined stack
|
||||
// u3t_slog_nara = print home road stack trace = call u3t_slog_trace on home road stack
|
||||
//
|
||||
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
|
||||
// |
|
||||
// V
|
||||
// mook
|
||||
//
|
||||
// No +wish in toy Arvo; missing +slap and a ton of parsing functions needed by +ream
|
||||
//
|
||||
// u3t_slog = print on thing directly
|
||||
// u3t_slog_trace = print stack trace = - convert tone to toon
|
||||
// - presume toon is [%2 tang]
|
||||
// - print each tank in tang one at at time using u3t_slog
|
||||
// u3t_slog_hela = print entire stack trace = - weld stacks from all roads together
|
||||
// - 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
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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)]
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user