Merge pull request #13 from urbit/philip/prints

Fixes and printing functions
This commit is contained in:
Edward Amsden 2023-02-02 12:04:58 -06:00 committed by GitHub
commit 9c09e81779
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 97 additions and 9 deletions

View File

@ -6,7 +6,7 @@ use bitvec::prelude::{BitSlice, Lsb0};
use either::Either::*; use either::Either::*;
use num_traits::cast::{FromPrimitive, ToPrimitive}; use num_traits::cast::{FromPrimitive, ToPrimitive};
#[derive(Copy, Clone, FromPrimitive, ToPrimitive)] #[derive(Copy, Clone, FromPrimitive, ToPrimitive, Debug)]
#[repr(u64)] #[repr(u64)]
enum NockWork { enum NockWork {
Done, Done,
@ -99,7 +99,7 @@ pub fn interpret(stack: &mut NockStack, mut subject: Noun, formula: Noun) -> Nou
} }
Nock0Axis => { Nock0Axis => {
if let Ok(atom) = unsafe { (*(stack.local_noun_pointer(1))).as_atom() } { if let Ok(atom) = unsafe { (*(stack.local_noun_pointer(1))).as_atom() } {
res = axis(subject, atom.as_bitslice()); res = slot(subject, atom.as_bitslice());
stack.pop(&mut res); stack.pop(&mut res);
} else { } else {
panic!("Axis must be atom"); panic!("Axis must be atom");
@ -279,7 +279,7 @@ pub fn interpret(stack: &mut NockStack, mut subject: Noun, formula: Noun) -> Nou
*(stack.local_noun_pointer(0)) = work_to_noun(Nock9RestoreSubject); *(stack.local_noun_pointer(0)) = work_to_noun(Nock9RestoreSubject);
*(stack.local_noun_pointer(2)) = subject; *(stack.local_noun_pointer(2)) = subject;
subject = res; subject = res;
push_formula(stack, axis(subject, formula_axis.as_bitslice())); push_formula(stack, slot(subject, formula_axis.as_bitslice()));
} else { } else {
panic!("Axis into core must be atom"); panic!("Axis into core must be atom");
} }
@ -505,7 +505,12 @@ fn push_formula(stack: &mut NockStack, formula: Noun) {
} }
} }
fn axis(mut noun: Noun, axis: &BitSlice<u64, Lsb0>) -> Noun { /** Note: axis must fit in a direct atom */
pub fn raw_slot(noun: Noun, axis: u64) -> Noun {
slot(noun, DirectAtom::new(axis).unwrap().as_bitslice())
}
pub fn slot(mut noun: Noun, axis: &BitSlice<u64, Lsb0>) -> Noun {
let mut cursor = if let Some(x) = axis.last_one() { let mut cursor = if let Some(x) = axis.last_one() {
x x
} else { } else {
@ -523,7 +528,7 @@ fn axis(mut noun: Noun, axis: &BitSlice<u64, Lsb0>) -> Noun {
noun = cell.head(); noun = cell.head();
} }
} else { } else {
panic!("Axis tried to descend through atom."); panic!("Axis tried to descend through atom: {:?}", noun);
}; };
} }
noun noun

View File

