macro_rules! impl_keyword { ( $vis:vis enum $name:ident { $($variant:ident => $s:literal),* $(,)? } ) => { #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] $vis enum $name { $($variant),* } impl $name { pub fn parse(s: &str) -> Option { match s { $( $s => Some(Self::$variant), )* _ => None, } } } impl std::fmt::Display for $name { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(match self { $( Self::$variant => $s ),* }) } } }; } impl_keyword! { pub enum Keyword { Lambda => "lambda", Defun => "defun", If => "if", Cond => "cond", While => "while", Otherwise => "&otherwise", Optional => "&optional", Rest => "&rest", Setq => "setq", Let => "let", LetStar => "let*", Defmacro => "defmacro", Quote => "quote", Progn => "progn", Loop => "loop", Break => "break", Continue => "continue", Declare => "declare", Error => "&error", // Cons => "cons", } }