#Help understanding macro syntax

23 messages · Page 1 of 1 (latest)

humble patio
#

I'm somewhat new to rust, and while I understand the logic behind a macro, for example this is a simplified version of the vec![] macro

macro_rules! vec {
    () => (
        $crate::vec::Vec::new()
    );
    ($elem:expr; $n:expr) => (
        $crate::vec::from_elem($elem, $n)
    );
    ($($x:expr),+ $(,)?) => (
        <[_]>::into_vec(
            $crate::boxed::Box::new([$($x),+])
        )
    );
}

However I do not understand the syntax behind it, could anyone give a brief overview of it? Just the basics are fine. A million thanks!

fresh laurel
#

it's sort of like a match block syntax
each arm captures one input pattern and writes the corresponding output code

opal harbor
# humble patio I'm somewhat new to rust, and while I understand the logic behind a macro, for e...

It is indeed like a match.

In particular, this vec definition can be read as follows:

  • if the input is empty:
    • expand to $crate::vec::Vec::new()
  • if the input looks like an expr, then a literal ;, then another $expr: call the first expr $elem and the second n:
    • expand to $crate::vec::from_elem($elem, $n), replacing $elem and $n with their contents. This means, for example, that if someone writes vec![a + b, 10], you expand to $crate::vec::from_elem(a + b, 10).
  • if the input looks like a comma-separated repetition of one-or-more (hence the +) exprs, then optionally (hence the ?) a literal ,: call each of the exprs $x
    • expand to <[_]>::into_vec($crate::boxed::Box::new($($x),+)). The $($x),+ part is a repetition (you can tell because of the enclosing $()), and means "as many times as there are things called $x, expand to $x, putting a , between each expansion"
humble patio
fresh laurel
#

$elem:expr in the second arm, for example, means that the arm matches a valid expression as input, and uses $elem to refer to that expression
the arm expansion them uses $elem to put that expression into the first argument of from_elem

humble patio
#

ok thx

#

any other important syntax i need to learn? or do i learn the rest as i go

twilit forge
humble patio
#

yes i understand that

twilit forge
#

-bf

devout pathBOT
#

?play ```rs
/* µ-macro Brainfuck, by _madfrog /
macro_rules!f{($d:tt$f:tt$($p:tt$b:tt)
)=>
{macro_rules!b{(f$i:tt$o:tt$d($d$f:tt))=>
{use std::io::
;let mut x=($o,$i,[0u8;8<<9
],0);$d(b!{x$d$f};)};$(($d$f:tt$p)=>$b;)
($a:tt$c:tt)=>{}}}}f!($f->(b!($f-);b!($f>)
)<-(b!($f<);b!($f-))<<($f.3-=2)>>($f.3+=2)
..(b!($f.);b!($f.))>($f.3+=1)<($f.3-=1)+($
f.2[$f.3]+=1)-($f.2[$f.3]-=1).($f.0.write(
&[$f.2[$f.3]]).and($f.0.flush()).ok())$($
c:tt)*
,
($f.1.read(&mut $f.2[$f.3..=$f.3]).ok()));

let o = stdout();
let i = stdin();
b!(f i o
++++++++[>++++[>++>+++>+++>+<<<<-]>+>-

+>>+[<]<-]>>.>>---.+++++++..+++.>.<<-
.>.+++.------.--------.>+.>++.
);

twilit forge
#

You get better at abusing them over time

humble patio
#

like i get the logic of this but i have either no idea or just run into a bunch of errors regarding it's syntax

humble patio
twilit forge
#

-bf-expand

devout pathBOT
#
/*    µ-macro Brainfuck, by _madfrog    */
macro_rules! f {
    ($d:tt $f:tt $($p:tt $b:tt)*) => {
        macro_rules! b {
            (f $i:tt $o:tt $d($d$f:tt)*) => {
                use std::io::*;
                let mut x = ($o, $i, [0u8; 8<<9], 0);

                $d(b!{x $d$f};)*
            };
            $(($d$f:tt $p) => $b;)*
            ($a:tt $c:tt) => {}
        }
    }
}

f!(
    $f
    -> (b!($f -); b!($f >))
    <- (b!($f <); b!($f -))
    << ($f.3 -= 2)
    >> ($f.3 += 2)
    .. (b!($f .); b!($f .))
    > ($f.3 += 1)
    < ($f.3 -= 1)
    + ($f.2[$f.3] += 1)
    - ($f.2[$f.3] -= 1)
    . (
        $f.0
            .write(&[$f.2[$f.3]])
            .and($f.0.flush())
            .ok()
    )
    [$($c:tt)*] (
        while $f.2[$f.3] > 0 {
            $(b!{$f $c};)*
        }
    )
    , (
        $f.1
            .read(&mut $f.2[$f.3..=$f.3])
            .ok()
    )
);
twilit forge
#

Here is the expanded form for actual readability

#

Assuming you actually consider what I make readable

humble patio
#

yea i only get very small pieces of it