Skip to content

Commit

Permalink
Added shorthand syntax for Rust objects in macros
Browse files Browse the repository at this point in the history
  • Loading branch information
bvssvni committed Jun 22, 2020
1 parent 73c21b8 commit 15c1d2e
Show file tree
Hide file tree
Showing 2 changed files with 203 additions and 13 deletions.
49 changes: 41 additions & 8 deletions examples/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,53 @@ dyon_fn!{fn origo() -> PhysicalState {
}}

// Create a custom Rust object.
dyon_fn!{fn custom_object() -> RustObject {
use std::sync::{Arc, Mutex};
dyon_fn!{fn custom_object() -> #i32 {42}}

let val: i32 = 42;
Arc::new(Mutex::new(val)) as RustObject
// Print out the content of a custom Rust object.
dyon_fn!{fn print_custom_object(a: #i32) {
println!("Custom value is {}", a);
}}

// Print out the content of a custom Rust object.
dyon_fn!{fn print_custom_object(obj: RustObject) {
let a_guard = obj.lock().unwrap();
let a = a_guard.downcast_ref::<i32>().unwrap();
// Macro example.
dyon_fn!{fn foo1(a: #i32, _b: f64) {
println!("Custom value is {}", a);
}}

// Macro example.
dyon_fn!{fn foo2(a: #i32, b: f64) -> f64 {
a as f64 + b
}}

// Macro example.
dyon_fn!{fn foo3(a: #&i32, b: f64) -> f64 {
*a as f64 + b
}}

// Macro example.
dyon_fn!{fn foo4(a: #&i32, b: #&i32) -> #i32 {
a + b
}}

// Macro example.
dyon_fn!{fn foo5(a: #&i32, b: f64) -> #f64 {
*a as f64 + b
}}

// Macro example.
dyon_fn!{fn foo6(a: f64) -> #i32 {
a as i32
}}

// Macro example.
dyon_fn!{fn foo7(a: #&i32) -> f64 {
*a as f64
}}

// Macro example.
dyon_fn!{fn foo8(a: #&mut f64, b: f64) {
*a = b
}}

dyon_fn!{fn id() -> Mat4 {
[
[1.0, 0.0, 0.0, 0.0],
Expand Down
167 changes: 162 additions & 5 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,43 @@ macro_rules! dyon_macro_items { ($($x:item)+) => ($($x)+) }
/// This macro is used by some other Dyon macros.
#[macro_export]
macro_rules! dyon_fn_pop {
(#&mut $rt:ident) => {};
(#&mut $rt:ident $arg:ident : $t:ty) => {
let $arg: RustObject = $rt.pop()?;
let mut $arg = $arg.lock().unwrap();
let $arg = $arg.downcast_mut::<$t>().unwrap();
};
(#&mut $rt:ident $arg:ident : $t:ty, $($args:tt : $ts:ty),+) => {
dyon_fn_pop!(#&mut $rt $($args: $ts),+);
let $arg: RustObject = $rt.pop()?;
let mut $arg = $arg.lock().unwrap();
let $arg = $arg.downcast_mut::<$t>().unwrap();
};
(#& $rt:ident) => {};
(#& $rt:ident $arg:ident : $t:ty) => {
let $arg: RustObject = $rt.pop()?;
let $arg = $arg.lock().unwrap();
let $arg = $arg.downcast_ref::<$t>().unwrap();
};
(#& $rt:ident $arg:ident : $t:ty, $($args:tt : $ts:ty),+) => {
dyon_fn_pop!(#& $rt $($args: $ts),+);
let $arg: RustObject = $rt.pop()?;
let $arg = $arg.lock().unwrap();
let $arg = $arg.downcast_ref::<$t>().unwrap();
};
(# $rt:ident) => {};
(# $rt:ident $arg:ident : $t:ty) => {
let $arg: RustObject = $rt.pop()?;
let $arg = $arg.lock().unwrap();
let $arg = *$arg.downcast_ref::<$t>().unwrap();
};
(# $rt:ident $arg:ident : $t:ty, $($args:tt : $ts:ty),+) => {
dyon_fn_pop!(# $rt $($args: $ts),+);
let $arg: RustObject = $rt.pop()?;
let $arg = $arg.lock().unwrap();
let $arg = *$arg.downcast_ref::<$t>().unwrap();
};
($rt:ident) => {};
($rt:ident $arg:ident : $t:ty) => {
let $arg: $t = $rt.pop()?;
};
Expand All @@ -22,26 +59,102 @@ macro_rules! dyon_fn_pop {
/// For example, see "examples/functions.rs".
#[macro_export]
macro_rules! dyon_fn {
(fn $name:ident () -> $rt:ty $b:block) => {
(fn $name:ident () -> # $rt:ty $b:block) => {
#[allow(non_snake_case)]
pub fn $name(_rt: &mut $crate::Runtime) -> Result<$crate::Variable, String> {
use std::sync::{Arc, Mutex};

fn inner() -> $rt {
$b
}

Ok($crate::embed::PushVariable::push_var(&inner()))
Ok($crate::Variable::RustObject(Arc::new(Mutex::new(inner())) as RustObject))
}
};
(fn $name:ident ($($rust_arg:tt : #&$rust_t:ty),+) -> # $rt:ty $b:block) => {
dyon_macro_items!{
#[allow(non_snake_case)]
pub fn $name(rt: &mut $crate::Runtime) -> Result<$crate::Variable, String> {
use std::sync::{Arc, Mutex};

fn inner($($rust_arg: &$rust_t),+) -> $rt {
$b
}

dyon_fn_pop!(#& rt $($rust_arg: $rust_t),+);
Ok($crate::Variable::RustObject(Arc::new(Mutex::new(inner($($rust_arg),+)))))
}
}
};
(fn $name:ident ($rust_arg:tt : #&$rust_t:ty, $($arg:tt : $t:ty),+) -> # $rt:ty $b:block) => {
dyon_macro_items!{
#[allow(non_snake_case)]
pub fn $name(rt: &mut $crate::Runtime) -> Result<$crate::Variable, String> {
use std::sync::{Arc, Mutex};

fn inner($rust_arg: &$rust_t, $($arg: $t),+) -> $rt {
$b
}

dyon_fn_pop!(#& rt $rust_arg: $rust_t);
dyon_fn_pop!(rt $($arg: $t),+);
Ok($crate::Variable::RustObject(Arc::new(Mutex::new(inner($rust_arg, $($arg),+)))))
}
}
};
(fn $name:ident ($rust_arg:tt : #&$rust_t:ty $(, $arg:tt : $t:ty),*) -> $rt:ty $b:block) => {
dyon_macro_items!{
#[allow(non_snake_case)]
pub fn $name(rt: &mut $crate::Runtime) -> Result<$crate::Variable, String> {
fn inner($rust_arg: &$rust_t $(, $arg: $t),*) -> $rt {
$b
}

dyon_fn_pop!(#& rt $rust_arg: $rust_t);
dyon_fn_pop!(rt $($arg: $t),*);
Ok($crate::embed::PushVariable::push_var(&inner($rust_arg, $($arg),*)))
}
}
};
(fn $name:ident ($($arg:tt : $t:ty),+) -> $rt:ty $b:block) => {
(fn $name:ident ($rust_arg:tt : #$rust_t:ty, $($arg:tt : $t:ty),+) -> $rt:ty $b:block) => {
dyon_macro_items!{
#[allow(non_snake_case)]
pub fn $name(rt: &mut $crate::Runtime) -> Result<$crate::Variable, String> {
fn inner($($arg: $t),+) -> $rt {
fn inner($rust_arg: $rust_t, $($arg: $t),+) -> $rt {
$b
}

dyon_fn_pop!(# rt $rust_arg: $rust_t);
dyon_fn_pop!(rt $($arg: $t),+);
Ok($crate::embed::PushVariable::push_var(&inner($($arg),+)))
Ok($crate::embed::PushVariable::push_var(&inner($rust_arg, $($arg),+)))
}
}
};
(fn $name:ident ($($arg:tt : $t:ty),*) -> # $rt:ty $b:block) => {
dyon_macro_items!{
#[allow(non_snake_case)]
pub fn $name(rt: &mut $crate::Runtime) -> Result<$crate::Variable, String> {
use std::sync::{Arc, Mutex};

fn inner($($arg: $t),*) -> $rt {
$b
}

dyon_fn_pop!(rt $($arg: $t),*);
Ok($crate::Variable::RustObject(Arc::new(Mutex::new(inner($($arg),*)))))
}
}
};
(fn $name:ident ($($arg:tt : $t:ty),*) -> $rt:ty $b:block) => {
dyon_macro_items!{
#[allow(non_snake_case)]
pub fn $name(_rt: &mut $crate::Runtime) -> Result<$crate::Variable, String> {
fn inner($($arg: $t),*) -> $rt {
$b
}

dyon_fn_pop!(_rt $($arg: $t),*);
Ok($crate::embed::PushVariable::push_var(&inner($($arg),*)))
}
}
};
Expand All @@ -56,6 +169,50 @@ macro_rules! dyon_fn {
Ok(())
}
};
(fn $name:ident ($($arg:tt : #$t:ty),+) $b:block) => {
dyon_macro_items!{
#[allow(non_snake_case)]
pub fn $name(rt: &mut $crate::Runtime) -> Result<(), String> {
fn inner($($arg: $t),+) {
$b
}

dyon_fn_pop!(# rt $($arg: $t),+);
inner($($arg),+);
Ok(())
}
}
};
(fn $name:ident ($rust_arg:tt : #&mut $rust_ty:ty , $($arg:tt : $t:ty),*) $b:block) => {
dyon_macro_items!{
#[allow(non_snake_case)]
pub fn $name(rt: &mut $crate::Runtime) -> Result<(), String> {
fn inner($rust_arg: &mut $rust_ty, $($arg: $t),*) {
$b
}

dyon_fn_pop!(#&mut rt $rust_arg: $rust_ty);
dyon_fn_pop!(rt $($arg: $t),*);
inner($rust_arg, $($arg),+);
Ok(())
}
}
};
(fn $name:ident ($rust_arg:tt : # $rust_ty:ty , $($arg:tt : $t:ty),*) $b:block) => {
dyon_macro_items!{
#[allow(non_snake_case)]
pub fn $name(rt: &mut $crate::Runtime) -> Result<(), String> {
fn inner($rust_arg: $rust_ty, $($arg: $t),*) {
$b
}

dyon_fn_pop!(# rt $rust_arg: $rust_ty);
dyon_fn_pop!(rt $($arg: $t),*);
inner($rust_arg, $($arg),+);
Ok(())
}
}
};
(fn $name:ident ($($arg:tt : $t:ty),+) $b:block) => {
dyon_macro_items!{
#[allow(non_snake_case)]
Expand Down

0 comments on commit 15c1d2e

Please sign in to comment.