Skip to content

Instantly share code, notes, and snippets.

Created June 24, 2015 09:02
Show Gist options
  • Save anonymous/cb61ee487c4c8ed63cd8 to your computer and use it in GitHub Desktop.
Save anonymous/cb61ee487c4c8ed63cd8 to your computer and use it in GitHub Desktop.
Shared via Rust Playground
#![allow(unused_mut, non_camel_case_types, dead_code, unused_variables)]
#![feature(trace_macros)]
use std::fmt::{self, Debug};
/*macro_rules! using {
[ $pp:path : ( $($elem:ident),* )
] => [
use $pp :: {self, $(elem),*};
];
}
using!{ std::fmt : (Debug) }*/
macro_rules! make_overloadable {
[ fn $fn_name:ident();
] => [
trait $fn_name {
type ReturnType;
fn $fn_name( &self ) -> Self::ReturnType;
}
];
/*[ fn $fn_name() -> void;
] => [
trait $fn_name {
type ReturnType;
fn $fn_name( &self );
}
];*/
}
//trait OVERLOADED_GENERIC_FUNCTIONS {}
macro_rules! overload_impl {
/*[ {$($func:tt)*} :: [ $($all:tt)* ] :: , $t:ident: $($trs:tt)*
] => [
overload_impl!{ {$($func)*} :: [ $($all)*, $t: ] :: $($trs)* }
];*/
[ {$($func:tt)*} :: [ $($all:tt)* ] :: , $t:ident $($trs:tt)*
] => [
overload_impl!{ {$($func)*} :: [ $($all)*, $t ] :: $($trs)* }
];
[ {$($func:tt)*} :: [ $($all:tt)* ] :: : !$tr:ident $($trs:tt)*
] => [
overload_impl!{ {$($func)*} :: [ $($all)* : !$tr ] :: $($trs)* }
];
[ {$($func:tt)*} :: [ $($all:tt)* ] :: : $tr:ident $($trs:tt)*
] => [
overload_impl!{ {$($func)*} :: [ $($all)* : $tr ] :: $($trs)* }
];
[ {$($func:tt)*} :: [ $($all:tt)* ] :: + !$tr:ident $($trs:tt)*
] => [
overload_impl!{ {$($func)*} :: [ $($all)* + !$tr ] :: $($trs)* }
];
[ {$($func:tt)*} :: [ $($all:tt)* ] :: + $tr:ident $($trs:tt)*
] => [
overload_impl!{ {$($func)*} :: [ $($all)* + $tr ] :: $($trs)* }
];
[ {$func:ident; ($( $arg:ident : $typ:ty ),+); $ret:ty => $body:block} :: [ $($all:tt)* ] :: ;
] => [
impl< $($all)* > $func for ( $( $typ ),+ ) {
type ReturnType = $ret;
fn $func ( &self ) -> $ret
{
let & ( $( ref $arg ),+ ) = self;
$body
}
}
];
[ {$func:ident; ($( $arg:ident : $typ:ty ),+); $ret:ty => $body:block} | $t:ident
] => [
impl< $t > $func for ( $( $typ ),+ ) {
type ReturnType = $ret;
fn $func ( &self ) -> $ret
{
let & ( $( ref $arg ),+ ) = self;
$body
}
}
];
[ {$($func:tt)*} | $t:ident, $($trs:tt)*
] => [
overload_impl!{ {$($func)*} :: [ $t, ] :: $($trs)*; }
];
[ {$($func:tt)*} | $t:ident, $($trs:tt)*
] => [
overload_impl!{ {$($func)*} :: [ $t, ] :: $($trs)*; }
];
[ {$($func:tt)*} | $t:ident : $tr:ident $($trs:tt)*
] => [
overload_impl!{ {$($func)*} :: [ $t : $tr ] :: $($trs)*; }
];
[ {$($func:tt)*} | $t:ident : ! $tr:ident $($trs:tt)*
] => [
overload_impl!{ {$($func)*} :: [ $t : ! $tr ] :: $($trs)*; }
];
[ $implementation:item ] => [ $implementation ];
}
trace_macros!(true);
macro_rules! overload {
( [ $( $t:ident $(:$tr:ident)+ ),* ]
fn $func:ident( $( $arg:ident : $typ:ident ),+ ) $body:block
) => [
impl< $( $t : $( $tr +)+ ),* > $func for ( $( $typ ),+ ) {
type ReturnType = ();
fn $func ( &self )
{
let & ( $( ref $arg ),+ ) = self;
$body
}
}
];
( [ $( $t:ident $(:$tr:ident)+ ),* ]
fn $func:ident( $( $arg:ident : $typ:ident ),+ ) -> $ret:ty => $body:block
) => [
impl< $( $t : $( $tr +)+ ),* > $func for ( $( $typ ),+ ) {
type ReturnType = $ret;
fn $func ( &self ) -> $ret
{
let & ( $( ref $arg ),+ ) = self;
$body
}
}
];
(
fn $func:ident( $( $arg:ident : $typ:ty ),+ )
[ $( $T1:ident $(.$tr:ident)* ),* ]
// older syntax
/*[ $($T0:ident.)* ] [ $( #$T1:ident $(+$tr:ident)* );* ]*/
$body:block
) => [
impl
<
/*$($T0),*/
$( $T1 : $( $tr +)* ),*
> $func for ( $( $typ ),+ ) {
type ReturnType = ();
fn $func ( &self )
{
let & ( $( ref $arg ),+ ) = self;
$body
}
}
];
(
fn $func:ident( $( $arg:ident : $typ:ty ),+ ) -> $ret:ty
/*[ $($T0:ident.)* ]*/ [$($generics:tt)*]//[ $( $T1:ident $(.$tr:tt)* );* ]
$body:block
) => [
/*impl
<
//expand_gens!{
$($generics)*
/*$($T0),*/
//$( $T1 : $( $tr +)* ),*
> $func for ( $( $typ ),+ ) {
{
type ReturnType = $ret;
fn $func ( &self ) -> $ret
{
let & ( $( ref $arg ),+ ) = self;
$body
}
}*/
overload_impl!{ {$func; ($( $arg : $typ ),+); $ret => $body} | $($generics)* }
];
}
make_overloadable! {
fn mk();
}
overload! {
fn mk( s: (T, bool), g: G ) -> (bool, u8)
[ T: Debug, G: !Debug + Copy ]
{
println!("{:?}'tup;
| {:?}", s, g);
(false, 9)
}
}//
/*
```{.rust}
haskell! {
mk :: U: Debug, Copy => () -> () {
}
}
```
*/
overload! {
[]fn mk( s: char, g: i32, c: char )
{
println!("{}; {:?}", s, g);
}
}
fn mk<U: fmt::Debug + Copy>(s: i32, g: U) -> bool {
println!("{}; {:?}", s, g);
false
}
fn main() {
println!("Hello, world!");
mk(32, 'a');
((42, false), 'Z').mk();
('F', 63, 'x').mk();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment