Help with macro_rules of DSL

I am writing a compiler IR lib for learning and meet this case:
I want to use macro_rules to generating code like:

// expect generated code by macro_rules
struct Instruction{
sub_class : InstClass,
opcode: InstOpcode,
}
enum InstClass{
Unary,
Binary,
Return,
Phi
}
enum InstOpcode{
Add,
Sub,
Mul,
Div,
Neg,
Cast,
Ret,
}

Then, the macro_rules I write is:

macro_rules!  InstructionDefine{
    ($name:ident: $($class:ident, $opcode:ident );*) => {
        #[derive(Debug)]
        pub enum $name{
            $($opcode),*
        }
        #[derive(Debug)]
        pub enum InstClass{
            $($class),*
        }
        fn get_class(n: $name) -> InstClass{
            match n{
                $( $name::$opcode =>  InstClass::Unary),*
            }
        }
    };
}

InstructionDefine!(InstOpcode: Unary, neg; Binary, add; Binary, sub; Binary, mul; Binary, div);

And rustc gives me

the name Binary is defined multiple times

Any way to dedup the item in enum InstClass?
Thanks!

I would use a build.rs script for that.

I don't have a concrete solution, but for macro_rules you'll likely need to represent the "one to many" mapping through nested repetitions input into the macro.

e.g. Instead of a, 1; a, 2; c, 3, refactor your inputs to be more like a (1, 2); c (3) or something similar

1 Like

Thanks for reply.
a (1, 2); c (3)is a good way to solve it

Sure, build.rs is one way. But I want IDE hint for this type. I am not sure whether build.rs also have hint.