mirror of
https://github.com/urbit/ares.git
synced 2024-12-24 13:55:23 +03:00
Merge branch 'status' into eamsden/integrate-pma-merge-tmp
This commit is contained in:
commit
7d0def5178
@ -9,6 +9,7 @@ use crate::jets::warm::Warm;
|
||||
use crate::jets::JetErr;
|
||||
use crate::mem::unifying_equality;
|
||||
use crate::mem::NockStack;
|
||||
use crate::mem::Preserve;
|
||||
use crate::newt::Newt;
|
||||
use crate::noun;
|
||||
use crate::noun::{Atom, Cell, IndirectAtom, Noun, Slots, D, T};
|
||||
@ -254,20 +255,59 @@ enum NockWork {
|
||||
Work12(Nock12),
|
||||
}
|
||||
|
||||
pub struct ContextSnapshot {
|
||||
cold: Cold,
|
||||
warm: Warm,
|
||||
}
|
||||
|
||||
pub struct Context {
|
||||
pub stack: NockStack,
|
||||
// For printing slogs; if None, print to stdout; Option slated to be removed
|
||||
pub newt: Newt,
|
||||
pub cold: Cold,
|
||||
pub warm: Warm,
|
||||
pub hot: Hot,
|
||||
// XX: persistent memo cache
|
||||
// Per-event cache; option to share cache with virtualized events
|
||||
pub cache: Hamt<Noun>,
|
||||
pub scry_stack: Noun,
|
||||
pub trace_info: Option<TraceInfo>,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub fn save(&self) -> ContextSnapshot {
|
||||
ContextSnapshot {
|
||||
cold: self.cold,
|
||||
warm: self.warm,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn restore(&mut self, saved: &ContextSnapshot) {
|
||||
self.cold = saved.cold;
|
||||
self.warm = saved.warm;
|
||||
}
|
||||
|
||||
/**
|
||||
* For jets that need a stack frame internally.
|
||||
*
|
||||
* This ensures that the frame is cleaned up even if the closure short-circuites to an error
|
||||
* result using e.g. the ? syntax. We need this method separately from with_frame to allow the
|
||||
* jet to use the entire context without the borrow checker complaining about the mutable
|
||||
* references.
|
||||
*/
|
||||
pub unsafe fn with_stack_frame<F, O>(&mut self, slots: usize, f: F) -> O
|
||||
where
|
||||
F: FnOnce(&mut Context) -> O,
|
||||
O: Preserve,
|
||||
{
|
||||
self.stack.frame_push(slots);
|
||||
let mut ret = f(self);
|
||||
ret.preserve(&mut self.stack);
|
||||
self.cache.preserve(&mut self.stack);
|
||||
self.cold.preserve(&mut self.stack);
|
||||
self.warm.preserve(&mut self.stack);
|
||||
self.stack.frame_pop();
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum Error {
|
||||
ScryBlocked(Noun), // path
|
||||
@ -276,6 +316,26 @@ pub enum Error {
|
||||
NonDeterministic(Noun), // trace
|
||||
}
|
||||
|
||||
impl Preserve for Error {
|
||||
unsafe fn preserve(&mut self, stack: &mut NockStack) {
|
||||
match self {
|
||||
Error::ScryBlocked(ref mut path) => path.preserve(stack),
|
||||
Error::ScryCrashed(ref mut trace) => trace.preserve(stack),
|
||||
Error::Deterministic(ref mut trace) => trace.preserve(stack),
|
||||
Error::NonDeterministic(ref mut trace) => trace.preserve(stack),
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn assert_in_stack(&self, stack: &NockStack) {
|
||||
match self {
|
||||
Error::ScryBlocked(ref path) => path.assert_in_stack(stack),
|
||||
Error::ScryCrashed(ref trace) => trace.assert_in_stack(stack),
|
||||
Error::Deterministic(ref trace) => trace.assert_in_stack(stack),
|
||||
Error::NonDeterministic(ref trace) => trace.assert_in_stack(stack),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<noun::Error> for Error {
|
||||
fn from(_: noun::Error) -> Self {
|
||||
Error::Deterministic(D(0))
|
||||
@ -301,6 +361,7 @@ fn debug_assertions(stack: &mut NockStack, noun: Noun) {
|
||||
pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Result {
|
||||
let terminator = Arc::clone(&TERMINATOR);
|
||||
let orig_subject = subject; // for debugging
|
||||
let snapshot = context.save();
|
||||
let virtual_frame: *const u64 = context.stack.get_frame_pointer();
|
||||
let mut res: Noun = D(0);
|
||||
|
||||
@ -858,7 +919,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
|
||||
|
||||
match nock {
|
||||
Ok(res) => Ok(res),
|
||||
Err(err) => Err(exit(context, virtual_frame, err)),
|
||||
Err(err) => Err(exit(context, &snapshot, virtual_frame, err)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1075,10 +1136,16 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> result::Res
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn exit(context: &mut Context, virtual_frame: *const u64, error: Error) -> Error {
|
||||
fn exit(
|
||||
context: &mut Context,
|
||||
snapshot: &ContextSnapshot,
|
||||
virtual_frame: *const u64,
|
||||
error: Error,
|
||||
) -> Error {
|
||||
unsafe {
|
||||
let stack = &mut context.stack;
|
||||
context.restore(snapshot);
|
||||
|
||||
let stack = &mut context.stack;
|
||||
let mut preserve = match error {
|
||||
Error::ScryBlocked(path) => path,
|
||||
Error::Deterministic(t) | Error::NonDeterministic(t) | Error::ScryCrashed(t) => {
|
||||
@ -1088,10 +1155,9 @@ fn exit(context: &mut Context, virtual_frame: *const u64, error: Error) -> Error
|
||||
}
|
||||
};
|
||||
|
||||
while (stack).get_frame_pointer() != virtual_frame {
|
||||
(stack).preserve(&mut preserve);
|
||||
// (stack).preserve(&mut context.cold);
|
||||
(stack).frame_pop();
|
||||
while stack.get_frame_pointer() != virtual_frame {
|
||||
stack.preserve(&mut preserve);
|
||||
stack.frame_pop();
|
||||
}
|
||||
|
||||
match error {
|
||||
@ -1225,8 +1291,9 @@ unsafe fn write_trace(context: &mut Context) {
|
||||
let trace_stack = *(context.stack.local_noun_pointer(1) as *mut *const TraceStack);
|
||||
// Abort writing to trace file if we encountered an error. This should
|
||||
// result in a well-formed partial trace file.
|
||||
if let Err(e) = write_nock_trace(&mut context.stack, info, trace_stack) {
|
||||
eprintln!("\rserf: error writing nock trace to file: {:?}", e);
|
||||
if let Err(_e) = write_nock_trace(&mut context.stack, info, trace_stack) {
|
||||
// XX: need NockStack allocated string interpolation
|
||||
// eprintln!("\rserf: error writing nock trace to file: {:?}", e);
|
||||
context.trace_info = None;
|
||||
}
|
||||
}
|
||||
@ -1291,31 +1358,21 @@ mod hint {
|
||||
&mut jet_res,
|
||||
)
|
||||
} {
|
||||
// XX: need string interpolation without allocation, then delete eprintln
|
||||
// XX: need NockStack allocated string interpolation
|
||||
// let tape = tape(stack, "jet mismatch in {}, raw: {}, jetted: {}", jet_name, nock_res, jet_res);
|
||||
eprintln!(
|
||||
"\rjet {} failed, raw: {:?}, jetted: {}",
|
||||
jet_name, nock_res, jet_res
|
||||
);
|
||||
let tape = tape(stack, "jet mismatch");
|
||||
let mean = T(stack, &[D(tas!(b"mean")), tape]);
|
||||
mean_push(stack, mean);
|
||||
// let mean = T(stack, &[D(tas!(b"mean")), tape]);
|
||||
// mean_push(stack, mean);
|
||||
Some(Err(Error::Deterministic(D(0))))
|
||||
} else {
|
||||
Some(Ok(nock_res))
|
||||
}
|
||||
}
|
||||
Err(error) => {
|
||||
let stack = &mut context.stack;
|
||||
// XX: need string interpolation without allocation, then delete eprintln
|
||||
// XX: need NockStack allocated string interpolation
|
||||
// let stack = &mut context.stack;
|
||||
// let tape = tape(stack, "jet mismatch in {}, raw: {}, jetted: {}", jet_name, err, jet_res);
|
||||
eprintln!(
|
||||
"\rjet {} failed, raw: {:?}, jetted: {}",
|
||||
jet_name, error, jet_res
|
||||
);
|
||||
let tape = tape(stack, "jet mismatch");
|
||||
let mean = T(stack, &[D(tas!(b"mean")), tape]);
|
||||
mean_push(stack, mean);
|
||||
// let mean = T(stack, &[D(tas!(b"mean")), tape]);
|
||||
// mean_push(stack, mean);
|
||||
|
||||
match error {
|
||||
Error::NonDeterministic(_) => {
|
||||
@ -1331,12 +1388,11 @@ mod hint {
|
||||
}
|
||||
Err(JetErr::Punt) => None,
|
||||
Err(err) => {
|
||||
let stack = &mut context.stack;
|
||||
// XX: need string interpolation without allocation
|
||||
// XX: need NockStack allocated string interpolation
|
||||
// let stack = &mut context.stack;
|
||||
// let tape = tape(stack, "{} jet error in {}", err, jet_name);
|
||||
let tape = tape(stack, "jet error");
|
||||
let mean = T(stack, &[D(tas!(b"mean")), tape]);
|
||||
mean_push(stack, mean);
|
||||
// let mean = T(stack, &[D(tas!(b"mean")), tape]);
|
||||
// mean_push(stack, mean);
|
||||
Some(Err(err.into()))
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ pub mod lock;
|
||||
pub mod lute;
|
||||
pub mod math;
|
||||
pub mod nock;
|
||||
pub mod parse;
|
||||
pub mod serial;
|
||||
pub mod sort;
|
||||
pub mod tree;
|
||||
@ -19,20 +20,21 @@ use crate::jets::bits::*;
|
||||
use crate::jets::cold::Cold;
|
||||
use crate::jets::form::*;
|
||||
use crate::jets::hash::*;
|
||||
use crate::jets::hot::Hot;
|
||||
use crate::jets::hot::{Hot, URBIT_HOT_STATE};
|
||||
use crate::jets::list::*;
|
||||
use crate::jets::lute::*;
|
||||
use crate::jets::math::*;
|
||||
use crate::jets::nock::*;
|
||||
use crate::jets::serial::*;
|
||||
use crate::jets::sort::*;
|
||||
|
||||
use crate::jets::lock::aes::*;
|
||||
use crate::jets::lock::ed::*;
|
||||
use crate::jets::lock::sha::*;
|
||||
use crate::jets::lute::*;
|
||||
use crate::jets::math::*;
|
||||
use crate::jets::nock::*;
|
||||
use crate::jets::parse::*;
|
||||
use crate::jets::serial::*;
|
||||
use crate::jets::sort::*;
|
||||
|
||||
use crate::jets::tree::*;
|
||||
use crate::jets::warm::Warm;
|
||||
use crate::mem::NockStack;
|
||||
use crate::mem::{NockStack, Preserve};
|
||||
use crate::newt::Newt;
|
||||
use crate::noun::{self, Noun, Slots, D};
|
||||
use ares_macros::tas;
|
||||
@ -53,6 +55,22 @@ pub enum JetErr {
|
||||
Fail(Error), // Error; do not retry
|
||||
}
|
||||
|
||||
impl Preserve for JetErr {
|
||||
unsafe fn preserve(&mut self, stack: &mut NockStack) {
|
||||
match self {
|
||||
JetErr::Punt => {}
|
||||
JetErr::Fail(ref mut err) => err.preserve(stack),
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn assert_in_stack(&self, stack: &NockStack) {
|
||||
match self {
|
||||
JetErr::Punt => {}
|
||||
JetErr::Fail(ref err) => err.assert_in_stack(stack),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Error> for JetErr {
|
||||
fn from(err: Error) -> Self {
|
||||
Self::Fail(err)
|
||||
@ -148,6 +166,7 @@ pub fn get_jet(jet_name: Noun) -> Option<Jet> {
|
||||
tas!(b"sivc_de") => Some(jet_sivc_de),
|
||||
//
|
||||
_ => {
|
||||
// XX: need NockStack allocated string interpolation
|
||||
// eprintln!("Unknown jet: {:?}", jet_name);
|
||||
None
|
||||
}
|
||||
@ -166,7 +185,8 @@ pub fn get_jet_test_mode(_jet_name: Noun) -> bool {
|
||||
|
||||
pub mod util {
|
||||
use super::*;
|
||||
use crate::noun::{Noun, D};
|
||||
use crate::interpreter::interpret;
|
||||
use crate::noun::{Noun, D, T};
|
||||
use bitvec::prelude::{BitSlice, Lsb0};
|
||||
use std::result;
|
||||
|
||||
@ -267,6 +287,23 @@ pub mod util {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn kick(context: &mut Context, core: Noun, axis: Noun) -> result::Result<Noun, JetErr> {
|
||||
let formula: Noun = T(&mut context.stack, &[D(9), axis, D(0), D(1)]);
|
||||
interpret(context, core, formula).map_err(JetErr::Fail)
|
||||
}
|
||||
|
||||
pub fn slam(context: &mut Context, gate: Noun, sample: Noun) -> result::Result<Noun, JetErr> {
|
||||
let core: Noun = T(
|
||||
&mut context.stack,
|
||||
&[
|
||||
gate.as_cell()?.head(),
|
||||
sample,
|
||||
gate.as_cell()?.tail().as_cell()?.tail(),
|
||||
],
|
||||
);
|
||||
kick(context, core, D(2))
|
||||
}
|
||||
|
||||
pub mod test {
|
||||
use super::*;
|
||||
use crate::hamt::Hamt;
|
||||
@ -280,7 +317,7 @@ pub mod util {
|
||||
let newt = Newt::new_mock();
|
||||
let cold = Cold::new(&mut stack);
|
||||
let warm = Warm::new(&mut stack);
|
||||
let hot = Hot::init(&mut stack);
|
||||
let hot = Hot::init(&mut stack, URBIT_HOT_STATE);
|
||||
let cache = Hamt::<Noun>::new(&mut stack);
|
||||
|
||||
Context {
|
||||
@ -306,7 +343,11 @@ pub mod util {
|
||||
}
|
||||
|
||||
pub fn assert_jet(context: &mut Context, jet: Jet, sam: Noun, res: Noun) {
|
||||
let sam = T(&mut context.stack, &[D(0), sam, D(0)]);
|
||||
assert_jet_door(context, jet, sam, D(0), res)
|
||||
}
|
||||
|
||||
pub fn assert_jet_door(context: &mut Context, jet: Jet, sam: Noun, pay: Noun, res: Noun) {
|
||||
let sam = T(&mut context.stack, &[D(0), sam, pay]);
|
||||
let jet_res = assert_no_alloc(|| jet(context, sam).unwrap());
|
||||
assert_noun_eq(&mut context.stack, jet_res, res);
|
||||
}
|
||||
|
@ -4,8 +4,9 @@ use ares_macros::tas;
|
||||
use either::Either::{self, Left, Right};
|
||||
use std::ptr::null_mut;
|
||||
|
||||
// const A_50: Either<u64, (u64, u64)> = Right((b"a", 50));
|
||||
const K_139: Either<&[u8], (u64, u64)> = Right((tas!(b"k"), 139));
|
||||
/** Root for Hoon %k.139
|
||||
*/
|
||||
pub const K_139: Either<&[u8], (u64, u64)> = Right((tas!(b"k"), 139));
|
||||
|
||||
// // This is the const state all in one spot as literals
|
||||
// #[allow(clippy::complexity)]
|
||||
@ -57,8 +58,14 @@ const K_139: Either<&[u8], (u64, u64)> = Right((tas!(b"k"), 139));
|
||||
// (&[A_50, Left(b"mink")], 1, jet_mink),
|
||||
// ];
|
||||
|
||||
/**
|
||||
* (path, axis in battery, jet function pointer)
|
||||
* see the [Jet] typedef in ares::jets for the proper prototype
|
||||
*/
|
||||
pub type HotEntry = (&'static [Either<&'static [u8], (u64, u64)>], u64, Jet);
|
||||
|
||||
#[allow(clippy::complexity)]
|
||||
const TRUE_HOT_STATE: &[(&[Either<&[u8], (u64, u64)>], u64, Jet)] = &[
|
||||
pub const URBIT_HOT_STATE: &[HotEntry] = &[
|
||||
(&[K_139, Left(b"one"), Left(b"add")], 1, jet_add),
|
||||
(&[K_139, Left(b"one"), Left(b"dec")], 1, jet_dec),
|
||||
(&[K_139, Left(b"one"), Left(b"div")], 1, jet_div),
|
||||
@ -269,6 +276,170 @@ const TRUE_HOT_STATE: &[(&[Either<&[u8], (u64, u64)>], u64, Jet)] = &[
|
||||
jet_sha1,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"last"),
|
||||
],
|
||||
1,
|
||||
jet_last,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"bend"),
|
||||
Left(b"fun"),
|
||||
],
|
||||
1,
|
||||
jet_bend,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"comp"),
|
||||
Left(b"fun"),
|
||||
],
|
||||
1,
|
||||
jet_comp,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"glue"),
|
||||
Left(b"fun"),
|
||||
],
|
||||
1,
|
||||
jet_glue,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"pfix"),
|
||||
],
|
||||
1,
|
||||
jet_pfix,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"pose"),
|
||||
],
|
||||
1,
|
||||
jet_pose,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"sfix"),
|
||||
],
|
||||
1,
|
||||
jet_sfix,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"easy"),
|
||||
Left(b"fun"),
|
||||
],
|
||||
1,
|
||||
jet_easy,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"here"),
|
||||
Left(b"fun"),
|
||||
],
|
||||
1,
|
||||
jet_here,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"just"),
|
||||
Left(b"fun"),
|
||||
],
|
||||
1,
|
||||
jet_just,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"mask"),
|
||||
Left(b"fun"),
|
||||
],
|
||||
1,
|
||||
jet_mask,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
Left(b"one"),
|
||||
Left(b"two"),
|
||||
Left(b"tri"),
|
||||
Left(b"qua"),
|
||||
Left(b"stag"),
|
||||
Left(b"fun"),
|
||||
],
|
||||
1,
|
||||
jet_stag,
|
||||
),
|
||||
//
|
||||
(
|
||||
&[
|
||||
K_139,
|
||||
@ -595,10 +766,10 @@ const TRUE_HOT_STATE: &[(&[Either<&[u8], (u64, u64)>], u64, Jet)] = &[
|
||||
pub struct Hot(*mut HotMem);
|
||||
|
||||
impl Hot {
|
||||
pub fn init(stack: &mut NockStack) -> Self {
|
||||
pub fn init(stack: &mut NockStack, constant_hot_state: &[HotEntry]) -> Self {
|
||||
unsafe {
|
||||
let mut next = Hot(null_mut());
|
||||
for (htap, axe, jet) in TRUE_HOT_STATE {
|
||||
for (htap, axe, jet) in constant_hot_state {
|
||||
let mut a_path = D(0);
|
||||
for i in *htap {
|
||||
match i {
|
||||
|
@ -1,13 +1,125 @@
|
||||
/** Virtualization jets
|
||||
*/
|
||||
use crate::hamt::Hamt;
|
||||
use crate::interpreter::{interpret, Context, Error};
|
||||
use crate::interpreter::Context;
|
||||
use crate::jets::util::slot;
|
||||
use crate::jets::{JetErr, Result};
|
||||
use crate::noun::{Cell, Noun, D, NO, T, YES};
|
||||
use crate::noun::{Noun, D, NO, T};
|
||||
|
||||
crate::gdb!();
|
||||
|
||||
pub fn jet_mink(context: &mut Context, subject: Noun) -> Result {
|
||||
let arg = slot(subject, 6)?;
|
||||
// mink sample = [nock scry_namespace]
|
||||
// = [[subject formula] scry_namespace]
|
||||
let v_subject = slot(arg, 4)?;
|
||||
let v_formula = slot(arg, 5)?;
|
||||
let scry_handler = slot(arg, 3)?;
|
||||
|
||||
// Implicit error conversion
|
||||
Ok(util::mink(context, v_subject, v_formula, scry_handler)?)
|
||||
}
|
||||
|
||||
pub fn jet_mole(context: &mut Context, subject: Noun) -> Result {
|
||||
jet_mure(context, subject)
|
||||
}
|
||||
|
||||
pub fn jet_mule(context: &mut Context, subject: Noun) -> Result {
|
||||
jet_mute(context, subject)
|
||||
}
|
||||
|
||||
pub fn jet_mure(context: &mut Context, subject: Noun) -> Result {
|
||||
let tap = slot(subject, 6)?;
|
||||
let fol = util::slam_gate_fol(&mut context.stack);
|
||||
let scry = util::pass_thru_scry(&mut context.stack);
|
||||
|
||||
match util::mink(context, tap, fol, scry) {
|
||||
Ok(tone) => {
|
||||
if unsafe { tone.as_cell()?.head().raw_equals(D(0)) } {
|
||||
Ok(tone)
|
||||
} else {
|
||||
Ok(D(0))
|
||||
}
|
||||
}
|
||||
Err(err) => Err(JetErr::Fail(err)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jet_mute(context: &mut Context, subject: Noun) -> Result {
|
||||
let tap = slot(subject, 6)?;
|
||||
let fol = util::slam_gate_fol(&mut context.stack);
|
||||
let scry = util::pass_thru_scry(&mut context.stack);
|
||||
|
||||
let tone = util::mink(context, tap, fol, scry);
|
||||
|
||||
match util::mook(context, tone?.as_cell()?, false) {
|
||||
Ok(toon) => {
|
||||
match toon.head() {
|
||||
x if unsafe { x.raw_equals(D(0)) } => Ok(toon.as_noun()),
|
||||
x if unsafe { x.raw_equals(D(1)) } => {
|
||||
// XX: Need to check that result is actually of type path
|
||||
// return [[%leaf "mute.hunk"] ~] if not
|
||||
let bon = util::smyt(&mut context.stack, toon.tail())?;
|
||||
Ok(T(&mut context.stack, &[NO, bon, D(0)]))
|
||||
}
|
||||
x if unsafe { x.raw_equals(D(2)) } => Ok(T(&mut context.stack, &[NO, toon.tail()])),
|
||||
_ => panic!("serf: mook: invalid toon"),
|
||||
}
|
||||
}
|
||||
Err(err) => Err(JetErr::Fail(err)),
|
||||
}
|
||||
}
|
||||
|
||||
pub mod util {
|
||||
use crate::hamt::Hamt;
|
||||
use crate::interpreter::{interpret, Context, Error};
|
||||
use crate::jets;
|
||||
use crate::jets::bits::util::rip;
|
||||
use crate::jets::form::util::scow;
|
||||
use crate::mem::NockStack;
|
||||
use crate::noun::{tape, Cell, Noun, D, T};
|
||||
use ares_macros::tas;
|
||||
use either::{Left, Right};
|
||||
use std::result;
|
||||
|
||||
pub const LEAF: Noun = D(tas!(b"leaf"));
|
||||
pub const ROSE: Noun = D(tas!(b"rose"));
|
||||
|
||||
/// The classic "slam gate" formula.
|
||||
pub fn slam_gate_fol(stack: &mut NockStack) -> Noun {
|
||||
T(stack, &[D(9), D(2), D(0), D(1)])
|
||||
}
|
||||
|
||||
/// The classic "pass-through" scry handler.
|
||||
pub fn pass_thru_scry(stack: &mut NockStack) -> Noun {
|
||||
// .* 0 != => ~ |=(a=^ ``.*(a [%12 [%0 2] %0 3]))
|
||||
// [[[1 0] [1 0] 2 [0 6] 1 12 [0 2] 0 3] [0 0] 0]
|
||||
let sig = T(stack, &[D(1), D(0)]);
|
||||
let sam = T(stack, &[D(0), D(6)]);
|
||||
let hed = T(stack, &[D(0), D(2)]);
|
||||
let tel = T(stack, &[D(0), D(3)]);
|
||||
let zap = T(stack, &[D(0), D(0)]);
|
||||
|
||||
let cry = T(stack, &[D(12), hed, tel]);
|
||||
let fol = T(stack, &[D(1), cry]);
|
||||
let res = T(stack, &[D(2), sam, fol]);
|
||||
let uno = T(stack, &[sig, res]);
|
||||
let dos = T(stack, &[sig, uno]);
|
||||
|
||||
let gat = T(stack, &[zap, D(0)]);
|
||||
|
||||
T(stack, &[dos, gat])
|
||||
}
|
||||
|
||||
/// The "always-fail" scry
|
||||
pub fn null_scry(stack: &mut NockStack) -> Noun {
|
||||
// .* 0 != => ~ |=(^ ~)
|
||||
// [[1 0] [0 0] 0]
|
||||
let sig = T(stack, &[D(1), D(0)]);
|
||||
let zap = T(stack, &[D(0), D(0)]);
|
||||
|
||||
T(stack, &[sig, zap, D(0)])
|
||||
}
|
||||
|
||||
// Deterministic scry crashes should have the following behaviour:
|
||||
//
|
||||
// root <-- bail, %crud
|
||||
@ -28,29 +140,37 @@ crate::gdb!();
|
||||
// scry <-- return ScryCrashed
|
||||
// scry
|
||||
//
|
||||
pub fn jet_mink(context: &mut Context, subject: Noun) -> Result {
|
||||
let arg = slot(subject, 6)?;
|
||||
// mink sample = [nock scry_namespace]
|
||||
// = [[subject formula] scry_namespace]
|
||||
let v_subject = slot(arg, 4)?;
|
||||
let v_formula = slot(arg, 5)?;
|
||||
let scry_handler = slot(arg, 3)?;
|
||||
|
||||
let old_cache = context.cache;
|
||||
let old_scry_stack = context.scry_stack;
|
||||
pub fn mink(
|
||||
context: &mut Context,
|
||||
subject: Noun,
|
||||
formula: Noun,
|
||||
scry: Noun,
|
||||
) -> Result<Noun, Error> {
|
||||
let cache_snapshot = context.cache;
|
||||
let scry_snapshot = context.scry_stack;
|
||||
|
||||
context.cache = Hamt::<Noun>::new(&mut context.stack);
|
||||
context.scry_stack = T(&mut context.stack, &[scry_handler, old_scry_stack]);
|
||||
context.scry_stack = T(&mut context.stack, &[scry, context.scry_stack]);
|
||||
|
||||
match util::mink(context, v_subject, v_formula) {
|
||||
Ok(noun) => {
|
||||
context.cache = old_cache;
|
||||
context.scry_stack = old_scry_stack;
|
||||
Ok(noun)
|
||||
match interpret(context, subject, formula) {
|
||||
Ok(res) => {
|
||||
context.cache = cache_snapshot;
|
||||
context.scry_stack = scry_snapshot;
|
||||
Ok(T(&mut context.stack, &[D(0), res]))
|
||||
}
|
||||
Err(err) => match err {
|
||||
Error::ScryBlocked(path) => {
|
||||
context.cache = cache_snapshot;
|
||||
context.scry_stack = scry_snapshot;
|
||||
Ok(T(&mut context.stack, &[D(1), path]))
|
||||
}
|
||||
Error::Deterministic(trace) => {
|
||||
context.cache = cache_snapshot;
|
||||
context.scry_stack = scry_snapshot;
|
||||
Ok(T(&mut context.stack, &[D(2), trace]))
|
||||
}
|
||||
Err(error) => match error {
|
||||
Error::NonDeterministic(_) => Err(JetErr::Fail(error)),
|
||||
Error::ScryCrashed(trace) => {
|
||||
context.cache = cache_snapshot;
|
||||
// When we enter a +mink call, we record the state of the scry handler stack at the
|
||||
// time (i.e. the Noun representing (list scry)). Each scry will pop the head off of
|
||||
// this scry handler stack and calls interpret(), using the rest of the scry handler
|
||||
@ -64,140 +184,35 @@ pub fn jet_mink(context: &mut Context, subject: Noun) -> Result {
|
||||
// Error::ScryCrashed, jet_mink() compares the two scry handler stack Nouns> If they
|
||||
// are identical, jet_mink() bails with Error::Deterministic. Otherwise, it forwards
|
||||
// the Error::ScryCrashed to the senior virtualization call.
|
||||
if unsafe { context.scry_stack.raw_equals(old_scry_stack) } {
|
||||
Err(JetErr::Fail(Error::Deterministic(trace)))
|
||||
if unsafe { context.scry_stack.raw_equals(scry_snapshot) } {
|
||||
Err(Error::Deterministic(trace))
|
||||
} else {
|
||||
Err(JetErr::Fail(error))
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
Error::Deterministic(_) | Error::ScryBlocked(_) => {
|
||||
panic!("scry: mink: unhandled errors in helper")
|
||||
Error::NonDeterministic(_) => {
|
||||
// We choose to restore the cache and scry stack even on NonDeterministic errors
|
||||
// to keep the logic all in one place (as opposed to having the serf reset them
|
||||
// manually ONLY for NonDeterministic errors).
|
||||
context.cache = cache_snapshot;
|
||||
context.scry_stack = scry_snapshot;
|
||||
Err(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jet_mole(context: &mut Context, subject: Noun) -> Result {
|
||||
jet_mure(context, subject)
|
||||
}
|
||||
|
||||
pub fn jet_mule(context: &mut Context, subject: Noun) -> Result {
|
||||
jet_mute(context, subject)
|
||||
}
|
||||
|
||||
pub fn jet_mure(context: &mut Context, subject: Noun) -> Result {
|
||||
let tap = slot(subject, 6)?;
|
||||
let fol = util::slam_gate_fol(&mut context.stack);
|
||||
let scry = util::pass_thru_scry(&mut context.stack);
|
||||
|
||||
context.scry_stack = T(&mut context.stack, &[scry, context.scry_stack]);
|
||||
match interpret(context, tap, fol) {
|
||||
Ok(res) => {
|
||||
context.scry_stack = context.scry_stack.as_cell()?.tail();
|
||||
Ok(T(&mut context.stack, &[D(0), res]))
|
||||
}
|
||||
Err(error) => match error {
|
||||
// Since we are using the pass-through scry handler, we know for a fact that a scry
|
||||
// crash must have come from a senior virtualization context.
|
||||
Error::NonDeterministic(_) | Error::ScryCrashed(_) => Err(JetErr::Fail(error)),
|
||||
Error::Deterministic(_) | Error::ScryBlocked(_) => Ok(D(0)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jet_mute(context: &mut Context, subject: Noun) -> Result {
|
||||
let tap = slot(subject, 6)?;
|
||||
let fol = util::slam_gate_fol(&mut context.stack);
|
||||
let scry = util::pass_thru_scry(&mut context.stack);
|
||||
|
||||
context.scry_stack = T(&mut context.stack, &[scry, context.scry_stack]);
|
||||
match interpret(context, tap, fol) {
|
||||
Ok(res) => {
|
||||
context.scry_stack = context.scry_stack.as_cell()?.tail();
|
||||
Ok(T(&mut context.stack, &[YES, res]))
|
||||
}
|
||||
Err(error) => match error {
|
||||
// Since we are using the pass-through scry handler, we know for a fact that a scry
|
||||
// crash must have come from a senior virtualization context.
|
||||
Error::NonDeterministic(_) | Error::ScryCrashed(_) => Err(JetErr::Fail(error)),
|
||||
Error::ScryBlocked(path) => {
|
||||
// XX: Need to check that result is actually of type path
|
||||
// return [[%leaf "mute.hunk"] ~] if not
|
||||
let bon = util::smyt(&mut context.stack, path)?;
|
||||
Ok(T(&mut context.stack, &[NO, bon, D(0)]))
|
||||
}
|
||||
Error::Deterministic(trace) => {
|
||||
let ton = Cell::new(&mut context.stack, D(2), trace);
|
||||
let tun = util::mook(context, ton, false)?;
|
||||
Ok(T(&mut context.stack, &[NO, tun.tail()]))
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub mod util {
|
||||
use crate::interpreter::{interpret, Context, Error};
|
||||
use crate::jets;
|
||||
use crate::jets::bits::util::rip;
|
||||
use crate::jets::form::util::scow;
|
||||
use crate::jets::JetErr;
|
||||
use crate::mem::NockStack;
|
||||
use crate::noun::{tape, Cell, Noun, D, T};
|
||||
use ares_macros::tas;
|
||||
use either::{Left, Right};
|
||||
use std::result;
|
||||
|
||||
pub const LEAF: Noun = D(tas!(b"leaf"));
|
||||
pub const ROSE: Noun = D(tas!(b"rose"));
|
||||
|
||||
/// The classic "slam gate" formula.
|
||||
pub fn slam_gate_fol(stack: &mut NockStack) -> Noun {
|
||||
T(stack, &[D(9), D(2), D(0), D(1)])
|
||||
}
|
||||
|
||||
/// The classic "pass-through" scry handler.
|
||||
pub fn pass_thru_scry(stack: &mut NockStack) -> Noun {
|
||||
// > .* 0 != => ~ |=(a=^ ``.*(a [%12 [%0 2] %0 3]))
|
||||
// [[[1 0] [1 0] 2 [0 6] 1 12 [0 2] 0 3] [0 0] 0]
|
||||
let sig = T(stack, &[D(1), D(0)]);
|
||||
let sam = T(stack, &[D(0), D(6)]);
|
||||
let hed = T(stack, &[D(0), D(2)]);
|
||||
let tel = T(stack, &[D(0), D(3)]);
|
||||
let zap = T(stack, &[D(0), D(0)]);
|
||||
|
||||
let cry = T(stack, &[D(12), hed, tel]);
|
||||
let fol = T(stack, &[D(1), cry]);
|
||||
let res = T(stack, &[D(2), sam, fol]);
|
||||
let uno = T(stack, &[sig, res]);
|
||||
let dos = T(stack, &[sig, uno]);
|
||||
|
||||
let gat = T(stack, &[zap, D(0)]);
|
||||
|
||||
T(stack, &[dos, gat])
|
||||
}
|
||||
|
||||
pub fn mink(context: &mut Context, subject: Noun, formula: Noun) -> Result<Noun, Error> {
|
||||
match interpret(context, subject, formula) {
|
||||
Ok(res) => Ok(T(&mut context.stack, &[D(0), res])),
|
||||
Err(err) => match err {
|
||||
Error::ScryBlocked(path) => Ok(T(&mut context.stack, &[D(1), path])),
|
||||
Error::Deterministic(trace) => Ok(T(&mut context.stack, &[D(2), trace])),
|
||||
Error::NonDeterministic(_) | Error::ScryCrashed(_) => Err(err),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/** Consume $tone, produce $toon
|
||||
*/
|
||||
// XX: should write a jet_mook wrapper for this function
|
||||
pub fn mook(context: &mut Context, tone: Cell, flop: bool) -> result::Result<Cell, JetErr> {
|
||||
pub fn mook(context: &mut Context, tone: Cell, flop: bool) -> result::Result<Cell, Error> {
|
||||
let tag = tone.head().as_direct()?;
|
||||
let original_list = tone.tail();
|
||||
|
||||
if (tag.data() != 2) | unsafe { original_list.raw_equals(D(0)) } {
|
||||
return Ok(tone);
|
||||
} else if original_list.atom().is_some() {
|
||||
return Err(JetErr::Fail(Error::Deterministic(D(0))));
|
||||
return Err(Error::Deterministic(D(0)));
|
||||
}
|
||||
|
||||
// XX: trim traces longer than 1024 frames
|
||||
@ -235,7 +250,8 @@ pub mod util {
|
||||
}
|
||||
Right(_cell) => {
|
||||
// 'tank: {
|
||||
// if let Ok(tone) = mink(context, dat, cell.head()) {
|
||||
// let scry = null_scry(context);
|
||||
// if let Ok(tone) = mink(context, dat, cell.head(), scry) {
|
||||
// if let Some(cell) = tone.cell() {
|
||||
// if cell.head().raw_equals(D(0)) {
|
||||
// // XX: need to check that this is
|
||||
@ -245,7 +261,6 @@ pub mod util {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
{
|
||||
let stack = &mut context.stack;
|
||||
let tape = tape(stack, "####");
|
||||
|
448
rust/ares/src/jets/parse.rs
Normal file
448
rust/ares/src/jets/parse.rs
Normal file
@ -0,0 +1,448 @@
|
||||
/** Parsing jets
|
||||
*/
|
||||
use crate::interpreter::Context;
|
||||
use crate::jets::util::{kick, slam, slot};
|
||||
use crate::jets::Result;
|
||||
use crate::noun::{Noun, D, T};
|
||||
|
||||
crate::gdb!();
|
||||
|
||||
//
|
||||
// Tracing
|
||||
//
|
||||
|
||||
pub fn jet_last(_context: &mut Context, subject: Noun) -> Result {
|
||||
let sam = slot(subject, 6)?;
|
||||
let zyc = slot(sam, 2)?;
|
||||
let naz = slot(sam, 3)?;
|
||||
|
||||
util::last(zyc, naz)
|
||||
}
|
||||
|
||||
//
|
||||
// Combinators
|
||||
//
|
||||
|
||||
pub fn jet_bend(context: &mut Context, subject: Noun) -> Result {
|
||||
let sam = slot(subject, 6)?;
|
||||
let vex = slot(sam, 2)?.as_cell()?;
|
||||
let sab = slot(sam, 3)?;
|
||||
let van = slot(subject, 7)?;
|
||||
let raq = slot(van, 6)?;
|
||||
|
||||
let p_vex = vex.head();
|
||||
let q_vex = vex.tail();
|
||||
|
||||
if unsafe { q_vex.raw_equals(D(0)) } {
|
||||
return Ok(vex.as_noun());
|
||||
}
|
||||
|
||||
let uq_vex = q_vex.as_cell()?.tail().as_cell()?;
|
||||
let puq_vex = uq_vex.head();
|
||||
let quq_vex = uq_vex.tail();
|
||||
|
||||
let yit = slam(context, sab, quq_vex)?.as_cell()?;
|
||||
let p_yit = yit.head();
|
||||
let q_yit = yit.tail();
|
||||
|
||||
let yur = util::last(p_vex, p_yit)?;
|
||||
|
||||
if unsafe { q_yit.raw_equals(D(0)) } {
|
||||
Ok(T(&mut context.stack, &[yur, q_vex]))
|
||||
} else {
|
||||
let uq_yit = q_yit.as_cell()?.tail().as_cell()?;
|
||||
let puq_yit = uq_yit.head();
|
||||
let quq_yit = uq_yit.tail();
|
||||
|
||||
let arg = T(&mut context.stack, &[puq_vex, puq_yit]);
|
||||
let vux = slam(context, raq, arg)?;
|
||||
|
||||
if unsafe { vux.raw_equals(D(0)) } {
|
||||
Ok(T(&mut context.stack, &[yur, q_vex]))
|
||||
} else {
|
||||
let q_vux = vux.as_cell()?.tail();
|
||||
Ok(T(&mut context.stack, &[yur, D(0), q_vux, quq_yit]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jet_comp(context: &mut Context, subject: Noun) -> Result {
|
||||
let sam = slot(subject, 6)?;
|
||||
let vex = slot(sam, 2)?.as_cell()?;
|
||||
let sab = slot(sam, 3)?;
|
||||
let van = slot(subject, 7)?;
|
||||
let raq = slot(van, 6)?;
|
||||
|
||||
let p_vex = vex.head();
|
||||
let q_vex = vex.tail();
|
||||
|
||||
if unsafe { q_vex.raw_equals(D(0)) } {
|
||||
return Ok(vex.as_noun());
|
||||
}
|
||||
|
||||
let uq_vex = q_vex.as_cell()?.tail().as_cell()?;
|
||||
let puq_vex = uq_vex.head();
|
||||
let quq_vex = uq_vex.tail();
|
||||
|
||||
let yit = slam(context, sab, quq_vex)?.as_cell()?;
|
||||
let p_yit = yit.head();
|
||||
let q_yit = yit.tail();
|
||||
|
||||
let yur = util::last(p_vex, p_yit)?;
|
||||
|
||||
if unsafe { q_yit.raw_equals(D(0)) } {
|
||||
Ok(T(&mut context.stack, &[yur, D(0)]))
|
||||
} else {
|
||||
let uq_yit = q_yit.as_cell()?.tail().as_cell()?;
|
||||
let puq_yit = uq_yit.head();
|
||||
let quq_yit = uq_yit.tail();
|
||||
|
||||
let arg = T(&mut context.stack, &[puq_vex, puq_yit]);
|
||||
let vux = slam(context, raq, arg)?;
|
||||
Ok(T(&mut context.stack, &[yur, D(0), vux, quq_yit]))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jet_glue(context: &mut Context, subject: Noun) -> Result {
|
||||
let sam = slot(subject, 6)?;
|
||||
let vex = slot(sam, 2)?.as_cell()?;
|
||||
let sab = slot(sam, 3)?;
|
||||
let van = slot(subject, 7)?;
|
||||
let bus = slot(van, 6)?;
|
||||
|
||||
let p_vex = vex.head();
|
||||
let q_vex = vex.tail();
|
||||
|
||||
if unsafe { q_vex.raw_equals(D(0)) } {
|
||||
return Ok(vex.as_noun());
|
||||
}
|
||||
|
||||
let uq_vex = q_vex.as_cell()?.tail().as_cell()?;
|
||||
let puq_vex = uq_vex.head();
|
||||
let quq_vex = uq_vex.tail();
|
||||
|
||||
let yit = slam(context, bus, quq_vex)?.as_cell()?;
|
||||
let p_yit = yit.head();
|
||||
let q_yit = yit.tail();
|
||||
|
||||
let yur = util::last(p_vex, p_yit)?;
|
||||
|
||||
if unsafe { q_yit.raw_equals(D(0)) } {
|
||||
Ok(T(&mut context.stack, &[yur, D(0)]))
|
||||
} else {
|
||||
let uq_yit = q_yit.as_cell()?.tail().as_cell()?;
|
||||
let quq_yit = uq_yit.tail();
|
||||
|
||||
let wam = slam(context, sab, quq_yit)?.as_cell()?;
|
||||
let p_wam = wam.head();
|
||||
let q_wam = wam.tail();
|
||||
|
||||
let goy = util::last(yur, p_wam)?;
|
||||
|
||||
if unsafe { q_wam.raw_equals(D(0)) } {
|
||||
Ok(T(&mut context.stack, &[goy, D(0)]))
|
||||
} else {
|
||||
let uq_wam = q_wam.as_cell()?.tail().as_cell()?;
|
||||
let puq_wam = uq_wam.head();
|
||||
let quq_wam = uq_wam.tail();
|
||||
|
||||
let puq_arg = T(&mut context.stack, &[puq_vex, puq_wam]);
|
||||
Ok(T(&mut context.stack, &[goy, D(0x0), puq_arg, quq_wam]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jet_pfix(context: &mut Context, subject: Noun) -> Result {
|
||||
let sam = slot(subject, 6)?;
|
||||
let vex = slot(sam, 2)?.as_cell()?;
|
||||
let sab = slot(sam, 3)?;
|
||||
|
||||
let p_vex = vex.head();
|
||||
let q_vex = vex.tail();
|
||||
|
||||
if unsafe { q_vex.raw_equals(D(0)) } {
|
||||
return Ok(vex.as_noun());
|
||||
}
|
||||
|
||||
let uq_vex = q_vex.as_cell()?.tail().as_cell()?;
|
||||
let quq_vex = uq_vex.tail();
|
||||
|
||||
let yit = slam(context, sab, quq_vex)?.as_cell()?;
|
||||
|
||||
let p_yit = yit.head();
|
||||
let q_yit = yit.tail();
|
||||
|
||||
// XX: Why don't we just return yit? When would p_vex ever be the later of the two?
|
||||
let arg = util::last(p_vex, p_yit)?;
|
||||
Ok(T(&mut context.stack, &[arg, q_yit]))
|
||||
}
|
||||
|
||||
pub fn jet_pose(context: &mut Context, subject: Noun) -> Result {
|
||||
let vex = slot(subject, 12)?.as_cell()?;
|
||||
let sab = slot(subject, 13)?;
|
||||
|
||||
let p_vex = vex.head();
|
||||
let q_vex = vex.tail();
|
||||
|
||||
if unsafe { !q_vex.raw_equals(D(0)) } {
|
||||
return Ok(vex.as_noun());
|
||||
}
|
||||
|
||||
let roq = kick(context, sab, D(2))?.as_cell()?;
|
||||
let yur = util::last(p_vex, roq.head())?;
|
||||
Ok(T(&mut context.stack, &[yur, roq.tail()]))
|
||||
}
|
||||
|
||||
pub fn jet_sfix(context: &mut Context, subject: Noun) -> Result {
|
||||
let sam = slot(subject, 6)?;
|
||||
let vex = slot(sam, 2)?.as_cell()?;
|
||||
let sab = slot(sam, 3)?;
|
||||
|
||||
let p_vex = vex.head();
|
||||
let q_vex = vex.tail();
|
||||
|
||||
if unsafe { q_vex.raw_equals(D(0)) } {
|
||||
return Ok(vex.as_noun());
|
||||
}
|
||||
|
||||
let uq_vex = q_vex.as_cell()?.tail().as_cell()?;
|
||||
let puq_vex = uq_vex.head();
|
||||
let quq_vex = uq_vex.tail();
|
||||
|
||||
let yit = slam(context, sab, quq_vex)?.as_cell()?;
|
||||
|
||||
let p_yit = yit.head();
|
||||
let q_yit = yit.tail();
|
||||
let yur = util::last(p_vex, p_yit)?;
|
||||
|
||||
if unsafe { q_yit.raw_equals(D(0)) } {
|
||||
Ok(T(&mut context.stack, &[yur, D(0)]))
|
||||
} else {
|
||||
let uq_yit = q_yit.as_cell()?.tail().as_cell()?;
|
||||
let quq_yit = uq_yit.tail();
|
||||
|
||||
Ok(T(&mut context.stack, &[yur, D(0), puq_vex, quq_yit]))
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Rule Builders
|
||||
//
|
||||
|
||||
pub fn jet_easy(context: &mut Context, subject: Noun) -> Result {
|
||||
let tub = slot(subject, 6)?;
|
||||
let van = slot(subject, 7)?;
|
||||
let huf = slot(van, 6)?;
|
||||
|
||||
Ok(T(
|
||||
&mut context.stack,
|
||||
&[tub.as_cell()?.head(), D(0), huf, tub],
|
||||
))
|
||||
}
|
||||
|
||||
pub fn jet_here(context: &mut Context, subject: Noun) -> Result {
|
||||
let tub = slot(subject, 6)?;
|
||||
let van = slot(subject, 7)?;
|
||||
let hez = slot(van, 12)?;
|
||||
let sef = slot(van, 13)?;
|
||||
|
||||
let p_tub = tub.as_cell()?.head();
|
||||
|
||||
let vex = slam(context, sef, tub)?.as_cell()?;
|
||||
let p_vex = vex.head();
|
||||
let q_vex = vex.tail();
|
||||
|
||||
// XX fixes Vere's jet mismatch with Hoon 139.
|
||||
if unsafe { q_vex.raw_equals(D(0)) } {
|
||||
return Ok(vex.as_noun());
|
||||
}
|
||||
|
||||
let uq_vex = q_vex.as_cell()?.tail().as_cell()?;
|
||||
let puq_vex = uq_vex.head();
|
||||
let quq_vex = uq_vex.tail();
|
||||
let pquq_vex = quq_vex.as_cell()?.head();
|
||||
|
||||
let inner_gud = T(&mut context.stack, &[p_tub, pquq_vex]);
|
||||
let gud = T(&mut context.stack, &[inner_gud, puq_vex]);
|
||||
let wag = slam(context, hez, gud)?;
|
||||
|
||||
Ok(T(&mut context.stack, &[p_vex, D(0), wag, quq_vex]))
|
||||
}
|
||||
|
||||
pub fn jet_just(context: &mut Context, subject: Noun) -> Result {
|
||||
let tub = slot(subject, 6)?;
|
||||
let van = slot(subject, 7)?;
|
||||
let daf = slot(van, 6)?;
|
||||
|
||||
let p_tub = tub.as_cell()?.head();
|
||||
let q_tub = tub.as_cell()?.tail();
|
||||
|
||||
if unsafe { q_tub.raw_equals(D(0)) || !daf.raw_equals(q_tub.as_cell()?.head()) } {
|
||||
util::fail(context, p_tub)
|
||||
} else {
|
||||
util::next(context, tub)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jet_mask(context: &mut Context, subject: Noun) -> Result {
|
||||
let tub = slot(subject, 6)?;
|
||||
let van = slot(subject, 7)?;
|
||||
let mut bud = slot(van, 6)?;
|
||||
|
||||
let p_tub = tub.as_cell()?.head();
|
||||
let q_tub = tub.as_cell()?.tail();
|
||||
|
||||
if unsafe { q_tub.raw_equals(D(0)) } {
|
||||
return util::fail(context, p_tub);
|
||||
}
|
||||
|
||||
let iq_tub = q_tub.as_cell()?.head();
|
||||
while unsafe { !bud.raw_equals(D(0)) } {
|
||||
let cell = bud.as_cell()?;
|
||||
if unsafe { cell.head().raw_equals(iq_tub) } {
|
||||
return util::next(context, tub);
|
||||
}
|
||||
bud = cell.tail();
|
||||
}
|
||||
util::fail(context, p_tub)
|
||||
}
|
||||
|
||||
pub fn jet_stag(context: &mut Context, subject: Noun) -> Result {
|
||||
let tub = slot(subject, 6)?;
|
||||
let van = slot(subject, 7)?;
|
||||
let gob = slot(van, 12)?;
|
||||
let sef = slot(van, 13)?;
|
||||
|
||||
let vex = slam(context, sef, tub)?.as_cell()?;
|
||||
let p_vex = vex.head();
|
||||
let q_vex = vex.tail();
|
||||
|
||||
if unsafe { q_vex.raw_equals(D(0)) } {
|
||||
Ok(vex.as_noun())
|
||||
} else {
|
||||
let uq_vex = q_vex.as_cell()?.tail().as_cell()?;
|
||||
let puq_vex = uq_vex.head();
|
||||
let quq_vex = uq_vex.tail();
|
||||
|
||||
let wag = T(&mut context.stack, &[gob, puq_vex]);
|
||||
Ok(T(&mut context.stack, &[p_vex, D(0), wag, quq_vex]))
|
||||
}
|
||||
}
|
||||
|
||||
pub mod util {
|
||||
use crate::interpreter::{inc, Context};
|
||||
use crate::jets::Result;
|
||||
use crate::noun::{Noun, D, T};
|
||||
use std::cmp::Ordering;
|
||||
|
||||
pub fn last(zyc: Noun, naz: Noun) -> Result {
|
||||
let zyl = zyc.as_cell()?;
|
||||
let nal = naz.as_cell()?;
|
||||
|
||||
let zyll = zyl.head().as_direct()?.data();
|
||||
let zylc = zyl.tail().as_direct()?.data();
|
||||
let nall = nal.head().as_direct()?.data();
|
||||
let nalc = nal.tail().as_direct()?.data();
|
||||
|
||||
match zyll.cmp(&nall) {
|
||||
Ordering::Equal => {
|
||||
if zylc > nalc {
|
||||
Ok(zyc)
|
||||
} else {
|
||||
Ok(naz)
|
||||
}
|
||||
}
|
||||
Ordering::Greater => Ok(zyc),
|
||||
Ordering::Less => Ok(naz),
|
||||
}
|
||||
}
|
||||
|
||||
// Passing Noun and doing Cell check inside next is best to keep jet semantics in sync w/ Hoon.
|
||||
pub fn next(context: &mut Context, tub: Noun) -> Result {
|
||||
let p_tub = tub.as_cell()?.head();
|
||||
let q_tub = tub.as_cell()?.tail();
|
||||
|
||||
if unsafe { q_tub.raw_equals(D(0)) } {
|
||||
return fail(context, p_tub);
|
||||
}
|
||||
|
||||
let iq_tub = q_tub.as_cell()?.head();
|
||||
let tq_tub = q_tub.as_cell()?.tail();
|
||||
|
||||
let zac = lust(context, iq_tub, p_tub)?;
|
||||
Ok(T(&mut context.stack, &[zac, D(0), iq_tub, zac, tq_tub]))
|
||||
}
|
||||
|
||||
// Passing Noun and doing Cell check inside next is best to keep jet semantics in sync w/ Hoon.
|
||||
pub fn lust(context: &mut Context, weq: Noun, naz: Noun) -> Result {
|
||||
let p_naz = naz.as_cell()?.head().as_atom()?;
|
||||
let q_naz = naz.as_cell()?.tail().as_atom()?;
|
||||
|
||||
if unsafe { weq.raw_equals(D(10)) } {
|
||||
let arg = inc(&mut context.stack, p_naz).as_noun();
|
||||
Ok(T(&mut context.stack, &[arg, D(1)]))
|
||||
} else {
|
||||
let arg = inc(&mut context.stack, q_naz).as_noun();
|
||||
Ok(T(&mut context.stack, &[p_naz.as_noun(), arg]))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fail(context: &mut Context, hair: Noun) -> Result {
|
||||
Ok(T(&mut context.stack, &[hair, D(0)]))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::jets::util::test::*;
|
||||
use crate::noun::{D, T};
|
||||
use crate::serialization::cue;
|
||||
use ibig::ubig;
|
||||
|
||||
// XX: need unit tests for:
|
||||
// +last
|
||||
// +bend
|
||||
// +comp
|
||||
// +glue
|
||||
// +pfix
|
||||
// +pose
|
||||
// +sfix
|
||||
// +here
|
||||
// +just
|
||||
// +mask
|
||||
// +stag
|
||||
|
||||
#[test]
|
||||
fn test_easy() {
|
||||
let c = &mut init_context();
|
||||
|
||||
// ((easy 'a') [[1 1] "abc"])
|
||||
// [[1 1] "abc"]
|
||||
let sam_jam = A(&mut c.stack, &ubig!(3205468216717221061))
|
||||
.as_atom()
|
||||
.unwrap();
|
||||
let sam = cue(&mut c.stack, sam_jam);
|
||||
// [p=[p=1 q=1] q=[~ [p='a' q=[p=[p=1 q=1] q="abc"]]]]
|
||||
let ans_jam = A(&mut c.stack, &ubig!(1720922644868600060465749189))
|
||||
.as_atom()
|
||||
.unwrap();
|
||||
let ans = cue(&mut c.stack, ans_jam);
|
||||
let ctx = T(&mut c.stack, &[D(0), D(97), D(0)]);
|
||||
assert_jet_door(c, jet_easy, sam, ctx, ans);
|
||||
|
||||
// ((easy %foo) [[1 1] "abc"])
|
||||
// [[1 1] "abc"]
|
||||
let sam_jam = A(&mut c.stack, &ubig!(3205468216717221061))
|
||||
.as_atom()
|
||||
.unwrap();
|
||||
let sam = cue(&mut c.stack, sam_jam);
|
||||
// [p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="abc"]]]]
|
||||
let ans_jam = A(&mut c.stack, &ubig!(3609036366588910247778413036281029))
|
||||
.as_atom()
|
||||
.unwrap();
|
||||
let ans = cue(&mut c.stack, ans_jam);
|
||||
let ctx = T(&mut c.stack, &[D(0), D(0x6f6f66), D(0)]);
|
||||
assert_jet_door(c, jet_easy, sam, ctx, ans);
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ use crate::noun::{Noun, Slots};
|
||||
use std::ptr::{copy_nonoverlapping, null_mut};
|
||||
|
||||
/// key = formula
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Warm(Hamt<WarmEntry>);
|
||||
|
||||
impl Preserve for Warm {
|
||||
@ -122,7 +123,8 @@ impl Warm {
|
||||
if let Ok(mut formula) = unsafe { (*battery).slot_atom(axis) } {
|
||||
warm.insert(stack, &mut formula, path, batteries, jet);
|
||||
} else {
|
||||
eprintln!("Bad axis {} into formula {:?}", axis, battery);
|
||||
// XX: need NockStack allocated string interpolation
|
||||
// eprintln!("Bad axis {} into formula {:?}", axis, battery);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,10 @@
|
||||
use ares::hamt::Hamt;
|
||||
use ares::interpreter::{interpret, Context};
|
||||
use ares::jets::cold::Cold;
|
||||
use ares::jets::hot::Hot;
|
||||
use ares::jets::warm::Warm;
|
||||
use ares::mem::NockStack;
|
||||
use ares::newt::Newt;
|
||||
use ares::noun::{IndirectAtom, Noun, D};
|
||||
use ares::jets::hot::URBIT_HOT_STATE;
|
||||
use ares::serf::serf;
|
||||
use ares::serialization::{cue, jam};
|
||||
use memmap::Mmap;
|
||||
use memmap::MmapMut;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io;
|
||||
use std::mem;
|
||||
use std::ptr::copy_nonoverlapping;
|
||||
use std::ptr::write_bytes;
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
// debug
|
||||
// eprintln!("serf: pid {}", std::process::id());
|
||||
// if unsafe { libc::kill(std::process::id() as i32, libc::SIGSTOP) } != 0 {
|
||||
// panic!("Could not stop ourselves.");
|
||||
@ -43,61 +29,8 @@ fn main() -> io::Result<()> {
|
||||
}
|
||||
|
||||
if filename == "serf" {
|
||||
return serf();
|
||||
return serf(URBIT_HOT_STATE);
|
||||
}
|
||||
|
||||
let output_filename = format!("{}.out", filename);
|
||||
let f = File::open(filename)?;
|
||||
let in_len = f.metadata()?.len();
|
||||
let mut stack = NockStack::new(8 << 10 << 10, 0);
|
||||
let jammed_input = unsafe {
|
||||
let in_map = Mmap::map(&f)?;
|
||||
let word_len = (in_len + 7) >> 3;
|
||||
let (mut atom, dest) = IndirectAtom::new_raw_mut(&mut stack, word_len as usize);
|
||||
write_bytes(dest.add(word_len as usize - 1), 0, 1);
|
||||
copy_nonoverlapping(in_map.as_ptr(), dest as *mut u8, in_len as usize);
|
||||
mem::drop(in_map);
|
||||
atom.normalize_as_atom()
|
||||
};
|
||||
let input = cue(&mut stack, jammed_input);
|
||||
let input_cell = input
|
||||
.as_cell()
|
||||
.expect("Input must be jam of subject/formula pair");
|
||||
let newt = Newt::new_mock();
|
||||
let cache = Hamt::<Noun>::new(&mut stack);
|
||||
let cold = Cold::new(&mut stack);
|
||||
let warm = Warm::new(&mut stack);
|
||||
let hot = Hot::init(&mut stack);
|
||||
let mut context = Context {
|
||||
stack,
|
||||
newt,
|
||||
cache,
|
||||
cold,
|
||||
warm,
|
||||
hot,
|
||||
scry_stack: D(0),
|
||||
trace_info: None,
|
||||
};
|
||||
let result =
|
||||
interpret(&mut context, input_cell.head(), input_cell.tail()).expect("nock failed");
|
||||
if let Ok(atom) = result.as_atom() {
|
||||
println!("Result: {}", atom);
|
||||
}
|
||||
let jammed_result = jam(&mut context.stack, result);
|
||||
let f_out = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.create(true)
|
||||
.open(output_filename)?;
|
||||
f_out.set_len((jammed_result.size() << 3) as u64)?;
|
||||
unsafe {
|
||||
let mut out_map = MmapMut::map_mut(&f_out)?;
|
||||
copy_nonoverlapping(
|
||||
jammed_result.data_pointer() as *mut u8,
|
||||
out_map.as_mut_ptr(),
|
||||
jammed_result.size() << 3,
|
||||
);
|
||||
out_map.flush()?;
|
||||
};
|
||||
Ok(())
|
||||
panic!("Ares can only run as a serf!");
|
||||
}
|
||||
|
@ -589,10 +589,12 @@ impl NockStack {
|
||||
*/
|
||||
pub unsafe fn with_frame<F, O>(&mut self, num_locals: usize, f: F) -> O
|
||||
where
|
||||
F: FnOnce() -> O,
|
||||
F: FnOnce(&mut NockStack) -> O,
|
||||
O: Preserve,
|
||||
{
|
||||
self.frame_push(num_locals);
|
||||
let ret = f();
|
||||
let mut ret = f(self);
|
||||
ret.preserve(self);
|
||||
self.frame_pop();
|
||||
ret
|
||||
}
|
||||
@ -1059,3 +1061,19 @@ impl Stack for NockStack {
|
||||
self.layout_alloc(layout)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Preserve, E: Preserve> Preserve for Result<T, E> {
|
||||
unsafe fn preserve(&mut self, stack: &mut NockStack) {
|
||||
match self.as_mut() {
|
||||
Ok(t_ref) => t_ref.preserve(stack),
|
||||
Err(e_ref) => e_ref.preserve(stack),
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn assert_in_stack(&self, stack: &NockStack) {
|
||||
match self.as_ref() {
|
||||
Ok(t_ref) => t_ref.assert_in_stack(stack),
|
||||
Err(e_ref) => e_ref.assert_in_stack(stack),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use crate::hamt::Hamt;
|
||||
use crate::interpreter;
|
||||
use crate::interpreter::{inc, interpret, Error};
|
||||
use crate::jets::cold::Cold;
|
||||
use crate::jets::hot::Hot;
|
||||
use crate::jets::hot::{Hot, HotEntry};
|
||||
use crate::jets::list::util::{lent, zing};
|
||||
use crate::jets::nock::util::mook;
|
||||
use crate::jets::warm::Warm;
|
||||
@ -79,17 +79,20 @@ struct SnapshotMem {
|
||||
|
||||
const PMA_CURRENT_SNAPSHOT_VERSION: u64 = 1;
|
||||
|
||||
struct Context {
|
||||
struct Context<'a> {
|
||||
epoch: u64,
|
||||
event_num: u64,
|
||||
pma: PMA,
|
||||
arvo: Noun,
|
||||
mug: u32,
|
||||
constant_hot_state: &'a [HotEntry],
|
||||
nock_context: interpreter::Context,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub fn load(snap_path: PathBuf, trace_info: Option<TraceInfo>) -> Context {
|
||||
impl<'a> Context<'a> {
|
||||
pub fn load(snap_path: PathBuf, trace_info: Option<TraceInfo>,
|
||||
constant_hot_state: &[HotEntry],
|
||||
) -> Context {
|
||||
let mut pma = PMA::open(snap_path).expect("serf: pma open failed");
|
||||
|
||||
let snapshot_version = pma.meta_get(BTMetaField::SnapshotVersion as usize);
|
||||
@ -102,7 +105,7 @@ impl Context {
|
||||
_ => panic!("Unsupported snapshot version"),
|
||||
};
|
||||
|
||||
Context::new(trace_info, pma, snapshot)
|
||||
Context::new(trace_info, pma, snapshot, constant_hot_state)
|
||||
}
|
||||
|
||||
pub fn save(&mut self) {
|
||||
@ -134,7 +137,9 @@ impl Context {
|
||||
self.pma.meta_set(BTMetaField::Snapshot as usize, handle);
|
||||
}
|
||||
|
||||
fn new(trace_info: Option<TraceInfo>, pma: PMA, snapshot: Option<Snapshot>) -> Self {
|
||||
fn new(trace_info: Option<TraceInfo>, pma: PMA, snapshot: Option<Snapshot>,
|
||||
constant_hot_state: &'a [HotEntry],
|
||||
) -> Self {
|
||||
let mut stack = NockStack::new(1024 << 10 << 10, 0);
|
||||
let newt = Newt::new();
|
||||
let cache = Hamt::<Noun>::new(&mut stack);
|
||||
@ -151,9 +156,8 @@ impl Context {
|
||||
}
|
||||
};
|
||||
|
||||
let mut hot = Hot::init(&mut stack);
|
||||
let mut hot = Hot::init(&mut stack, constant_hot_state);
|
||||
let warm = Warm::init(&mut stack, &mut cold, &mut hot);
|
||||
|
||||
let mug = mug_u32(&mut stack, arvo);
|
||||
|
||||
let nock_context = interpreter::Context {
|
||||
@ -174,6 +178,7 @@ impl Context {
|
||||
arvo,
|
||||
mug,
|
||||
nock_context,
|
||||
constant_hot_state,
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,7 +202,7 @@ impl Context {
|
||||
// Then, save the stack and reset to the saved stack for each event, thus avoiding the need
|
||||
// to recreate the hot state each event, since it does not change over the execution of the
|
||||
// interpreter.
|
||||
self.nock_context.hot = Hot::init(&mut self.nock_context.stack);
|
||||
self.nock_context.hot = Hot::init(&mut self.nock_context.stack, self.constant_hot_state);
|
||||
|
||||
// XX the above trick won't work for the warm state, since it changes whenever the cold
|
||||
// state does. One possibility is to just save the warm and hot states in the snapshot
|
||||
@ -306,7 +311,7 @@ lazy_static! {
|
||||
* This is suitable for talking to the king process. To test, change the arg_c[0] line in
|
||||
* u3_lord_init in vere to point at this binary and start vere like normal.
|
||||
*/
|
||||
pub fn serf() -> io::Result<()> {
|
||||
pub fn serf(constant_hot_state: &[HotEntry]) -> io::Result<()> {
|
||||
// Register SIGINT signal hook to set flag first time, shutdown second time
|
||||
signal_hook::flag::register_conditional_shutdown(SIGINT, 1, Arc::clone(&TERMINATOR))?;
|
||||
signal_hook::flag::register(SIGINT, Arc::clone(&TERMINATOR))?;
|
||||
@ -335,13 +340,14 @@ pub fn serf() -> io::Result<()> {
|
||||
None
|
||||
};
|
||||
if let Some(ref mut info) = trace_info.as_mut() {
|
||||
if let Err(e) = write_metadata(info) {
|
||||
eprintln!("\rError initializing trace file: {:?}", e);
|
||||
if let Err(_e) = write_metadata(info) {
|
||||
// XX: need NockStack allocated string interpolation
|
||||
// eprintln!("\rError initializing trace file: {:?}", e);
|
||||
trace_info = None;
|
||||
}
|
||||
}
|
||||
|
||||
let mut context = Context::load(snap_path, trace_info);
|
||||
let mut context = Context::load(snap_path, trace_info, constant_hot_state);
|
||||
context.ripe();
|
||||
|
||||
// Can't use for loop because it borrows newt
|
||||
@ -576,6 +582,7 @@ fn work_swap(context: &mut Context, job: Noun, goof: Noun) {
|
||||
clear_interrupt();
|
||||
|
||||
let stack = &mut context.nock_context.stack;
|
||||
context.nock_context.cache = Hamt::<Noun>::new(stack);
|
||||
// crud ovo = [+(now) [%$ %arvo ~] [%crud goof ovo]]
|
||||
let job_cell = job.as_cell().expect("serf: work: job not a cell");
|
||||
let job_now = job_cell.head().as_atom().expect("serf: work: now not atom");
|
||||
|
@ -99,8 +99,9 @@ pub fn write_metadata(info: &mut TraceInfo) -> Result<(), Error> {
|
||||
///
|
||||
/// This should result in a well-formed partial trace file.
|
||||
pub fn write_serf_trace_safe(info: &mut Option<TraceInfo>, name: &str, start: Instant) {
|
||||
if let Err(e) = write_serf_trace(info.as_mut().unwrap(), name, start) {
|
||||
eprintln!("\rserf: error writing event trace to file: {:?}", e);
|
||||
if let Err(_e) = write_serf_trace(info.as_mut().unwrap(), name, start) {
|
||||
// XX: need NockStack allocated string interpolation
|
||||
// eprintln!("\rserf: error writing event trace to file: {:?}", e);
|
||||
*info = None;
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,6 @@
|
||||
"rustfmt"
|
||||
"rust-src"
|
||||
])
|
||||
pkgs.autoconf-archive
|
||||
pkgs.cargo-watch
|
||||
pkgs.bacon
|
||||
pkgs.iconv
|
||||
|
@ -1,5 +1,5 @@
|
||||
{ stdenv, fetchFromGitHub, autoreconfHook, pkg-config, openssl, cryptopp, secp256k1, libaes_siv }:
|
||||
let rev = "375fa7e6a730d8aa517ca981b2b7b505bf4e1103";
|
||||
{ stdenv, fetchFromGitHub, autoreconfHook, autoconf-archive, pkg-config, openssl, cryptopp, secp256k1, libaes_siv }:
|
||||
let rev = "43479c3262a11e20da5f6218f3b0b3d63931ceea";
|
||||
in stdenv.mkDerivation {
|
||||
pname = "urcrypt";
|
||||
version = "git-${rev}";
|
||||
@ -7,14 +7,14 @@ in stdenv.mkDerivation {
|
||||
inherit rev;
|
||||
owner = "urbit";
|
||||
repo = "urcrypt";
|
||||
hash = "sha256:1c3cqmwr5mys4v9y0834hxqfr6aynm2gav7730bjzfvrdc21ijqa";
|
||||
hash = "sha256-GkhqvhDyhsdzjWpR8uqmhdRdhxdpmLGWXtIUZPAbWZs=";
|
||||
};
|
||||
|
||||
preConfigure = ''
|
||||
./autogen.sh
|
||||
'';
|
||||
# preConfigure = ''
|
||||
# ./autogen.sh
|
||||
# '';
|
||||
|
||||
nativeBuildInputs = [autoreconfHook pkg-config];
|
||||
nativeBuildInputs = [autoreconfHook autoconf-archive pkg-config];
|
||||
|
||||
buildInputs = [openssl cryptopp secp256k1 libaes_siv];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user