Refactor Context

This commit is contained in:
Alex Shelkovnykov 2023-10-22 22:50:03 -06:00
parent 96f9e89e7e
commit d4f9b907b1
11 changed files with 898 additions and 848 deletions

View File

@ -254,16 +254,16 @@ enum NockWork {
Work12(Nock12),
}
pub struct Context<'a> {
pub stack: &'a mut NockStack,
pub struct Context {
pub stack: NockStack,
// For printing slogs; if None, print to stdout; Option slated to be removed
pub newt: Option<&'a mut Newt>,
// Per-event cache; option to share cache with virtualized events
pub cache: &'a mut Hamt<Noun>,
pub newt: Newt,
pub cold: Cold,
pub warm: Warm,
pub hot: Hot,
// XX: persistent memo cache
pub cold: &'a mut Cold,
pub warm: &'a mut Warm,
pub hot: &'a Hot,
// Per-event cache; option to share cache with virtualized events
pub cache: Hamt<Noun>,
pub scry_stack: Noun,
}
@ -335,7 +335,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
context.stack.frame_push(1);
// Bottom of mean stack
*(context.stack.local_noun_pointer(0)) = D(0);
*context.stack.push() = NockWork::Done;
*(context.stack.push()) = NockWork::Done;
};
// DO NOT REMOVE THIS ASSERTION
@ -350,56 +350,61 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
//
// (See https://docs.rs/assert_no_alloc/latest/assert_no_alloc/#advanced-use)
let nock = assert_no_alloc(|| unsafe {
push_formula(context.stack, formula, true)?;
push_formula(&mut context.stack, formula, true)?;
loop {
let work: NockWork = *context.stack.top();
match work {
NockWork::Done => {
debug_assertions(context.stack, orig_subject);
debug_assertions(context.stack, subject);
debug_assertions(context.stack, res);
let stack = &mut context.stack;
context.stack.preserve(context.cache);
context.stack.preserve(context.cold);
context.stack.preserve(context.warm);
context.stack.preserve(&mut res);
context.stack.frame_pop();
debug_assertions(stack, orig_subject);
debug_assertions(stack, subject);
debug_assertions(stack, res);
debug_assertions(context.stack, orig_subject);
debug_assertions(context.stack, res);
stack.preserve(&mut context.cache);
stack.preserve(&mut context.cold);
stack.preserve(&mut context.warm);
stack.preserve(&mut res);
stack.frame_pop();
debug_assertions(stack, orig_subject);
debug_assertions(stack, res);
break Ok(res);
}
NockWork::Ret => {
debug_assertions(context.stack, orig_subject);
debug_assertions(context.stack, subject);
debug_assertions(context.stack, res);
let stack = &mut context.stack;
context.stack.preserve(context.cache);
context.stack.preserve(context.cold);
context.stack.preserve(context.warm);
context.stack.preserve(&mut res);
context.stack.frame_pop();
debug_assertions(stack, orig_subject);
debug_assertions(stack, subject);
debug_assertions(stack, res);
debug_assertions(context.stack, orig_subject);
debug_assertions(context.stack, res);
stack.preserve(&mut context.cache);
stack.preserve(&mut context.cold);
stack.preserve(&mut context.warm);
stack.preserve(&mut res);
stack.frame_pop();
debug_assertions(stack, orig_subject);
debug_assertions(stack, res);
}
NockWork::WorkCons(mut cons) => match cons.todo {
TodoCons::ComputeHead => {
cons.todo = TodoCons::ComputeTail;
*context.stack.top() = NockWork::WorkCons(cons);
push_formula(context.stack, cons.head, false)?;
push_formula(&mut context.stack, cons.head, false)?;
}
TodoCons::ComputeTail => {
cons.todo = TodoCons::Cons;
cons.head = res;
*context.stack.top() = NockWork::WorkCons(cons);
push_formula(context.stack, cons.tail, false)?;
push_formula(&mut context.stack, cons.tail, false)?;
}
TodoCons::Cons => {
res = T(context.stack, &[cons.head, res]);
context.stack.pop::<NockWork>();
let stack = &mut context.stack;
res = T(stack, &[cons.head, res]);
stack.pop::<NockWork>();
}
},
NockWork::Work0(zero) => {
@ -424,20 +429,20 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
Todo2::ComputeSubject => {
vale.todo = Todo2::ComputeFormula;
*context.stack.top() = NockWork::Work2(vale);
push_formula(context.stack, vale.subject, false)?;
push_formula(&mut context.stack, vale.subject, false)?;
}
Todo2::ComputeFormula => {
vale.todo = Todo2::ComputeResult;
vale.subject = res;
*context.stack.top() = NockWork::Work2(vale);
push_formula(context.stack, vale.formula, false)?;
push_formula(&mut context.stack, vale.formula, false)?;
}
Todo2::ComputeResult => {
if let Some(jet) =
context
.warm
.find_jet(context.stack, &mut vale.subject, &mut res)
{
if let Some(jet) = context.warm.find_jet(
&mut context.stack,
&mut vale.subject,
&mut res,
) {
match jet(context, vale.subject) {
Ok(jet_res) => {
res = jet_res;
@ -451,31 +456,34 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
}
};
let stack = &mut context.stack;
if vale.tail {
context.stack.pop::<NockWork>();
stack.pop::<NockWork>();
subject = vale.subject;
push_formula(context.stack, res, true)?;
push_formula(stack, res, true)?;
} else {
vale.todo = Todo2::RestoreSubject;
std::mem::swap(&mut vale.subject, &mut subject);
*context.stack.top() = NockWork::Work2(vale);
*stack.top() = NockWork::Work2(vale);
debug_assertions(context.stack, orig_subject);
debug_assertions(context.stack, subject);
debug_assertions(context.stack, res);
debug_assertions(stack, orig_subject);
debug_assertions(stack, subject);
debug_assertions(stack, res);
mean_frame_push(context.stack, 0);
*context.stack.push() = NockWork::Ret;
push_formula(context.stack, res, true)?;
mean_frame_push(stack, 0);
*stack.push() = NockWork::Ret;
push_formula(stack, res, true)?;
}
}
Todo2::RestoreSubject => {
subject = vale.subject;
context.stack.pop::<NockWork>();
let stack = &mut context.stack;
debug_assertions(context.stack, orig_subject);
debug_assertions(context.stack, subject);
debug_assertions(context.stack, res);
subject = vale.subject;
stack.pop::<NockWork>();
debug_assertions(stack, orig_subject);
debug_assertions(stack, subject);
debug_assertions(stack, res);
}
}
}
@ -483,7 +491,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
Todo3::ComputeChild => {
thee.todo = Todo3::ComputeType;
*context.stack.top() = NockWork::Work3(thee);
push_formula(context.stack, thee.child, false)?;
push_formula(&mut context.stack, thee.child, false)?;
}
Todo3::ComputeType => {
res = if res.is_cell() { D(0) } else { D(1) };
@ -494,11 +502,11 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
Todo4::ComputeChild => {
four.todo = Todo4::Increment;
*context.stack.top() = NockWork::Work4(four);
push_formula(context.stack, four.child, false)?;
push_formula(&mut context.stack, four.child, false)?;
}
Todo4::Increment => {
if let Ok(atom) = res.as_atom() {
res = inc(context.stack, atom).as_noun();
res = inc(&mut context.stack, atom).as_noun();
context.stack.pop::<NockWork>();
} else {
// Cannot increment (Nock 4) a cell
@ -510,37 +518,39 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
Todo5::ComputeLeftChild => {
five.todo = Todo5::ComputeRightChild;
*context.stack.top() = NockWork::Work5(five);
push_formula(context.stack, five.left, false)?;
push_formula(&mut context.stack, five.left, false)?;
}
Todo5::ComputeRightChild => {
five.todo = Todo5::TestEquals;
five.left = res;
*context.stack.top() = NockWork::Work5(five);
push_formula(context.stack, five.right, false)?;
push_formula(&mut context.stack, five.right, false)?;
}
Todo5::TestEquals => {
let stack = &mut context.stack;
let saved_value_ptr = &mut five.left;
res = if unifying_equality(context.stack, &mut res, saved_value_ptr) {
res = if unifying_equality(stack, &mut res, saved_value_ptr) {
D(0)
} else {
D(1)
};
context.stack.pop::<NockWork>();
stack.pop::<NockWork>();
}
},
NockWork::Work6(mut cond) => match cond.todo {
Todo6::ComputeTest => {
cond.todo = Todo6::ComputeBranch;
*context.stack.top() = NockWork::Work6(cond);
push_formula(context.stack, cond.test, false)?;
push_formula(&mut context.stack, cond.test, false)?;
}
Todo6::ComputeBranch => {
context.stack.pop::<NockWork>();
let stack = &mut context.stack;
stack.pop::<NockWork>();
if let Left(direct) = res.as_either_direct_allocated() {
if direct.data() == 0 {
push_formula(context.stack, cond.zero, cond.tail)?;
push_formula(stack, cond.zero, cond.tail)?;
} else if direct.data() == 1 {
push_formula(context.stack, cond.once, cond.tail)?;
push_formula(stack, cond.once, cond.tail)?;
} else {
// Test branch of Nock 6 must return 0 or 1
break Err(Failure::Deterministic);
@ -555,19 +565,20 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
Todo7::ComputeSubject => {
pose.todo = Todo7::ComputeResult;
*context.stack.top() = NockWork::Work7(pose);
push_formula(context.stack, pose.subject, false)?;
push_formula(&mut context.stack, pose.subject, false)?;
}
Todo7::ComputeResult => {
let stack = &mut context.stack;
if pose.tail {
context.stack.pop::<NockWork>();
stack.pop::<NockWork>();
subject = res;
push_formula(context.stack, pose.formula, true)?;
push_formula(stack, pose.formula, true)?;
} else {
pose.todo = Todo7::RestoreSubject;
pose.subject = subject;
*context.stack.top() = NockWork::Work7(pose);
*stack.top() = NockWork::Work7(pose);
subject = res;
push_formula(context.stack, pose.formula, false)?;
push_formula(stack, pose.formula, false)?;
}
}
Todo7::RestoreSubject => {
@ -579,19 +590,20 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
Todo8::ComputeSubject => {
pins.todo = Todo8::ComputeResult;
*context.stack.top() = NockWork::Work8(pins);
push_formula(context.stack, pins.pin, false)?;
push_formula(&mut context.stack, pins.pin, false)?;
}
Todo8::ComputeResult => {
let stack = &mut context.stack;
if pins.tail {
subject = T(context.stack, &[res, subject]);
context.stack.pop::<NockWork>();
push_formula(context.stack, pins.formula, true)?;
subject = T(stack, &[res, subject]);
stack.pop::<NockWork>();
push_formula(stack, pins.formula, true)?;
} else {
pins.todo = Todo8::RestoreSubject;
pins.pin = subject;
*context.stack.top() = NockWork::Work8(pins);
subject = T(context.stack, &[res, subject]);
push_formula(context.stack, pins.formula, false)?;
*stack.top() = NockWork::Work8(pins);
subject = T(stack, &[res, subject]);
push_formula(stack, pins.formula, false)?;
}
}
Todo8::RestoreSubject => {
@ -608,13 +620,15 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
Todo9::ComputeCore => {
kale.todo = Todo9::ComputeResult;
*context.stack.top() = NockWork::Work9(kale);
push_formula(context.stack, kale.core, false)?;
push_formula(&mut context.stack, kale.core, false)?;
}
Todo9::ComputeResult => {
if let Ok(mut formula) = res.slot_atom(kale.axis) {
if let Some(jet) =
context.warm.find_jet(context.stack, &mut res, &mut formula)
{
if let Some(jet) = context.warm.find_jet(
&mut context.stack,
&mut res,
&mut formula,
) {
match jet(context, res) {
Ok(jet_res) => {
res = jet_res;
@ -628,23 +642,24 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
}
};
let stack = &mut context.stack;
if kale.tail {
context.stack.pop::<NockWork>();
stack.pop::<NockWork>();
subject = res;
push_formula(context.stack, formula, true)?;
push_formula(stack, formula, true)?;
} else {
kale.todo = Todo9::RestoreSubject;
kale.core = subject;
*context.stack.top() = NockWork::Work9(kale);
*stack.top() = NockWork::Work9(kale);
debug_assertions(context.stack, orig_subject);
debug_assertions(context.stack, subject);
debug_assertions(context.stack, res);
debug_assertions(stack, orig_subject);
debug_assertions(stack, subject);
debug_assertions(stack, res);
subject = res;
mean_frame_push(context.stack, 0);
*context.stack.push() = NockWork::Ret;
push_formula(context.stack, formula, true)?;
mean_frame_push(stack, 0);
*stack.push() = NockWork::Ret;
push_formula(stack, formula, true)?;
}
} else {
// Axis into core must be atom
@ -652,12 +667,14 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
}
}
Todo9::RestoreSubject => {
subject = kale.core;
context.stack.pop::<NockWork>();
let stack = &mut context.stack;
debug_assertions(context.stack, orig_subject);
debug_assertions(context.stack, subject);
debug_assertions(context.stack, res);
subject = kale.core;
stack.pop::<NockWork>();
debug_assertions(stack, orig_subject);
debug_assertions(stack, subject);
debug_assertions(stack, res);
}
}
}
@ -666,16 +683,16 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
Todo10::ComputeTree => {
diet.todo = Todo10::ComputePatch; // should we compute patch then tree?
*context.stack.top() = NockWork::Work10(diet);
push_formula(context.stack, diet.tree, false)?;
push_formula(&mut context.stack, diet.tree, false)?;
}
Todo10::ComputePatch => {
diet.todo = Todo10::Edit;
diet.tree = res;
*context.stack.top() = NockWork::Work10(diet);
push_formula(context.stack, diet.patch, false)?;
push_formula(&mut context.stack, diet.patch, false)?;
}
Todo10::Edit => {
res = edit(context.stack, diet.axis.as_bitslice(), res, diet.tree);
res = edit(&mut context.stack, diet.axis.as_bitslice(), res, diet.tree);
context.stack.pop::<NockWork>();
}
}
@ -691,7 +708,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
Ok(None) => {
dint.todo = Todo11D::ComputeResult;
*context.stack.top() = NockWork::Work11D(dint);
push_formula(context.stack, dint.hint, false)?;
push_formula(&mut context.stack, dint.hint, false)?;
}
Err(err) => {
break Err(err);
@ -718,7 +735,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
dint.hint = res;
*context.stack.top() = NockWork::Work11D(dint);
}
push_formula(context.stack, dint.body, dint.tail)?;
push_formula(&mut context.stack, dint.body, dint.tail)?;
}
Err(err) => {
break Err(err);
@ -755,7 +772,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
sint.todo = Todo11S::Done;
*context.stack.top() = NockWork::Work11S(sint);
}
push_formula(context.stack, sint.body, sint.tail)?;
push_formula(&mut context.stack, sint.body, sint.tail)?;
}
Err(err) => {
break Err(err);
@ -775,30 +792,33 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
},
NockWork::Work12(mut scry) => match scry.todo {
Todo12::ComputeReff => {
let stack = &mut context.stack;
scry.todo = Todo12::ComputePath;
*context.stack.top() = NockWork::Work12(scry);
push_formula(context.stack, scry.reff, false)?;
*stack.top() = NockWork::Work12(scry);
push_formula(stack, scry.reff, false)?;
}
Todo12::ComputePath => {
let stack = &mut context.stack;
scry.todo = Todo12::Scry;
scry.reff = res;
*context.stack.top() = NockWork::Work12(scry);
push_formula(context.stack, scry.path, false)?;
*stack.top() = NockWork::Work12(scry);
push_formula(stack, scry.path, false)?;
}
Todo12::Scry => {
let stack = &mut context.stack;
if let Some(cell) = context.scry_stack.cell() {
let scry_handler = cell.head();
let scry_gate = scry_handler.as_cell()?;
let payload = T(context.stack, &[scry.reff, res]);
let payload = T(stack, &[scry.reff, res]);
let scry_core = T(
context.stack,
stack,
&[
scry_gate.head(),
payload,
scry_gate.tail().as_cell()?.tail(),
],
);
let scry_form = T(context.stack, &[D(9), D(2), D(1), scry_core]);
let scry_form = T(stack, &[D(9), D(2), D(1), scry_core]);
scry.todo = Todo12::Done;
scry.path = res;
@ -806,8 +826,8 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
scry.flag = Some(scry_flag);
scry_flag = true;
context.scry_stack = cell.tail();
*context.stack.top() = NockWork::Work12(scry);
push_formula(context.stack, scry_form, false)?;
*stack.top() = NockWork::Work12(scry);
push_formula(stack, scry_form, false)?;
} else {
// No scry handler
break Err(Failure::Deterministic);
@ -824,10 +844,10 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
}
Right(cell) => match cell.tail().as_either_atom_cell() {
Left(_) => {
let stack = &mut context.stack;
scry_flag = scry.flag.unwrap();
let hunk =
T(context.stack, &[D(tas!(b"hunk")), scry.reff, scry.path]);
mean_push(context.stack, hunk);
let hunk = T(stack, &[D(tas!(b"hunk")), scry.reff, scry.path]);
mean_push(stack, hunk);
break Err(Failure::Deterministic);
}
Right(cell) => {
@ -1078,9 +1098,9 @@ pub fn exit(
_ => *(stack.local_noun_pointer(0)),
};
while (*stack).get_frame_pointer() != virtual_frame {
(*stack).preserve(&mut preserve);
(*stack).frame_pop();
while (stack).get_frame_pointer() != virtual_frame {
(stack).preserve(&mut preserve);
(stack).frame_pop();
}
match error {
@ -1275,8 +1295,8 @@ mod hint {
"\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]);
let tape = tape(stack, "jet mismatch");
let mean = T(stack, &[D(tas!(b"mean")), tape]);
mean_push(stack, mean);
Err(Failure::Deterministic)
} else {
@ -1291,8 +1311,8 @@ mod hint {
"\rjet {} failed, raw: {:?}, jetted: {}",
jet_name, error, jet_res
);
let tape = tape(*stack, "jet mismatch");
let mean = T(*stack, &[D(tas!(b"mean")), tape]);
let tape = tape(stack, "jet mismatch");
let mean = T(stack, &[D(tas!(b"mean")), tape]);
mean_push(stack, mean);
match error {
@ -1312,8 +1332,8 @@ mod hint {
let stack = &mut context.stack;
// XX: need string interpolation without allocation
// 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]);
let tape = tape(stack, "jet error");
let mean = T(stack, &[D(tas!(b"mean")), tape]);
mean_push(stack, mean);
Err(err.into())
}
@ -1327,7 +1347,7 @@ mod hint {
}
tas!(b"memo") => {
let stack = &mut context.stack;
let mut key = Cell::new(*stack, subject, body).as_noun();
let mut key = Cell::new(stack, subject, body).as_noun();
Ok(context.cache.lookup(stack, &mut key))
}
_ => Ok(None),
@ -1345,12 +1365,15 @@ mod hint {
// XX: handle IndirectAtom tags
match tag.as_direct()?.data() {
tas!(b"slog") => {
let stack = &mut context.stack;
let newt = &mut context.newt;
let (_form, clue) = hint.ok_or(Failure::Deterministic)?;
let slog_cell = clue.as_cell()?;
let pri = slog_cell.head().as_direct()?.data();
let tank = slog_cell.tail();
slog(context.stack, &mut context.newt, pri, tank);
newt.slog(stack, pri, tank);
Ok(None)
}
tas!(b"hand") | tas!(b"hunk") | tas!(b"lose") | tas!(b"mean") | tas!(b"spot") => {
@ -1361,7 +1384,7 @@ mod hint {
let stack = &mut context.stack;
let (_form, clue) = hint.ok_or(Failure::Deterministic)?;
let noun = T(*stack, &[tag.as_noun(), clue]);
let noun = T(stack, &[tag.as_noun(), clue]);
mean_push(stack, noun);
Ok(None)
}
@ -1370,14 +1393,16 @@ mod hint {
// pretty sure we should be bailing on error
// might need to switch return type to Result<Option<Noun>, Failure>
let mean = unsafe { *(context.stack.local_noun_pointer(0)) };
let tone = Cell::new(context.stack, D(2), mean);
let tone = Cell::new(&mut context.stack, D(2), mean);
match mook(context, tone, true) {
Ok(toon) => {
let stack = &mut context.stack;
let newt = &mut context.newt;
if unsafe { !toon.head().raw_equals(D(2)) } {
let tape = tape(*stack, "%hela failed: toon not %2");
let mean = T(*stack, &[D(tas!(b"mean")), tape]);
let tape = tape(stack, "%hela failed: toon not %2");
let mean = T(stack, &[D(tas!(b"mean")), tape]);
mean_push(stack, mean);
return Err(Failure::Deterministic);
}
@ -1389,7 +1414,7 @@ mod hint {
}
let cell = list.as_cell().unwrap();
slog(stack, &mut context.newt, 0, cell.head());
newt.slog(stack, 0, cell.head());
list = cell.tail();
}
@ -1398,8 +1423,8 @@ mod hint {
}
Err(err) => {
let stack = &mut context.stack;
let tape = tape(*stack, "%hela failed: mook error");
let mean = T(*stack, &[D(tas!(b"mean")), tape]);
let tape = tape(stack, "%hela failed: mook error");
let mean = T(stack, &[D(tas!(b"mean")), tape]);
mean_push(stack, mean);
Err(err.into())
}
@ -1419,14 +1444,16 @@ mod hint {
res: Noun,
) -> Result<Option<Noun>, Failure> {
let stack = &mut context.stack;
let cache = &mut context.cache;
let newt = &mut context.newt;
let cold = &mut context.cold;
let hot = &context.hot;
let cache = &mut context.cache;
// XX: handle IndirectAtom tags
match tag.as_direct()?.data() {
tas!(b"memo") => {
let mut key = Cell::new(*stack, subject, body).as_noun();
**cache = (*cache).insert(stack, &mut key, res);
let mut key = Cell::new(stack, subject, body).as_noun();
context.cache = cache.insert(stack, &mut key, res);
}
tas!(b"hand") | tas!(b"hunk") | tas!(b"lose") | tas!(b"mean") | tas!(b"spot") => {
mean_pop(stack);
@ -1440,27 +1467,27 @@ mod hint {
if parent_formula_op.data() == 1 {
if parent_formula_ax.as_direct()?.data() == 0 {
context.cold.register(stack, res, parent_formula_ax, chum)
cold.register(stack, res, parent_formula_ax, chum)
} else {
// XX: Need better message in slog; need better slogging tools
// format!("invalid root parent axis: {} {}", chum, parent_formula_ax)
let tape =
tape(*stack, "serf: cold: register: invalid root parent axis");
tape(stack, "serf: cold: register: invalid root parent axis");
slog_leaf(stack, newt, tape);
Ok(false)
}
} else {
context.cold.register(stack, res, parent_formula_ax, chum)
cold.register(stack, res, parent_formula_ax, chum)
}
};
match cold_res {
Ok(true) => *context.warm = Warm::init(stack, context.cold, context.hot),
Ok(true) => context.warm = Warm::init(stack, cold, hot),
Err(cold::Error::NoParent) => {
// XX: Need better message in slog; need better slogging tools
// format!("could not find parent battery at given axis: {} {}", chum, parent_formula_ax)
let tape = tape(
*stack,
stack,
"serf: cold: register: could not find parent battery at given axis",
);
slog_leaf(stack, newt, tape);
@ -1468,13 +1495,13 @@ mod hint {
Err(cold::Error::BadNock) => {
// XX: Need better message in slog; need better slogging tools
// format!("bad clue formula: {}", clue)
let tape = tape(*stack, "serf: cold: register: bad clue formula");
let tape = tape(stack, "serf: cold: register: bad clue formula");
slog_leaf(stack, newt, tape);
}
_ => {}
}
} else {
let tape = tape(*stack, "serf: cold: register: no clue for %fast");
let tape = tape(stack, "serf: cold: register: no clue for %fast");
slog_leaf(stack, newt, tape);
}
}
@ -1484,16 +1511,8 @@ mod hint {
Ok(None)
}
fn slog_leaf(stack: &mut NockStack, newt: &mut Option<&mut Newt>, tape: Noun) {
fn slog_leaf(stack: &mut NockStack, newt: &mut Newt, tape: Noun) {
let tank = T(stack, &[LEAF, tape]);
slog(stack, newt, 0u64, tank);
}
fn slog(stack: &mut NockStack, newt: &mut Option<&mut Newt>, pri: u64, tank: Noun) {
if newt.is_none() {
eprintln!("raw slog: {} {}", pri, tank);
} else {
newt.as_mut().unwrap().slog(stack, pri, tank);
}
newt.slog(stack, 0u64, tank);
}
}

View File

@ -302,8 +302,23 @@ pub mod util {
use assert_no_alloc::assert_no_alloc;
use ibig::UBig;
pub fn init_stack() -> NockStack {
NockStack::new(8 << 10 << 10, 0)
pub fn init_context() -> Context {
let mut stack = NockStack::new(8 << 10 << 10, 0);
let newt = Newt::new_mock();
let cold = Cold::new(&mut stack);
let warm = Warm::new();
let hot = Hot::init(&mut stack);
let cache = Hamt::<Noun>::new();
Context {
stack,
newt,
cold,
warm,
hot,
cache,
scry_stack: D(0),
}
}
#[allow(non_snake_case)]
@ -316,55 +331,25 @@ pub mod util {
assert!(eq, "got: {}, need: {}", a, b);
}
pub fn assert_jet(stack: &mut NockStack, jet: Jet, sam: Noun, res: Noun) {
// XX: consider making a mock context singleton that tests can use
let mut newt = Newt::new_mock();
let mut cache = Hamt::<Noun>::new();
let mut cold = Cold::new(stack);
let mut warm = Warm::new();
let hot = Hot::init(stack);
let mut context = Context {
stack,
newt: Some(&mut newt),
cache: &mut cache,
cold: &mut cold,
warm: &mut warm,
hot: &hot,
scry_stack: D(0),
};
let sam = T(context.stack, &[D(0), sam, D(0)]);
let jet_res = assert_no_alloc(|| jet(&mut context, sam).unwrap());
assert_noun_eq(stack, jet_res, res);
pub fn assert_jet(context: &mut Context, jet: Jet, sam: Noun, res: Noun) {
let sam = T(&mut context.stack, &[D(0), sam, D(0)]);
let jet_res = assert_no_alloc(|| jet(context, sam).unwrap());
assert_noun_eq(&mut context.stack, jet_res, res);
}
pub fn assert_jet_ubig(stack: &mut NockStack, jet: Jet, sam: Noun, res: UBig) {
let res = A(stack, &res);
assert_jet(stack, jet, sam, res);
pub fn assert_jet_ubig(context: &mut Context, jet: Jet, sam: Noun, res: UBig) {
let res = A(&mut context.stack, &res);
assert_jet(context, jet, sam, res);
}
pub fn assert_nary_jet_ubig(stack: &mut NockStack, jet: Jet, sam: &[Noun], res: UBig) {
let sam = T(stack, sam);
assert_jet_ubig(stack, jet, sam, res);
pub fn assert_nary_jet_ubig(context: &mut Context, jet: Jet, sam: &[Noun], res: UBig) {
let sam = T(&mut context.stack, sam);
assert_jet_ubig(context, jet, sam, res);
}
pub fn assert_jet_err(stack: &mut NockStack, jet: Jet, sam: Noun, err: JetErr) {
// XX: consider making a mock context singleton that tests can use
let mut newt = Newt::new_mock();
let mut cache = Hamt::<Noun>::new();
let mut cold = Cold::new(stack);
let mut warm = Warm::new();
let hot = Hot::init(stack);
let mut context = Context {
stack,
newt: Some(&mut newt),
cache: &mut cache,
cold: &mut cold,
warm: &mut warm,
hot: &hot,
scry_stack: D(0),
};
let sam = T(context.stack, &[D(0), sam, D(0)]);
let jet_res = jet(&mut context, sam);
pub fn assert_jet_err(context: &mut Context, jet: Jet, sam: Noun, err: JetErr) {
let sam = T(&mut context.stack, &[D(0), sam, D(0)]);
let jet_res = jet(context, sam);
assert!(
jet_res.is_err(),
"with sample: {}, expected err: {:?}, got: {:?}",
@ -383,13 +368,14 @@ pub mod util {
#[cfg(test)]
mod tests {
use super::test::{init_stack, A};
use super::test::{init_context, A};
use super::*;
use ibig::ubig;
#[test]
fn test_met() {
let s = &mut init_stack();
let c = &mut init_context();
let s = &mut c.stack;
let a = A(s, &ubig!(0xdeadbeef12345678fedcba9876543210))
.as_atom()

View File

@ -15,7 +15,7 @@ crate::gdb!();
pub fn jet_bex(context: &mut Context, subject: Noun) -> Result {
let arg = slot(subject, 6)?.as_direct()?.data() as usize;
Ok(bex(context.stack, arg).as_noun())
Ok(bex(&mut context.stack, arg).as_noun())
}
pub fn jet_can(context: &mut Context, subject: Noun) -> Result {
@ -43,7 +43,7 @@ pub fn jet_can(context: &mut Context, subject: Noun) -> Result {
} else {
unsafe {
let (mut new_indirect, new_slice) =
IndirectAtom::new_raw_mut_bitslice(context.stack, bite_to_word(bloq, len)?);
IndirectAtom::new_raw_mut_bitslice(&mut context.stack, bite_to_word(bloq, len)?);
let mut pos = 0;
let mut list = original_list;
loop {
@ -79,7 +79,7 @@ pub fn jet_cat(context: &mut Context, subject: Noun) -> Result {
} else {
unsafe {
let (mut new_indirect, new_slice) =
IndirectAtom::new_raw_mut_bitslice(context.stack, new_len);
IndirectAtom::new_raw_mut_bitslice(&mut context.stack, new_len);
chop(bloq, 0, len_a, 0, new_slice, a.as_bitslice())?;
chop(bloq, 0, len_b, len_a, new_slice, b.as_bitslice())?;
Ok(new_indirect.normalize_as_atom().as_noun())
@ -100,7 +100,7 @@ pub fn jet_cut(context: &mut Context, subject: Noun) -> Result {
let new_indirect = unsafe {
let (mut new_indirect, new_slice) =
IndirectAtom::new_raw_mut_bitslice(context.stack, bite_to_word(bloq, run)?);
IndirectAtom::new_raw_mut_bitslice(&mut context.stack, bite_to_word(bloq, run)?);
chop(bloq, start, run, 0, new_slice, atom.as_bitslice())?;
new_indirect.normalize_as_atom()
};
@ -119,7 +119,7 @@ pub fn jet_end(context: &mut Context, subject: Noun) -> Result {
} else {
unsafe {
let (mut new_indirect, new_slice) =
IndirectAtom::new_raw_mut_bitslice(context.stack, bite_to_word(bloq, step)?);
IndirectAtom::new_raw_mut_bitslice(&mut context.stack, bite_to_word(bloq, step)?);
chop(bloq, 0, step, 0, new_slice, a.as_bitslice())?;
Ok(new_indirect.normalize_as_atom().as_noun())
}
@ -138,7 +138,7 @@ pub fn jet_lsh(context: &mut Context, subject: Noun) -> Result {
let new_size = bits_to_word(checked_add(a.bit_size(), checked_left_shift(bloq, step)?)?)?;
unsafe {
let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(context.stack, new_size);
let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(&mut context.stack, new_size);
chop(bloq, 0, len, step, dest, a.as_bitslice())?;
Ok(atom.normalize_as_atom().as_noun())
}
@ -175,7 +175,7 @@ pub fn jet_rap(context: &mut Context, subject: Noun) -> Result {
} else {
unsafe {
let (mut new_indirect, new_slice) =
IndirectAtom::new_raw_mut_bitslice(context.stack, bite_to_word(bloq, len)?);
IndirectAtom::new_raw_mut_bitslice(&mut context.stack, bite_to_word(bloq, len)?);
let mut pos = 0;
let mut list = original_list;
@ -221,7 +221,7 @@ pub fn jet_rep(context: &mut Context, subject: Noun) -> Result {
} else {
unsafe {
let (mut new_indirect, new_slice) =
IndirectAtom::new_raw_mut_bitslice(context.stack, bite_to_word(bloq, len)?);
IndirectAtom::new_raw_mut_bitslice(&mut context.stack, bite_to_word(bloq, len)?);
let mut pos = 0;
let mut list = original_list;
loop {
@ -261,7 +261,9 @@ pub fn jet_rev(context: &mut Context, subject: Noun) -> Result {
let mut output = if dat.is_direct() && bits < 64 {
unsafe { DirectAtom::new_unchecked(0).as_atom() }
} else {
unsafe { IndirectAtom::new_raw(context.stack, ((bits + 7) / 8) as usize, &0).as_atom() }
unsafe {
IndirectAtom::new_raw(&mut context.stack, ((bits + 7) / 8) as usize, &0).as_atom()
}
};
let src = dat.as_bitslice();
@ -281,7 +283,7 @@ pub fn jet_rip(context: &mut Context, subject: Noun) -> Result {
let arg = slot(subject, 6)?;
let (bloq, step) = bite(slot(arg, 2)?)?;
let atom = slot(arg, 3)?.as_atom()?;
rip(context.stack, bloq, step, atom)
rip(&mut context.stack, bloq, step, atom)
}
pub fn jet_rsh(context: &mut Context, subject: Noun) -> Result {
@ -296,7 +298,7 @@ pub fn jet_rsh(context: &mut Context, subject: Noun) -> Result {
let new_size = bits_to_word(checked_sub(a.bit_size(), checked_left_shift(bloq, step)?)?)?;
unsafe {
let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(context.stack, new_size);
let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(&mut context.stack, new_size);
chop(bloq, step, len - step, 0, dest, a.as_bitslice())?;
Ok(atom.normalize_as_atom().as_noun())
}
@ -311,7 +313,7 @@ pub fn jet_con(context: &mut Context, subject: Noun) -> Result {
let a = slot(arg, 2)?.as_atom()?;
let b = slot(arg, 3)?.as_atom()?;
Ok(con(context.stack, a, b).as_noun())
Ok(con(&mut context.stack, a, b).as_noun())
}
pub fn jet_dis(context: &mut Context, subject: Noun) -> Result {
@ -322,7 +324,7 @@ pub fn jet_dis(context: &mut Context, subject: Noun) -> Result {
let new_size = cmp::max(a.size(), b.size());
unsafe {
let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(context.stack, new_size);
let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(&mut context.stack, new_size);
let a_bit = a.as_bitslice();
dest[..a_bit.len()].copy_from_bitslice(a_bit);
*dest &= b.as_bitslice();
@ -338,7 +340,7 @@ pub fn jet_mix(context: &mut Context, subject: Noun) -> Result {
let new_size = cmp::max(a.size(), b.size());
unsafe {
let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(context.stack, new_size);
let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(&mut context.stack, new_size);
let a_bit = a.as_bitslice();
dest[..a_bit.len()].copy_from_bitslice(a_bit);
*dest ^= b.as_bitslice();
@ -349,7 +351,7 @@ pub fn jet_mix(context: &mut Context, subject: Noun) -> Result {
#[cfg(test)]
mod tests {
use super::*;
use crate::jets::util::test::{assert_jet, assert_jet_ubig, init_stack, A};
use crate::jets::util::test::{assert_jet, assert_jet_ubig, init_context, A};
use crate::mem::NockStack;
use crate::noun::{Noun, D, T};
use ibig::ubig;
@ -384,12 +386,13 @@ mod tests {
#[test]
fn test_bex() {
let s = &mut init_stack();
assert_jet(s, jet_bex, D(0), D(1));
assert_jet(s, jet_bex, D(5), D(32));
assert_jet(s, jet_bex, D(62), D(0x4000000000000000));
let c = &mut init_context();
assert_jet(c, jet_bex, D(0), D(1));
assert_jet(c, jet_bex, D(5), D(32));
assert_jet(c, jet_bex, D(62), D(0x4000000000000000));
assert_jet_ubig(
s,
c,
jet_bex,
D(256),
ubig!(_0x10000000000000000000000000000000000000000000000000000000000000000),
@ -398,218 +401,243 @@ mod tests {
#[test]
fn test_can() {
let s = &mut init_stack();
let (a0, _a24, _a63, _a96, a128) = atoms(s);
let c = &mut init_context();
let (a0, _a24, _a63, _a96, a128) = atoms(&mut c.stack);
let bloq0 = D(0);
let bloq3 = D(3);
let bloq4 = D(4);
let sam = T(s, &[bloq0, D(0)]);
assert_jet(s, jet_can, sam, D(0));
let sam = T(s, &[bloq3, D(0)]);
assert_jet(s, jet_can, sam, D(0));
let run1 = T(s, &[D(0), a0]);
let run2 = T(s, &[D(1), a0]);
let run3 = T(s, &[D(2), a0]);
let sam = T(s, &[bloq0, run1, run2, run3, D(0)]);
assert_jet(s, jet_can, sam, D(0));
let sam = T(s, &[bloq3, run1, run2, run3, D(0)]);
assert_jet(s, jet_can, sam, D(0));
let run1 = T(s, &[D(1), a128]);
let run2 = T(s, &[D(3), a0]);
let sam = T(s, &[bloq3, run1, run2, D(0)]);
assert_jet(s, jet_can, sam, D(0x10));
let run1 = T(s, &[D(3), a0]);
let run2 = T(s, &[D(1), a128]);
let sam = T(s, &[bloq3, run1, run2, D(0)]);
assert_jet(s, jet_can, sam, D(0x10000000));
let run1 = T(s, &[D(8), D(0xfe)]);
let run2 = T(s, &[D(4), D(0xa)]);
let run3 = T(s, &[D(0), D(0xbbbb)]);
let run4 = T(s, &[D(1), D(0)]);
let run5 = T(s, &[D(1), D(0)]);
let run6 = T(s, &[D(1), D(1)]);
let run7 = T(s, &[D(1), D(1)]);
let sam = T(s, &[bloq0, run1, run2, run3, run4, run5, run6, run7, D(0)]);
assert_jet(s, jet_can, sam, D(0xcafe));
let run1 = T(s, &[D(1), D(0xfe)]);
let run2 = T(s, &[D(1), D(0xca)]);
let sam = T(s, &[bloq4, run1, run2, D(0)]);
assert_jet(s, jet_can, sam, D(0xca00fe));
let sam = T(&mut c.stack, &[bloq0, D(0)]);
assert_jet(c, jet_can, sam, D(0));
let sam = T(&mut c.stack, &[bloq3, D(0)]);
assert_jet(c, jet_can, sam, D(0));
let run1 = T(&mut c.stack, &[D(0), a0]);
let run2 = T(&mut c.stack, &[D(1), a0]);
let run3 = T(&mut c.stack, &[D(2), a0]);
let sam = T(&mut c.stack, &[bloq0, run1, run2, run3, D(0)]);
assert_jet(c, jet_can, sam, D(0));
let sam = T(&mut c.stack, &[bloq3, run1, run2, run3, D(0)]);
assert_jet(c, jet_can, sam, D(0));
let run1 = T(&mut c.stack, &[D(1), a128]);
let run2 = T(&mut c.stack, &[D(3), a0]);
let sam = T(&mut c.stack, &[bloq3, run1, run2, D(0)]);
assert_jet(c, jet_can, sam, D(0x10));
let run1 = T(&mut c.stack, &[D(3), a0]);
let run2 = T(&mut c.stack, &[D(1), a128]);
let sam = T(&mut c.stack, &[bloq3, run1, run2, D(0)]);
assert_jet(c, jet_can, sam, D(0x10000000));
let run1 = T(&mut c.stack, &[D(8), D(0xfe)]);
let run2 = T(&mut c.stack, &[D(4), D(0xa)]);
let run3 = T(&mut c.stack, &[D(0), D(0xbbbb)]);
let run4 = T(&mut c.stack, &[D(1), D(0)]);
let run5 = T(&mut c.stack, &[D(1), D(0)]);
let run6 = T(&mut c.stack, &[D(1), D(1)]);
let run7 = T(&mut c.stack, &[D(1), D(1)]);
let sam = T(
&mut c.stack,
&[bloq0, run1, run2, run3, run4, run5, run6, run7, D(0)],
);
assert_jet(c, jet_can, sam, D(0xcafe));
let run1 = T(&mut c.stack, &[D(1), D(0xfe)]);
let run2 = T(&mut c.stack, &[D(1), D(0xca)]);
let sam = T(&mut c.stack, &[bloq4, run1, run2, D(0)]);
assert_jet(c, jet_can, sam, D(0xca00fe));
}
#[test]
fn test_cat() {
let s = &mut init_stack();
let (a0, a24, _a63, _a96, a128) = atoms(s);
let c = &mut init_context();
let (a0, a24, _a63, _a96, a128) = atoms(&mut c.stack);
let bloq0 = D(0);
let bloq3 = D(3);
let bloq4 = D(4);
let sam = T(s, &[bloq0, a0, a0]);
assert_jet(s, jet_cat, sam, D(0));
let sam = T(s, &[bloq3, a0, a0]);
assert_jet(s, jet_cat, sam, D(0));
let sam = T(s, &[bloq0, a24, a128]);
let res = A(s, &ubig!(_0xdeadbeef12345678fedcba9876543210876543));
assert_jet(s, jet_cat, sam, res);
let sam = T(s, &[bloq3, a24, a128]);
let res = A(s, &ubig!(_0xdeadbeef12345678fedcba9876543210876543));
assert_jet(s, jet_cat, sam, res);
let sam = T(s, &[bloq4, a24, a128]);
let res = A(s, &ubig!(_0xdeadbeef12345678fedcba987654321000876543));
assert_jet(s, jet_cat, sam, res);
let sam = T(&mut c.stack, &[bloq0, a0, a0]);
assert_jet(c, jet_cat, sam, D(0));
let sam = T(&mut c.stack, &[bloq3, a0, a0]);
assert_jet(c, jet_cat, sam, D(0));
let sam = T(&mut c.stack, &[bloq0, a24, a128]);
let res = A(
&mut c.stack,
&ubig!(_0xdeadbeef12345678fedcba9876543210876543),
);
assert_jet(c, jet_cat, sam, res);
let sam = T(&mut c.stack, &[bloq3, a24, a128]);
let res = A(
&mut c.stack,
&ubig!(_0xdeadbeef12345678fedcba9876543210876543),
);
assert_jet(c, jet_cat, sam, res);
let sam = T(&mut c.stack, &[bloq4, a24, a128]);
let res = A(
&mut c.stack,
&ubig!(_0xdeadbeef12345678fedcba987654321000876543),
);
assert_jet(c, jet_cat, sam, res);
}
#[test]
fn test_cut() {
let s = &mut init_stack();
let (_a0, a24, _a63, a96, a128) = atoms(s);
let run = T(s, &[D(0), D(0)]);
let sam = T(s, &[D(0), run, a24]);
assert_jet(s, jet_cut, sam, D(0));
let run = T(s, &[D(0), D(5)]);
let sam = T(s, &[D(0), run, a24]);
assert_jet(s, jet_cut, sam, D(0x3));
let run = T(s, &[D(4), D(6)]);
let sam = T(s, &[D(3), run, a96]);
assert_jet(s, jet_cut, sam, D(0xb00c15deadbe));
let run = T(s, &[D(4), D(1)]);
let sam = T(s, &[D(4), run, a24]);
assert_jet(s, jet_cut, sam, D(0));
let run = T(s, &[D(2), D(10)]);
let sam = T(s, &[D(4), run, a128]);
let res = A(s, &ubig!(0xdeadbeef12345678fedcba98));
assert_jet(s, jet_cut, sam, res);
let c = &mut init_context();
let (_a0, a24, _a63, a96, a128) = atoms(&mut c.stack);
let run = T(&mut c.stack, &[D(0), D(0)]);
let sam = T(&mut c.stack, &[D(0), run, a24]);
assert_jet(c, jet_cut, sam, D(0));
let run = T(&mut c.stack, &[D(0), D(5)]);
let sam = T(&mut c.stack, &[D(0), run, a24]);
assert_jet(c, jet_cut, sam, D(0x3));
let run = T(&mut c.stack, &[D(4), D(6)]);
let sam = T(&mut c.stack, &[D(3), run, a96]);
assert_jet(c, jet_cut, sam, D(0xb00c15deadbe));
let run = T(&mut c.stack, &[D(4), D(1)]);
let sam = T(&mut c.stack, &[D(4), run, a24]);
assert_jet(c, jet_cut, sam, D(0));
let run = T(&mut c.stack, &[D(2), D(10)]);
let sam = T(&mut c.stack, &[D(4), run, a128]);
let res = A(&mut c.stack, &ubig!(0xdeadbeef12345678fedcba98));
assert_jet(c, jet_cut, sam, res);
}
#[test]
fn test_end() {
let s = &mut init_stack();
let (a0, a24, _a63, a96, a128) = atoms(s);
let sam = T(s, &[a0, a24]);
assert_jet(s, jet_end, sam, D(0x1));
let sam = T(s, &[D(3), a24]);
assert_jet(s, jet_end, sam, D(0x43));
let sam = T(s, &[D(7), a24]);
assert_jet(s, jet_end, sam, a24);
let sam = T(s, &[D(6), a128]);
let res = A(s, &ubig!(0xfedcba9876543210));
assert_jet(s, jet_end, sam, res);
let c = &mut init_context();
let bit = T(s, &[D(0), D(5)]);
let sam = T(s, &[bit, a24]);
assert_jet(s, jet_end, sam, D(0x3));
let bit = T(s, &[D(4), D(6)]);
let sam = T(s, &[bit, a96]);
assert_jet(s, jet_end, sam, a96);
let (a0, a24, _a63, a96, a128) = atoms(&mut c.stack);
let sam = T(&mut c.stack, &[a0, a24]);
assert_jet(c, jet_end, sam, D(0x1));
let sam = T(&mut c.stack, &[D(3), a24]);
assert_jet(c, jet_end, sam, D(0x43));
let sam = T(&mut c.stack, &[D(7), a24]);
assert_jet(c, jet_end, sam, a24);
let sam = T(&mut c.stack, &[D(6), a128]);
let res = A(&mut c.stack, &ubig!(0xfedcba9876543210));
assert_jet(c, jet_end, sam, res);
let bit = T(&mut c.stack, &[D(0), D(5)]);
let sam = T(&mut c.stack, &[bit, a24]);
assert_jet(c, jet_end, sam, D(0x3));
let bit = T(&mut c.stack, &[D(4), D(6)]);
let sam = T(&mut c.stack, &[bit, a96]);
assert_jet(c, jet_end, sam, a96);
}
#[test]
fn test_lsh() {
let s = &mut init_stack();
let (a0, a24, _a63, a96, a128) = atoms(s);
let sam = T(s, &[a0, a24]);
assert_jet(s, jet_lsh, sam, D(0x10eca86));
let sam = T(s, &[D(3), a24]);
assert_jet(s, jet_lsh, sam, D(0x87654300));
let sam = T(s, &[D(7), a24]);
let res = A(s, &ubig!(_0x87654300000000000000000000000000000000));
assert_jet(s, jet_lsh, sam, res);
let sam = T(s, &[D(6), a128]);
let c = &mut init_context();
let (a0, a24, _a63, a96, a128) = atoms(&mut c.stack);
let sam = T(&mut c.stack, &[a0, a24]);
assert_jet(c, jet_lsh, sam, D(0x10eca86));
let sam = T(&mut c.stack, &[D(3), a24]);
assert_jet(c, jet_lsh, sam, D(0x87654300));
let sam = T(&mut c.stack, &[D(7), a24]);
let res = A(
s,
&mut c.stack,
&ubig!(_0x87654300000000000000000000000000000000),
);
assert_jet(c, jet_lsh, sam, res);
let sam = T(&mut c.stack, &[D(6), a128]);
let res = A(
&mut c.stack,
&ubig!(_0xdeadbeef12345678fedcba98765432100000000000000000),
);
assert_jet(s, jet_lsh, sam, res);
assert_jet(c, jet_lsh, sam, res);
let bit = T(s, &[D(0), D(5)]);
let sam = T(s, &[bit, a24]);
assert_jet(s, jet_lsh, sam, D(0x10eca860));
let bit = T(s, &[D(4), D(6)]);
let sam = T(s, &[bit, a96]);
let bit = T(&mut c.stack, &[D(0), D(5)]);
let sam = T(&mut c.stack, &[bit, a24]);
assert_jet(c, jet_lsh, sam, D(0x10eca860));
let bit = T(&mut c.stack, &[D(4), D(6)]);
let sam = T(&mut c.stack, &[bit, a96]);
let res = A(
s,
&mut c.stack,
&ubig!(_0xfaceb00c15deadbeef123456000000000000000000000000),
);
assert_jet(s, jet_lsh, sam, res);
assert_jet(c, jet_lsh, sam, res);
}
#[test]
fn test_met() {
let s = &mut init_stack();
let (a0, a24, _a63, _a96, a128) = atoms(s);
let sam = T(s, &[a0, a0]);
assert_jet(s, jet_met, sam, D(0));
let sam = T(s, &[a0, a24]);
assert_jet(s, jet_met, sam, D(24));
let sam = T(s, &[D(3), a24]);
assert_jet(s, jet_met, sam, D(3));
let sam = T(s, &[D(1), a128]);
assert_jet(s, jet_met, sam, D(64));
let c = &mut init_context();
let (a0, a24, _a63, _a96, a128) = atoms(&mut c.stack);
let sam = T(&mut c.stack, &[a0, a0]);
assert_jet(c, jet_met, sam, D(0));
let sam = T(&mut c.stack, &[a0, a24]);
assert_jet(c, jet_met, sam, D(24));
let sam = T(&mut c.stack, &[D(3), a24]);
assert_jet(c, jet_met, sam, D(3));
let sam = T(&mut c.stack, &[D(1), a128]);
assert_jet(c, jet_met, sam, D(64));
}
#[test]
fn test_rap() {
let s = &mut init_stack();
let c = &mut init_context();
let bloq0 = D(0);
let bloq2 = D(2);
let bloq3 = D(3);
let empty_list = D(0);
let zero_list = T(s, &[D(0), D(0), D(0)]);
let test_list = T(s, &[D(0xe), D(0xf), D(0xa), D(0xc), D(0)]);
let wide_list = T(s, &[D(0xafe), D(0xc), D(0)]);
let sam = T(s, &[bloq0, empty_list]);
assert_jet(s, jet_rap, sam, D(0));
let sam = T(s, &[bloq0, zero_list]);
assert_jet(s, jet_rap, sam, D(0));
let sam = T(s, &[bloq3, zero_list]);
assert_jet(s, jet_rap, sam, D(0));
let sam = T(s, &[bloq0, test_list]);
assert_jet(s, jet_rap, sam, D(0xcafe));
let sam = T(s, &[bloq2, test_list]);
assert_jet(s, jet_rap, sam, D(0xcafe));
let sam = T(s, &[bloq2, wide_list]);
assert_jet(s, jet_rap, sam, D(0xcafe));
let sam = T(s, &[bloq3, test_list]);
let res = A(s, &ubig!(0xc0a0f0e));
assert_jet(s, jet_rap, sam, res);
let sam = T(s, &[bloq3, wide_list]);
assert_jet(s, jet_rap, sam, D(0xc0afe));
let zero_list = T(&mut c.stack, &[D(0), D(0), D(0)]);
let test_list = T(&mut c.stack, &[D(0xe), D(0xf), D(0xa), D(0xc), D(0)]);
let wide_list = T(&mut c.stack, &[D(0xafe), D(0xc), D(0)]);
let sam = T(&mut c.stack, &[bloq0, empty_list]);
assert_jet(c, jet_rap, sam, D(0));
let sam = T(&mut c.stack, &[bloq0, zero_list]);
assert_jet(c, jet_rap, sam, D(0));
let sam = T(&mut c.stack, &[bloq3, zero_list]);
assert_jet(c, jet_rap, sam, D(0));
let sam = T(&mut c.stack, &[bloq0, test_list]);
assert_jet(c, jet_rap, sam, D(0xcafe));
let sam = T(&mut c.stack, &[bloq2, test_list]);
assert_jet(c, jet_rap, sam, D(0xcafe));
let sam = T(&mut c.stack, &[bloq2, wide_list]);
assert_jet(c, jet_rap, sam, D(0xcafe));
let sam = T(&mut c.stack, &[bloq3, test_list]);
let res = A(&mut c.stack, &ubig!(0xc0a0f0e));
assert_jet(c, jet_rap, sam, res);
let sam = T(&mut c.stack, &[bloq3, wide_list]);
assert_jet(c, jet_rap, sam, D(0xc0afe));
}
#[test]
fn test_rep() {
let s = &mut init_stack();
let (a0, a24, a63, a96, a128) = atoms(s);
let sam = T(s, &[D(0), D(0)]);
assert_jet(s, jet_rep, sam, D(0));
let bit = T(s, &[D(3), D(2)]);
let sam = T(s, &[bit, a0, a24, a63, a96, a128, D(0)]);
let res = A(s, &ubig!(0x32103456ffff65430000));
assert_jet(s, jet_rep, sam, res);
let c = &mut init_context();
let (a0, a24, a63, a96, a128) = atoms(&mut c.stack);
let sam = T(&mut c.stack, &[D(0), D(0)]);
assert_jet(c, jet_rep, sam, D(0));
let bit = T(&mut c.stack, &[D(3), D(2)]);
let sam = T(&mut c.stack, &[bit, a0, a24, a63, a96, a128, D(0)]);
let res = A(&mut c.stack, &ubig!(0x32103456ffff65430000));
assert_jet(c, jet_rep, sam, res);
}
#[test]
fn test_rev() {
let s = &mut init_stack();
let (_a0, a24, _a63, _a96, _a128) = atoms(s);
let sam = T(s, &[D(0), D(60), a24]);
assert_jet(s, jet_rev, sam, D(0xc2a6e1000000000));
let c = &mut init_context();
let (_a0, a24, _a63, _a96, _a128) = atoms(&mut c.stack);
let sam = T(&mut c.stack, &[D(0), D(60), a24]);
assert_jet(c, jet_rev, sam, D(0xc2a6e1000000000));
let test = 0x1234567890123u64;
let sam = T(s, &[D(3), D(7), D(test)]);
assert_jet(s, jet_rev, sam, D(test.swap_bytes() >> 8));
let sam = T(&mut c.stack, &[D(3), D(7), D(test)]);
assert_jet(c, jet_rev, sam, D(test.swap_bytes() >> 8));
}
#[test]
fn test_rip() {
let s = &mut init_stack();
let (_a0, _a24, _a63, _a96, a128) = atoms(s);
let sam = T(s, &[D(0), D(0)]);
assert_jet(s, jet_rip, sam, D(0));
let bit = T(s, &[D(1), D(2)]);
let sam = T(s, &[bit, a128]);
let c = &mut init_context();
let (_a0, _a24, _a63, _a96, a128) = atoms(&mut c.stack);
let sam = T(&mut c.stack, &[D(0), D(0)]);
assert_jet(c, jet_rip, sam, D(0));
let bit = T(&mut c.stack, &[D(1), D(2)]);
let sam = T(&mut c.stack, &[bit, a128]);
#[rustfmt::skip]
let res = T(
s,
&mut c.stack,
&[
D(0x0), D(0x1), D(0x2), D(0x3), D(0x4), D(0x5), D(0x6), D(0x7),
D(0x8), D(0x9), D(0xa), D(0xb), D(0xc), D(0xd), D(0xe), D(0xf),
@ -618,33 +646,33 @@ mod tests {
D(0x0),
],
);
assert_jet(s, jet_rip, sam, res);
assert_jet(c, jet_rip, sam, res);
}
#[test]
fn test_rsh() {
let s = &mut init_stack();
let (a0, a24, _a63, a96, a128) = atoms(s);
let sam = T(s, &[a0, a24]);
assert_jet(s, jet_rsh, sam, D(0x43b2a1));
let sam = T(s, &[D(3), a24]);
assert_jet(s, jet_rsh, sam, D(0x8765));
let sam = T(s, &[D(7), a24]);
assert_jet(s, jet_rsh, sam, D(0));
let sam = T(s, &[D(2), a128]);
let res = A(s, &ubig!(0xdeadbeef12345678fedcba987654321));
assert_jet(s, jet_rsh, sam, res);
let sam = T(s, &[D(6), a128]);
let res = A(s, &ubig!(0xdeadbeef12345678));
assert_jet(s, jet_rsh, sam, res);
let c = &mut init_context();
let bit = T(s, &[D(0), D(5)]);
let sam = T(s, &[bit, a24]);
assert_jet(s, jet_rsh, sam, D(0x43b2a));
let bit = T(s, &[D(4), D(6)]);
let sam = T(s, &[bit, a96]);
assert_jet(s, jet_rsh, sam, D(0));
let (a0, a24, _a63, a96, a128) = atoms(&mut c.stack);
let sam = T(&mut c.stack, &[a0, a24]);
assert_jet(c, jet_rsh, sam, D(0x43b2a1));
let sam = T(&mut c.stack, &[D(3), a24]);
assert_jet(c, jet_rsh, sam, D(0x8765));
let sam = T(&mut c.stack, &[D(7), a24]);
assert_jet(c, jet_rsh, sam, D(0));
let sam = T(&mut c.stack, &[D(2), a128]);
let res = A(&mut c.stack, &ubig!(0xdeadbeef12345678fedcba987654321));
assert_jet(c, jet_rsh, sam, res);
let sam = T(&mut c.stack, &[D(6), a128]);
let res = A(&mut c.stack, &ubig!(0xdeadbeef12345678));
assert_jet(c, jet_rsh, sam, res);
let bit = T(&mut c.stack, &[D(0), D(5)]);
let sam = T(&mut c.stack, &[bit, a24]);
assert_jet(c, jet_rsh, sam, D(0x43b2a));
let bit = T(&mut c.stack, &[D(4), D(6)]);
let sam = T(&mut c.stack, &[bit, a96]);
assert_jet(c, jet_rsh, sam, D(0));
}
/*
@ -653,61 +681,64 @@ mod tests {
#[test]
fn test_con() {
let s = &mut init_stack();
let (a0, a24, a63, a96, a128) = atoms(s);
let sam = T(s, &[a0, a0]);
assert_jet(s, jet_con, sam, D(0));
let sam = T(s, &[a24, a96]);
let res = A(s, &ubig!(0xfaceb00c15deadbeef977557));
assert_jet(s, jet_con, sam, res);
let sam = T(s, &[a96, a128]);
let res = A(s, &ubig!(0xdeadbeeffafef67cffdebfbeff563656));
assert_jet(s, jet_con, sam, res);
let sam = T(s, &[a24, a63]);
assert_jet(s, jet_con, sam, a63);
let sam = T(s, &[a0, a128]);
assert_jet(s, jet_con, sam, a128);
let sam = T(s, &[a128, a0]);
assert_jet(s, jet_con, sam, a128);
let c = &mut init_context();
let (a0, a24, a63, a96, a128) = atoms(&mut c.stack);
let sam = T(&mut c.stack, &[a0, a0]);
assert_jet(c, jet_con, sam, D(0));
let sam = T(&mut c.stack, &[a24, a96]);
let res = A(&mut c.stack, &ubig!(0xfaceb00c15deadbeef977557));
assert_jet(c, jet_con, sam, res);
let sam = T(&mut c.stack, &[a96, a128]);
let res = A(&mut c.stack, &ubig!(0xdeadbeeffafef67cffdebfbeff563656));
assert_jet(c, jet_con, sam, res);
let sam = T(&mut c.stack, &[a24, a63]);
assert_jet(c, jet_con, sam, a63);
let sam = T(&mut c.stack, &[a0, a128]);
assert_jet(c, jet_con, sam, a128);
let sam = T(&mut c.stack, &[a128, a0]);
assert_jet(c, jet_con, sam, a128);
}
#[test]
fn test_dis() {
let s = &mut init_stack();
let (a0, a24, a63, a96, a128) = atoms(s);
let sam = T(s, &[a0, a0]);
assert_jet(s, jet_dis, sam, D(0));
let sam = T(s, &[a24, a96]);
assert_jet(s, jet_dis, sam, D(0x22442));
let sam = T(s, &[a96, a128]);
let res = A(s, &ubig!(0x1204100814dca89866103010));
assert_jet(s, jet_dis, sam, res);
let sam = T(s, &[a24, a63]);
assert_jet(s, jet_dis, sam, a24);
let sam = T(s, &[a0, a128]);
assert_jet(s, jet_dis, sam, a0);
let sam = T(s, &[a128, a0]);
assert_jet(s, jet_dis, sam, a0);
let c = &mut init_context();
let (a0, a24, a63, a96, a128) = atoms(&mut c.stack);
let sam = T(&mut c.stack, &[a0, a0]);
assert_jet(c, jet_dis, sam, D(0));
let sam = T(&mut c.stack, &[a24, a96]);
assert_jet(c, jet_dis, sam, D(0x22442));
let sam = T(&mut c.stack, &[a96, a128]);
let res = A(&mut c.stack, &ubig!(0x1204100814dca89866103010));
assert_jet(c, jet_dis, sam, res);
let sam = T(&mut c.stack, &[a24, a63]);
assert_jet(c, jet_dis, sam, a24);
let sam = T(&mut c.stack, &[a0, a128]);
assert_jet(c, jet_dis, sam, a0);
let sam = T(&mut c.stack, &[a128, a0]);
assert_jet(c, jet_dis, sam, a0);
}
#[test]
fn test_mix() {
let s = &mut init_stack();
let (a0, a24, a63, a96, a128) = atoms(s);
let sam = T(s, &[a0, a0]);
assert_jet(s, jet_mix, sam, D(0));
let sam = T(s, &[a24, a96]);
let res = A(s, &ubig!(0xfaceb00c15deadbeef955115));
assert_jet(s, jet_mix, sam, res);
let sam = T(s, &[a96, a128]);
let res = A(s, &ubig!(0xdeadbeefe8fae674eb02172699460646));
assert_jet(s, jet_mix, sam, res);
let sam = T(s, &[a24, a63]);
let res = A(s, &ubig!(0x7fffffffff789abc));
assert_jet(s, jet_mix, sam, res);
let sam = T(s, &[a0, a128]);
assert_jet(s, jet_mix, sam, a128);
let sam = T(s, &[a128, a0]);
assert_jet(s, jet_mix, sam, a128);
let c = &mut init_context();
let (a0, a24, a63, a96, a128) = atoms(&mut c.stack);
let sam = T(&mut c.stack, &[a0, a0]);
assert_jet(c, jet_mix, sam, D(0));
let sam = T(&mut c.stack, &[a24, a96]);
let res = A(&mut c.stack, &ubig!(0xfaceb00c15deadbeef955115));
assert_jet(c, jet_mix, sam, res);
let sam = T(&mut c.stack, &[a96, a128]);
let res = A(&mut c.stack, &ubig!(0xdeadbeefe8fae674eb02172699460646));
assert_jet(c, jet_mix, sam, res);
let sam = T(&mut c.stack, &[a24, a63]);
let res = A(&mut c.stack, &ubig!(0x7fffffffff789abc));
assert_jet(c, jet_mix, sam, res);
let sam = T(&mut c.stack, &[a0, a128]);
assert_jet(c, jet_mix, sam, a128);
let sam = T(&mut c.stack, &[a128, a0]);
assert_jet(c, jet_mix, sam, a128);
}
}

View File

@ -10,7 +10,7 @@ crate::gdb!();
pub fn jet_scow(context: &mut Context, subject: Noun) -> Result {
let aura = slot(subject, 12)?.as_direct()?;
let atom = slot(subject, 13)?.as_atom()?;
util::scow(context.stack, aura, atom)
util::scow(&mut context.stack, aura, atom)
}
pub mod util {
@ -79,7 +79,7 @@ pub mod util {
#[cfg(test)]
mod tests {
use super::*;
use crate::jets::util::test::{assert_jet, assert_jet_err, init_stack, A};
use crate::jets::util::test::{assert_jet, assert_jet_err, init_context, A};
use crate::jets::JetErr;
use crate::noun::{Noun, D, T};
use ares_macros::tas;
@ -93,28 +93,35 @@ mod tests {
#[test]
fn test_scow() {
let s = &mut init_stack();
let c = &mut init_context();
let aura = D(tas!(b"ud"));
let sam = T(s, &[aura, D(0)]);
let res = T(s, &[B(b'0'), D(0)]);
assert_jet(s, jet_scow, sam, res);
let sam = T(s, &[aura, D(100)]);
let res = T(s, &[B(b'1'), B(b'0'), B(b'0'), D(0)]);
assert_jet(s, jet_scow, sam, res);
let big = A(s, &ubig!(100));
let sam = T(s, &[aura, big]);
let res = T(s, &[B(b'1'), B(b'0'), B(b'0'), D(0)]);
assert_jet(s, jet_scow, sam, res);
let sam = T(s, &[aura, D(1000)]);
let res = T(s, &[B(b'1'), B(b'.'), B(b'0'), B(b'0'), B(b'0'), D(0)]);
assert_jet(s, jet_scow, sam, res);
let big = A(s, &ubig!(1000));
let sam = T(s, &[aura, big]);
let res = T(s, &[B(b'1'), B(b'.'), B(b'0'), B(b'0'), B(b'0'), D(0)]);
assert_jet(s, jet_scow, sam, res);
let sam = T(s, &[aura, D(9876543210)]);
let sam = T(&mut c.stack, &[aura, D(0)]);
let res = T(&mut c.stack, &[B(b'0'), D(0)]);
assert_jet(c, jet_scow, sam, res);
let sam = T(&mut c.stack, &[aura, D(100)]);
let res = T(&mut c.stack, &[B(b'1'), B(b'0'), B(b'0'), D(0)]);
assert_jet(c, jet_scow, sam, res);
let big = A(&mut c.stack, &ubig!(100));
let sam = T(&mut c.stack, &[aura, big]);
let res = T(&mut c.stack, &[B(b'1'), B(b'0'), B(b'0'), D(0)]);
assert_jet(c, jet_scow, sam, res);
let sam = T(&mut c.stack, &[aura, D(1000)]);
let res = T(
s,
&mut c.stack,
&[B(b'1'), B(b'.'), B(b'0'), B(b'0'), B(b'0'), D(0)],
);
assert_jet(c, jet_scow, sam, res);
let big = A(&mut c.stack, &ubig!(1000));
let sam = T(&mut c.stack, &[aura, big]);
let res = T(
&mut c.stack,
&[B(b'1'), B(b'.'), B(b'0'), B(b'0'), B(b'0'), D(0)],
);
assert_jet(c, jet_scow, sam, res);
let sam = T(&mut c.stack, &[aura, D(9876543210)]);
let res = T(
&mut c.stack,
&[
B(b'9'),
B(b'.'),
@ -132,9 +139,9 @@ mod tests {
D(0),
],
);
assert_jet(s, jet_scow, sam, res);
assert_jet(c, jet_scow, sam, res);
let bad_aura = D(tas!(b"ux"));
let sam = T(s, &[bad_aura, D(0)]);
assert_jet_err(s, jet_scow, sam, JetErr::Punt);
let sam = T(&mut c.stack, &[bad_aura, D(0)]);
assert_jet_err(c, jet_scow, sam, JetErr::Punt);
}
}

View File

@ -10,13 +10,13 @@ crate::gdb!();
pub fn jet_mug(context: &mut Context, subject: Noun) -> Result {
let arg = slot(subject, 6)?;
Ok(mug(context.stack, arg).as_noun())
Ok(mug(&mut context.stack, arg).as_noun())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::jets::util::test::{assert_jet, init_stack, A};
use crate::jets::util::test::{assert_jet, init_context, A};
use crate::mem::NockStack;
use crate::noun::{Noun, D, T};
use ibig::ubig;
@ -47,22 +47,23 @@ mod tests {
#[test]
fn test_mug() {
let s = &mut init_stack();
let (a0, a24, a63, a96, a128) = atoms(s);
assert_jet(s, jet_mug, a0, D(0x79ff04e8));
assert_jet(s, jet_mug, a24, D(0x69d59d90));
assert_jet(s, jet_mug, a63, D(0x7a9f252e));
assert_jet(s, jet_mug, a96, D(0x2aa4c8fb));
assert_jet(s, jet_mug, a128, D(0x44fb2c0c));
let sam = T(s, &[a128, a128]);
assert_jet(s, jet_mug, sam, D(0x61c0ea5c));
let sam = T(s, &[a96, a128]);
assert_jet(s, jet_mug, sam, D(0x20fb143f));
let sam = T(s, &[a0, a0]);
assert_jet(s, jet_mug, sam, D(0x192f5588));
let sam = T(s, &[a0, a24, a63, a96, a128]);
let sam = T(s, &[sam, a0, a24, a63, a96, a128]);
let sam = T(s, &[sam, a0, a24, a63, a96, a128]);
assert_jet(s, jet_mug, sam, D(0x7543cac7));
let c = &mut init_context();
let (a0, a24, a63, a96, a128) = atoms(&mut c.stack);
assert_jet(c, jet_mug, a0, D(0x79ff04e8));
assert_jet(c, jet_mug, a24, D(0x69d59d90));
assert_jet(c, jet_mug, a63, D(0x7a9f252e));
assert_jet(c, jet_mug, a96, D(0x2aa4c8fb));
assert_jet(c, jet_mug, a128, D(0x44fb2c0c));
let sam = T(&mut c.stack, &[a128, a128]);
assert_jet(c, jet_mug, sam, D(0x61c0ea5c));
let sam = T(&mut c.stack, &[a96, a128]);
assert_jet(c, jet_mug, sam, D(0x20fb143f));
let sam = T(&mut c.stack, &[a0, a0]);
assert_jet(c, jet_mug, sam, D(0x192f5588));
let sam = T(&mut c.stack, &[a0, a24, a63, a96, a128]);
let sam = T(&mut c.stack, &[sam, a0, a24, a63, a96, a128]);
let sam = T(&mut c.stack, &[sam, a0, a24, a63, a96, a128]);
assert_jet(c, jet_mug, sam, D(0x7543cac7));
}
}

View File

@ -5,7 +5,7 @@
*
* In any case, it's important to ensure that the library only allocates on the nock stack. Gmp
* has mp_set_memory_functions. I don't know if rug does any allocation on top of that. ibig does
* not appear to support custom allocation functions, but we could probably patch it. If we're
* not appear to support custom allocation functionc, but we could probably patch it. If we're
* patching it, we might even be able to avoid copying the input and output at all, which might
* give a greater performance advantage than using gmp anyway.
*
@ -30,12 +30,12 @@ pub fn jet_add(context: &mut Context, subject: Noun) -> Result {
let b = slot(arg, 3)?.as_atom()?;
if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
Ok(Atom::new(*stack, a.data() + b.data()).as_noun())
Ok(Atom::new(stack, a.data() + b.data()).as_noun())
} else {
let a_big = a.as_ubig(*stack);
let b_big = b.as_ubig(*stack);
let res = UBig::add_stack(*stack, a_big, b_big);
Ok(Atom::from_ubig(*stack, &res).as_noun())
let a_big = a.as_ubig(stack);
let b_big = b.as_ubig(stack);
let res = UBig::add_stack(stack, a_big, b_big);
Ok(Atom::from_ubig(stack, &res).as_noun())
}
}
@ -58,7 +58,7 @@ pub fn jet_dec(context: &mut Context, subject: Noun) -> Result {
}
Some(first_one) => {
let (mut new_indirect, new_slice) = unsafe {
IndirectAtom::new_raw_mut_bitslice(context.stack, indirect.size())
IndirectAtom::new_raw_mut_bitslice(&mut context.stack, indirect.size())
};
if first_one > 0 {
new_slice[..first_one].fill(true);
@ -88,10 +88,10 @@ pub fn jet_div(context: &mut Context, subject: Noun) -> Result {
} else if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
Ok(unsafe { DirectAtom::new_unchecked(a.data() / b.data()) }.as_noun())
} else {
let a_big = a.as_ubig(*stack);
let b_big = b.as_ubig(*stack);
let res = UBig::div_stack(*stack, a_big, b_big);
Ok(Atom::from_ubig(*stack, &res).as_noun())
let a_big = a.as_ubig(stack);
let b_big = b.as_ubig(stack);
let res = UBig::div_stack(stack, a_big, b_big);
Ok(Atom::from_ubig(stack, &res).as_noun())
}
}
@ -113,18 +113,19 @@ pub fn jet_dvr(context: &mut Context, subject: Noun) -> Result {
)
}
} else {
let (div, rem) = a.as_ubig(*stack).div_rem(b.as_ubig(*stack));
let (div, rem) = a.as_ubig(stack).div_rem(b.as_ubig(stack));
(
Atom::from_ubig(*stack, &div).as_noun(),
Atom::from_ubig(*stack, &rem).as_noun(),
Atom::from_ubig(stack, &div).as_noun(),
Atom::from_ubig(stack, &rem).as_noun(),
)
};
Ok(T(*stack, &[div, rem]))
Ok(T(stack, &[div, rem]))
}
}
pub fn jet_gte(context: &mut Context, subject: Noun) -> Result {
let stack = &mut context.stack;
let arg = slot(subject, 6)?;
let a = slot(arg, 2)?.as_atom()?;
let b = slot(arg, 3)?.as_atom()?;
@ -139,7 +140,7 @@ pub fn jet_gte(context: &mut Context, subject: Noun) -> Result {
YES
} else if a.bit_size() < b.bit_size() {
NO
} else if a.as_ubig(context.stack) >= b.as_ubig(context.stack) {
} else if a.as_ubig(stack) >= b.as_ubig(stack) {
YES
} else {
NO
@ -147,6 +148,7 @@ pub fn jet_gte(context: &mut Context, subject: Noun) -> Result {
}
pub fn jet_gth(context: &mut Context, subject: Noun) -> Result {
let stack = &mut context.stack;
let arg = slot(subject, 6)?;
let a = slot(arg, 2)?.as_atom()?;
let b = slot(arg, 3)?.as_atom()?;
@ -161,7 +163,7 @@ pub fn jet_gth(context: &mut Context, subject: Noun) -> Result {
YES
} else if a.bit_size() < b.bit_size() {
NO
} else if a.as_ubig(context.stack) > b.as_ubig(context.stack) {
} else if a.as_ubig(stack) > b.as_ubig(stack) {
YES
} else {
NO
@ -169,6 +171,7 @@ pub fn jet_gth(context: &mut Context, subject: Noun) -> Result {
}
pub fn jet_lte(context: &mut Context, subject: Noun) -> Result {
let stack = &mut context.stack;
let arg = slot(subject, 6)?;
let a = slot(arg, 2)?.as_atom()?;
let b = slot(arg, 3)?.as_atom()?;
@ -183,7 +186,7 @@ pub fn jet_lte(context: &mut Context, subject: Noun) -> Result {
YES
} else if a.bit_size() > b.bit_size() {
NO
} else if a.as_ubig(context.stack) <= b.as_ubig(context.stack) {
} else if a.as_ubig(stack) <= b.as_ubig(stack) {
YES
} else {
NO
@ -191,6 +194,7 @@ pub fn jet_lte(context: &mut Context, subject: Noun) -> Result {
}
pub fn jet_lth(context: &mut Context, subject: Noun) -> Result {
let stack = &mut context.stack;
let arg = slot(subject, 6)?;
let a = slot(arg, 2)?.as_atom()?;
let b = slot(arg, 3)?.as_atom()?;
@ -205,7 +209,7 @@ pub fn jet_lth(context: &mut Context, subject: Noun) -> Result {
YES
} else if a.bit_size() > b.bit_size() {
NO
} else if a.as_ubig(context.stack) < b.as_ubig(context.stack) {
} else if a.as_ubig(stack) < b.as_ubig(stack) {
YES
} else {
NO
@ -223,8 +227,8 @@ pub fn jet_mod(context: &mut Context, subject: Noun) -> Result {
} else if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
Ok(unsafe { DirectAtom::new_unchecked(a.data() % b.data()) }.as_noun())
} else {
let res = a.as_ubig(*stack) % b.as_ubig(*stack);
Ok(Atom::from_ubig(*stack, &res).as_noun())
let res = a.as_ubig(stack) % b.as_ubig(stack);
Ok(Atom::from_ubig(stack, &res).as_noun())
}
}
@ -237,11 +241,11 @@ pub fn jet_mul(context: &mut Context, subject: Noun) -> Result {
if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
let res = a.data() as u128 * b.data() as u128;
if res < DIRECT_MAX as u128 {
Ok(Atom::new(*stack, res as u64).as_noun())
Ok(Atom::new(stack, res as u64).as_noun())
} else {
Ok(unsafe {
IndirectAtom::new_raw_bytes(
*stack,
stack,
if res < u64::MAX as u128 { 8 } else { 16 },
&res as *const u128 as *const u8,
)
@ -249,10 +253,10 @@ pub fn jet_mul(context: &mut Context, subject: Noun) -> Result {
.as_noun())
}
} else {
let a_big = a.as_ubig(*stack);
let b_big = b.as_ubig(*stack);
let res = UBig::mul_stack(*stack, a_big, b_big);
Ok(Atom::from_ubig(*stack, &res).as_noun())
let a_big = a.as_ubig(stack);
let b_big = b.as_ubig(stack);
let res = UBig::mul_stack(stack, a_big, b_big);
Ok(Atom::from_ubig(stack, &res).as_noun())
}
}
@ -261,14 +265,14 @@ pub fn jet_sub(context: &mut Context, subject: Noun) -> Result {
let a = slot(arg, 2)?.as_atom()?;
let b = slot(arg, 3)?.as_atom()?;
Ok(sub(context.stack, a, b)?.as_noun())
Ok(sub(&mut context.stack, a, b)?.as_noun())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::jets::util::test::{
assert_jet, assert_jet_err, assert_jet_ubig, assert_nary_jet_ubig, init_stack, A,
assert_jet, assert_jet_err, assert_jet_ubig, assert_nary_jet_ubig, init_context, A,
};
use crate::jets::{Jet, JetErr};
use crate::mem::NockStack;
@ -315,74 +319,78 @@ mod tests {
}
fn assert_math_jet(
stack: &mut NockStack,
context: &mut Context,
jet: Jet,
sam: &[fn(&mut NockStack) -> Noun],
res: UBig,
) {
let sam: Vec<Noun> = sam.iter().map(|f| f(stack)).collect();
assert_nary_jet_ubig(stack, jet, &sam, res);
let sam: Vec<Noun> = sam.iter().map(|f| f(&mut context.stack)).collect();
assert_nary_jet_ubig(context, jet, &sam, res);
}
fn assert_math_jet_noun(
stack: &mut NockStack,
context: &mut Context,
jet: Jet,
sam: &[fn(&mut NockStack) -> Noun],
res: Noun,
) {
let sam: Vec<Noun> = sam.iter().map(|f| f(stack)).collect();
let sam = T(stack, &sam);
assert_jet(stack, jet, sam, res);
let sam: Vec<Noun> = sam.iter().map(|f| f(&mut context.stack)).collect();
let sam = T(&mut context.stack, &sam);
assert_jet(context, jet, sam, res);
}
fn assert_math_jet_err(
stack: &mut NockStack,
context: &mut Context,
jet: Jet,
sam: &[fn(&mut NockStack) -> Noun],
err: JetErr,
) {
let sam: Vec<Noun> = sam.iter().map(|f| f(stack)).collect();
let sam = T(stack, &sam);
assert_jet_err(stack, jet, sam, err);
let sam: Vec<Noun> = sam.iter().map(|f| f(&mut context.stack)).collect();
let sam = T(&mut context.stack, &sam);
assert_jet_err(context, jet, sam, err);
}
#[test]
fn test_add() {
let s = &mut init_stack();
let c = &mut init_context();
assert_math_jet(
s,
c,
jet_add,
&[atom_128, atom_96],
ubig!(0xdeadbef00d03068514bb685765666666),
);
assert_math_jet(
s,
c,
jet_add,
&[atom_63, atom_96],
ubig!(0xfaceb00c95deadbeef123455),
);
assert_math_jet(s, jet_add, &[atom_63, atom_63], ubig!(0xfffffffffffffffe));
assert_math_jet(c, jet_add, &[atom_63, atom_63], ubig!(0xfffffffffffffffe));
}
#[test]
fn test_dec() {
let s = &mut init_stack();
let c = &mut init_context();
let s = &mut c.stack;
let (a0, _a24, a63, _a96, a128) = atoms(s);
assert_jet_ubig(s, jet_dec, a128, ubig!(0xdeadbeef12345678fedcba987654320f));
assert_jet(s, jet_dec, a63, D(0x7ffffffffffffffe));
assert_jet_err(s, jet_dec, a0, Deterministic);
assert_jet_ubig(c, jet_dec, a128, ubig!(0xdeadbeef12345678fedcba987654320f));
assert_jet(c, jet_dec, a63, D(0x7ffffffffffffffe));
assert_jet_err(c, jet_dec, a0, Deterministic);
}
#[test]
fn test_div() {
let s = &mut init_stack();
assert_math_jet(s, jet_div, &[atom_128, atom_96], ubig!(0xe349f8f0));
assert_math_jet(s, jet_div, &[atom_96, atom_63], ubig!(0x1f59d6018));
assert_math_jet(s, jet_div, &[atom_63, atom_96], ubig!(0));
assert_math_jet(s, jet_div, &[atom_63, atom_63], ubig!(1));
assert_math_jet(s, jet_div, &[atom_63, atom_24], ubig!(0xf2044dacfe));
let c = &mut init_context();
assert_math_jet(c, jet_div, &[atom_128, atom_96], ubig!(0xe349f8f0));
assert_math_jet(c, jet_div, &[atom_96, atom_63], ubig!(0x1f59d6018));
assert_math_jet(c, jet_div, &[atom_63, atom_96], ubig!(0));
assert_math_jet(c, jet_div, &[atom_63, atom_63], ubig!(1));
assert_math_jet(c, jet_div, &[atom_63, atom_24], ubig!(0xf2044dacfe));
assert_math_jet(
s,
c,
jet_div,
&[atom_128, atom_24],
ubig!(0x1a507f98b6fa8605ea3a79e97bf),
@ -390,168 +398,176 @@ mod tests {
let res = ubig!(
_0x00000000000001000000000000000000000000000000000000000000000000000000000000000001
);
assert_math_jet(s, jet_div, &[atom_528, atom_264], res);
assert_math_jet_err(s, jet_div, &[atom_63, atom_0], Deterministic);
assert_math_jet_err(s, jet_div, &[atom_0, atom_0], Deterministic);
assert_math_jet(c, jet_div, &[atom_528, atom_264], res);
assert_math_jet_err(c, jet_div, &[atom_63, atom_0], Deterministic);
assert_math_jet_err(c, jet_div, &[atom_0, atom_0], Deterministic);
}
#[test]
fn test_dvr() {
let s = &mut init_stack();
let (a0, a24, a63, a96, a128) = atoms(s);
let a264 = atom_264(s);
let a528 = atom_528(s);
let c = &mut init_context();
let sam = T(s, &[a128, a96]);
let res_a = A(s, &ubig!(0xe349f8f0));
let res_b = A(s, &ubig!(0xcb0ce564ec598f658409d170));
let res = T(s, &[res_a, res_b]);
assert_jet(s, jet_dvr, sam, res);
let (a0, a24, a63, a96, a128) = atoms(&mut c.stack);
let a264 = atom_264(&mut c.stack);
let a528 = atom_528(&mut c.stack);
let sam = T(s, &[a128, a24]);
let res_a = A(s, &ubig!(0x1a507f98b6fa8605ea3a79e97bf));
let res_b = A(s, &ubig!(0x3b2013));
let res = T(s, &[res_a, res_b]);
assert_jet(s, jet_dvr, sam, res);
let sam = T(&mut c.stack, &[a128, a96]);
let res_a = A(&mut c.stack, &ubig!(0xe349f8f0));
let res_b = A(&mut c.stack, &ubig!(0xcb0ce564ec598f658409d170));
let res = T(&mut c.stack, &[res_a, res_b]);
assert_jet(c, jet_dvr, sam, res);
let sam = T(s, &[a63, a63]);
let res_a = A(s, &ubig!(1));
let res_b = A(s, &ubig!(0));
let res = T(s, &[res_a, res_b]);
assert_jet(s, jet_dvr, sam, res);
let sam = T(&mut c.stack, &[a128, a24]);
let res_a = A(&mut c.stack, &ubig!(0x1a507f98b6fa8605ea3a79e97bf));
let res_b = A(&mut c.stack, &ubig!(0x3b2013));
let res = T(&mut c.stack, &[res_a, res_b]);
assert_jet(c, jet_dvr, sam, res);
let sam = T(s, &[a0, a24]);
let res_a = A(s, &ubig!(0));
let res_b = A(s, &ubig!(0));
let res = T(s, &[res_a, res_b]);
assert_jet(s, jet_dvr, sam, res);
let sam = T(&mut c.stack, &[a63, a63]);
let res_a = A(&mut c.stack, &ubig!(1));
let res_b = A(&mut c.stack, &ubig!(0));
let res = T(&mut c.stack, &[res_a, res_b]);
assert_jet(c, jet_dvr, sam, res);
let sam = T(s, &[a528, a264]);
let sam = T(&mut c.stack, &[a0, a24]);
let res_a = A(&mut c.stack, &ubig!(0));
let res_b = A(&mut c.stack, &ubig!(0));
let res = T(&mut c.stack, &[res_a, res_b]);
assert_jet(c, jet_dvr, sam, res);
let sam = T(&mut c.stack, &[a528, a264]);
let res_a = A(
s,
&mut c.stack,
&ubig!(
_0x00000000000001000000000000000000000000000000000000000000000000000000000000000001
),
);
let res_b = A(s, &ubig!(0x100));
let res = T(s, &[res_a, res_b]);
assert_jet(s, jet_dvr, sam, res);
let res_b = A(&mut c.stack, &ubig!(0x100));
let res = T(&mut c.stack, &[res_a, res_b]);
assert_jet(c, jet_dvr, sam, res);
assert_math_jet_err(s, jet_dvr, &[atom_63, atom_0], Deterministic);
assert_math_jet_err(c, jet_dvr, &[atom_63, atom_0], Deterministic);
}
#[test]
fn test_gte() {
let s = &mut init_stack();
assert_math_jet_noun(s, jet_gte, &[atom_128, atom_96], YES);
assert_math_jet_noun(s, jet_gte, &[atom_96, atom_63], YES);
assert_math_jet_noun(s, jet_gte, &[atom_63, atom_96], NO);
assert_math_jet_noun(s, jet_gte, &[atom_63, atom_63], YES);
assert_math_jet_noun(s, jet_gte, &[atom_63, atom_24], YES);
assert_math_jet_noun(s, jet_gte, &[atom_128, atom_24], YES);
assert_math_jet_noun(s, jet_gte, &[atom_128, atom_128_b], YES);
assert_math_jet_noun(s, jet_gte, &[atom_128_b, atom_128], NO);
let c = &mut init_context();
assert_math_jet_noun(c, jet_gte, &[atom_128, atom_96], YES);
assert_math_jet_noun(c, jet_gte, &[atom_96, atom_63], YES);
assert_math_jet_noun(c, jet_gte, &[atom_63, atom_96], NO);
assert_math_jet_noun(c, jet_gte, &[atom_63, atom_63], YES);
assert_math_jet_noun(c, jet_gte, &[atom_63, atom_24], YES);
assert_math_jet_noun(c, jet_gte, &[atom_128, atom_24], YES);
assert_math_jet_noun(c, jet_gte, &[atom_128, atom_128_b], YES);
assert_math_jet_noun(c, jet_gte, &[atom_128_b, atom_128], NO);
}
#[test]
fn test_gth() {
let s = &mut init_stack();
assert_math_jet_noun(s, jet_gth, &[atom_128, atom_96], YES);
assert_math_jet_noun(s, jet_gth, &[atom_96, atom_63], YES);
assert_math_jet_noun(s, jet_gth, &[atom_63, atom_96], NO);
assert_math_jet_noun(s, jet_gth, &[atom_63, atom_63], NO);
assert_math_jet_noun(s, jet_gth, &[atom_63, atom_24], YES);
assert_math_jet_noun(s, jet_gth, &[atom_128, atom_24], YES);
assert_math_jet_noun(s, jet_gth, &[atom_128, atom_128_b], YES);
assert_math_jet_noun(s, jet_gth, &[atom_128_b, atom_128], NO);
let c = &mut init_context();
assert_math_jet_noun(c, jet_gth, &[atom_128, atom_96], YES);
assert_math_jet_noun(c, jet_gth, &[atom_96, atom_63], YES);
assert_math_jet_noun(c, jet_gth, &[atom_63, atom_96], NO);
assert_math_jet_noun(c, jet_gth, &[atom_63, atom_63], NO);
assert_math_jet_noun(c, jet_gth, &[atom_63, atom_24], YES);
assert_math_jet_noun(c, jet_gth, &[atom_128, atom_24], YES);
assert_math_jet_noun(c, jet_gth, &[atom_128, atom_128_b], YES);
assert_math_jet_noun(c, jet_gth, &[atom_128_b, atom_128], NO);
}
#[test]
fn test_lte() {
let s = &mut init_stack();
assert_math_jet_noun(s, jet_lte, &[atom_128, atom_96], NO);
assert_math_jet_noun(s, jet_lte, &[atom_96, atom_63], NO);
assert_math_jet_noun(s, jet_lte, &[atom_63, atom_96], YES);
assert_math_jet_noun(s, jet_lte, &[atom_63, atom_63], YES);
assert_math_jet_noun(s, jet_lte, &[atom_63, atom_24], NO);
assert_math_jet_noun(s, jet_lte, &[atom_128, atom_24], NO);
assert_math_jet_noun(s, jet_lte, &[atom_128, atom_128_b], NO);
assert_math_jet_noun(s, jet_lte, &[atom_128_b, atom_128], YES);
let c = &mut init_context();
assert_math_jet_noun(c, jet_lte, &[atom_128, atom_96], NO);
assert_math_jet_noun(c, jet_lte, &[atom_96, atom_63], NO);
assert_math_jet_noun(c, jet_lte, &[atom_63, atom_96], YES);
assert_math_jet_noun(c, jet_lte, &[atom_63, atom_63], YES);
assert_math_jet_noun(c, jet_lte, &[atom_63, atom_24], NO);
assert_math_jet_noun(c, jet_lte, &[atom_128, atom_24], NO);
assert_math_jet_noun(c, jet_lte, &[atom_128, atom_128_b], NO);
assert_math_jet_noun(c, jet_lte, &[atom_128_b, atom_128], YES);
}
#[test]
fn test_lth() {
let s = &mut init_stack();
assert_math_jet_noun(s, jet_lth, &[atom_128, atom_96], NO);
assert_math_jet_noun(s, jet_lth, &[atom_96, atom_63], NO);
assert_math_jet_noun(s, jet_lth, &[atom_63, atom_96], YES);
assert_math_jet_noun(s, jet_lth, &[atom_63, atom_63], NO);
assert_math_jet_noun(s, jet_lth, &[atom_63, atom_24], NO);
assert_math_jet_noun(s, jet_lth, &[atom_128, atom_24], NO);
assert_math_jet_noun(s, jet_lth, &[atom_128, atom_128_b], NO);
assert_math_jet_noun(s, jet_lth, &[atom_128_b, atom_128], YES);
let c = &mut init_context();
assert_math_jet_noun(c, jet_lth, &[atom_128, atom_96], NO);
assert_math_jet_noun(c, jet_lth, &[atom_96, atom_63], NO);
assert_math_jet_noun(c, jet_lth, &[atom_63, atom_96], YES);
assert_math_jet_noun(c, jet_lth, &[atom_63, atom_63], NO);
assert_math_jet_noun(c, jet_lth, &[atom_63, atom_24], NO);
assert_math_jet_noun(c, jet_lth, &[atom_128, atom_24], NO);
assert_math_jet_noun(c, jet_lth, &[atom_128, atom_128_b], NO);
assert_math_jet_noun(c, jet_lth, &[atom_128_b, atom_128], YES);
}
#[test]
fn test_mod() {
let s = &mut init_stack();
let c = &mut init_context();
assert_math_jet(
s,
c,
jet_mod,
&[atom_128, atom_96],
ubig!(0xcb0ce564ec598f658409d170),
);
assert_math_jet(s, jet_mod, &[atom_96, atom_63], ubig!(0x15deadc0e4af946e));
assert_math_jet(s, jet_mod, &[atom_63, atom_96], ubig!(0x7fffffffffffffff));
assert_math_jet(s, jet_mod, &[atom_63, atom_63], ubig!(0));
assert_math_jet(s, jet_mod, &[atom_63, atom_24], ubig!(0x798385));
assert_math_jet(s, jet_mod, &[atom_128, atom_24], ubig!(0x3b2013));
assert_math_jet(s, jet_mod, &[atom_528, atom_264], ubig!(0x100));
assert_math_jet_err(s, jet_mod, &[atom_63, atom_0], Deterministic);
assert_math_jet_err(s, jet_mod, &[atom_0, atom_0], Deterministic);
assert_math_jet(c, jet_mod, &[atom_96, atom_63], ubig!(0x15deadc0e4af946e));
assert_math_jet(c, jet_mod, &[atom_63, atom_96], ubig!(0x7fffffffffffffff));
assert_math_jet(c, jet_mod, &[atom_63, atom_63], ubig!(0));
assert_math_jet(c, jet_mod, &[atom_63, atom_24], ubig!(0x798385));
assert_math_jet(c, jet_mod, &[atom_128, atom_24], ubig!(0x3b2013));
assert_math_jet(c, jet_mod, &[atom_528, atom_264], ubig!(0x100));
assert_math_jet_err(c, jet_mod, &[atom_63, atom_0], Deterministic);
assert_math_jet_err(c, jet_mod, &[atom_0, atom_0], Deterministic);
}
#[test]
fn test_mul() {
let s = &mut init_stack();
let c = &mut init_context();
assert_math_jet(
s,
c,
jet_mul,
&[atom_128, atom_96],
ubig!(_0xda297567129704bf42e744f13ff0ea4fc4ac01215b708bc94f941160),
);
assert_math_jet(
s,
c,
jet_mul,
&[atom_63, atom_96],
ubig!(_0x7d6758060aef56de7cba6a1eea21524110edcbaa),
);
assert_math_jet(
s,
c,
jet_mul,
&[atom_63, atom_63],
ubig!(0x3fffffffffffffff0000000000000001),
);
assert_math_jet(s, jet_mul, &[atom_24, atom_24], ubig!(0x479bf4b7ef89));
assert_math_jet(c, jet_mul, &[atom_24, atom_24], ubig!(0x479bf4b7ef89));
}
#[test]
fn test_sub() {
let s = &mut init_stack();
let c = &mut init_context();
assert_math_jet(
s,
c,
jet_sub,
&[atom_128, atom_96],
ubig!(0xdeadbeee1765a66ce8fe0cd98741fdba),
);
assert_math_jet(
s,
c,
jet_sub,
&[atom_96, atom_63],
ubig!(0xfaceb00b95deadbeef123457),
);
assert_math_jet(s, jet_sub, &[atom_63, atom_63], ubig!(0));
assert_math_jet(s, jet_sub, &[atom_128, atom_128], ubig!(0));
assert_math_jet_err(s, jet_sub, &[atom_63, atom_96], Deterministic);
assert_math_jet(c, jet_sub, &[atom_63, atom_63], ubig!(0));
assert_math_jet(c, jet_sub, &[atom_128, atom_128], ubig!(0));
assert_math_jet_err(c, jet_sub, &[atom_63, atom_96], Deterministic);
}
}

View File

@ -15,7 +15,7 @@ pub fn jet_mink(context: &mut Context, subject: Noun) -> Result {
let v_subject = slot(arg, 4)?;
let v_formula = slot(arg, 5)?;
let scry_handler = slot(arg, 3)?;
let new_scry_stack = T(context.stack, &[scry_handler, context.scry_stack]);
let new_scry_stack = T(&mut context.stack, &[scry_handler, context.scry_stack]);
context.scry_stack = new_scry_stack;
let res = util::mink(context, v_subject, v_formula);
@ -40,15 +40,15 @@ pub mod util {
pub fn mink(context: &mut Context, subject: Noun, formula: Noun) -> jets::Result {
match interpret(context, subject, formula) {
Ok(res) => Ok(T(context.stack, &[D(0), res])),
Ok(res) => Ok(T(&mut context.stack, &[D(0), res])),
Err(err) => match err {
Error::Nock(nock_err) => match nock_err {
NockError::Deterministic(trace) => Ok(T(context.stack, &[D(2), trace])),
NockError::Deterministic(trace) => Ok(T(&mut context.stack, &[D(2), trace])),
// XX: trace is unused; needs to be printed or welded to trace from outer context
NockError::NonDeterministic(_trace) => Err(JetErr::NonDeterministic),
},
Error::Scry(scry_err) => match scry_err {
ScryError::Blocked(path) => Ok(T(context.stack, &[D(1), path])),
ScryError::Blocked(path) => Ok(T(&mut context.stack, &[D(1), path])),
// XX: trace is unused; needs to be printed or welded to trace from outer context
ScryError::Deterministic(_trace) => Err(JetErr::Deterministic),
// XX: trace is unused; needs to be printed or welded to trace from outer context
@ -83,7 +83,7 @@ pub mod util {
let mut res = D(0);
let mut list = original_list;
// Unused if flopping
let (mut new_cell, mut new_memory) = Cell::new_raw_mut(context.stack);
let (mut new_cell, mut new_memory) = Cell::new_raw_mut(&mut context.stack);
let mut memory = new_memory;
// loop guaranteed to run at least once
@ -93,7 +93,7 @@ pub mod util {
} else if !flop && res.raw_equals(D(0)) {
res = new_cell.as_noun();
} else if !flop {
(new_cell, new_memory) = Cell::new_raw_mut(context.stack);
(new_cell, new_memory) = Cell::new_raw_mut(&mut context.stack);
(*memory).tail = new_cell.as_noun();
memory = new_memory
}
@ -106,26 +106,29 @@ pub mod util {
let tank: Noun = match tag.data() {
tas!(b"hunk") => match dat.as_either_atom_cell() {
Left(_) => {
let tape = tape(context.stack, "mook.hunk");
T(context.stack, &[LEAF, tape])
let stack = &mut context.stack;
let tape = tape(stack, "mook.hunk");
T(stack, &[LEAF, tape])
}
Right(cell) => {
// XX: need to check that this is actually a path
// return leaf+"mook.hunk" if not
let path = cell.tail();
smyt(context.stack, path)?
smyt(&mut context.stack, path)?
}
},
tas!(b"mean") => match dat.as_either_atom_cell() {
Left(atom) => {
let tape = rip(context.stack, 3, 1, atom)?;
T(context.stack, &[LEAF, tape])
let stack = &mut context.stack;
let tape = rip(stack, 3, 1, atom)?;
T(stack, &[LEAF, tape])
}
Right(cell) => {
let tone = mink(context, dat, cell.head())?.as_cell()?;
if !tone.head().raw_equals(D(0)) {
let tape = tape(context.stack, "####");
T(context.stack, &[LEAF, tape])
let stack = &mut context.stack;
let tape = tape(stack, "####");
T(stack, &[LEAF, tape])
} else {
// XX: need to check that this is actually a tank
// return leaf+"mook.mean" if not
@ -135,13 +138,14 @@ pub mod util {
},
tas!(b"spot") => {
let stack = &mut context.stack;
let spot = dat.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(b':' as u64), D(0)]);
let trel = T(*stack, &[colo, D(0), D(0)]);
let colo = T(stack, &[D(b':' as u64), D(0)]);
let trel = T(stack, &[colo, D(0), D(0)]);
let smyt = smyt(stack, spot.head())?;
@ -159,7 +163,7 @@ pub mod util {
list = list.tail().as_cell()?;
}
// "{end_col}]>"
let p4 = T(*stack, &[D(b']' as u64), D(b'>' as u64), D(0)]);
let p4 = T(stack, &[D(b']' as u64), D(b'>' as u64), D(0)]);
(*list.tail_as_mut()) = p4;
list = end_lin.as_cell()?;
@ -170,7 +174,7 @@ pub mod util {
list = list.tail().as_cell()?;
}
// "{end_lin} {end_col}]>"
let p3 = T(*stack, &[D(b' ' as u64), end_col]);
let p3 = T(stack, &[D(b' ' as u64), end_col]);
(*list.tail_as_mut()) = p3;
list = str_col.as_cell()?;
@ -182,7 +186,7 @@ pub mod util {
}
// "{str_col}].[{end_lin} {end_col}]>"
let p2 = T(
*stack,
stack,
&[D(b']' as u64), D(b'.' as u64), D(b'[' as u64), end_lin],
);
(*list.tail_as_mut()) = p2;
@ -195,19 +199,20 @@ pub mod util {
list = list.tail().as_cell()?;
}
// "{str_lin} {str_col}].[{end_lin} {end_col}]>"
let p1 = T(*stack, &[D(b' ' as u64), str_col]);
let p1 = T(stack, &[D(b' ' as u64), str_col]);
(*list.tail_as_mut()) = p1;
// "<[{str_lin} {str_col}].[{end_lin} {end_col}]>"
let tape = T(*stack, &[D(b'<' as u64), D(b'[' as u64), str_lin]);
let finn = T(*stack, &[LEAF, tape]);
let tape = T(stack, &[D(b'<' as u64), D(b'[' as u64), str_lin]);
let finn = T(stack, &[LEAF, tape]);
T(*stack, &[ROSE, trel, smyt, finn, D(0)])
T(stack, &[ROSE, trel, smyt, finn, D(0)])
}
_ => {
let tape = rip(context.stack, 3, 1, tag.as_atom())?;
let stack = &mut context.stack;
let tape = rip(stack, 3, 1, tag.as_atom())?;
T(
context.stack,
stack,
&[
D(tas!(b"m")),
D(tas!(b"o")),
@ -223,7 +228,7 @@ pub mod util {
};
if flop {
res = T(context.stack, &[tank, res]);
res = T(&mut context.stack, &[tank, res]);
} else {
(*memory).head = tank;
}
@ -234,7 +239,7 @@ pub mod util {
(*memory).tail = D(0);
}
let toon = Cell::new(context.stack, D(2), res);
let toon = Cell::new(&mut context.stack, D(2), res);
Ok(toon)
}
}
@ -268,7 +273,7 @@ pub mod util {
#[cfg(test)]
mod tests {
use super::*;
use crate::jets::util::test::{assert_jet, init_stack};
use crate::jets::util::test::{assert_jet, init_context};
use crate::mem::NockStack;
use crate::noun::{D, T};
use crate::serf::TERMINATOR;
@ -289,31 +294,36 @@ mod tests {
#[test]
fn test_mink_success() {
let sack = &mut init_stack();
let context = &mut init_context();
let stack = &mut context.stack;
let subj = D(0);
let form = T(sack, &[D(1), D(53)]);
let nock = T(sack, &[subj, form]);
let form = T(stack, &[D(1), D(53)]);
let nock = T(stack, &[subj, form]);
let scry = D(0);
let samp = T(sack, &[nock, scry]);
let rest = T(sack, &[D(0), D(53)]);
assert_jet(sack, jet_mink, samp, rest);
let samp = T(stack, &[nock, scry]);
let rest = T(stack, &[D(0), D(53)]);
assert_jet(context, jet_mink, samp, rest);
}
#[test]
fn test_mink_zapzap() {
let sack = &mut init_stack();
let context = &mut init_context();
let stack = &mut context.stack;
let subj = D(0);
let form = T(sack, &[D(0), D(0)]);
let nock = T(sack, &[subj, form]);
let form = T(stack, &[D(0), D(0)]);
let nock = T(stack, &[subj, form]);
let scry = D(0);
let samp = T(sack, &[nock, scry]);
let rest = T(sack, &[D(2), D(0)]);
assert_jet(sack, jet_mink, samp, rest);
let samp = T(stack, &[nock, scry]);
let rest = T(stack, &[D(2), D(0)]);
assert_jet(context, jet_mink, samp, rest);
}
#[test]
fn test_mink_trace() {
let sack = &mut init_stack();
let context = &mut init_context();
let stack = &mut context.stack;
let subj = D(0);
let scry = D(0);
@ -337,63 +347,63 @@ mod tests {
// https://stackoverflow.com/questions/60686259/mutable-borrow-in-function-argument
let hint_spot = D(1953460339);
let hint_path = T(sack, &[D(1953719668), D(0)]);
let hint_path = T(stack, &[D(1953719668), D(0)]);
let hint_dyn = D(1);
let hint_row = D(1);
let make_hint = |sack: &mut NockStack, col_start: u64, col_end: u64| {
let start = T(sack, &[hint_row, D(col_start)]);
let end = T(sack, &[hint_row, D(col_end)]);
let make_hint = |stack: &mut NockStack, col_start: u64, col_end: u64| {
let start = T(stack, &[hint_row, D(col_start)]);
let end = T(stack, &[hint_row, D(col_end)]);
T(sack, &[hint_spot, hint_dyn, hint_path, start, end])
T(stack, &[hint_spot, hint_dyn, hint_path, start, end])
};
let sss3s1 = T(sack, &[D(0), D(3)]);
let sss3s2s1 = make_hint(sack, 20, 22);
let sss3s2s2 = T(sack, &[D(1), D(53)]);
let sss3s2 = T(sack, &[D(11), sss3s2s1, sss3s2s2]);
let sss3 = T(sack, &[D(7), sss3s1, sss3s2]);
let sss3s1 = T(stack, &[D(0), D(3)]);
let sss3s2s1 = make_hint(stack, 20, 22);
let sss3s2s2 = T(stack, &[D(1), D(53)]);
let sss3s2 = T(stack, &[D(11), sss3s2s1, sss3s2s2]);
let sss3 = T(stack, &[D(7), sss3s1, sss3s2]);
let sss2s1 = sss3s1;
let sss2s2s1 = make_hint(sack, 16, 18);
let sss2s2s2 = T(sack, &[D(0), D(0)]);
let sss2s2 = T(sack, &[D(11), sss2s2s1, sss2s2s2]);
let sss2 = T(sack, &[D(7), sss2s1, sss2s2]);
let sss2s2s1 = make_hint(stack, 16, 18);
let sss2s2s2 = T(stack, &[D(0), D(0)]);
let sss2s2 = T(stack, &[D(11), sss2s2s1, sss2s2s2]);
let sss2 = T(stack, &[D(7), sss2s1, sss2s2]);
let sss1s1 = T(sack, &[D(1), D(0)]);
let sss1s2 = T(sack, &[D(0), D(2)]);
let sss1 = T(sack, &[D(5), sss1s1, sss1s2]);
let sss1s1 = T(stack, &[D(1), D(0)]);
let sss1s2 = T(stack, &[D(0), D(2)]);
let sss1 = T(stack, &[D(5), sss1s1, sss1s2]);
let ss2 = T(sack, &[D(6), sss1, sss2, sss3]);
let ss2 = T(stack, &[D(6), sss1, sss2, sss3]);
let ss1s1 = make_hint(sack, 13, 14);
let ss1s1 = make_hint(stack, 13, 14);
let ss1s2 = sss1s1;
let ss1 = T(sack, &[D(11), ss1s1, ss1s2]);
let ss1 = T(stack, &[D(11), ss1s1, ss1s2]);
let s2 = T(sack, &[D(8), ss1, ss2]);
let s1 = make_hint(sack, 9, 22);
let form = T(sack, &[D(11), s1, s2]);
let s2 = T(stack, &[D(8), ss1, ss2]);
let s1 = make_hint(stack, 9, 22);
let form = T(stack, &[D(11), s1, s2]);
let nock = T(sack, &[subj, form]);
let samp = T(sack, &[nock, scry]);
let nock = T(stack, &[subj, form]);
let samp = T(stack, &[nock, scry]);
// trace
// [%2 trace=~[[~.spot [[1.953.719.668 0] [1 16] 1 18]] [~.spot [[1.953.719.668 0] [1 9] 1 22]]]]
let ttt2t1 = T(sack, &[D(1), D(9)]);
let ttt2t2 = T(sack, &[D(1), D(22)]);
let ttt2 = T(sack, &[hint_path, ttt2t1, ttt2t2]);
let ttt2t1 = T(stack, &[D(1), D(9)]);
let ttt2t2 = T(stack, &[D(1), D(22)]);
let ttt2 = T(stack, &[hint_path, ttt2t1, ttt2t2]);
let ttt1t1 = T(sack, &[D(1), D(16)]);
let ttt1t2 = T(sack, &[D(1), D(18)]);
let ttt1 = T(sack, &[hint_path, ttt1t1, ttt1t2]);
let ttt1t1 = T(stack, &[D(1), D(16)]);
let ttt1t2 = T(stack, &[D(1), D(18)]);
let ttt1 = T(stack, &[hint_path, ttt1t1, ttt1t2]);
let tt2 = T(sack, &[hint_spot, ttt2]);
let tt1 = T(sack, &[hint_spot, ttt1]);
let tt2 = T(stack, &[hint_spot, ttt2]);
let tt1 = T(stack, &[hint_spot, ttt1]);
let t1 = T(sack, &[tt1, tt2, D(0)]);
let t1 = T(stack, &[tt1, tt2, D(0)]);
let rest = T(sack, &[D(2), t1]);
let rest = T(stack, &[D(2), t1]);
assert_jet(sack, jet_mink, samp, rest);
assert_jet(context, jet_mink, samp, rest);
}
}

View File

@ -39,20 +39,21 @@ pub mod util {
#[cfg(test)]
mod tests {
use super::*;
use crate::jets::util::test::{assert_jet, assert_jet_err, init_stack};
use crate::jets::util::test::{assert_jet, assert_jet_err, init_context};
use crate::jets::JetErr;
use crate::noun::{D, T};
#[test]
fn test_lent() {
let s = &mut init_stack();
assert_jet(s, jet_lent, D(0), D(0));
let sam = T(s, &[D(1), D(2), D(3), D(0)]);
assert_jet(s, jet_lent, sam, D(3));
let sam = T(s, &[D(3), D(2), D(1), D(0)]);
assert_jet(s, jet_lent, sam, D(3));
assert_jet_err(s, jet_lent, D(1), JetErr::Deterministic);
let sam = T(s, &[D(3), D(2), D(1)]);
assert_jet_err(s, jet_lent, sam, JetErr::Deterministic);
let c = &mut init_context();
assert_jet(c, jet_lent, D(0), D(0));
let sam = T(&mut c.stack, &[D(1), D(2), D(3), D(0)]);
assert_jet(c, jet_lent, sam, D(3));
let sam = T(&mut c.stack, &[D(3), D(2), D(1), D(0)]);
assert_jet(c, jet_lent, sam, D(3));
assert_jet_err(c, jet_lent, D(1), JetErr::Deterministic);
let sam = T(&mut c.stack, &[D(3), D(2), D(1)]);
assert_jet_err(c, jet_lent, sam, JetErr::Deterministic);
}
}

View File

@ -44,39 +44,39 @@ pub fn jet_mas(context: &mut Context, subject: Noun) -> Result {
#[cfg(test)]
mod tests {
use super::*;
use crate::jets::util::test::{assert_jet, assert_jet_err, init_stack};
use crate::jets::util::test::{assert_jet, assert_jet_err, init_context};
use crate::jets::JetErr;
use crate::noun::D;
#[test]
fn test_cap() {
let s = &mut init_stack();
let c = &mut init_context();
assert_jet_err(s, jet_cap, D(0), JetErr::Deterministic);
assert_jet_err(s, jet_cap, D(1), JetErr::Deterministic);
assert_jet_err(c, jet_cap, D(0), JetErr::Deterministic);
assert_jet_err(c, jet_cap, D(1), JetErr::Deterministic);
assert_jet(s, jet_cap, D(2), D(2));
assert_jet(s, jet_cap, D(3), D(3));
assert_jet(s, jet_cap, D(4), D(2));
assert_jet(s, jet_cap, D(5), D(2));
assert_jet(s, jet_cap, D(6), D(3));
assert_jet(s, jet_cap, D(7), D(3));
assert_jet(s, jet_cap, D(8), D(2));
assert_jet(c, jet_cap, D(2), D(2));
assert_jet(c, jet_cap, D(3), D(3));
assert_jet(c, jet_cap, D(4), D(2));
assert_jet(c, jet_cap, D(5), D(2));
assert_jet(c, jet_cap, D(6), D(3));
assert_jet(c, jet_cap, D(7), D(3));
assert_jet(c, jet_cap, D(8), D(2));
}
#[test]
fn test_mas() {
let s = &mut init_stack();
let c = &mut init_context();
assert_jet_err(s, jet_mas, D(0), JetErr::Deterministic);
assert_jet_err(s, jet_mas, D(1), JetErr::Deterministic);
assert_jet_err(c, jet_mas, D(0), JetErr::Deterministic);
assert_jet_err(c, jet_mas, D(1), JetErr::Deterministic);
assert_jet(s, jet_mas, D(2), D(1));
assert_jet(s, jet_mas, D(3), D(1));
assert_jet(s, jet_mas, D(4), D(2));
assert_jet(s, jet_mas, D(5), D(3));
assert_jet(s, jet_mas, D(6), D(2));
assert_jet(s, jet_mas, D(7), D(3));
assert_jet(s, jet_mas, D(8), D(4));
assert_jet(c, jet_mas, D(2), D(1));
assert_jet(c, jet_mas, D(3), D(1));
assert_jet(c, jet_mas, D(4), D(2));
assert_jet(c, jet_mas, D(5), D(3));
assert_jet(c, jet_mas, D(6), D(2));
assert_jet(c, jet_mas, D(7), D(3));
assert_jet(c, jet_mas, D(8), D(4));
}
}

View File

@ -66,18 +66,18 @@ fn main() -> io::Result<()> {
let input_cell = input
.as_cell()
.expect("Input must be jam of subject/formula pair");
let mut newt = Newt::new_mock();
let mut cache = Hamt::<Noun>::new();
let mut cold = Cold::new(&mut stack);
let mut warm = Warm::new();
let newt = Newt::new_mock();
let cache = Hamt::<Noun>::new();
let cold = Cold::new(&mut stack);
let warm = Warm::new();
let hot = Hot::init(&mut stack);
let mut context = Context {
stack: &mut stack,
newt: Some(&mut newt),
cache: &mut cache,
cold: &mut cold,
warm: &mut warm,
hot: &hot,
stack,
newt,
cache,
cold,
warm,
hot,
scry_stack: D(0),
};
let result =
@ -85,7 +85,7 @@ fn main() -> io::Result<()> {
if let Ok(atom) = result.as_atom() {
println!("Result: {}", atom);
}
let jammed_result = jam(&mut stack, result);
let jammed_result = jam(&mut context.stack, result);
let f_out = OpenOptions::new()
.read(true)
.write(true)

View File

@ -30,13 +30,7 @@ struct Context {
snapshot: DoubleJam,
arvo: Noun,
mug: u32,
stack: NockStack,
newt: Newt,
cache: Hamt<Noun>,
// XX: persistent memo cache
cold: Cold,
warm: Warm,
hot: Hot,
nock_context: interpreter::Context,
}
impl Context {
@ -55,52 +49,23 @@ impl Context {
let (epoch, event_num, arvo) = snapshot.load(&mut stack).unwrap_or((0, 0, D(0)));
let mug = mug_u32(&mut stack, arvo);
let nock_context = interpreter::Context {
stack,
newt,
cold,
warm,
hot,
cache,
scry_stack: D(0),
};
Context {
epoch,
event_num,
snapshot,
arvo,
mug,
stack,
newt,
cache,
cold,
warm,
hot,
}
}
//
// Getters
//
pub fn epoch(&self) -> u64 {
self.epoch
}
pub fn event_num(&self) -> u64 {
self.event_num
}
pub fn arvo(&self) -> Noun {
self.arvo
}
pub fn stack_as_mut(&mut self) -> &mut NockStack {
&mut self.stack
}
pub fn for_interpreter(&mut self) -> interpreter::Context {
self.cache = Hamt::<Noun>::new();
interpreter::Context {
stack: &mut self.stack,
newt: Some(&mut self.newt),
cache: &mut self.cache,
cold: &mut self.cold,
warm: &mut self.warm,
hot: &self.hot,
scry_stack: D(0),
nock_context,
}
}
@ -112,8 +77,9 @@ impl Context {
// XX: assert event numbers are continuous
self.arvo = new_arvo;
self.event_num = new_event_num;
self.snapshot.save(&mut self.stack, &mut self.arvo);
self.mug = mug_u32(&mut self.stack, self.arvo);
self.snapshot
.save(&mut self.nock_context.stack, &mut self.arvo);
self.mug = mug_u32(&mut self.nock_context.stack, self.arvo);
}
//
@ -122,7 +88,7 @@ impl Context {
pub fn sync(&mut self) {
self.snapshot
.sync(&mut self.stack, self.epoch, self.event_num);
.sync(&mut self.nock_context.stack, self.epoch, self.event_num);
}
//
@ -130,43 +96,65 @@ impl Context {
//
pub fn next(&mut self) -> Option<Noun> {
self.newt.next(&mut self.stack)
self.nock_context.newt.next(&mut self.nock_context.stack)
}
pub fn ripe(&mut self) {
self.newt
.ripe(&mut self.stack, self.event_num, self.mug as u64);
self.nock_context.newt.ripe(
&mut self.nock_context.stack,
self.event_num,
self.mug as u64,
);
}
pub fn live(&mut self) {
self.newt.live(&mut self.stack);
self.nock_context.newt.live(&mut self.nock_context.stack);
}
pub fn peek_done(&mut self, dat: Noun) {
self.newt.peek_done(&mut self.stack, dat);
self.nock_context
.newt
.peek_done(&mut self.nock_context.stack, dat);
}
pub fn play_done(&mut self) {
self.newt.play_done(&mut self.stack, self.mug as u64);
self.nock_context
.newt
.play_done(&mut self.nock_context.stack, self.mug as u64);
}
pub fn play_bail(&mut self, dud: Noun) {
self.newt
.play_bail(&mut self.stack, self.event_num, self.mug as u64, dud);
self.nock_context.newt.play_bail(
&mut self.nock_context.stack,
self.event_num,
self.mug as u64,
dud,
);
}
pub fn work_done(&mut self, fec: Noun) {
self.newt
.work_done(&mut self.stack, self.event_num, self.mug as u64, fec);
self.nock_context.newt.work_done(
&mut self.nock_context.stack,
self.event_num,
self.mug as u64,
fec,
);
}
pub fn work_swap(&mut self, job: Noun, fec: Noun) {
self.newt
.work_swap(&mut self.stack, self.event_num, self.mug as u64, job, fec);
self.nock_context.newt.work_swap(
&mut self.nock_context.stack,
self.event_num,
self.mug as u64,
job,
fec,
);
}
pub fn work_bail(&mut self, lud: Noun) {
self.newt.work_bail(&mut self.stack, lud);
self.nock_context
.newt
.work_bail(&mut self.nock_context.stack, lud);
}
}
@ -232,7 +220,7 @@ pub fn serf() -> io::Result<()> {
}
tas!(b"play") => {
let lit = slot(writ, 7)?;
if context.epoch() == 0 && context.event_num() == 0 {
if context.epoch == 0 && context.event_num == 0 {
// apply lifecycle to first batch
play_life(&mut context, lit);
} else {
@ -253,34 +241,25 @@ pub fn serf() -> io::Result<()> {
Ok(())
}
fn burn(context: &mut Context, subject: Noun, formula: Noun) -> Result<Noun, Error> {
let burn_context = &mut context.for_interpreter();
interpret(burn_context, subject, formula)
}
fn slam(context: &mut Context, axis: u64, ovo: Noun) -> Result<Noun, Error> {
let arvo = context.arvo();
let pul = T(context.stack_as_mut(), &[D(9), D(axis), D(0), D(2)]);
let sam = T(context.stack_as_mut(), &[D(6), D(0), D(7)]);
let fol = T(
context.stack_as_mut(),
&[D(8), pul, D(9), D(2), D(10), sam, D(0), D(2)],
);
let sub = T(context.stack_as_mut(), &[arvo, ovo]);
burn(context, sub, fol)
let arvo = context.arvo;
let stack = &mut context.nock_context.stack;
let pul = T(stack, &[D(9), D(axis), D(0), D(2)]);
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 sub = T(stack, &[arvo, ovo]);
interpret(&mut context.nock_context, sub, fol)
}
fn goof(context: &mut Context, trace: Noun) -> Noun {
let tone = Cell::new(context.stack_as_mut(), D(2), trace);
let mook_context = &mut context.for_interpreter();
let tang = mook(mook_context, tone, false)
let tone = Cell::new(&mut context.nock_context.stack, D(2), trace);
let tang = mook(&mut context.nock_context, tone, false)
.expect("serf: goof: +mook crashed on bail")
.tail();
// XX: noun::Error should use a bail enum system similar to u3m_bail motes;
// might be able to replace NockErr with mote and map determinism to individual motes;
// for, always set to %exit
T(mook_context.stack, &[D(tas!(b"exit")), tang])
T(&mut context.nock_context.stack, &[D(tas!(b"exit")), tang])
}
/** Run slam, process stack trace to tang if error */
@ -299,9 +278,10 @@ fn soft(context: &mut Context, ovo: Noun) -> Result<Noun, Noun> {
}
fn play_life(context: &mut Context, eve: Noun) {
let sub = T(context.stack_as_mut(), &[D(0), D(3)]);
let lyf = T(context.stack_as_mut(), &[D(2), sub, D(0), D(2)]);
match burn(context, eve, lyf) {
let stack = &mut context.nock_context.stack;
let sub = T(stack, &[D(0), D(3)]);
let lyf = T(stack, &[D(2), sub, D(0), D(2)]);
match interpret(&mut context.nock_context, eve, lyf) {
Ok(gat) => {
let eved = lent(eve).expect("serf: play: boot event number failure") as u64;
let arvo = slot(gat, 7).expect("serf: play: lifecycle didn't return initial Arvo");
@ -322,7 +302,7 @@ fn play_life(context: &mut Context, eve: Noun) {
}
fn play_list(context: &mut Context, mut lit: Noun) {
let mut eve = context.event_num();
let mut eve = context.event_num;
while let Ok(cell) = lit.as_cell() {
let ovo = cell.head();
match soft(context, ovo) {
@ -349,7 +329,7 @@ fn work(context: &mut Context, job: Noun) {
Ok(res) => {
let cell = res.as_cell().expect("serf: work: +slam returned atom");
let fec = cell.head();
let eve = context.event_num();
let eve = context.event_num;
context.event_update(eve + 1, cell.tail());
context.work_done(fec);
@ -367,21 +347,19 @@ fn work_swap(context: &mut Context, job: Noun, goof: Noun) {
clear_interrupt();
let stack = &mut context.nock_context.stack;
// crud = [+(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");
let now = inc(context.stack_as_mut(), job_now).as_noun();
let wire = T(context.stack_as_mut(), &[D(0), D(tas!(b"arvo")), D(0)]);
let crud = T(
context.stack_as_mut(),
&[now, wire, D(tas!(b"crud")), goof, job_cell.tail()],
);
let now = inc(stack, job_now).as_noun();
let wire = T(stack, &[D(0), D(tas!(b"arvo")), D(0)]);
let crud = T(stack, &[now, wire, D(tas!(b"crud")), goof, job_cell.tail()]);
match soft(context, crud) {
Ok(res) => {
let cell = res.as_cell().expect("serf: work: crud +slam returned atom");
let fec = cell.head();
let eve = context.event_num();
let eve = context.event_num;
context.event_update(eve + 1, cell.tail());
context.work_swap(crud, fec);
@ -393,8 +371,9 @@ fn work_swap(context: &mut Context, job: Noun, goof: Noun) {
}
fn work_bail(context: &mut Context, goofs: &[Noun]) {
let lest = T(context.stack_as_mut(), goofs);
let lud = T(context.stack_as_mut(), &[lest, D(0)]);
let stack = &mut context.nock_context.stack;
let lest = T(stack, goofs);
let lud = T(stack, &[lest, D(0)]);
context.work_bail(lud);
}