Merge pull request #17 from urbit/i/15/tas-macro

Add tas!() procedural macro
This commit is contained in:
Philip Monk 2023-02-03 12:51:51 -07:00 committed by GitHub
commit 7a3338cb19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 107 additions and 3 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

@ -3,6 +3,7 @@ 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};
@ -316,7 +317,7 @@ pub fn interpret(stack: &mut NockStack, mut subject: Noun, formula: Noun) -> Nou
// match %sham hints, which are scaffolding until we have a real jet dashboard
if hint_cell
.head()
.raw_equals(DirectAtom::new_unchecked(0x6d616873).as_noun())
.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();

View File

@ -1,12 +1,13 @@
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() {
0x636564 => Ok(jet_dec),
0x747563 => Ok(jet_cut),
tas!(b"dec") => Ok(jet_dec),
tas!(b"cut") => Ok(jet_cut),
_ => Err(()),
}
}

View File

@ -6,3 +6,15 @@ 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()
}