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 num_traits::cast::{FromPrimitive, ToPrimitive};
#[derive(Copy, Clone, FromPrimitive, ToPrimitive)]
#[derive(Copy, Clone, FromPrimitive, ToPrimitive, Debug)]
#[repr(u64)]
enum NockWork {
Done,
@ -99,7 +99,7 @@ pub fn interpret(stack: &mut NockStack, mut subject: Noun, formula: Noun) -> Nou
}
Nock0Axis => {
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);
} else {
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(2)) = subject;
subject = res;
push_formula(stack, axis(subject, formula_axis.as_bitslice()));
push_formula(stack, slot(subject, formula_axis.as_bitslice()));
} else {
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() {
x
} else {
@ -523,7 +528,7 @@ fn axis(mut noun: Noun, axis: &BitSlice<u64, Lsb0>) -> Noun {
noun = cell.head();
}
} else {
panic!("Axis tried to descend through atom.");
panic!("Axis tried to descend through atom: {:?}", noun);
};
}
noun

View File

@ -32,6 +32,9 @@ fn main() -> io::Result<()> {
.as_cell()
.expect("Input must be jam of subject/formula pair");
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 f_out = OpenOptions::new()
.read(true)

View File

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

View File

@ -1,7 +1,7 @@
use bitvec::prelude::{BitSlice, Lsb0};
use either::Either;
use intmap::IntMap;
use std::fmt::Debug;
use std::fmt;
use std::ptr;
use std::slice::{from_raw_parts, from_raw_parts_mut};
@ -131,6 +131,10 @@ impl DirectAtom {
Atom { direct: self }
}
pub fn as_noun(self) -> Noun {
Noun { direct: self }
}
pub fn data(self) -> u64 {
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.
*
* 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.
*
@ -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
* at a fixed offset.
*/
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone)]
#[repr(C)]
#[repr(packed(8))]
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
*/
@ -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)]
#[repr(C)]
#[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)]
#[repr(C)]
#[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
* a certain number of nouns