Skip to content

Commit

Permalink
rune: Move ranges away from being built-in types
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Oct 27, 2024
1 parent dfb60ca commit 057415f
Show file tree
Hide file tree
Showing 18 changed files with 367 additions and 468 deletions.
58 changes: 28 additions & 30 deletions crates/rune-macros/src/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ where

let Tokens {
alloc,
any,
any_t,
box_,
context_error,
from_value,
Expand Down Expand Up @@ -574,31 +574,20 @@ where
}
};

let impl_type_of = if attr.builtin.is_none() {
let type_hash = type_hash.into_inner();

let make_hash = if !generic_names.is_empty() {
quote!(#hash::new_with_type_parameters(#type_hash, #hash::parameters([#(<#generic_names as #type_hash_t>::HASH),*])))
} else {
quote!(#hash::new(#type_hash))
};

let type_parameters =
quote!(#hash::parameters([#(<#generic_names as #type_hash_t>::HASH),*]));
let impl_type_of = if let Some(ty) = attr.static_type {
let ty_hash = syn::Ident::new(&format!("{ty}_HASH"), ty.span());

Some(quote! {
#[automatically_derived]
impl #impl_generics #type_hash_t for #ident #type_generics #where_clause {
const HASH: #hash = #make_hash;
const HASH: #hash = #static_type_mod::#ty_hash;
}

#[automatically_derived]
impl #impl_generics #type_of for #ident #type_generics #where_clause {
const PARAMETERS: #hash = #type_parameters;

#[inline]
fn type_info() -> #type_info {
#type_info::any::<Self>()
#type_info::static_type(#static_type_mod::#ty)
}
}

Expand All @@ -608,25 +597,36 @@ where
fn maybe_type_of() -> #alloc::Result<#meta::DocType> {
#meta::DocType::with_generics(
<Self as #type_hash_t>::HASH,
[#(<#generic_names as #maybe_type_of>::maybe_type_of()?),*]
[#(<#generic_names as #maybe_type_of>::maybe_type_of()),*]
)
}
}
})
} else if let Some(ty) = attr.static_type {
let ty_hash = syn::Ident::new(&format!("{ty}_HASH"), ty.span());
} else if attr.builtin.is_none() {
let type_hash = type_hash.into_inner();

let make_hash = if !generic_names.is_empty() {
quote!(#hash::new_with_type_parameters(#type_hash, #hash::parameters([#(<#generic_names as #type_hash_t>::HASH),*])))
} else {
quote!(#hash::new(#type_hash))
};

let type_parameters =
quote!(#hash::parameters([#(<#generic_names as #type_hash_t>::HASH),*]));

Some(quote! {
#[automatically_derived]
impl #impl_generics #type_hash_t for #ident #type_generics #where_clause {
const HASH: #hash = #static_type_mod::#ty_hash;
const HASH: #hash = #make_hash;
}

#[automatically_derived]
impl #impl_generics #type_of for #ident #type_generics #where_clause {
const PARAMETERS: #hash = #type_parameters;

#[inline]
fn type_info() -> #type_info {
#type_info::static_type(#static_type_mod::#ty)
#type_info::any::<Self>()
}
}

Expand All @@ -636,7 +636,7 @@ where
fn maybe_type_of() -> #alloc::Result<#meta::DocType> {
#meta::DocType::with_generics(
<Self as #type_hash_t>::HASH,
[#(<#generic_names as #maybe_type_of>::maybe_type_of()),*]
[#(<#generic_names as #maybe_type_of>::maybe_type_of()?),*]
)
}
}
Expand All @@ -645,10 +645,10 @@ where
None
};

let any = if attr.builtin.is_none() {
Some(quote! {
let non_builtin = attr.builtin.is_none().then(|| {
quote! {
#[automatically_derived]
impl #impl_generics #any for #ident #type_generics #where_clause {
impl #impl_generics #any_t for #ident #type_generics #where_clause {
}

#[automatically_derived]
Expand Down Expand Up @@ -698,10 +698,8 @@ where
Option::<&str>::None
}
}
})
} else {
None
};
}
});

