mirror of
https://github.com/urbit/ares.git
synced 2024-11-26 09:57:56 +03:00
Merge pull request #12 from urbit/philip/jets
"implement" "jet" "dashboard"
This commit is contained in:
commit
145a5632e2
9
rust/ares/Cargo.lock
generated
9
rust/ares/Cargo.lock
generated
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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
65
rust/ares/src/jets.rs
Normal 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() }
|
||||
}
|
@ -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
46
rust/ares_macros/Cargo.lock
generated
Normal 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"
|
12
rust/ares_macros/Cargo.toml
Normal file
12
rust/ares_macros/Cargo.toml
Normal 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"
|
22
rust/ares_macros/src/lib.rs
Normal file
22
rust/ares_macros/src/lib.rs
Normal 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()
|
||||
}
|
Loading…
Reference in New Issue
Block a user