Skip to main content

palladium/macros/
parser.rs

1// Macro pattern parser for Palladium
2// "Parsing the patterns of power"
3
4use crate::errors::{CompileError, Result};
5use crate::lexer::Token;
6
7/// Macro pattern element
8#[derive(Debug, Clone, PartialEq)]
9pub enum PatternElement {
10    /// Literal token to match
11    Literal(Token),
12    /// Variable to capture (e.g., $expr:expr)
13    Variable { name: String, kind: CaptureKind },
14    /// Repetition (e.g., $($x:expr),*)
15    Repetition {
16        pattern: Vec<PatternElement>,
17        separator: Option<Token>,
18        kind: RepetitionKind,
19    },
20}
21
22/// Kind of capture variable
23#[derive(Debug, Clone, PartialEq)]
24pub enum CaptureKind {
25    /// Expression
26    Expr,
27    /// Statement
28    Stmt,
29    /// Type
30    Type,
31    /// Pattern
32    Pat,
33    /// Identifier
34    Ident,
35    /// Literal
36    Lit,
37    /// Token tree (any tokens)
38    Tt,
39}
40
41/// Kind of repetition
42#[derive(Debug, Clone, PartialEq)]
43pub enum RepetitionKind {
44    /// Zero or more (*)
45    ZeroOrMore,
46    /// One or more (+)
47    OneOrMore,
48    /// Zero or one (?)
49    ZeroOrOne,
50}
51
52/// Macro pattern parser
53pub struct PatternParser {
54    tokens: Vec<Token>,
55    pos: usize,
56}
57
58impl PatternParser {
59    pub fn new(tokens: Vec<Token>) -> Self {
60        Self { tokens, pos: 0 }
61    }
62
63    /// Parse a macro pattern
64    pub fn parse_pattern(&mut self) -> Result<Vec<PatternElement>> {
65        let mut elements = Vec::new();
66
67        while !self.is_at_end() {
68            elements.push(self.parse_element()?);
69        }
70
71        Ok(elements)
72    }
73
74    /// Parse a single pattern element
75    fn parse_element(&mut self) -> Result<PatternElement> {
76        if self.check_token(&Token::Dollar) {
77            self.parse_capture_or_repetition()
78        } else {
79            // Literal token
80            let token = self.advance()?;
81            Ok(PatternElement::Literal(token))
82        }
83    }
84
85    /// Parse a capture variable or repetition
86    fn parse_capture_or_repetition(&mut self) -> Result<PatternElement> {
87        self.consume(Token::Dollar)?;
88
89        if self.check_token(&Token::LeftParen) {
90            // Repetition: $(...)
91            self.parse_repetition()
92        } else {
93            // Capture variable: $name:kind
94            self.parse_capture()
95        }
96    }
97
98    /// Parse a capture variable
99    fn parse_capture(&mut self) -> Result<PatternElement> {
100        let name = self.expect_ident()?;
101        self.consume(Token::Colon)?;
102        let kind = self.parse_capture_kind()?;
103
104        Ok(PatternElement::Variable { name, kind })
105    }
106
107    /// Parse capture kind
108    fn parse_capture_kind(&mut self) -> Result<CaptureKind> {
109        let kind_name = self.expect_ident()?;
110
111        match kind_name.as_str() {
112            "expr" => Ok(CaptureKind::Expr),
113            "stmt" => Ok(CaptureKind::Stmt),
114            "type" => Ok(CaptureKind::Type),
115            "pat" => Ok(CaptureKind::Pat),
116            "ident" => Ok(CaptureKind::Ident),
117            "lit" => Ok(CaptureKind::Lit),
118            "tt" => Ok(CaptureKind::Tt),
119            _ => Err(CompileError::Generic(format!(
120                "Unknown capture kind: {}",
121                kind_name
122            ))),
123        }
124    }
125
126    /// Parse a repetition
127    fn parse_repetition(&mut self) -> Result<PatternElement> {
128        self.consume(Token::LeftParen)?;
129
130        // Parse inner pattern
131        let mut pattern = Vec::new();
132        while !self.check_token(&Token::RightParen) {
133            pattern.push(self.parse_element()?);
134        }
135
136        self.consume(Token::RightParen)?;
137
138        // Parse separator (optional)
139        let separator = if self.check_token(&Token::Comma) || self.check_token(&Token::Semicolon) {
140            Some(self.advance()?)
141        } else {
142            None
143        };
144
145        // Parse repetition kind
146        let kind = if self.check_token(&Token::Star) {
147            self.advance()?;
148            RepetitionKind::ZeroOrMore
149        } else if self.check_token(&Token::Plus) {
150            self.advance()?;
151            RepetitionKind::OneOrMore
152        } else if self.check_token(&Token::Question) {
153            self.advance()?;
154            RepetitionKind::ZeroOrOne
155        } else {
156            return Err(CompileError::Generic(
157                "Expected repetition operator (*, +, or ?)".to_string(),
158            ));
159        };
160
161        Ok(PatternElement::Repetition {
162            pattern,
163            separator,
164            kind,
165        })
166    }
167
168    /// Check if we're at the end
169    fn is_at_end(&self) -> bool {
170        self.pos >= self.tokens.len()
171    }
172
173    /// Check if current token matches
174    fn check_token(&self, expected: &Token) -> bool {
175        if self.is_at_end() {
176            false
177        } else {
178            std::mem::discriminant(&self.tokens[self.pos]) == std::mem::discriminant(expected)
179        }
180    }
181
182    /// Consume a specific token
183    fn consume(&mut self, expected: Token) -> Result<()> {
184        if self.check_token(&expected) {
185            self.advance()?;
186            Ok(())
187        } else {
188            Err(CompileError::Generic(format!(
189                "Expected {:?}, found {:?}",
190                expected,
191                self.current()
192            )))
193        }
194    }
195
196    /// Advance to next token
197    fn advance(&mut self) -> Result<Token> {
198        if self.is_at_end() {
199            Err(CompileError::Generic("Unexpected end of input".to_string()))
200        } else {
201            let token = self.tokens[self.pos].clone();
202            self.pos += 1;
203            Ok(token)
204        }
205    }
206
207    /// Get current token
208    fn current(&self) -> Option<&Token> {
209        if self.is_at_end() {
210            None
211        } else {
212            Some(&self.tokens[self.pos])
213        }
214    }
215
216    /// Expect an identifier
217    fn expect_ident(&mut self) -> Result<String> {
218        match self.advance()? {
219            Token::Identifier(name) => Ok(name),
220            other => Err(CompileError::Generic(format!(
221                "Expected identifier, found {:?}",
222                other
223            ))),
224        }
225    }
226}