@@ -1,29 +1,32 @@
2− borrow::{Borrow, BorrowMut},
4− cmp::{self, Ordering},
1+use std::{cell::Cell, cmp::Ordering, rc::Rc, str::FromStr};
9use num_bigint::BigUint;
3use num_bigint::BigUint;
4+use num_traits::ToBytes;
10use std::fmt;
5use std::fmt;
11use xxhash_rust::xxh3::xxh3_128;
6use xxhash_rust::xxh3::xxh3_128;
8+use crate::interpreter::InterpreterContext;
13pub type Atom = BigUint;
10pub type Atom = BigUint;
15pub type Hash = u128;
12pub type Hash = u128;
17−#[derive(Clone, Debug, Eq)]
14+#[derive(Clone, Debug)]
18pub enum Noun {
15pub enum Noun {
19 Atom(Atom),
16 Atom(Atom),
21 p: Rc<Noun>,
18 p: Rc<Noun>,
22 q: Rc<Noun>,
19 q: Rc<Noun>,
23 hash: Cell<Option<Hash>>,
20 hash: Cell<Option<Hash>>,
21+ compiled_gate: Option<(
23+ Rc<fn(&InterpreterContext, Rc<Noun>, Rc<Noun>) -> Option<Rc<Noun>>>,
27impl Ord for Noun {
30impl Ord for Noun {
28 fn cmp(&self, other: &Self) -> Ordering {
31 fn cmp(&self, other: &Self) -> Ordering {
29 compare_nouns(self, other)
32 compare_nouns(self, other)
@@ -55,11 +58,13 @@ impl PartialEq for Noun {
57 hash: lhs_hash,
60 hash: lhs_hash,
59 Noun::Cell {
63 Noun::Cell {
62 hash: rhs_hash,
66 hash: rhs_hash,
64 ) => lhs_hash == rhs_hash && lhs_p == rhs_p && lhs_q == rhs_q,
69 ) => lhs_hash == rhs_hash && lhs_p == rhs_p && lhs_q == rhs_q,
65 _ => false,
70 _ => false,
@@ -153,7 +158,12 @@ impl Noun {
154 pub fn hash(self: &Self) -> Hash {
159 pub fn hash(self: &Self) -> Hash {
155 match self {
160 match self {
156− Noun::Cell { hash, p, q } => match hash.get() {
166+ } => match hash.get() {
157 Some(x) => x.clone(),
167 Some(x) => x.clone(),
158 None => {
168 None => {
159 let hash_value = stacker::maybe_grow(32 * 1024, 1024 * 1024, || {
169 let hash_value = stacker::maybe_grow(32 * 1024, 1024 * 1024, || {
@@ -169,24 +179,23 @@ impl Noun {
170 /// returns the hash and the current sample
180 /// returns the hash and the current sample
171 pub fn hash_gate(self: &Self) -> (Hash, Rc<Noun>) {
181 pub fn hash_gate(self: &Self) -> (Hash, Rc<Noun>) {
172− let Noun::Cell {
182+ let (battery, payload) = self.as_cell().unwrap();
173− p: battery,
183+ let (sample, context) = payload.as_cell().unwrap();
175− ..
185+ (hash_pair(battery.clone(), context), sample)
184− } = (**payload).clone()
189− (hash_pair((*battery).clone(), context), sample)
188+ /// returns the hash and the current sample
189+ pub fn hash_double_gate(self: &Self) -> (Hash, Rc<Noun>, Rc<Noun>) {
190+ let (battery, payload) = self.as_cell().unwrap();
191+ let (sample_2, context) = payload.as_cell().unwrap();
192+ let (inner_hash, sample_1) = context.hash_gate();
195+ hash_tripple(battery.clone(), inner_hash),
192 pub fn as_bite(self: &Self) -> Bite {
201 pub fn as_bite(self: &Self) -> Bite {
@@ -233,7 +242,7 @@ impl Noun {
233 let (hair, tape) = self.as_cell()?;
242 let (hair, tape) = self.as_cell()?;
234 Some(Nail {
243 Some(Nail {
235 hair: hair.as_hair()?,
244 hair: hair.as_hair()?,
236− rest: tape.as_atom()?.clone(),
245+ rest: tape.clone(),
@@ -251,6 +260,29 @@ impl Noun {
252 Some(Edge { hair, result })
261 Some(Edge { hair, result })
268+ Rc<fn(&InterpreterContext, Rc<Noun>, Rc<Noun>) -> Option<Rc<Noun>>>,
272+ Noun::Atom(_) => self.clone(),
282+ compiled_gate: Some(jet),
256#[derive(Clone)]
288#[derive(Clone)]
@@ -259,6 +291,18 @@ pub struct Edge {
259 pub result: Option<(Rc<Noun>, Nail)>,
291 pub result: Option<(Rc<Noun>, Nail)>,
295+ pub fn as_noun(self: &Self) -> Rc<Noun> {
297+ self.hair.as_noun(),
298+ match self.result.clone() {
299+ None => Rc::new(Noun::SIG),
300+ Some((result, nail)) => cell(Rc::new(Noun::SIG), cell(result, nail.as_noun())),
262#[derive(Clone)]
306#[derive(Clone)]
263pub struct Hair {
307pub struct Hair {
264 pub line: u32,
308 pub line: u32,
@@ -277,12 +321,12 @@ impl Hair {
277#[derive(Clone)]
321#[derive(Clone)]
278pub struct Nail {
322pub struct Nail {
279 pub hair: Hair,
323 pub hair: Hair,
280− pub rest: Atom,
324+ pub rest: Rc<Noun>,
283impl Nail {
327impl Nail {
284 pub fn as_noun(self: &Self) -> Rc<Noun> {
328 pub fn as_noun(self: &Self) -> Rc<Noun> {
285− cell(self.hair.as_noun(), Rc::new(Noun::Atom(self.rest.clone())))
329+ cell(self.hair.as_noun(), self.rest.clone())
@@ -360,9 +404,14 @@ pub fn cell(p: Rc<Noun>, q: Rc<Noun>) -> Rc<Noun> {
360 p: p.clone(),
404 p: p.clone(),
361 q: q.clone(),
405 q: q.clone(),
362 hash: Cell::new(None),
406 hash: Cell::new(None),
407+ compiled_gate: None,
366fn hash_pair(p: Rc<Noun>, q: Rc<Noun>) -> Hash {
411fn hash_pair(p: Rc<Noun>, q: Rc<Noun>) -> Hash {
367 xxh3_128(&[p.hash().to_le_bytes(), q.hash().to_le_bytes()].as_flattened())
412 xxh3_128(&[p.hash().to_le_bytes(), q.hash().to_le_bytes()].as_flattened())
415+fn hash_tripple(p: Rc<Noun>, q: Hash) -> Hash {
416+ xxh3_128(&[p.hash().to_le_bytes(), q.to_le_bytes()].as_flattened())