macro_rules! define_language {
    ($(#[$meta:meta])* $vis:vis enum $name:ident $variants:tt) => { ... };
}
Expand description

A macro to easily create a Language.

define_language derives Debug, PartialEq, Eq, PartialOrd, Ord, Hash, and Clone on the given enum so it can implement Language. The macro also implements Display and FromOp for the enum based on either the data of variants or the provided strings.

The final variant must have a trailing comma; this is due to limitations in macro parsing.

The language discriminant will use the cases of the enum (the enum discriminant).

See LanguageChildren for acceptable types of children Ids.

Note that you can always implement Language yourself by just not using this macro.

Presently, the macro does not support data variant with children, but that may be added later.

Example

The following macro invocation shows the the accepted forms of variants:

define_language! {
    enum SimpleLanguage {
        // string variant with no children
        "pi" = Pi,

        // string variants with an array of child `Id`s (any static size)
        // any type that implements LanguageChildren may be used here
        "+" = Add([Id; 2]),
        "-" = Sub([Id; 2]),
        "*" = Mul([Id; 2]),

        // can also do a variable number of children in a boxed slice
        // this will only match if the lengths are the same
        "list" = List(Box<[Id]>),

        // string variants with a single child `Id`
        // note that this is distinct from `Sub`, even though it has the same
        // string, because it has a different number of children
        "-"  = Neg(Id),

        // data variants with a single field
        // this field must implement `FromStr` and `Display`
        Num(i32),
        // language items are parsed in order, and we want symbol to
        // be a fallback, so we put it last
        Symbol(Symbol),
        // This is the ultimate fallback, it will parse any operator (as a string)
        // and any number of children.
        // Note that if there were 0 children, the previous branch would have succeeded
        Other(Symbol, Vec<Id>),
    }
}