mirror of
https://github.com/urbit/ares.git
synced 2024-12-23 21:31:57 +03:00
Merge remote-tracking branch 'origin/peter/lint' into philip/pma
This commit is contained in:
commit
b4d007174e
34
.github/scripts/hoon/boot-ship.sh
vendored
Executable file
34
.github/scripts/hoon/boot-ship.sh
vendored
Executable file
@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -xeuo pipefail
|
||||
|
||||
PILL_NAME='solid.pill'
|
||||
|
||||
curl -L $URBIT_URL | tar xzk --transform='s/.*/urbit/g'
|
||||
curl -L $PILL_URL -o $PILL_NAME
|
||||
|
||||
./urbit \
|
||||
--bootstrap $PILL_NAME \
|
||||
--local \
|
||||
--lite-boot \
|
||||
--daemon \
|
||||
--fake bus \
|
||||
-c $URBIT_PIER
|
||||
|
||||
LENS_PORT=$(grep 'loopback' $URBIT_PIER/.http.ports | awk -F ' ' '{print $1}')
|
||||
lensecho() {
|
||||
curl -s \
|
||||
--data '{"source":{"data":"'"$1"'"},"sink":{"stdout":null}}' \
|
||||
"http://localhost:$LENS_PORT" | xargs printf %s | sed 's/\\n//g'
|
||||
}
|
||||
|
||||
check() {
|
||||
[ "'3'" == "$(lensecho 3)" ]
|
||||
}
|
||||
|
||||
if check; then
|
||||
echo "boot success"
|
||||
else
|
||||
echo "boot failure"
|
||||
exit 1
|
||||
fi
|
66
.github/scripts/hoon/setup-ship.sh
vendored
Executable file
66
.github/scripts/hoon/setup-ship.sh
vendored
Executable file
@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -xeuo pipefail
|
||||
|
||||
DESK_DIR="$URBIT_PIER/$DESK"
|
||||
DESK_LIB_DIR="$DESK_DIR/lib"
|
||||
DESK_TST_DIR="$DESK_DIR/tests"
|
||||
|
||||
LENS_PORT=$(grep 'loopback' $URBIT_PIER/.http.ports | awk -F ' ' '{print $1}')
|
||||
lensapp() {
|
||||
curl -s --max-time 10 \
|
||||
--data '{"source":{"dojo":"'"$2"'"},"sink":{"app":"'"$1"'"}}' \
|
||||
"http://localhost:$LENS_PORT"
|
||||
}
|
||||
|
||||
lensdojo() {
|
||||
curl -s --max-time 10 \
|
||||
--data '{"source":{"dojo":"'"$1"'"},"sink":{"stdout":null}}' \
|
||||
"http://localhost:$LENS_PORT"
|
||||
}
|
||||
|
||||
# XX: temporary; eventually should actually load files as pills
|
||||
lensapp 'hood' "+hood/merge %$DESK our %base"
|
||||
|
||||
lensapp 'hood' "+hood/rm /=$DESK=/desk/bill"
|
||||
lensapp 'hood' "+hood/rm /=$DESK=/sys/hoon/hoon"
|
||||
lensapp 'hood' "+hood/rm /=$DESK=/sys/arvo/hoon"
|
||||
lensapp 'hood' "+hood/rm /=$DESK=/sys/lull/hoon"
|
||||
lensapp 'hood' "+hood/rm /=$DESK=/sys/zuse/hoon"
|
||||
lensapp 'hood' "+hood/rm /=$DESK=/sys/vane/ames/hoon"
|
||||
lensapp 'hood' "+hood/rm /=$DESK=/sys/vane/behn/hoon"
|
||||
lensapp 'hood' "+hood/rm /=$DESK=/sys/vane/clay/hoon"
|
||||
lensapp 'hood' "+hood/rm /=$DESK=/sys/vane/dill/hoon"
|
||||
lensapp 'hood' "+hood/rm /=$DESK=/sys/vane/eyre/hoon"
|
||||
lensapp 'hood' "+hood/rm /=$DESK=/sys/vane/gall/hoon"
|
||||
lensapp 'hood' "+hood/rm /=$DESK=/sys/vane/iris/hoon"
|
||||
lensapp 'hood' "+hood/rm /=$DESK=/sys/vane/jael/hoon"
|
||||
lensapp 'hood' "+hood/rm /=$DESK=/sys/vane/khan/hoon"
|
||||
|
||||
lensapp 'hood' "+hood/mount %$DESK"
|
||||
|
||||
cp -rfL ./hoon/scaffolding/azimuth-pill.hoon $DESK_DIR
|
||||
cp -rfL ./hoon/scaffolding/baby.hoon $DESK_DIR
|
||||
|
||||
cp -rfL ./hoon/scaffolding/cradle.hoon $DESK_LIB_DIR
|
||||
cp -rfL ./hoon/scaffolding/naive-cradle.hoon $DESK_LIB_DIR
|
||||
cp -rfL ./hoon/scaffolding/logs.jam $DESK_LIB_DIR
|
||||
cp -rfL ./hoon/scaffolding/mainnet.azimuth-snapshot $DESK_LIB_DIR
|
||||
|
||||
lensapp 'hood' "+hood/commit %$DESK"
|
||||
|
||||
# XX: No tests yet
|
||||
#mkdir $DESK_TST_DIR
|
||||
# cp -rfL ./hoon/scaffolding/tests/* $DESK_TST_DIR
|
||||
|
||||
# XX: redo when conn.c cli available
|
||||
check() {
|
||||
[ -z "$(lensdojo "-build-file /=$DESK=/$1/hoon" | grep 'thread failed')" ]
|
||||
}
|
||||
|
||||
if check 'baby' && check 'azimuth-pill'; then
|
||||
echo "boot success"
|
||||
else
|
||||
echo "boot failure"
|
||||
exit 1
|
||||
fi
|
13
.github/scripts/hoon/test-ship.sh
vendored
Executable file
13
.github/scripts/hoon/test-ship.sh
vendored
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -xeuo pipefail
|
||||
|
||||
LENS_PORT=$(grep 'loopback' $URBIT_PIER/.http.ports | awk -F ' ' '{print $1}')
|
||||
lensdojo() {
|
||||
curl -s \
|
||||
--data '{"source":{"dojo":"'"$1"'"},"sink":{"stdout":null}}' \
|
||||
"http://localhost:$LENS_PORT"
|
||||
}
|
||||
|
||||
# XX: redo when conn.c cli available; just runs tests whether they pass or fail
|
||||
lensdojo "-test /=$DESK=/tests ~"
|
14
.github/workflows/ares-feature.yml
vendored
Normal file
14
.github/workflows/ares-feature.yml
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
name: 'Ares: Pull request'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/ares-feature.yml'
|
||||
- '.github/workflows/ares-shared.yml'
|
||||
- 'rust/ares/**'
|
||||
- 'rust/ares_macros/**'
|
||||
- 'rust/ibig-rs/**'
|
||||
|
||||
jobs:
|
||||
urbit:
|
||||
uses: ./.github/workflows/ares-shared.yml
|
30
.github/workflows/ares-shared.yml
vendored
Normal file
30
.github/workflows/ares-shared.yml
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: rust/ares
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ 'ubuntu-latest', 'macos-latest' ]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Format
|
||||
run: cargo fmt --check
|
||||
|
||||
- name: Lint
|
||||
run: cargo clippy -- --deny warnings --allow clippy::missing_safety_doc
|
||||
|
||||
- name: Build
|
||||
run: cargo build --verbose
|
||||
|
||||
- name: Run tests
|
||||
run: cargo test --verbose
|
16
.github/workflows/ares-status.yml
vendored
Normal file
16
.github/workflows/ares-status.yml
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
name: 'Ares: Push to status'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- status
|
||||
paths:
|
||||
- '.github/workflows/ares-shared.yml'
|
||||
- '.github/workflows/ares-status.yml'
|
||||
- 'rust/ares/**'
|
||||
- 'rust/ares_macros/**'
|
||||
- 'rust/ibig-rs/**'
|
||||
|
||||
jobs:
|
||||
urbit:
|
||||
uses: ./.github/workflows/ares-shared.yml
|
28
.github/workflows/ares.yml
vendored
28
.github/workflows/ares.yml
vendored
@ -1,28 +0,0 @@
|
||||
name: Ares
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "status" ]
|
||||
pull_request:
|
||||
branches: [ "status" ]
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: rust/ares
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Format
|
||||
run: cargo fmt --check
|
||||
- name: Build
|
||||
run: cargo build --verbose
|
||||
- name: Run tests
|
||||
run: cargo test --verbose
|
13
.github/workflows/hoon-feature.yml
vendored
Normal file
13
.github/workflows/hoon-feature.yml
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
name: 'Hoon: Pull request'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/scripts/hoon/**.yml'
|
||||
- '.github/workflows/hoon-feature.yml'
|
||||
- '.github/workflows/hoon-shared.yml'
|
||||
- 'hoon/scaffolding/**'
|
||||
|
||||
jobs:
|
||||
urbit:
|
||||
uses: ./.github/workflows/hoon-shared.yml
|
23
.github/workflows/hoon-shared.yml
vendored
Normal file
23
.github/workflows/hoon-shared.yml
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
env:
|
||||
URBIT_URL: 'https://urbit.org/install/linux-x86_64/latest'
|
||||
PILL_URL: 'https://github.com/urbit/urbit/raw/master/bin/solid.pill'
|
||||
URBIT_PIER: './pier'
|
||||
DESK: 'sandbox'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: 'ubuntu-latest'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: 'Boot fake ship'
|
||||
run: ./.github/scripts/hoon/boot-ship.sh
|
||||
|
||||
- name: 'Setup fake ship'
|
||||
run: ./.github/scripts/hoon/setup-ship.sh
|
||||
|
||||
- name: 'Test fake ship'
|
||||
run: ./.github/scripts/hoon/test-ship.sh
|
15
.github/workflows/hoon-status.yml
vendored
Normal file
15
.github/workflows/hoon-status.yml
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
name: 'Hoon: Push to status'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- status
|
||||
paths:
|
||||
- '.github/scripts/hoon/**.yml'
|
||||
- '.github/workflows/hoon-shared.yml'
|
||||
- '.github/workflows/hoon-status.yml'
|
||||
- 'hoon/scaffolding/**'
|
||||
|
||||
jobs:
|
||||
urbit:
|
||||
uses: ./.github/workflows/hoon-shared.yml
|
@ -1,7 +1,6 @@
|
||||
use ares::mem::NockStack;
|
||||
use ares::noun::{DirectAtom, IndirectAtom};
|
||||
use ares::serialization::{cue, jam};
|
||||
use memmap;
|
||||
use std::env;
|
||||
use std::fs::{File, OpenOptions};
|
||||
use std::io;
|
||||
@ -11,7 +10,7 @@ use std::time::SystemTime;
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let filename = env::args().nth(1).expect("Must provide input filename");
|
||||
let output_filename = format!("{}.out", filename.clone());
|
||||
let output_filename = format!("{}.out", filename);
|
||||
let f = File::open(filename)?;
|
||||
let in_len = f.metadata()?.len();
|
||||
let mut stack = NockStack::new(1 << 10 << 10 << 10, 0);
|
||||
|
@ -5,6 +5,10 @@ use either::Either::{self, *};
|
||||
use std::ptr::{copy_nonoverlapping, null};
|
||||
use std::slice;
|
||||
|
||||
type MutStemEntry<T> = Either<*mut MutStem<T>, Leaf<T>>;
|
||||
|
||||
type StemEntry<T> = Either<Stem<T>, Leaf<T>>;
|
||||
|
||||
#[inline]
|
||||
fn chunk_to_bit(chunk: u32) -> u32 {
|
||||
1u32 << chunk
|
||||
@ -37,7 +41,7 @@ impl<T: Copy> MutStem<T> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn entry(&self, chunk: u32) -> Option<Either<*mut MutStem<T>, Leaf<T>>> {
|
||||
fn entry(&self, chunk: u32) -> Option<MutStemEntry<T>> {
|
||||
if self.has_index(chunk) {
|
||||
if self.typemap & chunk_to_bit(chunk) != 0 {
|
||||
unsafe { Some(Left(self.buffer[chunk as usize].stem)) }
|
||||
@ -69,7 +73,7 @@ impl<T: Copy> MutHamt<T> {
|
||||
unsafe {
|
||||
'lookup: loop {
|
||||
let chunk = mug & 0x1f;
|
||||
mug = mug >> 5;
|
||||
mug >>= 5;
|
||||
match (*stem).entry(chunk) {
|
||||
None => {
|
||||
break None;
|
||||
@ -79,8 +83,8 @@ impl<T: Copy> MutHamt<T> {
|
||||
}
|
||||
Some(Right(leaf)) => {
|
||||
for pair in leaf.to_mut_slice().iter_mut() {
|
||||
if unifying_equality(stack, n, &mut (*pair).0) {
|
||||
break 'lookup Some((*pair).1);
|
||||
if unifying_equality(stack, n, &mut pair.0) {
|
||||
break 'lookup Some(pair.1);
|
||||
}
|
||||
}
|
||||
break None;
|
||||
@ -97,13 +101,13 @@ impl<T: Copy> MutHamt<T> {
|
||||
unsafe {
|
||||
'insert: loop {
|
||||
let chunk = mug & 0x1f;
|
||||
mug = mug >> 5;
|
||||
mug >>= 5;
|
||||
match (*stem).entry(chunk) {
|
||||
None => {
|
||||
let new_leaf_buffer = stack.struct_alloc(1);
|
||||
*new_leaf_buffer = (*n, t);
|
||||
(*stem).bitmap = (*stem).bitmap | chunk_to_bit(chunk);
|
||||
(*stem).typemap = (*stem).typemap & !chunk_to_bit(chunk);
|
||||
(*stem).bitmap |= chunk_to_bit(chunk);
|
||||
(*stem).typemap &= !chunk_to_bit(chunk);
|
||||
(*stem).buffer[chunk as usize] = MutEntry {
|
||||
leaf: Leaf {
|
||||
len: 1,
|
||||
@ -119,8 +123,8 @@ impl<T: Copy> MutHamt<T> {
|
||||
}
|
||||
Some(Right(leaf)) => {
|
||||
for pair in leaf.to_mut_slice().iter_mut() {
|
||||
if unifying_equality(stack, n, &mut (*pair).0) {
|
||||
(*pair).1 = t;
|
||||
if unifying_equality(stack, n, &mut pair.0) {
|
||||
pair.1 = t;
|
||||
break 'insert;
|
||||
}
|
||||
}
|
||||
@ -142,9 +146,9 @@ impl<T: Copy> MutHamt<T> {
|
||||
let leaf_chunk = (leaf_mug >> ((depth + 1) * 5)) & 0x1f;
|
||||
(*new_stem).bitmap = chunk_to_bit(leaf_chunk);
|
||||
(*new_stem).typemap = 0;
|
||||
(*new_stem).buffer[leaf_chunk as usize] = MutEntry { leaf: leaf };
|
||||
(*new_stem).buffer[leaf_chunk as usize] = MutEntry { leaf };
|
||||
(*stem).buffer[chunk as usize] = MutEntry { stem: new_stem };
|
||||
(*stem).typemap = (*stem).typemap | chunk_to_bit(chunk);
|
||||
(*stem).typemap |= chunk_to_bit(chunk);
|
||||
stem = new_stem;
|
||||
depth += 1;
|
||||
continue;
|
||||
@ -201,7 +205,7 @@ impl<T: Copy> Stem<T> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn entry(self, chunk: u32) -> Option<(Either<Stem<T>, Leaf<T>>, usize)> {
|
||||
fn entry(self, chunk: u32) -> Option<(StemEntry<T>, usize)> {
|
||||
self.index(chunk).map(|idx| {
|
||||
(
|
||||
unsafe {
|
||||
@ -281,7 +285,7 @@ impl<T: Copy> Hamt<T> {
|
||||
let mut mug = mug_u32(stack, *n);
|
||||
'lookup: loop {
|
||||
let chunk = mug & 0x1F; // 5 bits
|
||||
mug = mug >> 5;
|
||||
mug >>= 5;
|
||||
match stem.entry(chunk) {
|
||||
None => {
|
||||
break None;
|
||||
@ -314,7 +318,7 @@ impl<T: Copy> Hamt<T> {
|
||||
unsafe {
|
||||
'insert: loop {
|
||||
let chunk = mug & 0x1F; // 5 bits
|
||||
mug = mug >> 5;
|
||||
mug >>= 5;
|
||||
match stem.entry(chunk) {
|
||||
None => {
|
||||
let new_leaf_buffer = stack.struct_alloc(1);
|
||||
@ -399,7 +403,7 @@ impl<T: Copy> Hamt<T> {
|
||||
// next time around
|
||||
assert!(leaf.len == 1);
|
||||
let fake_buffer = stack.struct_alloc(1);
|
||||
*fake_buffer = Entry { leaf: leaf };
|
||||
*fake_buffer = Entry { leaf };
|
||||
// get the mug chunk for the noun at *the next level* so
|
||||
// we can build a fake stem for it
|
||||
let fake_mug = mug_u32(stack, (*leaf.buffer).0);
|
||||
@ -428,15 +432,21 @@ impl<T: Copy> Hamt<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy> Default for Hamt<T> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Preserve> Preserve for Hamt<T> {
|
||||
unsafe fn preserve(&mut self, stack: &mut NockStack) {
|
||||
if stack.in_frame((*self).0.buffer) {
|
||||
let dest_buffer = stack.struct_alloc_in_previous_frame((*self).0.size());
|
||||
copy_nonoverlapping((*self).0.buffer, dest_buffer, (*self).0.size());
|
||||
(*self).0.buffer = dest_buffer;
|
||||
if stack.in_frame(self.0.buffer) {
|
||||
let dest_buffer = stack.struct_alloc_in_previous_frame(self.0.size());
|
||||
copy_nonoverlapping(self.0.buffer, dest_buffer, self.0.size());
|
||||
self.0.buffer = dest_buffer;
|
||||
let traversal_stack = stack.struct_alloc::<(Stem<T>, u32)>(6);
|
||||
let mut traversal_depth = 1;
|
||||
*traversal_stack = ((*self).0, 0);
|
||||
*traversal_stack = (self.0, 0);
|
||||
'preserve: loop {
|
||||
if traversal_depth == 0 {
|
||||
break;
|
||||
@ -487,8 +497,8 @@ impl<T: Copy + Preserve> Preserve for Hamt<T> {
|
||||
buffer: dest_buffer,
|
||||
};
|
||||
for pair in new_leaf.to_mut_slice().iter_mut() {
|
||||
(*pair).0.preserve(stack);
|
||||
(*pair).1.preserve(stack);
|
||||
pair.0.preserve(stack);
|
||||
pair.1.preserve(stack);
|
||||
}
|
||||
*(stem.buffer.add(idx) as *mut Entry<T>) = Entry { leaf: new_leaf };
|
||||
}
|
||||
|
@ -640,7 +640,7 @@ fn match_pre_hint(
|
||||
let jet_formula = cell.tail().as_cell()?;
|
||||
let jet_name = jet_formula.tail();
|
||||
|
||||
let jet = jets::get_jet(jet_name)?;
|
||||
let jet = jets::get_jet(jet_name).ok_or(())?;
|
||||
if let Ok(mut jet_res) = jet(stack, subject) {
|
||||
// if in test mode, check that the jet returns the same result as the raw nock
|
||||
if jets::get_jet_test_mode(jet_name) {
|
||||
@ -653,20 +653,20 @@ fn match_pre_hint(
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
return Ok(jet_res);
|
||||
Ok(jet_res)
|
||||
} else {
|
||||
// Print jet errors and punt to Nock
|
||||
eprintln!("\rJet {} failed", jet_name);
|
||||
return Err(());
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
tas!(b"memo") => {
|
||||
let formula = unsafe { *stack.local_noun_pointer(2) };
|
||||
let mut key = Cell::new(stack, subject, formula).as_noun();
|
||||
if let Some(res) = cache.lookup(stack, &mut key) {
|
||||
return Ok(res);
|
||||
Ok(res)
|
||||
} else {
|
||||
return Err(());
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
_ => Err(()),
|
||||
@ -711,10 +711,8 @@ fn match_post_hinted(
|
||||
let formula = unsafe { *stack.local_noun_pointer(2) };
|
||||
let mut key = Cell::new(stack, subject, formula).as_noun();
|
||||
*cache = cache.insert(stack, &mut key, res);
|
||||
return Ok(());
|
||||
}
|
||||
_ => {
|
||||
return Err(());
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ pub mod math;
|
||||
|
||||
use crate::jets::math::*;
|
||||
use crate::mem::NockStack;
|
||||
use crate::noun::Noun;
|
||||
use crate::noun::{self, Noun};
|
||||
use ares_macros::tas;
|
||||
|
||||
crate::gdb!();
|
||||
@ -24,47 +24,56 @@ impl From<()> for JetErr {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<noun::Error> for JetErr {
|
||||
fn from(_err: noun::Error) -> Self {
|
||||
Self::NonDeterministic
|
||||
}
|
||||
}
|
||||
|
||||
impl From<JetErr> for () {
|
||||
fn from(_: JetErr) -> Self {}
|
||||
}
|
||||
|
||||
pub fn get_jet(jet_name: Noun) -> Result<Jet, ()> {
|
||||
match jet_name.as_direct()?.data() {
|
||||
tas!(b"dec") => Ok(jet_dec),
|
||||
tas!(b"add") => Ok(jet_add),
|
||||
tas!(b"sub") => Ok(jet_sub),
|
||||
tas!(b"mul") => Ok(jet_mul),
|
||||
tas!(b"div") => Ok(jet_div),
|
||||
tas!(b"mod") => Ok(jet_mod),
|
||||
tas!(b"dvr") => Ok(jet_dvr),
|
||||
tas!(b"lth") => Ok(jet_lth),
|
||||
tas!(b"lte") => Ok(jet_lte),
|
||||
tas!(b"gth") => Ok(jet_gth),
|
||||
tas!(b"gte") => Ok(jet_gte),
|
||||
tas!(b"bex") => Ok(jet_bex),
|
||||
tas!(b"lsh") => Ok(jet_lsh),
|
||||
tas!(b"rsh") => Ok(jet_rsh),
|
||||
tas!(b"con") => Ok(jet_con),
|
||||
tas!(b"dis") => Ok(jet_dis),
|
||||
tas!(b"mix") => Ok(jet_mix),
|
||||
tas!(b"end") => Ok(jet_end),
|
||||
tas!(b"cat") => Ok(jet_cat),
|
||||
tas!(b"cut") => Ok(jet_cut),
|
||||
tas!(b"can") => Ok(jet_can),
|
||||
tas!(b"rep") => Ok(jet_rep),
|
||||
tas!(b"rip") => Ok(jet_rip),
|
||||
tas!(b"met") => Ok(jet_met),
|
||||
tas!(b"mug") => Ok(jet_mug),
|
||||
pub fn get_jet(jet_name: Noun) -> Option<Jet> {
|
||||
match jet_name.as_direct().ok()?.data() {
|
||||
tas!(b"dec") => Some(jet_dec),
|
||||
tas!(b"add") => Some(jet_add),
|
||||
tas!(b"sub") => Some(jet_sub),
|
||||
tas!(b"mul") => Some(jet_mul),
|
||||
tas!(b"div") => Some(jet_div),
|
||||
tas!(b"mod") => Some(jet_mod),
|
||||
tas!(b"dvr") => Some(jet_dvr),
|
||||
tas!(b"lth") => Some(jet_lth),
|
||||
tas!(b"lte") => Some(jet_lte),
|
||||
tas!(b"gth") => Some(jet_gth),
|
||||
tas!(b"gte") => Some(jet_gte),
|
||||
tas!(b"bex") => Some(jet_bex),
|
||||
tas!(b"lsh") => Some(jet_lsh),
|
||||
tas!(b"rsh") => Some(jet_rsh),
|
||||
tas!(b"con") => Some(jet_con),
|
||||
tas!(b"dis") => Some(jet_dis),
|
||||
tas!(b"mix") => Some(jet_mix),
|
||||
tas!(b"end") => Some(jet_end),
|
||||
tas!(b"cat") => Some(jet_cat),
|
||||
tas!(b"cut") => Some(jet_cut),
|
||||
tas!(b"can") => Some(jet_can),
|
||||
tas!(b"rep") => Some(jet_rep),
|
||||
tas!(b"rip") => Some(jet_rip),
|
||||
tas!(b"met") => Some(jet_met),
|
||||
tas!(b"mug") => Some(jet_mug),
|
||||
_ => {
|
||||
// eprintln!("Unknown jet: {:?}", jet_name);
|
||||
Err(())
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_jet_test_mode(jet_name: Noun) -> bool {
|
||||
pub fn get_jet_test_mode(_jet_name: Noun) -> bool {
|
||||
/*
|
||||
match jet_name.as_direct().unwrap().data() {
|
||||
// tas!(b"cut") => true,
|
||||
tas!(b"cut") => true,
|
||||
_ => false,
|
||||
}
|
||||
*/
|
||||
false
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use bitvec::prelude::{BitSlice, Lsb0};
|
||||
use either::Either::*;
|
||||
use ibig::ops::DivRem;
|
||||
use ibig::UBig;
|
||||
use std::cmp;
|
||||
use std::{cmp, convert::TryFrom};
|
||||
|
||||
crate::gdb!();
|
||||
|
||||
@ -136,15 +136,13 @@ pub fn jet_div(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
||||
|
||||
if unsafe { b.as_noun().raw_equals(D(0)) } {
|
||||
Err(Deterministic)
|
||||
} else if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
|
||||
Ok(unsafe { DirectAtom::new_unchecked(a.data() / b.data()) }.as_noun())
|
||||
} else {
|
||||
if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
|
||||
Ok(unsafe { DirectAtom::new_unchecked(a.data() / b.data()) }.as_noun())
|
||||
} else {
|
||||
let a_big = a.as_ubig(stack);
|
||||
let b_big = b.as_ubig(stack);
|
||||
let res = UBig::div_stack(stack, a_big, b_big);
|
||||
Ok(Atom::from_ubig(stack, &res).as_noun())
|
||||
}
|
||||
let a_big = a.as_ubig(stack);
|
||||
let b_big = b.as_ubig(stack);
|
||||
let res = UBig::div_stack(stack, a_big, b_big);
|
||||
Ok(Atom::from_ubig(stack, &res).as_noun())
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,13 +153,11 @@ pub fn jet_mod(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
||||
|
||||
if unsafe { b.as_noun().raw_equals(D(0)) } {
|
||||
Err(Deterministic)
|
||||
} else if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
|
||||
Ok(unsafe { DirectAtom::new_unchecked(a.data() % b.data()) }.as_noun())
|
||||
} else {
|
||||
if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
|
||||
Ok(unsafe { DirectAtom::new_unchecked(a.data() % b.data()) }.as_noun())
|
||||
} else {
|
||||
let res = a.as_ubig(stack) % b.as_ubig(stack);
|
||||
Ok(Atom::from_ubig(stack, &res).as_noun())
|
||||
}
|
||||
let res = a.as_ubig(stack) % b.as_ubig(stack);
|
||||
Ok(Atom::from_ubig(stack, &res).as_noun())
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,18 +200,14 @@ pub fn jet_lth(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
||||
} else {
|
||||
NO
|
||||
}
|
||||
} else if a.bit_size() < b.bit_size() {
|
||||
YES
|
||||
} else if a.bit_size() > b.bit_size() {
|
||||
NO
|
||||
} else if a.as_ubig(stack) < b.as_ubig(stack) {
|
||||
YES
|
||||
} else {
|
||||
if a.bit_size() < b.bit_size() {
|
||||
YES
|
||||
} else if a.bit_size() > b.bit_size() {
|
||||
NO
|
||||
} else {
|
||||
if a.as_ubig(stack) < b.as_ubig(stack) {
|
||||
YES
|
||||
} else {
|
||||
NO
|
||||
}
|
||||
}
|
||||
NO
|
||||
})
|
||||
}
|
||||
|
||||
@ -230,18 +222,14 @@ pub fn jet_lte(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
||||
} else {
|
||||
NO
|
||||
}
|
||||
} else if a.bit_size() < b.bit_size() {
|
||||
YES
|
||||
} else if a.bit_size() > b.bit_size() {
|
||||
NO
|
||||
} else if a.as_ubig(stack) <= b.as_ubig(stack) {
|
||||
YES
|
||||
} else {
|
||||
if a.bit_size() < b.bit_size() {
|
||||
YES
|
||||
} else if a.bit_size() > b.bit_size() {
|
||||
NO
|
||||
} else {
|
||||
if a.as_ubig(stack) <= b.as_ubig(stack) {
|
||||
YES
|
||||
} else {
|
||||
NO
|
||||
}
|
||||
}
|
||||
NO
|
||||
})
|
||||
}
|
||||
|
||||
@ -256,18 +244,14 @@ pub fn jet_gth(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
||||
} else {
|
||||
NO
|
||||
}
|
||||
} else if a.bit_size() > b.bit_size() {
|
||||
YES
|
||||
} else if a.bit_size() < b.bit_size() {
|
||||
NO
|
||||
} else if a.as_ubig(stack) > b.as_ubig(stack) {
|
||||
YES
|
||||
} else {
|
||||
if a.bit_size() > b.bit_size() {
|
||||
YES
|
||||
} else if a.bit_size() < b.bit_size() {
|
||||
NO
|
||||
} else {
|
||||
if a.as_ubig(stack) > b.as_ubig(stack) {
|
||||
YES
|
||||
} else {
|
||||
NO
|
||||
}
|
||||
}
|
||||
NO
|
||||
})
|
||||
}
|
||||
|
||||
@ -282,18 +266,14 @@ pub fn jet_gte(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
||||
} else {
|
||||
NO
|
||||
}
|
||||
} else if a.bit_size() > b.bit_size() {
|
||||
YES
|
||||
} else if a.bit_size() < b.bit_size() {
|
||||
NO
|
||||
} else if a.as_ubig(stack) >= b.as_ubig(stack) {
|
||||
YES
|
||||
} else {
|
||||
if a.bit_size() > b.bit_size() {
|
||||
YES
|
||||
} else if a.bit_size() < b.bit_size() {
|
||||
NO
|
||||
} else {
|
||||
if a.as_ubig(stack) >= b.as_ubig(stack) {
|
||||
YES
|
||||
} else {
|
||||
NO
|
||||
}
|
||||
}
|
||||
NO
|
||||
})
|
||||
}
|
||||
|
||||
@ -468,7 +448,7 @@ pub fn jet_can(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
||||
}
|
||||
let original_list = raw_slot(arg, 3);
|
||||
|
||||
let mut len = 0 as usize;
|
||||
let mut len = 0usize;
|
||||
let mut list = original_list;
|
||||
loop {
|
||||
if unsafe { list.raw_equals(D(0)) } {
|
||||
@ -477,7 +457,7 @@ pub fn jet_can(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
||||
|
||||
let cell = list.as_cell()?;
|
||||
let item = cell.head().as_cell()?;
|
||||
let step = item.head().as_direct()?.data() as usize;
|
||||
let step = usize::try_from(item.head().as_direct()?.data()).unwrap();
|
||||
|
||||
len = len.checked_add(step).ok_or(NonDeterministic)?;
|
||||
list = cell.tail();
|
||||
@ -515,7 +495,7 @@ pub fn jet_rep(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
||||
let (bloq, step) = bite(raw_slot(arg, 2))?;
|
||||
let original_list = raw_slot(arg, 3);
|
||||
|
||||
let mut len = 0 as usize;
|
||||
let mut len = 0usize;
|
||||
let mut list = original_list;
|
||||
loop {
|
||||
if unsafe { list.raw_equals(D(0)) } {
|
||||
@ -663,13 +643,11 @@ unsafe fn chop(
|
||||
pub fn met(bloq: usize, a: Atom) -> usize {
|
||||
if unsafe { a.as_noun().raw_equals(D(0)) } {
|
||||
0
|
||||
} else if bloq < 6 {
|
||||
(a.bit_size() + ((1 << bloq) - 1)) >> bloq
|
||||
} else {
|
||||
if bloq < 6 {
|
||||
(a.bit_size() + ((1 << bloq) - 1)) >> bloq
|
||||
} else {
|
||||
let bloq_word = bloq - 6;
|
||||
(a.size() + ((1 << bloq_word) - 1)) >> bloq_word
|
||||
}
|
||||
let bloq_word = bloq - 6;
|
||||
(a.size() + ((1 << bloq_word) - 1)) >> bloq_word
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ fn main() -> io::Result<()> {
|
||||
return serf();
|
||||
}
|
||||
|
||||
let output_filename = format!("{}.out", filename.clone());
|
||||
let output_filename = format!("{}.out", filename);
|
||||
let f = File::open(filename)?;
|
||||
let in_len = f.metadata()?.len();
|
||||
let mut stack = NockStack::new(8 << 10 << 10, 0);
|
||||
|
@ -98,12 +98,12 @@ impl NockStack {
|
||||
*frame_pointer.add(1) = ptr::null::<u64>() as u64;
|
||||
};
|
||||
NockStack {
|
||||
start: start,
|
||||
size: size,
|
||||
start,
|
||||
size,
|
||||
polarity: Polarity::West,
|
||||
stack_pointer: stack_pointer,
|
||||
frame_pointer: frame_pointer,
|
||||
memory: memory,
|
||||
stack_pointer,
|
||||
frame_pointer,
|
||||
memory,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ impl Newt {
|
||||
fn write_noun(&mut self, stack: &mut NockStack, noun: Noun) {
|
||||
let atom = jam(stack, noun);
|
||||
let size = atom.size() << 3;
|
||||
let mut buf = vec![0 as u8; size + 5];
|
||||
let mut buf = vec![0u8; size + 5];
|
||||
buf[1] = size as u8;
|
||||
buf[2] = (size >> 8) as u8;
|
||||
buf[3] = (size >> 16) as u8;
|
||||
@ -192,8 +192,7 @@ impl Newt {
|
||||
|
||||
/** Fetch next message. */
|
||||
pub fn next(&mut self, stack: &mut NockStack) -> Option<Noun> {
|
||||
let mut header: Vec<u8> = Vec::with_capacity(5);
|
||||
header.resize(5, 0);
|
||||
let mut header: Vec<u8> = vec![0; 5];
|
||||
if let Err(err) = self.input.read_exact(&mut header) {
|
||||
if err.kind() == std::io::ErrorKind::UnexpectedEof {
|
||||
return None;
|
||||
@ -219,3 +218,9 @@ impl Newt {
|
||||
Some(cue(stack, atom))
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Newt {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ fn acyclic_noun_go(noun: Noun, seen: &mut IntMap<()>) -> bool {
|
||||
match noun.as_either_atom_cell() {
|
||||
Either::Left(_atom) => true,
|
||||
Either::Right(cell) => {
|
||||
if let Some(_) = seen.get(cell.0) {
|
||||
if seen.get(cell.0).is_some() {
|
||||
false
|
||||
} else {
|
||||
seen.insert(cell.0, ());
|
||||
@ -97,6 +97,30 @@ fn is_cell(noun: u64) -> bool {
|
||||
noun & CELL_MASK == CELL_TAG
|
||||
}
|
||||
|
||||
/** A noun-related error. */
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Error {
|
||||
/** Expected type [`Allocated`]. */
|
||||
NotAllocated,
|
||||
/** Expected type [`Atom`]. */
|
||||
NotAtom,
|
||||
/** Expected type [`Cell`]. */
|
||||
NotCell,
|
||||
/** Expected type [`DirectAtom`]. */
|
||||
NotDirectAtom,
|
||||
/** Expected type [`IndirectAtom`]. */
|
||||
NotIndirectAtom,
|
||||
/** The value can't be represented by the given type. */
|
||||
NotRepresentable,
|
||||
}
|
||||
|
||||
impl From<Error> for () {
|
||||
fn from(_: Error) -> Self {}
|
||||
}
|
||||
|
||||
/** A [`Result`] that returns an [`Error`] on error. */
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
/** A direct atom.
|
||||
*
|
||||
* Direct atoms represent an atom up to and including DIRECT_MAX as a machine word.
|
||||
@ -117,9 +141,9 @@ impl DirectAtom {
|
||||
}
|
||||
|
||||
/** Create a new direct atom, or return Err if the value is greater than DIRECT_MAX */
|
||||
pub const fn new(value: u64) -> Result<Self, ()> {
|
||||
pub const fn new(value: u64) -> Result<Self> {
|
||||
if value > DIRECT_MAX {
|
||||
Err(())
|
||||
Err(Error::NotRepresentable)
|
||||
} else {
|
||||
Ok(DirectAtom(value))
|
||||
}
|
||||
@ -155,8 +179,8 @@ impl DirectAtom {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn as_bitslice<'a>(&'a self) -> &'a BitSlice<u64, Lsb0> {
|
||||
&(BitSlice::from_element(&self.0))
|
||||
pub fn as_bitslice(&self) -> &BitSlice<u64, Lsb0> {
|
||||
BitSlice::from_element(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
@ -345,16 +369,16 @@ impl IndirectAtom {
|
||||
unsafe { self.to_raw_pointer().add(2) as *const u64 }
|
||||
}
|
||||
|
||||
pub fn as_slice<'a>(&'a self) -> &'a [u64] {
|
||||
pub fn as_slice(&self) -> &[u64] {
|
||||
unsafe { from_raw_parts(self.data_pointer(), self.size()) }
|
||||
}
|
||||
|
||||
pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
unsafe { from_raw_parts(self.data_pointer() as *const u8, self.size() << 3) }
|
||||
}
|
||||
|
||||
/** BitSlice view on an indirect atom, with lifetime tied to reference to indirect atom. */
|
||||
pub fn as_bitslice<'a>(&'a self) -> &'a BitSlice<u64, Lsb0> {
|
||||
pub fn as_bitslice(&self) -> &BitSlice<u64, Lsb0> {
|
||||
BitSlice::from_slice(self.as_slice())
|
||||
}
|
||||
|
||||
@ -370,7 +394,7 @@ impl IndirectAtom {
|
||||
if index == 0 || *(data.add(index)) != 0 {
|
||||
break;
|
||||
}
|
||||
index = index - 1;
|
||||
index -= 1;
|
||||
}
|
||||
*(self.to_raw_pointer_mut().add(1)) = (index + 1) as u64;
|
||||
self
|
||||
@ -445,7 +469,7 @@ impl Cell {
|
||||
&mut (*self.to_raw_pointer_mut()).head as *mut Noun
|
||||
}
|
||||
|
||||
pub unsafe fn tail_as_mut<'a>(mut self) -> *mut Noun {
|
||||
pub unsafe fn tail_as_mut(mut self) -> *mut Noun {
|
||||
&mut (*self.to_raw_pointer_mut()).tail as *mut Noun
|
||||
}
|
||||
|
||||
@ -593,19 +617,19 @@ impl Atom {
|
||||
unsafe { is_indirect_atom(self.raw) }
|
||||
}
|
||||
|
||||
pub fn as_direct(&self) -> Result<DirectAtom, ()> {
|
||||
pub fn as_direct(&self) -> Result<DirectAtom> {
|
||||
if self.is_direct() {
|
||||
unsafe { Ok(self.direct) }
|
||||
} else {
|
||||
Err(())
|
||||
Err(Error::NotDirectAtom)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_indirect(&self) -> Result<IndirectAtom, ()> {
|
||||
pub fn as_indirect(&self) -> Result<IndirectAtom> {
|
||||
if self.is_indirect() {
|
||||
unsafe { Ok(self.indirect) }
|
||||
} else {
|
||||
Err(())
|
||||
Err(Error::NotIndirectAtom)
|
||||
}
|
||||
}
|
||||
|
||||
@ -617,11 +641,11 @@ impl Atom {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_bitslice<'a>(&'a self) -> &'a BitSlice<u64, Lsb0> {
|
||||
pub fn as_bitslice(&self) -> &BitSlice<u64, Lsb0> {
|
||||
if self.is_indirect() {
|
||||
unsafe { self.indirect.as_bitslice() }
|
||||
} else {
|
||||
unsafe { &(self.direct.as_bitslice()) }
|
||||
unsafe { self.direct.as_bitslice() }
|
||||
}
|
||||
}
|
||||
|
||||
@ -781,43 +805,43 @@ impl Noun {
|
||||
unsafe { is_cell(self.raw) }
|
||||
}
|
||||
|
||||
pub fn as_direct(&self) -> Result<DirectAtom, ()> {
|
||||
pub fn as_direct(&self) -> Result<DirectAtom> {
|
||||
if self.is_direct() {
|
||||
unsafe { Ok(self.direct) }
|
||||
} else {
|
||||
Err(())
|
||||
Err(Error::NotDirectAtom)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_indirect(&self) -> Result<IndirectAtom, ()> {
|
||||
pub fn as_indirect(&self) -> Result<IndirectAtom> {
|
||||
if self.is_indirect() {
|
||||
unsafe { Ok(self.indirect) }
|
||||
} else {
|
||||
Err(())
|
||||
Err(Error::NotIndirectAtom)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_cell(&self) -> Result<Cell, ()> {
|
||||
pub fn as_cell(&self) -> Result<Cell> {
|
||||
if self.is_cell() {
|
||||
unsafe { Ok(self.cell) }
|
||||
} else {
|
||||
Err(())
|
||||
Err(Error::NotCell)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_atom(&self) -> Result<Atom, ()> {
|
||||
pub fn as_atom(&self) -> Result<Atom> {
|
||||
if self.is_atom() {
|
||||
unsafe { Ok(self.atom) }
|
||||
} else {
|
||||
Err(())
|
||||
Err(Error::NotAtom)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_allocated(&self) -> Result<Allocated, ()> {
|
||||
pub fn as_allocated(&self) -> Result<Allocated> {
|
||||
if self.is_allocated() {
|
||||
unsafe { Ok(self.allocated) }
|
||||
} else {
|
||||
Err(())
|
||||
Err(Error::NotAllocated)
|
||||
}
|
||||
}
|
||||
|
||||
@ -847,7 +871,7 @@ impl Noun {
|
||||
}
|
||||
|
||||
pub unsafe fn from_raw(raw: u64) -> Noun {
|
||||
Noun { raw: raw }
|
||||
Noun { raw }
|
||||
}
|
||||
|
||||
/** Produce the total size of a noun, in words
|
||||
|
@ -33,10 +33,10 @@ pub fn serf() -> io::Result<()> {
|
||||
snap_path.push(".urb");
|
||||
snap_path.push("chk");
|
||||
create_dir_all(&snap_path)?;
|
||||
let ref mut snap = snapshot::double_jam::DoubleJam::new(snap_path);
|
||||
let snap = &mut snapshot::double_jam::DoubleJam::new(snap_path);
|
||||
|
||||
let ref mut stack = NockStack::new(96 << 10 << 10, 0);
|
||||
let ref mut newt = Newt::new();
|
||||
let stack = &mut NockStack::new(96 << 10 << 10, 0);
|
||||
let newt = &mut Newt::new();
|
||||
|
||||
let (_epoch, mut event_number, mut arvo) = snap.load(stack).unwrap_or((0, 0, D(0)));
|
||||
let mug = mug_u32(stack, arvo);
|
||||
@ -44,13 +44,7 @@ pub fn serf() -> io::Result<()> {
|
||||
newt.ripe(stack, event_number, mug as u64);
|
||||
|
||||
// Can't use for loop because it borrows newt
|
||||
loop {
|
||||
let writ = if let Some(writ) = newt.next(stack) {
|
||||
writ
|
||||
} else {
|
||||
break;
|
||||
};
|
||||
|
||||
while let Some(writ) = newt.next(stack) {
|
||||
let tag = raw_slot(writ, 2).as_direct().unwrap();
|
||||
match tag.data() {
|
||||
tas!(b"live") => {
|
||||
@ -91,18 +85,14 @@ pub fn serf() -> io::Result<()> {
|
||||
// event_number = raw_slot(writ, 6).as_direct().unwrap().data();
|
||||
|
||||
let mut lit = raw_slot(writ, 7);
|
||||
loop {
|
||||
if let Ok(cell) = lit.as_cell() {
|
||||
if run {
|
||||
let ovo = cell.head();
|
||||
let res = slam(stack, newt, arvo, POKE_AXIS, ovo).as_cell().unwrap();
|
||||
arvo = res.tail();
|
||||
}
|
||||
event_number += 1;
|
||||
lit = cell.tail();
|
||||
} else {
|
||||
break;
|
||||
while let Ok(cell) = lit.as_cell() {
|
||||
if run {
|
||||
let ovo = cell.head();
|
||||
let res = slam(stack, newt, arvo, POKE_AXIS, ovo).as_cell().unwrap();
|
||||
arvo = res.tail();
|
||||
}
|
||||
event_number += 1;
|
||||
lit = cell.tail();
|
||||
}
|
||||
|
||||
snap.save(stack, &mut arvo);
|
||||
|
@ -168,9 +168,9 @@ pub fn jam(stack: &mut NockStack, noun: Noun) -> Atom {
|
||||
let (atom, slice) = unsafe { IndirectAtom::new_raw_mut_bitslice(stack, size) };
|
||||
let mut state = JamState {
|
||||
cursor: 0,
|
||||
size: size,
|
||||
atom: atom,
|
||||
slice: slice,
|
||||
size,
|
||||
atom,
|
||||
slice,
|
||||
};
|
||||
stack.push(1);
|
||||
unsafe {
|
||||
|
@ -7,6 +7,7 @@ pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
(fenix.stable.withComponents [
|
||||
"cargo"
|
||||
"clippy"
|
||||
"rustc"
|
||||
"rustfmt"
|
||||
"rust-src"
|
||||
|
Loading…
Reference in New Issue
Block a user