1use crate::ast::{BinaryOp, Expr, Stmt, StringPart, UnaryOp};
4use crate::error::{JsonnetError, Result};
5use crate::lexer::Token;
6
7pub struct Parser {
9 tokens: Vec<Token>,
10 position: usize,
11}
12
13impl Parser {
14 pub fn new(tokens: Vec<Token>) -> Self {
16 Self {
17 tokens,
18 position: 0,
19 }
20 }
21
22 fn current(&self) -> Option<&Token> {
24 self.tokens.get(self.position)
25 }
26
27 fn advance(&mut self) {
29 self.position += 1;
30 }
31
32 pub fn parse(&mut self) -> Result<Expr> {
34 let mut expr = self.parse_expression()?;
36
37 while matches!(self.current(), Some(Token::Semicolon)) {
38 self.advance(); if matches!(self.current(), Some(Token::Eof)) {
40 break; }
42 expr = self.parse_expression()?;
43 }
44
45 if !matches!(self.current(), Some(Token::Eof)) {
46 return Err(JsonnetError::parse_error(
47 0, 0, "Unexpected tokens after expression"
49 ));
50 }
51 Ok(expr)
52 }
53
54 fn parse_expression(&mut self) -> Result<Expr> {
56 self.parse_local()
57 }
58
59 fn parse_local(&mut self) -> Result<Expr> {
61 if matches!(self.current(), Some(Token::Local)) {
62 self.advance(); let mut bindings = Vec::new();
65
66 loop {
67 let name = match self.current().cloned() {
69 Some(Token::Identifier(id)) => {
70 self.advance();
71 id
72 }
73 _ => return Err(JsonnetError::parse_error(0, 0, "Expected variable name after 'local'")),
74 };
75
76 self.expect_token(Token::Equal)?;
77 let value = self.parse_expression()?;
78 bindings.push((name, value));
79
80 if matches!(self.current(), Some(Token::Comma)) {
82 self.advance(); } else {
84 break;
85 }
86 }
87
88 self.expect_token(Token::Semicolon)?;
89 let body = self.parse_expression()?;
90
91 Ok(Expr::Local(bindings, Box::new(body)))
92 } else {
93 self.parse_conditional()
94 }
95 }
96
97 fn parse_conditional(&mut self) -> Result<Expr> {
99 if matches!(self.current(), Some(Token::If)) {
100 self.advance(); let condition = self.parse_expression()?;
103
104 self.expect_token(Token::Then)?;
105 let then_branch = self.parse_expression()?;
106
107 self.expect_token(Token::Else)?;
108 let else_branch = self.parse_expression()?;
109
110 Ok(Expr::Conditional(
111 Box::new(condition),
112 Box::new(then_branch),
113 Box::new(else_branch),
114 ))
115 } else {
116 self.parse_or()
117 }
118 }
119
120 fn parse_or(&mut self) -> Result<Expr> {
122 let mut expr = self.parse_and()?;
123
124 while let Some(Token::Or) = self.current() {
125 self.advance();
126 let right = self.parse_and()?;
127 expr = Expr::BinaryOp(BinaryOp::Or, Box::new(expr), Box::new(right));
128 }
129
130 Ok(expr)
131 }
132
133 fn parse_and(&mut self) -> Result<Expr> {
135 let mut expr = self.parse_comparison()?;
136
137 while let Some(Token::And) = self.current() {
138 self.advance();
139 let right = self.parse_comparison()?;
140 expr = Expr::BinaryOp(BinaryOp::And, Box::new(expr), Box::new(right));
141 }
142
143 Ok(expr)
144 }
145
146 fn parse_comparison(&mut self) -> Result<Expr> {
148 let mut expr = self.parse_additive()?;
149
150 loop {
151 let op = match self.current() {
152 Some(Token::Equal) => BinaryOp::Eq,
153 Some(Token::NotEqual) => BinaryOp::Ne,
154 Some(Token::LessThan) => BinaryOp::Lt,
155 Some(Token::LessThanEqual) => BinaryOp::Le,
156 Some(Token::GreaterThan) => BinaryOp::Gt,
157 Some(Token::GreaterThanEqual) => BinaryOp::Ge,
158 _ => break,
159 };
160 self.advance();
161 let right = self.parse_additive()?;
162 expr = Expr::BinaryOp(op, Box::new(expr), Box::new(right));
163 }
164
165 Ok(expr)
166 }
167
168 fn parse_additive(&mut self) -> Result<Expr> {
170 let mut expr = self.parse_multiplicative()?;
171
172 loop {
173 let op = match self.current() {
174 Some(Token::Plus) => BinaryOp::Add,
175 Some(Token::Minus) => BinaryOp::Sub,
176 _ => break,
177 };
178 self.advance();
179 let right = self.parse_multiplicative()?;
180 expr = Expr::BinaryOp(op, Box::new(expr), Box::new(right));
181 }
182
183 Ok(expr)
184 }
185
186 fn parse_multiplicative(&mut self) -> Result<Expr> {
188 let mut expr = self.parse_unary()?;
189
190 loop {
191 let op = match self.current() {
192 Some(Token::Star) => BinaryOp::Mul,
193 Some(Token::Slash) => BinaryOp::Div,
194 Some(Token::Percent) => BinaryOp::Mod,
195 _ => break,
196 };
197 self.advance();
198 let right = self.parse_unary()?;
199 expr = Expr::BinaryOp(op, Box::new(expr), Box::new(right));
200 }
201
202 Ok(expr)
203 }
204
205 fn parse_unary(&mut self) -> Result<Expr> {
207 if let Some(Token::Minus) = self.current() {
208 self.advance();
209 let expr = self.parse_unary()?;
210 return Ok(Expr::UnaryOp(UnaryOp::Neg, Box::new(expr)));
211 }
212 if let Some(Token::Plus) = self.current() {
213 self.advance();
214 let expr = self.parse_unary()?;
215 return Ok(Expr::UnaryOp(UnaryOp::Plus, Box::new(expr)));
216 }
217 if let Some(Token::Not) = self.current() {
218 self.advance();
219 let expr = self.parse_unary()?;
220 return Ok(Expr::UnaryOp(UnaryOp::Not, Box::new(expr)));
221 }
222
223 self.parse_postfix()
224 }
225
226 fn parse_primary(&mut self) -> Result<Expr> {
228 match self.current().cloned() {
229 Some(Token::String(s)) => {
230 self.advance();
231 if s.contains("%(") && s.contains(")s") {
233 self.parse_string_interpolation(&s)
234 } else {
235 Ok(Expr::String(s))
236 }
237 }
238 Some(Token::Number(n)) => {
239 self.advance();
240 Ok(Expr::Number(n))
241 }
242 Some(Token::Boolean(b)) => {
243 self.advance();
244 Ok(Expr::Boolean(b))
245 }
246 Some(Token::Null) => {
247 self.advance();
248 Ok(Expr::Null)
249 }
250 Some(Token::Identifier(id)) => {
251 self.advance();
252 Ok(Expr::Identifier(id))
253 }
254 Some(Token::LeftBrace) => self.parse_object(),
255 Some(Token::LeftBracket) => {
256 self.advance(); self.parse_array()
258 },
259 Some(Token::Function) => self.parse_function(),
260 Some(Token::LeftParen) => {
261 self.advance(); let expr = self.parse_expression()?;
263 self.expect_token(Token::RightParen)?;
264 Ok(expr)
265 }
266 _ => Err(JsonnetError::parse_error(0, 0, "Expected expression")),
267 }
268 }
269
270 fn parse_postfix(&mut self) -> Result<Expr> {
272 let mut expr = self.parse_primary()?;
273
274 loop {
275 match self.current() {
276 Some(Token::LeftBracket) => {
277 self.advance(); let index = self.parse_expression()?;
279 self.expect_token(Token::RightBracket)?;
280 expr = Expr::ArrayAccess(Box::new(expr), Box::new(index));
281 }
282 Some(Token::Dot) => {
283 self.advance(); match self.current().cloned() {
285 Some(Token::Identifier(field)) => {
286 self.advance();
287 expr = Expr::FieldAccess(Box::new(expr), field);
288 }
289 _ => return Err(JsonnetError::parse_error(0, 0, "Expected field name after '.'")),
290 }
291 }
292 Some(Token::LeftParen) => {
293 self.advance(); let mut args = Vec::new();
296
297 if !matches!(self.current(), Some(Token::RightParen)) {
298 loop {
299 let arg = self.parse_expression()?;
300 args.push(arg);
301
302 if !matches!(self.current(), Some(Token::Comma)) {
303 break;
304 }
305 self.advance(); }
307 }
308
309 self.expect_token(Token::RightParen)?;
310 expr = Expr::Call(Box::new(expr), args);
311 }
312 _ => break,
313 }
314 }
315
316 Ok(expr)
317 }
318
319 fn parse_object(&mut self) -> Result<Expr> {
321 self.expect_token(Token::LeftBrace)?;
322 let mut fields = Vec::new();
323
324 if !matches!(self.current(), Some(Token::RightBrace)) {
325 loop {
326 let key = match self.current().cloned() {
328 Some(Token::String(s)) => {
329 self.advance();
330 s
331 }
332 Some(Token::Identifier(id)) => {
333 self.advance();
334 id
335 }
336 _ => return Err(JsonnetError::parse_error(0, 0, "Expected object key")),
337 };
338
339 self.expect_token(Token::Colon)?;
340 let value = self.parse_expression()?;
341 fields.push((key, value));
342
343 if !matches!(self.current(), Some(Token::Comma)) {
344 break;
345 }
346 self.advance(); }
348 }
349
350 self.expect_token(Token::RightBrace)?;
351 Ok(Expr::Object(fields))
352 }
353
354 fn parse_array(&mut self) -> Result<Expr> {
356 if matches!(self.current(), Some(Token::RightBracket)) {
359 self.advance(); return Ok(Expr::Array(Vec::new()));
362 }
363
364 let expr = self.parse_expression()?;
366
367 if matches!(self.current(), Some(Token::For)) {
369 self.advance(); let var_name = match self.current().cloned() {
372 Some(Token::Identifier(name)) => {
373 self.advance();
374 name
375 }
376 _ => return Err(JsonnetError::parse_error(0, 0, "Expected variable name after 'for'")),
377 };
378
379 self.expect_token(Token::In)?;
380 let array_expr = self.parse_expression()?;
381
382 let condition = if matches!(self.current(), Some(Token::If)) {
384 self.advance(); Some(Box::new(self.parse_expression()?))
386 } else {
387 None
388 };
389
390 self.expect_token(Token::RightBracket)?;
391
392 return Ok(Expr::ArrayComprehension {
393 expr: Box::new(expr),
394 var_name,
395 array_expr: Box::new(array_expr),
396 condition,
397 });
398 }
399
400 let mut elements = vec![expr];
402 while matches!(self.current(), Some(Token::Comma)) {
403 self.advance(); let expr = self.parse_expression()?;
405 elements.push(expr);
406 }
407
408 self.expect_token(Token::RightBracket)?;
409 Ok(Expr::Array(elements))
410 }
411
412
413 fn parse_function(&mut self) -> Result<Expr> {
415 self.expect_token(Token::Function)?;
416
417 self.expect_token(Token::LeftParen)?;
419 let mut params = Vec::new();
420
421 if !matches!(self.current(), Some(Token::RightParen)) {
422 loop {
423 match self.current().cloned() {
424 Some(Token::Identifier(param)) => {
425 self.advance();
426 params.push(param);
427 }
428 _ => return Err(JsonnetError::parse_error(0, 0, "Expected parameter name")),
429 }
430
431 if !matches!(self.current(), Some(Token::Comma)) {
432 break;
433 }
434 self.advance(); }
436 }
437
438 self.expect_token(Token::RightParen)?;
439
440 let body = self.parse_expression()?;
442
443 Ok(Expr::Function(params, Box::new(body)))
444 }
445
446 fn parse_string_interpolation(&mut self, s: &str) -> Result<Expr> {
448 let mut parts = Vec::new();
449 let mut remaining = s;
450
451 while let Some(start) = remaining.find("%(") {
452 if start > 0 {
454 parts.push(StringPart::Literal(remaining[..start].to_string()));
455 }
456
457 if let Some(end) = remaining[start..].find(")s") {
459 let var_part = &remaining[start + 2..start + end];
460 parts.push(StringPart::Interpolation(Expr::Identifier(var_part.to_string())));
462 remaining = &remaining[start + end + 2..];
463 } else {
464 parts.push(StringPart::Literal(remaining.to_string()));
466 break;
467 }
468 }
469
470 if !remaining.is_empty() {
472 parts.push(StringPart::Literal(remaining.to_string()));
473 }
474
475 if parts.is_empty() {
476 return Ok(Expr::String(s.to_string()));
478 }
479
480 Ok(Expr::StringInterpolation(parts))
481 }
482
483 fn expect_token(&mut self, expected: Token) -> Result<()> {
485 match self.current() {
486 Some(token) if token == &expected => {
487 self.advance();
488 Ok(())
489 }
490 _ => Err(JsonnetError::parse_error(0, 0, format!("Expected {:?}", expected))),
491 }
492 }
493}
494
495impl Default for Parser {
496 fn default() -> Self {
497 Self::new(vec![])
498 }
499}