This commit is contained in:
Matthew LeVan 2023-12-07 19:26:42 -05:00
parent 89506c4f1f
commit 4312ecb952
6 changed files with 65 additions and 14 deletions

View File

@ -12,9 +12,9 @@ edition = "2018"
# Please keep these alphabetized # Please keep these alphabetized
[dependencies] [dependencies]
ares_macros = { path = "../ares_macros" } ares_macros = { path = "../ares_macros" }
assert_no_alloc = "1.1.2" # assert_no_alloc = "1.1.2"
# use this when debugging requires allocation (e.g. eprintln) # use this when debugging requires allocation (e.g. eprintln)
# assert_no_alloc = {version="1.1.2", features=["warn_debug"]} assert_no_alloc = {version="1.1.2", features=["warn_debug"]}
bitvec = "1.0.0" bitvec = "1.0.0"
criterion = "0.4" criterion = "0.4"
either = "1.9.0" either = "1.9.0"

View File

@ -348,6 +348,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
push_formula(&mut context.stack, formula, true)?; push_formula(&mut context.stack, formula, true)?;
loop { loop {
assert_is_list(*(context.stack.local_noun_pointer(0)), "loop top");
let work: NockWork = *context.stack.top(); let work: NockWork = *context.stack.top();
match work { match work {
NockWork::Done => { NockWork::Done => {
@ -410,6 +411,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
context.stack.pop::<NockWork>(); context.stack.pop::<NockWork>();
} else { } else {
// Axis invalid for input Noun // Axis invalid for input Noun
assert_is_list(*(context.stack.local_noun_pointer(0)), "WORK 0");
break Err(Error::Deterministic(D(0))); break Err(Error::Deterministic(D(0)));
} }
} }
@ -419,6 +421,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
} }
NockWork::Work2(mut vale) => { NockWork::Work2(mut vale) => {
if (*terminator).load(Ordering::Relaxed) { if (*terminator).load(Ordering::Relaxed) {
assert_is_list(*(context.stack.local_noun_pointer(0)), "WORK 2");
break Err(Error::NonDeterministic(D(0))); break Err(Error::NonDeterministic(D(0)));
} }
@ -489,6 +492,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
context.stack.pop::<NockWork>(); context.stack.pop::<NockWork>();
} else { } else {
// Cannot increment (Nock 4) a cell // Cannot increment (Nock 4) a cell
assert_is_list(*(context.stack.local_noun_pointer(0)), "TODO 4");
break Err(Error::Deterministic(D(0))); break Err(Error::Deterministic(D(0)));
} }
} }
@ -532,10 +536,12 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
push_formula(stack, cond.once, cond.tail)?; push_formula(stack, cond.once, cond.tail)?;
} else { } else {
// Test branch of Nock 6 must return 0 or 1 // Test branch of Nock 6 must return 0 or 1
assert_is_list(*(context.stack.local_noun_pointer(0)), "TODO 6");
break Err(Error::Deterministic(D(0))); break Err(Error::Deterministic(D(0)));
} }
} else { } else {
// Test branch of Nock 6 must return a direct atom // Test branch of Nock 6 must return a direct atom
assert_is_list(*(context.stack.local_noun_pointer(0)), "TODO 6.1");
break Err(Error::Deterministic(D(0))); break Err(Error::Deterministic(D(0)));
} }
} }
@ -592,6 +598,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
}, },
NockWork::Work9(mut kale) => { NockWork::Work9(mut kale) => {
if (*terminator).load(Ordering::Relaxed) { if (*terminator).load(Ordering::Relaxed) {
assert_is_list(*(context.stack.local_noun_pointer(0)), "WORK 9");
break Err(Error::NonDeterministic(D(0))); break Err(Error::NonDeterministic(D(0)));
} }
@ -617,6 +624,10 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
} }
Err(JetErr::Punt) => {} Err(JetErr::Punt) => {}
Err(err) => { Err(err) => {
assert_is_list(
*(context.stack.local_noun_pointer(0)),
"WORK 9.1"
);
break Err(err.into()); break Err(err.into());
} }
} }
@ -663,6 +674,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
} }
} else { } else {
// Axis into core must be atom // Axis into core must be atom
assert_is_list(*(context.stack.local_noun_pointer(0)), "WORK 9.2");
break Err(Error::Deterministic(D(0))); break Err(Error::Deterministic(D(0)));
} }
} }
@ -708,6 +720,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
context.stack.pop::<NockWork>(); context.stack.pop::<NockWork>();
} }
Err(err) => { Err(err) => {
assert_is_list(*(context.stack.local_noun_pointer(0)), "TODO 11D COMPHINT");
break Err(err); break Err(err);
} }
} }
@ -731,6 +744,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
context.stack.pop::<NockWork>(); context.stack.pop::<NockWork>();
} }
Err(err) => { Err(err) => {
assert_is_list(*(context.stack.local_noun_pointer(0)), "TODO 11D COMPRES");
break Err(err); break Err(err);
} }
} }
@ -770,6 +784,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
context.stack.pop::<NockWork>(); context.stack.pop::<NockWork>();
} }
Err(err) => { Err(err) => {
assert_is_list(*(context.stack.local_noun_pointer(0)), "TODO 11S COMP RES");
break Err(err); break Err(err);
} }
} }
@ -831,8 +846,10 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
Ok(noun) => match noun.as_either_atom_cell() { Ok(noun) => match noun.as_either_atom_cell() {
Left(atom) => { Left(atom) => {
if atom.as_noun().raw_equals(D(0)) { if atom.as_noun().raw_equals(D(0)) {
assert_is_list(*(context.stack.local_noun_pointer(0)), "WORK 12 SCRY BLOK");
break Err(Error::ScryBlocked(scry.path)); break Err(Error::ScryBlocked(scry.path));
} else { } else {
assert_is_list(*(context.stack.local_noun_pointer(0)), "WORK 12 SCRY CRASH");
break Err(Error::ScryCrashed(D(0))); break Err(Error::ScryCrashed(D(0)));
} }
} }
@ -842,6 +859,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
let hunk = let hunk =
T(stack, &[D(tas!(b"hunk")), scry.reff, scry.path]); T(stack, &[D(tas!(b"hunk")), scry.reff, scry.path]);
mean_push(stack, hunk); mean_push(stack, hunk);
assert_is_list(*(context.stack.local_noun_pointer(0)), "WORK 12 SCRY CRASH 2");
break Err(Error::ScryCrashed(D(0))); break Err(Error::ScryCrashed(D(0)));
} }
Right(cell) => { Right(cell) => {
@ -853,18 +871,22 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
}, },
Err(error) => match error { Err(error) => match error {
Error::Deterministic(trace) | Error::ScryCrashed(trace) => { Error::Deterministic(trace) | Error::ScryCrashed(trace) => {
assert_is_list(*(context.stack.local_noun_pointer(0)), "WORK 12.1");
break Err(Error::ScryCrashed(trace)); break Err(Error::ScryCrashed(trace));
} }
Error::NonDeterministic(_) => { Error::NonDeterministic(_) => {
assert_is_list(*(context.stack.local_noun_pointer(0)), "WORK 12.2");
break Err(error); break Err(error);
} }
Error::ScryBlocked(_) => { Error::ScryBlocked(_) => {
assert_is_list(*(context.stack.local_noun_pointer(0)), "WORK 12.3");
break Err(Error::NonDeterministic(D(0))); break Err(Error::NonDeterministic(D(0)));
} }
}, },
} }
} else { } else {
// No scry handler // No scry handler
assert_is_list(*(context.stack.local_noun_pointer(0)), "WORK 12 NO HANDLER");
break Err(Error::Deterministic(D(0))); break Err(Error::Deterministic(D(0)));
} }
} }
@ -875,7 +897,11 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
match nock { match nock {
Ok(res) => Ok(res), Ok(res) => Ok(res),
Err(err) => Err(exit(context, &snapshot, virtual_frame, err)), Err(err) => {
let h = unsafe { *(context.stack.local_noun_pointer(0)) };
assert_is_list(h, "FINAL MATCH");
return Err(exit(context, &snapshot, virtual_frame, err));
}
} }
} }
@ -1092,6 +1118,19 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> result::Res
Ok(()) Ok(())
} }
fn assert_is_list(mut noun: Noun, tag: &str) {
loop {
if let Ok(cell) = noun.as_cell() {
noun = cell.tail();
} else {
if ! unsafe { noun.raw_equals(D(0)) } {
panic!("assertion failed: {} is not a list", tag);
break;
}
}
}
}
fn exit( fn exit(
context: &mut Context, context: &mut Context,
snapshot: &ContextSnapshot, snapshot: &ContextSnapshot,
@ -1107,6 +1146,8 @@ fn exit(
Error::Deterministic(t) | Error::NonDeterministic(t) | Error::ScryCrashed(t) => { Error::Deterministic(t) | Error::NonDeterministic(t) | Error::ScryCrashed(t) => {
// Return $tang of traces // Return $tang of traces
let h = *(stack.local_noun_pointer(0)); let h = *(stack.local_noun_pointer(0));
assert_is_list(h, "EXIT");
// eprintln!("crashing with mean stack: {:?}", h);
T(stack, &[h, t]) T(stack, &[h, t])
} }
}; };

View File

@ -73,12 +73,15 @@ pub mod util {
let mut dest = &mut res as *mut Noun; let mut dest = &mut res as *mut Noun;
while !list.raw_equals(D(0)) { while !list.raw_equals(D(0)) {
let pair = list.as_cell()?; let pair = list.as_cell().expect("outer");
let mut sublist = pair.head(); let mut sublist = pair.head();
list = pair.tail(); list = pair.tail();
while !sublist.raw_equals(D(0)) { while !sublist.raw_equals(D(0)) {
let it = sublist.as_cell()?; if sublist.is_atom() {
panic!("zing: sublist is atom: {:?}", sublist);
};
let it = sublist.as_cell().expect("inner");
let i = it.head(); let i = it.head();
sublist = it.tail(); sublist = it.tail();

View File

@ -256,17 +256,23 @@ pub fn jet_stir(context: &mut Context, subject: Noun) -> Result {
while unsafe { !q_vex.raw_equals(D(0)) } { while unsafe { !q_vex.raw_equals(D(0)) } {
eprintln!("stir: starting vex loop {}\r", i); eprintln!("stir: starting vex loop {}\r", i);
let puq_vex = q_vex.as_cell()?.head(); let puq_vex = q_vex.as_cell()?.head();
let quq_vex = q_vex.as_cell()?.tail();
unsafe { unsafe {
*(context.stack.push::<StirPair>()) = StirPair{ *(context.stack.push::<StirPair>()) = StirPair {
har: p_vex, har: p_vex,
res: puq_vex, res: puq_vex,
}; };
}; };
tub = q_vex.as_cell()?.tail(); tub = quq_vex;
vex = slam(context, fel, tub)?.as_cell()?; let slam_vex = slam(context, fel, tub);
if slam_vex.is_err() {
eprintln!("stir: slam vex failed\r");
}
vex = slam_vex?.as_cell()?;
p_vex = vex.head(); p_vex = vex.head();
q_vex = vex.tail(); q_vex = vex.tail();
} }

View File

@ -5,10 +5,10 @@ use std::io;
fn main() -> io::Result<()> { fn main() -> io::Result<()> {
// debug // debug
// eprintln!("serf: pid {}", std::process::id()); eprintln!("serf: pid {}", std::process::id());
// if unsafe { libc::kill(std::process::id() as i32, libc::SIGSTOP) } != 0 { if unsafe { libc::kill(std::process::id() as i32, libc::SIGSTOP) } != 0 {
// panic!("Could not stop ourselves."); panic!("Could not stop ourselves.");
// }; };
let filename = env::args().nth(1).expect("Must provide input filename"); let filename = env::args().nth(1).expect("Must provide input filename");

View File

@ -1,5 +1,4 @@
use crate::hamt::Hamt; use crate::hamt::Hamt;
use crate::interpreter;
use crate::interpreter::{inc, interpret, Error}; use crate::interpreter::{inc, interpret, Error};
use crate::jets::cold::Cold; use crate::jets::cold::Cold;
use crate::jets::hot::{Hot, HotEntry}; use crate::jets::hot::{Hot, HotEntry};
@ -13,6 +12,7 @@ use crate::noun::{Atom, Cell, DirectAtom, Noun, Slots, D, T};
use crate::snapshot::double_jam::DoubleJam; use crate::snapshot::double_jam::DoubleJam;
use crate::snapshot::Snapshot; use crate::snapshot::Snapshot;
use crate::trace::*; use crate::trace::*;
use crate::{interpreter, trace};
use ares_macros::tas; use ares_macros::tas;
use signal_hook; use signal_hook;
use signal_hook::consts::SIGINT; use signal_hook::consts::SIGINT;
@ -307,7 +307,8 @@ fn peek(context: &mut Context, ovo: Noun) -> Noun {
} }
fn goof(context: &mut Context, traces: Noun) -> Noun { fn goof(context: &mut Context, traces: Noun) -> Noun {
let trace = zing(&mut context.nock_context.stack, traces).unwrap(); // eprintln!("serf: goof: traces: {}", traces);
let trace = zing(&mut context.nock_context.stack, traces).expect("serf: goof: zing failed");
let tone = Cell::new(&mut context.nock_context.stack, D(2), trace); let tone = Cell::new(&mut context.nock_context.stack, D(2), trace);
let tang = mook(&mut context.nock_context, tone, false) let tang = mook(&mut context.nock_context, tone, false)
.expect("serf: goof: +mook crashed on bail") .expect("serf: goof: +mook crashed on bail")