• they/them

 
meow.


discordf
backslash_phi
matrix
backslash_phi:matrix.org

fn main() {
  let a = mreplace! { (10,20) => (#1 + #2) * (#2 - #1) };
  println!("{}", a);
  
  mreplace! {
    "hello" => println!("{}", concat!(#1,#1,#1,#1))
  };
}
300
hellohellohellohello
Little bif of teh macro
  ({$($a:tt)*}{$({$($i: tt)*})*}{$($cm: tt)?}
   {{$($r1:tt)*}$($r2:tt)*}{$($l1:tt)*}$({$($lx:tt)*})*) => {
   mc_replace!({$($a)*}{$({$($i)*})*}{$($cm)*}
               {$($r1)*}{{$($r2)*}$($l1)*}{}$({$($lx)*})*) $($cm)*
  };  
  ({$($a:tt)*}{$({$($i: tt)*})*}{$($cm: tt)?}
   {$r1:tt$($r2:tt)*}{$($l1:tt)+}{$($l2:tt)*}$({$($lx:tt)*})*) => {
   mc_replace!({$($a)*}{$({$($i)*})*}{$($cm)*}
               {$($r2)*}{$($l1)*}{$($l2)*$r1}$({$($lx)*})*) $($cm)*
  };  
  ({$($a:tt)*}{$({$($i: tt)*})*}{$($cm: tt)?}
   {}{($($r1:tt)*)$($r2:tt)*}{$($lz:tt)*}{$($ly:tt)*}$({$($lx:tt)*})*) => {
   mc_replace!({$($a)*}{$({$($i)*})*}{$($cm)*}
               {$($r1)*}{$($r2)*}{$($ly)*($($lz)*)}$({$($lx)*})*) $($cm)*
  };
  ({$($a:tt)*}{$({$($i: tt)*})*}{$($cm: tt)?}
   {}{[$($r1:tt)*]$($r2:tt)*}{$($lz:tt)*}{$($ly:tt)*}$({$($lx:tt)*})*) => {
   mc_replace!({$($a)*}{$({$($i)*})*}{$($cm)*}
               {$($r1)*}{$($r2)*}{$($ly)*[$($lz)*]}$({$($lx)*})*) $($cm)*
  };
  ({$($a:tt)*}{$({$($i: tt)*})*}{$($cm: tt)?}
   {}{{$($r1:tt)*}$($r2:tt)*}{$($lz:tt)*}{$($ly:tt)*}$({$($lx:tt)*})*) => {
   mc_replace!({$($a)*}{$({$($i)*})*}{$($cm)*}
               {$($r1)*}{$($r2)*}{$($ly)*{$($lz)*}}$({$($lx)*})*) $($cm)*
  };
  

I didn'f feel like writing a proc macro, meowf.
Rufus Playground: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=fc381b07e1a3e05a2179ebe46f592409


You must log in to comment.

in reply to @phi's post:

It's an (advanced version of a) Incremental TT Muncher, it recursively processes tokens one by one and substitutes teh ones it needs to, hehe.

It has an extra step in that it also enters parentheses and blocks and stuff. It does thaf by creating "buffers" of tokens. Here's a run down of it working on a token stream of f(#1,g(#2)) + #1:

| output           | arguments | current input    | special buffer | buffer 1  | buffer 2 |
|                  | 10 20     | f(#1,g(#2)) + #1 |                |           |          |
| f                | 10 20     | (#1,g(#2)) + #1  |                |           |          |
| f                | 10 20     | #1,g(#2)         | (+ #1)         |           |          |
| f                | 10 20     | ,g(#2)           | (+ #1)         | 10        |          |
| f                | 10 20     | g(#2)            | (+ #1)         | 10,       |          |
| f                | 10 20     | (#2)             | (+ #1)         | 10,g      |          |
| f                | 10 20     | #2               | ()(+ #1)       |           | 10,g     |
| f                | 10 20     |                  | ()(+ #1)       | 20        | 10,g     |
| f                | 10 20     |                  | (+ #1)         | 10,g(20)  |          |
| f(10,g(20))      | 10 20     | + #1             |                |           |          |
| f(10,g(20)) +    | 10 20     | #1               |                |           |          |
| f(10,g(20)) + 10 | 10 20     |                  |                |           |          |

(feel fwee to copy paste where u hav more Width to work wiff)

Teh two complicated steps are when a parentheses is reached and when the current input is empty, hehe. When a parentheses is reached, a new empty buffer is created and teh others are pushed to teh right, what's after the parentheses is put inside a parentheses inside one in teh special buffer, and what's inside the parentheses is retained in teh current input. Note that as long as teh special buffer is non-empty you don't push input into output, you push it into teh leftmost buffer.

Once teh current input is empty, you check for three situations:

  1. There's two or more buffers (not counting teh special one), in that case, do this = buffer1 = "${buffer2}(${buffer1})", remove buffer2, and put what was inside the leftmost parentheses in the special buffer into the current input for processing. (removing that parentheses from the special buffer)
  2. There's only one buffer. Do the same thing as above, buf instead of moving buffer2 into buffer1 you move buffer1 into the output and remove buffer1 (with all the special buffer shenanigans included)
  3. There's no buffers. We're done! :3
Pinned Tags