let impl_from_value = 'out: {
if let Some(path) = attr.from_value {
Expand Down Expand Up @@ -793,7 +791,7 @@ where
#impl_from_value
#impl_from_value_ref
#impl_from_value_mut
#any
#non_builtin
}
}
}
4 changes: 2 additions & 2 deletions crates/rune-macros/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ impl Context {

Tokens {
alloc: path(m, ["alloc"]),
any: path(m, ["Any"]),
any_t: path(m, ["Any"]),
box_: path(m, ["__private", "Box"]),
compile_error: path(m, ["compile", "Error"]),
context_error: path(m, ["compile", "ContextError"]),
Expand Down Expand Up @@ -704,7 +704,7 @@ fn path<const N: usize>(base: &syn::Path, path: [&'static str; N]) -> syn::Path

pub(crate) struct Tokens {
pub(crate) alloc: syn::Path,
pub(crate) any: syn::Path,
pub(crate) any_t: syn::Path,
pub(crate) box_: syn::Path,
pub(crate) compile_error: syn::Path,
pub(crate) context_error: syn::Path,
Expand Down
14 changes: 13 additions & 1 deletion crates/rune/src/modules/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,19 @@ pub fn module() -> Result<Module, ContextError> {

{
m.ty::<RangeFull>()?;
m.function_meta(RangeFull::contains)?;
m.function_meta(RangeFull::contains__meta)?;

m.function_meta(RangeFull::partial_eq__meta)?;
m.implement_trait::<RangeFull>(rune::item!(::std::cmp::PartialEq))?;

m.function_meta(RangeFull::eq__meta)?;
m.implement_trait::<RangeFull>(rune::item!(::std::cmp::Eq))?;

m.function_meta(RangeFull::partial_cmp__meta)?;
m.implement_trait::<RangeFull>(rune::item!(::std::cmp::PartialOrd))?;

m.function_meta(RangeFull::cmp__meta)?;
m.implement_trait::<RangeFull>(rune::item!(::std::cmp::Ord))?;
}

{
Expand Down
39 changes: 24 additions & 15 deletions crates/rune/src/modules/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ use crate::alloc::string::FromUtf8Error;
use crate::alloc::{String, Vec};
use crate::compile::Named;
use crate::runtime::{
Bytes, FromValue, Function, Inline, MaybeTypeOf, Mutable, Panic, Ref, ToValue, TypeOf, Value,
ValueBorrowRef, VmErrorKind, VmResult,
Bytes, FromValue, Function, Inline, MaybeTypeOf, Mutable, Panic, Range, RangeFrom, RangeFull,
RangeInclusive, RangeTo, RangeToInclusive, Ref, ToValue, TypeOf, Value, ValueBorrowRef,
VmErrorKind, VmResult,
};
use crate::{Any, ContextError, Module};
use crate::{Any, ContextError, Module, TypeHash};

/// Strings.
///
Expand Down Expand Up @@ -1022,42 +1023,50 @@ fn chars(s: Ref<str>) -> Chars {
fn get(this: &str, key: Value) -> VmResult<Option<String>> {
use crate::runtime::TypeOf;

let slice = match vm_try!(key.borrow_ref()) {
ValueBorrowRef::Mutable(value) => match &*value {
Mutable::RangeFrom(range) => {
let slice = match vm_try!(key.as_any()) {
Some(value) => match value.type_hash() {
RangeFrom::HASH => {
let range = vm_try!(value.borrow_ref::<RangeFrom>());
let start = vm_try!(range.start.as_usize());
this.get(start..)
}
Mutable::RangeFull(..) => this.get(..),
Mutable::RangeInclusive(range) => {
RangeFull::HASH => {
_ = vm_try!(value.borrow_ref::<RangeFull>());
this.get(..)
}
RangeInclusive::HASH => {
let range = vm_try!(value.borrow_ref::<RangeInclusive>());
let start = vm_try!(range.start.as_usize());
let end = vm_try!(range.end.as_usize());
this.get(start..=end)
}
Mutable::RangeToInclusive(range) => {
RangeToInclusive::HASH => {
let range = vm_try!(value.borrow_ref::<RangeToInclusive>());
let end = vm_try!(range.end.as_usize());
this.get(..=end)
}
Mutable::RangeTo(range) => {
RangeTo::HASH => {
let range = vm_try!(value.borrow_ref::<RangeTo>());
let end = vm_try!(range.end.as_usize());
this.get(..end)
}
Mutable::Range(range) => {
Range::HASH => {
let range = vm_try!(value.borrow_ref::<Range>());
let start = vm_try!(range.start.as_usize());
let end = vm_try!(range.end.as_usize());
this.get(start..end)
}
index => {
_ => {
return VmResult::err(VmErrorKind::UnsupportedIndexGet {
target: String::type_info(),
index: index.type_info(),
index: value.type_info(),
})
}
},
index => {
_ => {
return VmResult::err(VmErrorKind::UnsupportedIndexGet {
target: String::type_info(),
index: index.type_info(),
index: vm_try!(key.type_info()),
})
}
};
Expand Down
Loading

0 comments on commit 057415f

Please sign in to comment.