Merge pull request #12 from urbit/philip/jets

"implement" "jet" "dashboard"
This commit is contained in:
Philip Monk 2023-02-03 12:52:46 -07:00 committed by GitHub
commit 145a5632e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 184 additions and 0 deletions

9
rust/ares/Cargo.lock generated
View File

@ -12,6 +12,7 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
name = "ares"
version = "0.1.0"
dependencies = [
"ares_macros",
"bitvec",
"criterion",
"either",
@ -23,6 +24,14 @@ dependencies = [
"num-traits",
]
[[package]]
name = "ares_macros"
version = "0.1.0"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "atty"
version = "0.2.14"

View File

@ -7,6 +7,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
ares_macros = { path = "../ares_macros" }
bitvec = "1.0.0"
either = "1.6.1"
libc = "0.2.126"

View File

@ -1,7 +1,9 @@
use self::NockWork::*;
use crate::jets;
use crate::mem::unifying_equality;
use crate::mem::NockStack;
use crate::noun::{Atom, Cell, DirectAtom, IndirectAtom, Noun};
use ares_macros::tas;
use bitvec::prelude::{BitSlice, Lsb0};
use either::Either::*;
use num_traits::cast::{FromPrimitive, ToPrimitive};
@ -312,6 +314,20 @@ pub fn interpret(stack: &mut NockStack, mut subject: Noun, formula: Noun) -> Nou
Nock11ComputeHint => unsafe {
let hint = *stack.local_noun_pointer(1);
if let Ok(hint_cell) = hint.as_cell() {
// match %sham hints, which are scaffolding until we have a real jet dashboard
if hint_cell
.head()
.raw_equals(DirectAtom::new_unchecked(tas!(b"sham")).as_noun())
{
if let Ok(jet_formula) = hint_cell.tail().as_cell() {
let jet_name = jet_formula.tail();
if let Ok(jet) = jets::get_jet(jet_name) {
res = jet(stack, subject);
stack.pop(&mut res);
continue;
}
}
}
*(stack.local_noun_pointer(0)) = work_to_noun(Nock11ComputeResult);
push_formula(stack, hint_cell.tail());
} else {

65
rust/ares/src/jets.rs Normal file
View File

@ -0,0 +1,65 @@
use crate::interpreter::raw_slot;
use crate::mem::NockStack;
use crate::noun::{DirectAtom, IndirectAtom, Noun};
use ares_macros::tas;
use either::Either::*;
pub fn get_jet(jet_name: Noun) -> Result<fn(&mut NockStack, Noun) -> Noun, ()> {
match jet_name.as_direct()?.data() {
tas!(b"dec") => Ok(jet_dec),
tas!(b"cut") => Ok(jet_cut),
_ => Err(()),
}
}
fn jet_dec(stack: &mut NockStack, subject: Noun) -> Noun {
let arg = raw_slot(subject, 6);
if let Ok(atom) = arg.as_atom() {
match atom.as_either() {
Left(direct) => {
if direct.data() == 0 {
panic!("Decrementing 0");
} else {
unsafe { DirectAtom::new_unchecked(direct.data() - 1) }.as_noun()
}
}
Right(indirect) => {
let indirect_slice = indirect.as_bitslice();
match indirect_slice.first_one() {
None => {
panic!("Decrementing 0");
}
Some(first_one) => {
let (mut new_indirect, new_slice) =
unsafe { IndirectAtom::new_raw_mut_bitslice(stack, indirect.size()) };
if first_one > 0 {
new_slice[..first_one].fill(true);
}
new_slice.set(first_one, false);
new_slice[first_one + 1..]
.copy_from_bitslice(&indirect_slice[first_one + 1..]);
let res = unsafe { new_indirect.normalize_as_atom() };
res.as_noun()
}
}
}
}
} else {
panic!("Argument to dec must be atom");
}
}
fn jet_cut(stack: &mut NockStack, subject: Noun) -> Noun {
let arg = raw_slot(subject, 6);
let bloq = raw_slot(arg, 2).as_direct().unwrap().data();
let start = raw_slot(arg, 12).as_direct().unwrap().data();
let run = raw_slot(arg, 13).as_direct().unwrap().data();
let atom = raw_slot(arg, 7).as_atom().unwrap();
let slice = atom.as_bitslice();
let unit = 1 << bloq;
let (mut new_indirect, new_slice) =
unsafe { IndirectAtom::new_raw_mut_bitslice(stack, ((run * unit + 63) >> 6) as usize) };
new_slice[..(unit * run) as usize]
.copy_from_bitslice(&slice[(unit * start) as usize..(unit * (start + run)) as usize]);
unsafe { new_indirect.normalize_as_atom().as_noun() }
}

View File

@ -1,7 +1,20 @@
#[macro_use]
extern crate num_derive;
pub mod interpreter;
pub mod jets;
pub mod mem;
pub mod mug;
pub mod noun;
pub mod serialization;
#[cfg(test)]
mod tests {
#[test]
fn tas() {
use ares_macros::tas;
assert_eq!(tas!(b"cut"), 0x747563);
assert_eq!(tas!(b"dec"), 0x636564);
assert_eq!(tas!(b"prop"), 0x706f7270);
}
}

46
rust/ares_macros/Cargo.lock generated Normal file
View File

@ -0,0 +1,46 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "ares_macros"
version = "0.1.0"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"

View File

@ -0,0 +1,12 @@
[package]
name = "ares_macros"
version = "0.1.0"
edition = "2021"
[lib]
proc-macro = true
[dependencies]
quote = "1.0"
syn = "1.0"

View File

@ -0,0 +1,22 @@
use proc_macro::TokenStream;
use quote::quote;
use std::mem::size_of;
use syn::{self, LitByteStr};
#[proc_macro]
pub fn tas(input: TokenStream) -> TokenStream {
let byte_str: LitByteStr = syn::parse(input).expect("failed to parse input");
let bytes = byte_str.value();
if bytes.len() > size_of::<u64>() {
panic!(
"\"{}\" does not fit in a u64: must be 8 or fewer characters, not {}",
byte_str.token(),
bytes.len()
);
}
let mut val: u64 = 0;
for byte in bytes.into_iter().rev() {
val = (val << u8::BITS) | u64::from(byte);
}
quote!(#val).into()
}