Skip to content

Commit

Permalink
Simplify how variants are handled (#877)
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog authored Nov 3, 2024
1 parent 276bfb6 commit 6b31eda
Show file tree
Hide file tree
Showing 55 changed files with 1,760 additions and 2,481 deletions.
8 changes: 8 additions & 0 deletions crates/rune-alloc/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Error types used by rune alloc.
use core::alloc::LayoutError;
use core::convert::Infallible;
use core::fmt;

Expand Down Expand Up @@ -65,6 +66,13 @@ impl From<Infallible> for Error {
}
}

impl From<LayoutError> for Error {
#[inline]
fn from(_: LayoutError) -> Self {
Error::LayoutError
}
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Expand Down
4 changes: 1 addition & 3 deletions crates/rune-core/src/item/component_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ pub enum ComponentRef<'a> {
}

impl<'a> ComponentRef<'a> {
/// Get the component as a string.
#[cfg(feature = "doc")]
#[doc(hidden)]
/// Get the component as a `&str` reference.
pub fn as_str(&self) -> Option<&'a str> {
match self {
ComponentRef::Str(string) => Some(string),
Expand Down
8 changes: 8 additions & 0 deletions crates/rune-core/src/item/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,14 @@ impl Item {
self.iter().next_back()
}

/// Access the base name of the item if available.
///
/// The base name is the last string component of the item.
#[inline]
pub fn base_name(&self) -> Option<&str> {
self.iter().next_back()?.as_str()
}

/// An iterator over the [Component]s that constitute this item.
///
/// # Examples
Expand Down
2 changes: 0 additions & 2 deletions crates/rune-macros/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,6 @@ impl Context {
value_mut_guard: path(m, ["runtime", "ValueMutGuard"]),
value_ref_guard: path(m, ["runtime", "ValueRefGuard"]),
value: path(m, ["runtime", "Value"]),
variant_data: path(m, ["runtime", "VariantData"]),
vec: path(m, ["alloc", "Vec"]),
vm_result: path(m, ["runtime", "VmResult"]),
vm_try: path(m, ["vm_try"]),
Expand Down Expand Up @@ -870,7 +869,6 @@ pub(crate) struct Tokens {
pub(crate) value_mut_guard: syn::Path,
pub(crate) value_ref_guard: syn::Path,
pub(crate) value: syn::Path,
pub(crate) variant_data: syn::Path,
pub(crate) vec: syn::Path,
pub(crate) vm_result: syn::Path,
pub(crate) vm_try: syn::Path,
Expand Down
43 changes: 23 additions & 20 deletions crates/rune-macros/src/from_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl Expander<'_> {
#[automatically_derived]
impl #from_value for #ident {
fn from_value(value: #value) -> #result<Self, #runtime_error> {
match #value::into_type_value(value)? {
match #value::as_type_value(&value)? {
#expanded
actual => {
#result::Err(#runtime_error::expected::<#expected>(#type_value::type_info(&actual)))
Expand All @@ -104,7 +104,6 @@ impl Expander<'_> {
let Tokens {
type_value,
from_value,
variant_data,
value,
result,
runtime_error,
Expand Down Expand Up @@ -145,27 +144,31 @@ impl Expander<'_> {
};

let variant = quote! {
#type_value::Variant(variant) => {
let mut it = variant.rtti().item.iter();
#type_value::EmptyStruct(data) => {
let Some(name) = data.rtti().item().base_name() else {
return #result::Err(#runtime_error::__rune_macros__missing_variant_name());
};

let Some(name) = it.next_back_str() else {
match name {
#(#unit_matches,)* #missing,
}
}
#type_value::TupleStruct(tuple) => {
let Some(name) = tuple.rtti().item().base_name() else {
return #result::Err(#runtime_error::__rune_macros__missing_variant_name());
};

match variant.data() {
#variant_data::Empty => match name {
#(#unit_matches,)* #missing,
},
#variant_data::Tuple(tuple) => match name {
#(#unnamed_matches,)* #missing,
},
#variant_data::Struct(data) => {
let object = variant.accessor(data);

match name {
#(#named_matches,)* #missing,
}
}
match name {
#(#unnamed_matches,)* #missing,
}
}
#type_value::Struct(object) => {
let Some(name) = object.rtti().item().base_name() else {
return #result::Err(#runtime_error::__rune_macros__missing_variant_name());
};

match name {
#(#named_matches,)* #missing,
}
}
};
Expand All @@ -174,7 +177,7 @@ impl Expander<'_> {
#[automatically_derived]
impl #from_value for #ident {
fn from_value(value: #value) -> #result<Self, #runtime_error> {
match #value::into_type_value(value)? {
match #value::as_type_value(&value)? {
#variant,
actual => {
#result::Err(#runtime_error::__rune_macros__expected_variant(#type_value::type_info(&actual)))
Expand Down
116 changes: 116 additions & 0 deletions crates/rune/benches/bf.rn
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
enum Op {
Inc(v),
Move(v),
Loop(ops),
Input,
Print,
}

struct Tape {
pos,
tape,
}

impl Tape {
fn new() {
Tape { pos: 0, tape: [0] }
}

fn get(self) {
self.tape[self.pos]
}

fn inc(self, x) {
self.tape[self.pos] = (self.tape[self.pos] + x) % 256;

if self.tape[self.pos] < 0 {
self.tape[self.pos] = self.tape[self.pos] + 256;
}
}

fn mov(self, x) {
self.pos += x;

while self.pos >= self.tape.len() {
self.tape.push(0);
}
}

fn set(self, v) {
self.tape[self.pos] = v;
}
}

fn run(program, tape, inputs) {
for op in program {
match op {
Op::Inc(x) => tape.inc(x),
Op::Move(x) => tape.mov(x),
Op::Loop(program) => while tape.get() != 0 {
run(program, tape, inputs);
},
Op::Print => {
let c = char::from_i64(tape.get()).expect("A valid char");
print!("{c}");
}
Op::Input => {
tape.set(0)
}
}
}
}

fn parse(it) {
let buf = Vec::new();

while let Some(c) = it.next() {
let op = match c {
'+' => Op::Inc(1),
'-' => Op::Inc(-1),
'>' => Op::Move(1),
'<' => Op::Move(-1),
'.' => Op::Print,
'[' => Op::Loop(parse(it)),
',' => Op::Input,
']' => break,
_ => continue,
};

buf.push(op);
}

buf
}

struct Program {
ops,
inputs,
}

impl Program {
fn new(code, inputs) {
Program { ops: parse(code), inputs }
}

fn run(self) {
let tape = Tape::new();
run(self.ops, tape, self.inputs);
}
}

fn bf(s, i) {
let program = Program::new(s.chars(), i);
program.run();
}

#[bench]
pub fn bf_hello_world(b) {
b.iter(
|| {
bf(
"++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.",
0,
)
},
)
}
17 changes: 17 additions & 0 deletions crates/rune/benches/fib.rn
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
fn fib(n) {
if n <= 1 {
n
} else {
fib(n - 2) + fib(n - 1)
}
}

#[bench]
pub fn fib15(b) {
b.iter(|| fib(15));
}

#[bench]
pub fn fib20(b) {
b.iter(|| fib(20));
}
31 changes: 31 additions & 0 deletions crates/rune/benches/primes.rn
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const MAX_NUMBER_TO_CHECK = 10_000;

#[bench]
pub fn primes(b) {
b.iter(
|| {
let prime_mask = [];

prime_mask.resize(MAX_NUMBER_TO_CHECK, true);

prime_mask[0] = false;
prime_mask[1] = false;

let total_primes_found = 0;

for p in 2..MAX_NUMBER_TO_CHECK {
if prime_mask[p] {
total_primes_found += 1;
let i = 2 * p;

while i < MAX_NUMBER_TO_CHECK {
prime_mask[i] = false;
i += p;
}
}
}

total_primes_found
},
);
}
Loading

0 comments on commit 6b31eda

Please sign in to comment.