GithubHelp home page GithubHelp logo

Comments (4)

kitlith avatar kitlith commented on September 2, 2024

in similar noodling: i think you could make gensym using macro_rules and paste if you can write a macro_rules! quine. because then you could write a macro that expands to itself + an extra character in the internal ident, then passing the current ident to a macro of the user's choosing. i've not been successful on the quine front yet, though, since i need to escape $ and i don't know how to preserve that through the quine.

from auroranssolis.github.io.

AuroransSolis avatar AuroransSolis commented on September 2, 2024

So yes this is a thing I realised you could do somewhat recently since macro defs shadow each other. However, this means that each time you want to test equality you're going to be doing two recursion steps, once to do the check and once more for a callback to whatever you want to happen on a true or false. As for preserving $, you can do that by passing it in as a token for use in expansion:

macro_rules! i_make_a_macro {
    ($give_me_a_dollar:tt) => {
        macro_rules! and_heres_that_macro {
            ($give_me_a_dollar tt:tt) => {
                println!(concat!("you gave me: `", stringify!($give_me_a_dollar tt), "`"));
            };
        }
    };
}

which is kind of annoying but sure whatever, it works.

from auroranssolis.github.io.

kitlith avatar kitlith commented on September 2, 2024

Yeah, I was using that, the issue is losing your escape values after your trip through the quine. The closest I got was this:

macro_rules! quine {
    () => { quine!($); };
    ($s:tt) => { quine!([$] ([$a:tt] $s ($s tt:tt)* ) => { macro_rules! quine {
        () => { quine!($); };
        ($s s:tt) => { quine!([$] $tt) }; // oops, i missed a repitition here to wrap the $tt
        $a tt
    }; }; ); };
    ([$a:tt] $($tt:tt)*) => {
        macro_rules! quine {
            () => { quine!($); };
            ($s:tt) => { quine!([$] $($tt)*); };
            $($tt)*
        }
    }
}

which expands to the following (after reformatting and annotating with the locations where it fails)

macro_rules! quine {
    () => { quine! ($); };
    // lost my escape here ------------\
    ($s:tt) => { quine!([$] ([$a : tt] $ ($tt : tt)*) => { macro_rules! quine {
        () => { quine! ($); };
    //   \/- lost an escape here
        ($s:tt) => { quine! ([$] $tt) };
        $a tt
    }; }; ); };
    ([$a:tt] $($tt:tt)*) => {
        macro_rules! quine {
            () => { quine!($); };
    // consequence of mistake earlier \/ -- might cause another escape lossage though
            ($s:tt) => { quine! ([$] $tt) };
            $a tt
        }; // extra semi-colon, probably easy to fix
    }; // ditto
}

it's probably possible and I just haven't spent enough time on figuring out how to tweak the escapes to be exactly correct. However, it actually wouldn't be useful, because if you do the following:

macro_rules! quine {
    () => { macro_rules! quine { () => {}; } };
}

quine!();
quine!();

you do get a compiler error talking about ambiguity:

error[E0659]: `quine` is ambiguous
  --> src/main.rs:64:1
   |
64 | quine!();
   | ^^^^^ ambiguous name
   |
   = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution
note: `quine` could refer to the macro defined here
  --> src/main.rs:60:13
   |
60 |     () => { macro_rules! quine { () => {}; } };
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
63 | quine!();
   | -------- in this macro invocation
note: `quine` could also refer to the macro defined here
  --> src/main.rs:59:1
   |
59 | / macro_rules! quine {
60 | |     () => { macro_rules! quine { () => {}; } };
61 | | }
   | |_^
   = note: this error originates in the macro `quine` (in Nightly builds, run with -Z macro-backtrace for more info)

and that still applies to cases like:

macro_rules! def_quine {
    () => {
        macro_rules! quine {
            () => {
                macro_rules! quine {
                    () => {}
                }
            }
        }
    }
}

def_quine!();
quine!();
quine!();

(which was my attempt at getting around the error by making both quines equally macro-generated)

from auroranssolis.github.io.

AuroransSolis avatar AuroransSolis commented on September 2, 2024

Took a sec (30min or so?) but I ended up getting it to work just fine. Here's an example program with token comparison.

macro_rules! def_eq {
    (
        d: [$d:tt],
        lookfor: [$lookfor:tt],
        input: [$input:tt],
        true: [$($true:tt)*],
        false: [$($false:tt)*],
    ) => {
        macro_rules! token_eq {
            ($lookfor) => {
                $($true)*
            };
            ($d($d _:tt)*) => {
                $($false)*
            };
        }

        token_eq! {
            $input
        }
    };
}

macro_rules! pair_eq {
    (
        @acc
        in: [],
        out: $out:tt,
    ) => {
        $out
    };
    (
        @acc
        in: [$e0:tt],
        out: [$($out:literal),*],
    ) => {
        [$($out,)* false]
    };
    (
        @acc
        in: [$e0:tt $e1:tt $($rest:tt)*],
        out: [$($out:literal),*],
    ) => {
        def_eq! {
            d: [$],
            lookfor: [$e0],
            input: [$e1],
            true: [
                pair_eq! {
                    @acc
                    in: [$($rest)*],
                    out: [$($out,)* true],
                }
            ],
            false: [
                pair_eq! {
                    @acc
                    in: [$($rest)*],
                    out: [$($out,)* false],
                }
            ],
        }
    };
    ($($input:tt)*) => {{
        pair_eq! {
            @acc
            in: [$($input)*],
            out: [],
        }
    }};
}

fn main() {
    let tmp = pair_eq!(a b b b c c d);
    println!("{tmp:?}");
}

from auroranssolis.github.io.

Related Issues (1)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.