1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
use crate::lexer::token::LexToken; use crate::parser::Parser; use crate::syntax::{Delimiter, NonEmptySyntax, Syntax}; use lark_debug_derive::DebugWith; use lark_error::ErrorReported; use lark_span::{FileName, Spanned}; macro_rules! sigil_type { ($($v:vis struct $name:ident = ($kind:path, $token:expr);)*) => { $( #[derive(DebugWith)] $v struct $name; impl $name { $v const KIND: LexToken = $kind; $v const TEXT: &'static str = $token; } impl Syntax<'parse> for $name { type Data = Spanned<LexToken, FileName>; fn test(&mut self, parser: &Parser<'parse>) -> bool { parser.is($kind) && parser.peek_str() == $name::TEXT } fn expect(&mut self, parser: &mut Parser<'parse>) -> Result<Self::Data, ErrorReported> { if self.test(parser) { Ok(parser.shift()) } else { Err(parser.report_error( format!("expected `{}`", $name::TEXT), parser.peek_span(), )) } } } impl NonEmptySyntax<'parse> for $name { } )* } } sigil_type! { pub struct OpenCurly = (LexToken::Sigil, "{"); pub struct CloseCurly = (LexToken::Sigil, "}"); pub struct OpenParenthesis = (LexToken::Sigil, "("); pub struct CloseParenthesis = (LexToken::Sigil, ")"); pub struct OpenSquare = (LexToken::Sigil, "["); pub struct CloseSquare = (LexToken::Sigil, "]"); pub struct Colon = (LexToken::Sigil, ":"); pub struct Semicolon = (LexToken::Sigil, ";"); pub struct Comma = (LexToken::Sigil, ","); pub struct RightArrow = (LexToken::Sigil, "->"); pub struct Dot = (LexToken::Sigil, "."); pub struct Let = (LexToken::Identifier, "let"); pub struct ExclamationPoint = (LexToken::Sigil, "!"); pub struct Plus = (LexToken::Sigil, "+"); pub struct Minus = (LexToken::Sigil, "-"); pub struct Star = (LexToken::Sigil, "*"); pub struct Slash = (LexToken::Sigil, "/"); pub struct Equals = (LexToken::Sigil, "="); } #[derive(DebugWith)] pub struct Curlies; impl Delimiter<'parse> for Curlies { type Open = OpenCurly; type Close = CloseCurly; fn open_syntax(&self) -> Self::Open { OpenCurly } fn close_syntax(&self) -> Self::Close { CloseCurly } } #[derive(DebugWith)] pub struct Parentheses; impl Delimiter<'parse> for Parentheses { type Open = OpenParenthesis; type Close = CloseParenthesis; fn open_syntax(&self) -> Self::Open { OpenParenthesis } fn close_syntax(&self) -> Self::Close { CloseParenthesis } }