Getting Nounable off the ground

This commit is contained in:
Chris Allen 2024-10-11 14:10:21 -05:00 committed by Chris A.
parent 1d88382545
commit 8e898c9fdb
3 changed files with 119 additions and 6 deletions

21
Cargo.lock generated
View File

@ -1266,6 +1266,7 @@ dependencies = [
"sword_guard",
"sword_macros",
"sword_pma",
"thiserror",
]
[[package]]
@ -1350,6 +1351,26 @@ version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
[[package]]
name = "thiserror"
version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.75",
]
[[package]]
name = "tinytemplate"
version = "1.2.1"

View File

@ -29,6 +29,7 @@ num-traits = "0.2"
rand = "0.8.5"
signal-hook = "0.3"
static_assertions = "1.1.0"
thiserror = "1.0.64"
[build-dependencies]
autotools = "0.2"

View File

@ -1,9 +1,10 @@
use crate::hamt::Hamt;
use crate::mem::{NockStack, Preserve};
use crate::noun;
use crate::noun::{self, IndirectAtom, NounAllocator};
use crate::noun::{Atom, DirectAtom, Noun, Slots, D, T};
use crate::persist::{pma_contains, Persist};
use crate::unifying_equality::unifying_equality;
use core::error;
use std::mem::size_of;
use std::ptr::copy_nonoverlapping;
use std::ptr::null_mut;
@ -768,12 +769,102 @@ impl Cold {
}
}
// pub trait Nominalizer9000 {
// fn nom_nom(&self, stack: &mut NockStack) -> Noun;
// }
pub struct NounListIterator(Noun);
// impl Nominalizer9000 for Cold {
// fn nom_nom(&self, stack: &mut NockStack) -> Noun {
impl Iterator for NounListIterator {
type Item = Noun;
fn next(&mut self) -> Option<Self::Item> {
if let Ok(it) = self.0.as_cell() {
self.0 = it.tail();
Some(it.head())
} else if unsafe { self.0.raw_equals(D(0)) } {
None
} else {
panic!("Improper list terminator: {:?}", self.0)
}
}
}
#[derive(thiserror::Error, Debug)]
pub enum FromNounError {
#[error("Not an atom")]
NotAtom,
#[error("Not a u64")]
NotU64,
#[error("Not a cell")]
NotCell,
#[error("Noun error: {0}")]
NounError(#[from] noun::Error),
#[error("UTF-8 error: {0}")]
Utf8Error(#[from] std::str::Utf8Error),
}
pub type NounableResult<T> = std::result::Result<T, FromNounError>;
pub trait Nounable {
type Target;
fn into_noun<A: NounAllocator>(self, stack: &mut A) -> Noun;
fn from_noun(noun: &Noun) -> NounableResult<Self::Target>
where
Self: Sized;
}
impl Nounable for Atom {
type Target = Self;
fn into_noun<A: NounAllocator>(self, _stack: &mut A) -> Noun {
self.as_noun()
}
fn from_noun(noun: &Noun) -> NounableResult<Self::Target> {
noun.atom().ok_or(FromNounError::NotAtom)
}
}
impl Nounable for u64 {
type Target = Self;
fn into_noun<A: NounAllocator>(self, _stack: &mut A) -> Noun {
// Copied from Crown's IntoNoun, not sure why this isn't D(*self)
unsafe { Atom::from_raw(self).into_noun(_stack) }
}
fn from_noun(noun: &Noun) -> NounableResult<Self::Target> {
let atom = noun.atom().ok_or(FromNounError::NotAtom)?;
let as_u64 = atom.as_u64()?;
Ok(as_u64)
}
}
impl Nounable for Noun {
type Target = Self;
fn into_noun<A: NounAllocator>(self, _stack: &mut A) -> Noun {
self
}
fn from_noun(noun: &Self) -> NounableResult<Self::Target> {
Ok(noun.clone())
}
}
impl Nounable for &str {
type Target = String;
fn into_noun<A: NounAllocator>(self, stack: &mut A) -> Noun {
let contents_atom = unsafe {
let bytes = self.bytes().collect::<Vec<u8>>();
IndirectAtom::new_raw_bytes_ref(stack, bytes.as_slice())
.normalize_as_atom()
};
contents_atom.into_noun(stack)
}
fn from_noun(noun: &Noun) -> NounableResult<Self::Target> {
let atom = noun.as_atom()?;
let bytes = atom.as_bytes();
let utf8 = std::str::from_utf8(bytes)?;
let allocated = utf8.to_string();
Ok(allocated)
}
}
// impl Nounable for Cold {
// fn into_noun<A: NounAllocator>(&self, stack: &mut A) -> Noun {
// unsafe {
// let mut cold = *self;
// let mut nom = T(stack, &[]);