Skip to content

Commit

Permalink
Simplify implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Aug 23, 2023
1 parent e4b6798 commit 7034356
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 344 deletions.
262 changes: 3 additions & 259 deletions crates/rune/src/modules/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use core::cmp::Ordering;

use crate as rune;
use crate::runtime::{
ControlFlow, EnvProtocolCaller, Function, Generator, GeneratorState, Iterator, Protocol, Range,
ControlFlow, EnvProtocolCaller, Function, Generator, GeneratorState, Iterator, Range,
RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive, Value, Vm, VmResult,
};
use crate::{ContextError, Module};
Expand All @@ -16,44 +16,6 @@ pub fn module() -> Result<Module, ContextError> {

{
m.ty::<RangeFrom>()?;
m.type_meta::<RangeFrom>()?
.make_named_struct(&["start"])?
.docs([
"Type for a from range expression `start..`.",
"",
"# Examples",
"",
"```rune",
"let range = 0..;",
"",
"assert!(!range.contains(-10));",
"assert!(range.contains(5));",
"assert!(range.contains(10));",
"assert!(range.contains(20));",
"",
"assert!(range is std::ops::RangeFrom);",
"```",
"",
"Ranges can contain any type:",
"",
"```rune",
"let range = 'a'..;",
"assert_eq!(range.start, 'a');",
"range.start = 'b';",
"assert_eq!(range.start, 'b');",
"```",
"",
"Certain ranges can be used as iterators:",
"",
"```rune",
"let range = 'a'..;",
"assert_eq!(range.iter().take(5).collect::<Vec>(), ['a', 'b', 'c', 'd', 'e']);",
"```",
]);
m.field_function(Protocol::GET, "start", |r: &RangeFrom| r.start.clone())?;
m.field_function(Protocol::SET, "start", |r: &mut RangeFrom, value: Value| {
r.start = value;
})?;
m.function_meta(RangeFrom::iter__meta)?;
m.function_meta(RangeFrom::contains__meta)?;
m.function_meta(RangeFrom::into_iter__meta)?;
Expand All @@ -65,80 +27,11 @@ pub fn module() -> Result<Module, ContextError> {

{
m.ty::<RangeFull>()?;
m.type_meta::<RangeFull>()?.make_empty_struct()?.docs([
"Type for a full range expression `..`.",
"",
"# Examples",
"",
"```rune",
"let range = ..;",
"",
"assert!(range.contains(-10));",
"assert!(range.contains(5));",
"assert!(range.contains(10));",
"assert!(range.contains(20));",
"",
"assert!(range is std::ops::RangeFull);",
"```",
]);
m.function_meta(RangeFull::contains)?;
}

{
m.ty::<RangeInclusive>()?;
m.type_meta::<RangeInclusive>()?
.make_named_struct(&["start", "end"])?
.docs([
"Type for an inclusive range expression `start..=end`.",
"",
"# Examples",
"",
"```rune",
"let range = 0..=10;",
"",
"assert!(!range.contains(-10));",
"assert!(range.contains(5));",
"assert!(range.contains(10));",
"assert!(!range.contains(20));",
"",
"assert!(range is std::ops::RangeInclusive);",
"```",
"",
"Ranges can contain any type:",
"",
"```rune",
"let range = 'a'..='f';",
"assert_eq!(range.start, 'a');",
"range.start = 'b';",
"assert_eq!(range.start, 'b');",
"assert_eq!(range.end, 'f');",
"range.end = 'g';",
"assert_eq!(range.end, 'g');",
"```",
"",
"Certain ranges can be used as iterators:",
"",
"```rune",
"let range = 'a'..='e';",
"assert_eq!(range.iter().collect::<Vec>(), ['a', 'b', 'c', 'd', 'e']);",
"```",
]);
m.field_function(Protocol::GET, "start", |r: &RangeInclusive| r.start.clone())?;
m.field_function(
Protocol::SET,
"start",
|r: &mut RangeInclusive, value: Value| {
r.start = value;
},
)?;
m.field_function(Protocol::GET, "end", |r: &RangeInclusive| r.end.clone())?;
m.field_function(
Protocol::SET,
"end",
|r: &mut RangeInclusive, value: Value| {
r.end = value;
},
)?;
m.function_meta(RangeInclusive::iter__meta)?;
m.function_meta(RangeInclusive::contains__meta)?;
m.function_meta(RangeInclusive::into_iter__meta)?;
Expand All @@ -150,40 +43,6 @@ pub fn module() -> Result<Module, ContextError> {

{
m.ty::<RangeToInclusive>()?;
m.type_meta::<RangeToInclusive>()?
.make_named_struct(&["end"])?
.docs([
"Type for an inclusive range expression `..=end`.",
"",
"# Examples",
"",
"```rune",
"let range = ..=10;",
"assert!(range.contains(-10));",
"assert!(range.contains(5));",
"assert!(range.contains(10));",
"assert!(!range.contains(20));",
"",
"assert!(range is std::ops::RangeToInclusive);",
"```",
"",
"Ranges can contain any type:",
"",
"```rune",
"let range = ..='f';",
"assert_eq!(range.end, 'f');",
"range.end = 'g';",
"assert_eq!(range.end, 'g');",
"```",
]);
m.field_function(Protocol::GET, "end", |r: &RangeToInclusive| r.end.clone())?;
m.field_function(
Protocol::SET,
"end",
|r: &mut RangeToInclusive, value: Value| {
r.end = value;
},
)?;
m.function_meta(RangeToInclusive::contains__meta)?;
m.function_meta(RangeToInclusive::partial_eq__meta)?;
m.function_meta(RangeToInclusive::eq__meta)?;
Expand All @@ -193,36 +52,6 @@ pub fn module() -> Result<Module, ContextError> {

{
m.ty::<RangeTo>()?;
m.type_meta::<RangeTo>()?
.make_named_struct(&["end"])?
.docs([
"Type for an inclusive range expression `..end`.",
"",
"# Examples",
"",
"```rune",
"let range = ..10;",
"assert!(range.contains(-10));",
"assert!(range.contains(5));",
"assert!(!range.contains(10));",
"assert!(!range.contains(20));",
"",
"assert!(range is std::ops::RangeTo);",
"```",
"",
"Ranges can contain any type:",
"",
"```rune",
"let range = ..'f';",
"assert_eq!(range.end, 'f');",
"range.end = 'g';",
"assert_eq!(range.end, 'g');",
"```",
]);
m.field_function(Protocol::GET, "end", |r: &RangeTo| r.end.clone())?;
m.field_function(Protocol::SET, "end", |r: &mut RangeTo, value: Value| {
r.end = value;
})?;
m.function_meta(RangeTo::contains__meta)?;
m.function_meta(RangeTo::partial_eq__meta)?;
m.function_meta(RangeTo::eq__meta)?;
Expand All @@ -232,50 +61,6 @@ pub fn module() -> Result<Module, ContextError> {

{
m.ty::<Range>()?;
m.type_meta::<Range>()?
.make_named_struct(&["start", "end"])?
.docs([
"Type for a range expression `start..end`.",
"",
"# Examples",
"",
"```rune",
"let range = 0..10;",
"assert!(!range.contains(-10));",
"assert!(range.contains(5));",
"assert!(!range.contains(10));",
"assert!(!range.contains(20));",
"",
"assert!(range is std::ops::Range);",
"```",
"",
"Ranges can contain any type:",
"",
"```rune",
"let range = 'a'..'f';",
"assert_eq!(range.start, 'a');",
"range.start = 'b';",
"assert_eq!(range.start, 'b');",
"assert_eq!(range.end, 'f');",
"range.end = 'g';",
"assert_eq!(range.end, 'g');",
"```",
"",
"Certain ranges can be used as iterators:",
"",
"```rune",
"let range = 'a'..'e';",
"assert_eq!(range.iter().collect::<Vec>(), ['a', 'b', 'c', 'd']);",
"```",
]);
m.field_function(Protocol::GET, "start", |r: &Range| r.start.clone())?;
m.field_function(Protocol::SET, "start", |r: &mut Range, value: Value| {
r.start = value;
})?;
m.field_function(Protocol::GET, "end", |r: &Range| r.end.clone())?;
m.field_function(Protocol::SET, "end", |r: &mut Range, value: Value| {
r.end = value;
})?;
m.function_meta(Range::iter__meta)?;
m.function_meta(Range::into_iter__meta)?;
m.function_meta(Range::contains__meta)?;
Expand All @@ -286,51 +71,10 @@ pub fn module() -> Result<Module, ContextError> {
}

{
m.ty::<ControlFlow>()?.docs([
" Used to tell an operation whether it should exit early or go on as usual.",
"",
" This acts as the basis of the [`TRY`] protocol in Rune.",
"",
" [`TRY`]: crate::Protocol::TRY",
"",
"# Examples",
"",
"```rune",
"use std::ops::ControlFlow;",
"",
"let c = ControlFlow::Continue(42);",
"assert_eq!(c.0, 42);",
"assert_eq!(c, ControlFlow::Continue(42));",
"```",
]);
m.ty::<ControlFlow>()?;
}

m.ty::<Function>()?.docs([
"The type of a function in Rune.",
"",
"Functions can be called using call expression syntax, such as `<expr>()`.",
"",
"There are multiple different kind of things which can be coerced into a function in Rune:",
"* Regular functions.",
"* Closures (which might or might not capture their environment).",
"* Built-in constructors for tuple types (tuple structs, tuple variants).",
"",
"# Examples",
"",
"```rune",
"// Captures the constructor for the `Some(<value>)` tuple variant.",
"let build_some = Some;",
"assert_eq!(build_some(42), Some(42));",
"",
"fn build(value) {",
" Some(value)",
"}",
"",
"// Captures the function previously defined.",
"let build_some = build;",
"assert_eq!(build_some(42), Some(42));",
"```",
]);
m.ty::<Function>()?;

{
m.ty::<Generator<Vm>>()?.docs([
Expand Down
12 changes: 11 additions & 1 deletion crates/rune/src/runtime/control_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,17 @@ use crate::Any;
///
/// This acts as the basis of the [`TRY`] protocol in Rune.
///
/// [`TRY`]: crate::Protocol::TRY
/// [`TRY`]: crate::runtime::Protocol::TRY
///
/// # Examples
///
/// ```rune
/// use std::ops::ControlFlow;
///
/// let c = ControlFlow::Continue(42);
/// assert_eq!(c.0, 42);
/// assert_eq!(c, ControlFlow::Continue(42));
/// ```
#[derive(Debug, Clone, Any)]
#[rune(builtin)]
pub enum ControlFlow {
Expand Down
43 changes: 32 additions & 11 deletions crates/rune/src/runtime/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,44 @@ use core::future::Future;
use crate::no_std::prelude::*;
use crate::no_std::sync::Arc;

use crate::compile::Named;
use crate::module::{self, InstallWith};
use crate as rune;
use crate::module;
use crate::runtime::{
Args, Call, ConstValue, FromValue, FunctionHandler, OwnedTuple, RawStr, Rtti, RuntimeContext,
Stack, Unit, Value, VariantRtti, Vm, VmCall, VmErrorKind, VmHalt, VmResult,
Args, Call, ConstValue, FromValue, FunctionHandler, OwnedTuple, Rtti, RuntimeContext, Stack,
Unit, Value, VariantRtti, Vm, VmCall, VmErrorKind, VmHalt, VmResult,
};
use crate::shared::AssertSend;
use crate::Any;
use crate::Hash;

/// A callable non-sync function.
/// The type of a function in Rune.
///
/// Functions can be called using call expression syntax, such as `<expr>()`.
///
/// There are multiple different kind of things which can be coerced into a
/// function in Rune:
/// * Regular functions.
/// * Closures (which might or might not capture their environment).
/// * Built-in constructors for tuple types (tuple structs, tuple variants).
///
/// # Examples
///
/// ```rune
/// // Captures the constructor for the `Some(<value>)` tuple variant.
/// let build_some = Some;
/// assert_eq!(build_some(42), Some(42));
///
/// fn build(value) {
/// Some(value)
/// }
///
/// // Captures the function previously defined.
/// let build_some = build;
/// assert_eq!(build_some(42), Some(42));
/// ```
#[derive(Any)]
#[repr(transparent)]
#[rune(builtin)]
pub struct Function(FunctionImpl<Value>);

impl Function {
Expand Down Expand Up @@ -909,12 +936,6 @@ impl FromValue for SyncFunction {
}
}

impl InstallWith for Function {}

impl Named for Function {
const BASE_NAME: RawStr = RawStr::from_str("Function");
}

from_value!(Function, into_function);

fn check_args(actual: usize, expected: usize) -> VmResult<()> {
Expand Down
Loading

0 comments on commit 7034356

Please sign in to comment.