@ -32,6 +32,9 @@ fn main() -> io::Result<()> {
.as_cell() .as_cell()
.expect("Input must be jam of subject/formula pair"); .expect("Input must be jam of subject/formula pair");
let result = interpret(&mut stack, input_cell.head(), input_cell.tail()); let result = interpret(&mut stack, input_cell.head(), input_cell.tail());
if let Ok(atom) = result.as_atom() {
println!("Result: {:?}", atom);
}
let jammed_result = jam(&mut stack, result); let jammed_result = jam(&mut stack, result);
let f_out = OpenOptions::new() let f_out = OpenOptions::new()
.read(true) .read(true)

View File

@ -157,8 +157,8 @@ impl NockStack {
} }
unsafe fn restore_prev_stack_pointer_from_local_west(&mut self, local: usize) { unsafe fn restore_prev_stack_pointer_from_local_west(&mut self, local: usize) {
*(self.previous_stack_pointer_pointer_east()) = *(self.previous_stack_pointer_pointer_west()) =
*(self.slot_pointer_east(local + 2) as *mut *mut u64); *(self.slot_pointer_west(local + 2) as *mut *mut u64);
} }
unsafe fn restore_prev_stack_pointer_from_local(&mut self, local: usize) { unsafe fn restore_prev_stack_pointer_from_local(&mut self, local: usize) {

View File

@ -1,7 +1,7 @@
use bitvec::prelude::{BitSlice, Lsb0}; use bitvec::prelude::{BitSlice, Lsb0};
use either::Either; use either::Either;
use intmap::IntMap; use intmap::IntMap;
use std::fmt::Debug; use std::fmt;
use std::ptr; use std::ptr;
use std::slice::{from_raw_parts, from_raw_parts_mut}; use std::slice::{from_raw_parts, from_raw_parts_mut};
@ -131,6 +131,10 @@ impl DirectAtom {
Atom { direct: self } Atom { direct: self }
} }
pub fn as_noun(self) -> Noun {
Noun { direct: self }
}
pub fn data(self) -> u64 { pub fn data(self) -> u64 {
self.0 self.0
} }
@ -140,6 +144,12 @@ impl DirectAtom {
} }
} }
impl fmt::Debug for DirectAtom {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
/** An indirect atom. /** An indirect atom.
* *
* Indirect atoms represent atoms above DIRECT_MAX as a tagged pointer to a memory buffer * Indirect atoms represent atoms above DIRECT_MAX as a tagged pointer to a memory buffer
@ -303,6 +313,21 @@ impl IndirectAtom {
} }
} }
impl fmt::Debug for IndirectAtom {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "0x")?;
let mut i = self.size() - 1;
loop {
write!(f, "_{:016x}", unsafe { *(self.data_pointer().add(i)) })?;
if i == 0 {
break;
}
i -= 1;
}
Ok(())
}
}
/** /**
* A cell. * A cell.
* *
@ -310,7 +335,7 @@ impl IndirectAtom {
* the noun which is the cell's head, and a word describing a noun which is the cell's tail, each * the noun which is the cell's head, and a word describing a noun which is the cell's tail, each
* at a fixed offset. * at a fixed offset.
*/ */
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
#[repr(packed(8))] #[repr(packed(8))]
pub struct Cell(u64); pub struct Cell(u64);
@ -385,6 +410,27 @@ impl Cell {
} }
} }
impl fmt::Debug for Cell {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[")?;
let mut cell = *self;
loop {
write!(f, "{:?}", cell.head())?;
match cell.tail().as_cell() {
Ok(next_cell) => {
write!(f, " ")?;
cell = next_cell;
}
Err(_) => {
write!(f, " {:?}]", cell.tail())?;
break;
}
}
}
Ok(())
}
}
/** /**
* Memory representation of the contents of a cell * Memory representation of the contents of a cell
*/ */
@ -481,6 +527,12 @@ impl Atom {
} }
} }
impl fmt::Debug for Atom {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_noun().fmt(f)
}
}
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
#[repr(packed(8))] #[repr(packed(8))]
@ -550,6 +602,12 @@ impl Allocated {
} }
} }
impl fmt::Debug for Allocated {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_noun().fmt(f)
}
}
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
#[repr(packed(8))] #[repr(packed(8))]
@ -645,6 +703,28 @@ impl Noun {
} }
} }
impl fmt::Debug for Noun {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
unsafe {
if self.is_direct() {
write!(f, "{:?}", self.direct)
} else if self.is_indirect() {
write!(f, "{:?}", self.indirect)
} else if self.is_cell() {
write!(f, "{:?}", self.cell)
} else if self.allocated.forwarding_pointer().is_some() {
write!(
f,
"Noun::Forwarding({:?})",
self.allocated.forwarding_pointer().unwrap()
)
} else {
write!(f, "Noun::Unknown({:x})", self.raw)
}
}
}
}
/** /**
* An allocation object (probably a mem::NockStack) which can allocate a memory buffer sized to * An allocation object (probably a mem::NockStack) which can allocate a memory buffer sized to
* a certain number of nouns * a certain number of nouns