pub struct ParseBuffer<'a> { /* private fields */ }Expand description
A cursor position within a token stream.
Implementations§
Source§impl<'a> ParseBuffer<'a>
impl<'a> ParseBuffer<'a>
Sourcepub fn parse<T: Parse>(&self) -> Result<T>
pub fn parse<T: Parse>(&self) -> Result<T>
Attempts to parse self into the given syntax tree node, using T’s
default parsing implementation.
§Errors
Returns an error if T’s Parse implementation fails.
Examples found in repository?
41 fn parse(input: ParseStream) -> Result<Self> {
42 let mut expr = factor(input)?;
43 loop {
44 if input.peek(Punct!["+"]) {
45 expr = Expr::Add(Box::new(expr), input.parse()?, Box::new(factor(input)?));
46 } else if input.peek(Punct!["-"]) {
47 expr = Expr::Sub(Box::new(expr), input.parse()?, Box::new(factor(input)?));
48 } else {
49 break;
50 }
51 }
52 Ok(expr)
53 }
54}
55
56fn factor(input: ParseStream) -> Result<Expr> {
57 let mut expr: Expr = unary(input)?;
58 loop {
59 if input.peek(Punct!["*"]) {
60 expr = Expr::Mul(Box::new(expr), input.parse()?, Box::new(unary(input)?));
61 } else if input.peek(Punct!["/"]) {
62 expr = Expr::Div(Box::new(expr), input.parse()?, Box::new(unary(input)?));
63 } else if input.peek(Punct!["%"]) {
64 expr = Expr::Mod(Box::new(expr), input.parse()?, Box::new(unary(input)?));
65 } else {
66 break;
67 }
68 }
69 Ok(expr)
70}
71
72fn unary(input: ParseStream) -> Result<Expr> {
73 if input.peek(Punct!["-"]) {
74 Ok(Expr::Neg(input.parse()?, Box::new(unary(input)?)))
75 } else {
76 primary(input)
77 }
78}
79
80#[allow(clippy::cast_precision_loss)]
81fn primary(input: ParseStream) -> Result<Expr> {
82 let lookahead = input.lookahead();
83 if lookahead.peek(token::LitFloat) {
84 Ok(Expr::Num(input.parse::<token::LitFloat>()?.value()))
85 } else if lookahead.peek(token::LitInt) {
86 Ok(Expr::Num(input.parse::<token::LitInt>()?.value() as f64))
87 } else if lookahead.peek(token::LeftParen) {
88 let group: Group<Parentheses> = input.parse()?;
89 parse(group.into_token_stream())
90 } else {
91 Err(lookahead.error())
92 }
93}More examples
192 fn assignment(input: ParseStream) -> Result<Self> {
193 let expr = Expr::or(input)?;
194
195 if input.peek(Punct!["="]) {
196 let equals: Punct!["="] = input.parse()?;
197 let value = Box::new(Expr::assignment(input)?);
198
199 if let Expr::Variable { name, .. } = expr {
200 return Ok(Expr::Assign {
201 name,
202 value,
203 distance: Cell::new(None),
204 });
205 } else if let Expr::Get { object, name } = expr {
206 return Ok(Expr::Set {
207 object,
208 name,
209 value,
210 });
211 }
212
213 input.add_error(input.new_error(
214 "Invalid assignment target".to_string(),
215 &equals,
216 error_codes::INVALID_ASSIGN,
217 ));
218 }
219
220 Ok(expr)
221 }
222
223 fn or(input: ParseStream) -> Result<Self> {
224 let mut expr = Expr::and(input)?;
225
226 while input.peek(kw::or) {
227 expr = Expr::Logical(Box::new(Logical::Or(
228 expr,
229 input.parse()?,
230 Expr::and(input)?,
231 )));
232 }
233
234 Ok(expr)
235 }
236
237 fn and(input: ParseStream) -> Result<Self> {
238 let mut expr = Expr::equality(input)?;
239
240 while input.peek(kw::and) {
241 expr = Expr::Logical(Box::new(Logical::And(
242 expr,
243 input.parse()?,
244 Expr::equality(input)?,
245 )));
246 }
247
248 Ok(expr)
249 }
250
251 fn equality(input: ParseStream) -> Result<Self> {
252 let mut expr = Expr::comparison(input)?;
253
254 loop {
255 if input.peek(Punct!["=="]) {
256 expr = Expr::binary(Binary::Equal(
257 expr,
258 input.parse()?,
259 Expr::comparison(input)?,
260 ));
261 } else if input.peek(Punct!["!="]) {
262 expr = Expr::binary(Binary::NotEqual(
263 expr,
264 input.parse()?,
265 Expr::comparison(input)?,
266 ));
267 } else {
268 break Ok(expr);
269 }
270 }
271 }
272
273 fn comparison(input: ParseStream) -> Result<Self> {
274 let mut expr = Expr::term(input)?;
275
276 loop {
277 if input.peek(Punct![">"]) {
278 expr = Expr::binary(Binary::Greater(expr, input.parse()?, Expr::term(input)?));
279 } else if input.peek(Punct![">="]) {
280 expr = Expr::binary(Binary::GreaterEqual(
281 expr,
282 input.parse()?,
283 Expr::term(input)?,
284 ));
285 } else if input.peek(Punct!["<"]) {
286 expr = Expr::binary(Binary::Less(expr, input.parse()?, Expr::term(input)?));
287 } else if input.peek(Punct!["<="]) {
288 expr = Expr::binary(Binary::LessEqual(expr, input.parse()?, Expr::term(input)?));
289 } else {
290 break Ok(expr);
291 }
292 }
293 }
294
295 fn term(input: ParseStream) -> Result<Self> {
296 let mut expr = Expr::factor(input)?;
297
298 loop {
299 if input.peek(Punct!["+"]) {
300 expr = Expr::binary(Binary::Add(expr, input.parse()?, Expr::factor(input)?));
301 } else if input.peek(Punct!["-"]) {
302 expr = Expr::binary(Binary::Sub(expr, input.parse()?, Expr::factor(input)?));
303 } else {
304 break Ok(expr);
305 }
306 }
307 }
308
309 fn factor(input: ParseStream) -> Result<Self> {
310 let mut expr = Expr::unary(input)?;
311
312 loop {
313 if input.peek(Punct!["*"]) {
314 expr = Expr::binary(Binary::Mul(expr, input.parse()?, Expr::unary(input)?));
315 } else if input.peek(Punct!["/"]) {
316 expr = Expr::binary(Binary::Div(expr, input.parse()?, Expr::unary(input)?));
317 } else {
318 break Ok(expr);
319 }
320 }
321 }
322
323 fn unary(input: ParseStream) -> Result<Self> {
324 if input.peek(Punct!["-"]) {
325 Ok(Expr::Unary(Box::new(Unary::Neg(
326 input.parse()?,
327 Expr::unary(input)?,
328 ))))
329 } else if input.peek(Punct!["!"]) {
330 Ok(Expr::Unary(Box::new(Unary::Not(
331 input.parse()?,
332 Expr::unary(input)?,
333 ))))
334 } else {
335 Expr::call(input)
336 }
337 }
338
339 fn call(input: ParseStream) -> Result<Self> {
340 let mut expr = Expr::primary(input)?;
341
342 loop {
343 if input.peek(Punct!["("]) {
344 expr = Expr::finish_call(input, expr)?;
345 } else if input.peek(Punct!["."]) {
346 let _: Punct!["."] = input.parse()?;
347 let name: Ident = input.parse()?;
348 expr = Expr::Get {
349 object: Box::new(expr),
350 name,
351 };
352 } else {
353 break Ok(expr);
354 }
355 }
356 }
357
358 fn finish_call(input: ParseStream<'_>, callee: Expr) -> Result<Self> {
359 let content;
360 let paren: Parentheses = group!(content in input);
361 let arguments: Punctuated<Expr, Punct![","]> =
362 Punctuated::parse_separated_trailing(&content)?;
363 let arguments: Vec<_> = arguments.into_iter().collect();
364 if arguments.len() >= 255 {
365 input.add_error(input.new_error(
366 "Can't have more than 254 arguments".to_string(),
367 paren.0.clone(),
368 error_codes::TOO_MANY_ARGS,
369 ));
370 }
371 Ok(Expr::Call {
372 callee: Box::new(callee),
373 paren,
374 arguments,
375 })
376 }
377
378 fn primary(input: ParseStream) -> Result<Self> {
379 let lookahead = input.lookahead();
380 if lookahead.peek(kw::kw_false) {
381 Ok(Expr::Literal(Literal::False(input.parse()?)))
382 } else if lookahead.peek(kw::kw_true) {
383 Ok(Expr::Literal(Literal::True(input.parse()?)))
384 } else if lookahead.peek(kw::nil) {
385 Ok(Expr::Literal(Literal::Nil(input.parse()?)))
386 } else if lookahead.peek(LitFloat) {
387 Ok(Expr::Literal(Literal::Float(input.parse()?)))
388 } else if lookahead.peek(LitInt) {
389 Ok(Expr::Literal(Literal::Int(input.parse()?)))
390 } else if lookahead.peek(LitStr) {
391 Ok(Expr::Literal(Literal::String(input.parse()?)))
392 } else if input.peek(kw::kw_super) {
393 Ok(Expr::Super {
394 keyword: input.parse()?,
395 distance: Cell::new(None),
396 dot: input.parse()?,
397 method: kw::ident(input)?,
398 })
399 } else if input.peek(kw::this) {
400 Ok(Expr::This {
401 keyword: input.parse()?,
402 distance: Cell::new(None),
403 })
404 } else if lookahead.peek(Ident) {
405 Ok(Expr::Variable {
406 name: kw::ident(input)?,
407 distance: Cell::new(None),
408 })
409 } else if lookahead.peek(Punct!["("]) {
410 let content;
411 let _: Parentheses = group!(content in input);
412 Ok(Expr::Group(Box::new(content.parse()?)))
413 } else {
414 Err(lookahead.error())
415 }
416 }
417}
418
419impl Parse for Expr {
420 fn parse(input: ParseStream) -> Result<Self> {
421 Expr::assignment(input)
422 }
423}
424
425#[derive(Debug, Clone, PartialEq)]
426struct Function {
427 name: Ident,
428 params: Vec<Ident>,
429 body: Vec<Stmt>,
430}
431
432impl Parse for Function {
433 fn parse(input: ParseStream) -> Result<Self> {
434 let name: Ident = input.parse()?;
435 let mut contents: Group<Parentheses> = input.parse()?;
436 contents.remove_whitespace();
437 let Parentheses(span) = contents.delimiters();
438 let tokens = contents.into_token_stream();
439 let params: Vec<Ident> = if tokens.is_empty() {
440 vec![]
441 } else {
442 let params: Punctuated<Ident, Punct![","]> =
443 Punctuated::parse_separated.parse(tokens)?;
444 params.into_iter().collect()
445 };
446 if params.len() >= 255 {
447 input.add_error(input.new_error(
448 "Can't have more than 254 parameters".to_string(),
449 span,
450 error_codes::TOO_MANY_ARGS,
451 ));
452 }
453 let mut contents: Group<Braces> = input.parse()?;
454 contents.remove_whitespace();
455 let body = block.parse(contents.into_token_stream())?;
456 Ok(Function { name, params, body })
457 }
458}
459
460#[derive(Debug, Clone, PartialEq)]
461enum Stmt {
462 Block(Vec<Stmt>),
463 Class {
464 name: Ident,
465 superclass: Option<Ident>,
466 superclass_distance: Cell<Option<usize>>,
467 methods: Vec<Function>,
468 },
469 Expr(Expr),
470 Function(Function),
471 If {
472 condition: Expr,
473 then_branch: Box<Stmt>,
474 else_branch: Option<Box<Stmt>>,
475 },
476 Print(Expr),
477 Return {
478 keyword: kw::kw_return,
479 value: Option<Expr>,
480 },
481 Variable {
482 name: Ident,
483 initialiser: Option<Expr>,
484 },
485 While {
486 condition: Expr,
487 body: Box<Stmt>,
488 },
489}
490
491fn block(input: ParseStream) -> Result<Vec<Stmt>> {
492 let mut statements = vec![];
493
494 while !input.is_empty() {
495 statements.push(Stmt::declaration(input)?);
496 }
497
498 Ok(statements)
499}
500
501impl Stmt {
502 fn declaration(input: ParseStream) -> Result<Self> {
503 if input.peek(kw::class) {
504 Stmt::class_declaration(input)
505 } else if input.peek(kw::fun) {
506 let _: kw::fun = input.parse()?;
507 Ok(Stmt::Function(Function::parse(input)?))
508 } else if input.peek(kw::var) {
509 Stmt::var_declaration(input)
510 } else {
511 Stmt::statement(input)
512 }
513 }
514
515 fn class_declaration(input: ParseStream) -> Result<Self> {
516 let _: kw::class = input.parse()?;
517 let name: Ident = input.parse()?;
518
519 let superclass = if input.peek(Punct!["<"]) {
520 let _: Punct!["<"] = input.parse()?;
521 Some(input.parse()?)
522 } else {
523 None
524 };
525
526 let content;
527 let _: Braces = group!(content in input);
528 let methods = parse_repeated(&content)?;
529
530 Ok(Stmt::Class {
531 name,
532 superclass,
533 superclass_distance: Cell::new(None),
534 methods,
535 })
536 }
537
538 fn var_declaration(input: ParseStream) -> Result<Self> {
539 let _: kw::var = input.parse()?;
540
541 let name = kw::ident(input)?;
542
543 let initialiser = if input.peek(Punct!["="]) {
544 let _: Punct!["="] = input.parse()?;
545 Some(input.parse()?)
546 } else {
547 None
548 };
549
550 let _: Punct![";"] = input.parse()?;
551 Ok(Stmt::Variable { name, initialiser })
552 }
553
554 fn statement(input: ParseStream) -> Result<Self> {
555 if input.peek(kw::kw_if) {
556 Stmt::if_statement(input)
557 } else if input.peek(kw::kw_for) {
558 Stmt::for_statement(input)
559 } else if input.peek(kw::print) {
560 Stmt::print_statement(input)
561 } else if input.peek(kw::kw_return) {
562 Stmt::return_statement(input)
563 } else if input.peek(kw::kw_while) {
564 Stmt::while_statement(input)
565 } else if input.peek(Punct!["{"]) {
566 let content;
567 let _: Braces = group!(content in input);
568 Ok(Stmt::Block(block(&content)?))
569 } else {
570 Stmt::expression_statement(input)
571 }
572 }
573
574 fn for_statement(input: ParseStream) -> Result<Self> {
575 let _: kw::kw_for = input.parse()?;
576
577 let content;
578 let _: Parentheses = group!(content in input);
579
580 let initialiser = if content.peek(Punct![";"]) {
581 let _: Punct![";"] = content.parse()?;
582 None
583 } else if content.peek(kw::var) {
584 Some(Stmt::var_declaration(&content)?)
585 } else {
586 Some(Stmt::expression_statement(&content)?)
587 };
588
589 let condition = if content.peek(Punct![";"]) {
590 Expr::Literal(Literal::True(kw::kw_true::new(&content)))
591 } else {
592 content.parse()?
593 };
594 let _: Punct![";"] = content.parse()?;
595
596 let increment = if content.is_empty() {
597 None
598 } else {
599 Some(content.parse()?)
600 };
601
602 let mut body = Stmt::statement(input)?;
603
604 if let Some(increment) = increment {
605 body = Stmt::Block(vec![body, Stmt::Expr(increment)]);
606 }
607
608 body = Stmt::While {
609 condition,
610 body: Box::new(body),
611 };
612
613 if let Some(initialiser) = initialiser {
614 body = Stmt::Block(vec![initialiser, body]);
615 }
616
617 Ok(body)
618 }
619
620 fn if_statement(input: ParseStream) -> Result<Self> {
621 let _: kw::kw_if = input.parse()?;
622 let content;
623 let _: Parentheses = group!(content in input);
624 let condition = content.parse()?;
625
626 let then_branch = Box::new(Stmt::statement(input)?);
627 let else_branch = if input.peek(kw::kw_else) {
628 Some(Box::new(Stmt::statement(input)?))
629 } else {
630 None
631 };
632
633 Ok(Stmt::If {
634 condition,
635 then_branch,
636 else_branch,
637 })
638 }
639
640 fn print_statement(input: ParseStream) -> Result<Self> {
641 let _: kw::print = input.parse()?;
642 let value = input.parse()?;
643 let _: Punct![";"] = input.parse()?;
644 Ok(Self::Print(value))
645 }
646
647 fn return_statement(input: ParseStream) -> Result<Self> {
648 let keyword: kw::kw_return = input.parse()?;
649 let value = if input.peek(Punct![";"]) {
650 None
651 } else {
652 Some(input.parse()?)
653 };
654 let _: Punct![";"] = input.parse()?;
655 Ok(Stmt::Return { keyword, value })
656 }
657
658 fn while_statement(input: ParseStream) -> Result<Self> {
659 let _: kw::kw_while = input.parse()?;
660 let content;
661 let _: Parentheses = group!(content in input);
662 let condition = content.parse()?;
663 let body = Box::new(Stmt::statement(input)?);
664
665 Ok(Stmt::While { condition, body })
666 }
667
668 fn expression_statement(input: ParseStream) -> Result<Self> {
669 let expr = input.parse()?;
670 let _: Punct![";"] = input.parse()?;
671 Ok(Self::Expr(expr))
672 }
673}
674
675impl Parse for Stmt {
676 fn parse(input: ParseStream) -> Result<Self> {
677 Stmt::declaration(input)
678 }
679}
680
681struct Ast(Vec<Stmt>);
682
683impl Ast {
684 #[allow(clippy::wildcard_imports)]
685 fn synchronise(input: ParseStream) {
686 input.synchronise(|input| {
687 use kw::*;
688 input.peek(Punct![";"]) && !input.peek2(Punct!["}"])
689 || peek2_any!(input, class, kw_for, fun, kw_if, print, kw_return, var, kw_while)
690 });
691 }
692}
693
694impl Parse for Ast {
695 fn parse(input: ParseStream) -> Result<Self> {
696 let mut stmts = vec![];
697
698 while !input.is_empty() {
699 match input.parse() {
700 Ok(stmt) => stmts.push(stmt),
701 Err(err) => {
702 Ast::synchronise(input);
703 input.add_error(err);
704 }
705 }
706 }
707
708 input.get_error().map_or(Ok(Ast(stmts)), Err)
709 }Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true if this stream has been exhausted.
Examples found in repository?
491fn block(input: ParseStream) -> Result<Vec<Stmt>> {
492 let mut statements = vec![];
493
494 while !input.is_empty() {
495 statements.push(Stmt::declaration(input)?);
496 }
497
498 Ok(statements)
499}
500
501impl Stmt {
502 fn declaration(input: ParseStream) -> Result<Self> {
503 if input.peek(kw::class) {
504 Stmt::class_declaration(input)
505 } else if input.peek(kw::fun) {
506 let _: kw::fun = input.parse()?;
507 Ok(Stmt::Function(Function::parse(input)?))
508 } else if input.peek(kw::var) {
509 Stmt::var_declaration(input)
510 } else {
511 Stmt::statement(input)
512 }
513 }
514
515 fn class_declaration(input: ParseStream) -> Result<Self> {
516 let _: kw::class = input.parse()?;
517 let name: Ident = input.parse()?;
518
519 let superclass = if input.peek(Punct!["<"]) {
520 let _: Punct!["<"] = input.parse()?;
521 Some(input.parse()?)
522 } else {
523 None
524 };
525
526 let content;
527 let _: Braces = group!(content in input);
528 let methods = parse_repeated(&content)?;
529
530 Ok(Stmt::Class {
531 name,
532 superclass,
533 superclass_distance: Cell::new(None),
534 methods,
535 })
536 }
537
538 fn var_declaration(input: ParseStream) -> Result<Self> {
539 let _: kw::var = input.parse()?;
540
541 let name = kw::ident(input)?;
542
543 let initialiser = if input.peek(Punct!["="]) {
544 let _: Punct!["="] = input.parse()?;
545 Some(input.parse()?)
546 } else {
547 None
548 };
549
550 let _: Punct![";"] = input.parse()?;
551 Ok(Stmt::Variable { name, initialiser })
552 }
553
554 fn statement(input: ParseStream) -> Result<Self> {
555 if input.peek(kw::kw_if) {
556 Stmt::if_statement(input)
557 } else if input.peek(kw::kw_for) {
558 Stmt::for_statement(input)
559 } else if input.peek(kw::print) {
560 Stmt::print_statement(input)
561 } else if input.peek(kw::kw_return) {
562 Stmt::return_statement(input)
563 } else if input.peek(kw::kw_while) {
564 Stmt::while_statement(input)
565 } else if input.peek(Punct!["{"]) {
566 let content;
567 let _: Braces = group!(content in input);
568 Ok(Stmt::Block(block(&content)?))
569 } else {
570 Stmt::expression_statement(input)
571 }
572 }
573
574 fn for_statement(input: ParseStream) -> Result<Self> {
575 let _: kw::kw_for = input.parse()?;
576
577 let content;
578 let _: Parentheses = group!(content in input);
579
580 let initialiser = if content.peek(Punct![";"]) {
581 let _: Punct![";"] = content.parse()?;
582 None
583 } else if content.peek(kw::var) {
584 Some(Stmt::var_declaration(&content)?)
585 } else {
586 Some(Stmt::expression_statement(&content)?)
587 };
588
589 let condition = if content.peek(Punct![";"]) {
590 Expr::Literal(Literal::True(kw::kw_true::new(&content)))
591 } else {
592 content.parse()?
593 };
594 let _: Punct![";"] = content.parse()?;
595
596 let increment = if content.is_empty() {
597 None
598 } else {
599 Some(content.parse()?)
600 };
601
602 let mut body = Stmt::statement(input)?;
603
604 if let Some(increment) = increment {
605 body = Stmt::Block(vec![body, Stmt::Expr(increment)]);
606 }
607
608 body = Stmt::While {
609 condition,
610 body: Box::new(body),
611 };
612
613 if let Some(initialiser) = initialiser {
614 body = Stmt::Block(vec![initialiser, body]);
615 }
616
617 Ok(body)
618 }
619
620 fn if_statement(input: ParseStream) -> Result<Self> {
621 let _: kw::kw_if = input.parse()?;
622 let content;
623 let _: Parentheses = group!(content in input);
624 let condition = content.parse()?;
625
626 let then_branch = Box::new(Stmt::statement(input)?);
627 let else_branch = if input.peek(kw::kw_else) {
628 Some(Box::new(Stmt::statement(input)?))
629 } else {
630 None
631 };
632
633 Ok(Stmt::If {
634 condition,
635 then_branch,
636 else_branch,
637 })
638 }
639
640 fn print_statement(input: ParseStream) -> Result<Self> {
641 let _: kw::print = input.parse()?;
642 let value = input.parse()?;
643 let _: Punct![";"] = input.parse()?;
644 Ok(Self::Print(value))
645 }
646
647 fn return_statement(input: ParseStream) -> Result<Self> {
648 let keyword: kw::kw_return = input.parse()?;
649 let value = if input.peek(Punct![";"]) {
650 None
651 } else {
652 Some(input.parse()?)
653 };
654 let _: Punct![";"] = input.parse()?;
655 Ok(Stmt::Return { keyword, value })
656 }
657
658 fn while_statement(input: ParseStream) -> Result<Self> {
659 let _: kw::kw_while = input.parse()?;
660 let content;
661 let _: Parentheses = group!(content in input);
662 let condition = content.parse()?;
663 let body = Box::new(Stmt::statement(input)?);
664
665 Ok(Stmt::While { condition, body })
666 }
667
668 fn expression_statement(input: ParseStream) -> Result<Self> {
669 let expr = input.parse()?;
670 let _: Punct![";"] = input.parse()?;
671 Ok(Self::Expr(expr))
672 }
673}
674
675impl Parse for Stmt {
676 fn parse(input: ParseStream) -> Result<Self> {
677 Stmt::declaration(input)
678 }
679}
680
681struct Ast(Vec<Stmt>);
682
683impl Ast {
684 #[allow(clippy::wildcard_imports)]
685 fn synchronise(input: ParseStream) {
686 input.synchronise(|input| {
687 use kw::*;
688 input.peek(Punct![";"]) && !input.peek2(Punct!["}"])
689 || peek2_any!(input, class, kw_for, fun, kw_if, print, kw_return, var, kw_while)
690 });
691 }
692}
693
694impl Parse for Ast {
695 fn parse(input: ParseStream) -> Result<Self> {
696 let mut stmts = vec![];
697
698 while !input.is_empty() {
699 match input.parse() {
700 Ok(stmt) => stmts.push(stmt),
701 Err(err) => {
702 Ast::synchronise(input);
703 input.add_error(err);
704 }
705 }
706 }
707
708 input.get_error().map_or(Ok(Ast(stmts)), Err)
709 }Sourcepub fn new_error<T: Into<Span>>(
&self,
message: String,
location: T,
code: u16,
) -> Error
pub fn new_error<T: Into<Span>>( &self, message: String, location: T, code: u16, ) -> Error
Creates a new error at the given location with the given message and code.
Examples found in repository?
192 fn assignment(input: ParseStream) -> Result<Self> {
193 let expr = Expr::or(input)?;
194
195 if input.peek(Punct!["="]) {
196 let equals: Punct!["="] = input.parse()?;
197 let value = Box::new(Expr::assignment(input)?);
198
199 if let Expr::Variable { name, .. } = expr {
200 return Ok(Expr::Assign {
201 name,
202 value,
203 distance: Cell::new(None),
204 });
205 } else if let Expr::Get { object, name } = expr {
206 return Ok(Expr::Set {
207 object,
208 name,
209 value,
210 });
211 }
212
213 input.add_error(input.new_error(
214 "Invalid assignment target".to_string(),
215 &equals,
216 error_codes::INVALID_ASSIGN,
217 ));
218 }
219
220 Ok(expr)
221 }
222
223 fn or(input: ParseStream) -> Result<Self> {
224 let mut expr = Expr::and(input)?;
225
226 while input.peek(kw::or) {
227 expr = Expr::Logical(Box::new(Logical::Or(
228 expr,
229 input.parse()?,
230 Expr::and(input)?,
231 )));
232 }
233
234 Ok(expr)
235 }
236
237 fn and(input: ParseStream) -> Result<Self> {
238 let mut expr = Expr::equality(input)?;
239
240 while input.peek(kw::and) {
241 expr = Expr::Logical(Box::new(Logical::And(
242 expr,
243 input.parse()?,
244 Expr::equality(input)?,
245 )));
246 }
247
248 Ok(expr)
249 }
250
251 fn equality(input: ParseStream) -> Result<Self> {
252 let mut expr = Expr::comparison(input)?;
253
254 loop {
255 if input.peek(Punct!["=="]) {
256 expr = Expr::binary(Binary::Equal(
257 expr,
258 input.parse()?,
259 Expr::comparison(input)?,
260 ));
261 } else if input.peek(Punct!["!="]) {
262 expr = Expr::binary(Binary::NotEqual(
263 expr,
264 input.parse()?,
265 Expr::comparison(input)?,
266 ));
267 } else {
268 break Ok(expr);
269 }
270 }
271 }
272
273 fn comparison(input: ParseStream) -> Result<Self> {
274 let mut expr = Expr::term(input)?;
275
276 loop {
277 if input.peek(Punct![">"]) {
278 expr = Expr::binary(Binary::Greater(expr, input.parse()?, Expr::term(input)?));
279 } else if input.peek(Punct![">="]) {
280 expr = Expr::binary(Binary::GreaterEqual(
281 expr,
282 input.parse()?,
283 Expr::term(input)?,
284 ));
285 } else if input.peek(Punct!["<"]) {
286 expr = Expr::binary(Binary::Less(expr, input.parse()?, Expr::term(input)?));
287 } else if input.peek(Punct!["<="]) {
288 expr = Expr::binary(Binary::LessEqual(expr, input.parse()?, Expr::term(input)?));
289 } else {
290 break Ok(expr);
291 }
292 }
293 }
294
295 fn term(input: ParseStream) -> Result<Self> {
296 let mut expr = Expr::factor(input)?;
297
298 loop {
299 if input.peek(Punct!["+"]) {
300 expr = Expr::binary(Binary::Add(expr, input.parse()?, Expr::factor(input)?));
301 } else if input.peek(Punct!["-"]) {
302 expr = Expr::binary(Binary::Sub(expr, input.parse()?, Expr::factor(input)?));
303 } else {
304 break Ok(expr);
305 }
306 }
307 }
308
309 fn factor(input: ParseStream) -> Result<Self> {
310 let mut expr = Expr::unary(input)?;
311
312 loop {
313 if input.peek(Punct!["*"]) {
314 expr = Expr::binary(Binary::Mul(expr, input.parse()?, Expr::unary(input)?));
315 } else if input.peek(Punct!["/"]) {
316 expr = Expr::binary(Binary::Div(expr, input.parse()?, Expr::unary(input)?));
317 } else {
318 break Ok(expr);
319 }
320 }
321 }
322
323 fn unary(input: ParseStream) -> Result<Self> {
324 if input.peek(Punct!["-"]) {
325 Ok(Expr::Unary(Box::new(Unary::Neg(
326 input.parse()?,
327 Expr::unary(input)?,
328 ))))
329 } else if input.peek(Punct!["!"]) {
330 Ok(Expr::Unary(Box::new(Unary::Not(
331 input.parse()?,
332 Expr::unary(input)?,
333 ))))
334 } else {
335 Expr::call(input)
336 }
337 }
338
339 fn call(input: ParseStream) -> Result<Self> {
340 let mut expr = Expr::primary(input)?;
341
342 loop {
343 if input.peek(Punct!["("]) {
344 expr = Expr::finish_call(input, expr)?;
345 } else if input.peek(Punct!["."]) {
346 let _: Punct!["."] = input.parse()?;
347 let name: Ident = input.parse()?;
348 expr = Expr::Get {
349 object: Box::new(expr),
350 name,
351 };
352 } else {
353 break Ok(expr);
354 }
355 }
356 }
357
358 fn finish_call(input: ParseStream<'_>, callee: Expr) -> Result<Self> {
359 let content;
360 let paren: Parentheses = group!(content in input);
361 let arguments: Punctuated<Expr, Punct![","]> =
362 Punctuated::parse_separated_trailing(&content)?;
363 let arguments: Vec<_> = arguments.into_iter().collect();
364 if arguments.len() >= 255 {
365 input.add_error(input.new_error(
366 "Can't have more than 254 arguments".to_string(),
367 paren.0.clone(),
368 error_codes::TOO_MANY_ARGS,
369 ));
370 }
371 Ok(Expr::Call {
372 callee: Box::new(callee),
373 paren,
374 arguments,
375 })
376 }
377
378 fn primary(input: ParseStream) -> Result<Self> {
379 let lookahead = input.lookahead();
380 if lookahead.peek(kw::kw_false) {
381 Ok(Expr::Literal(Literal::False(input.parse()?)))
382 } else if lookahead.peek(kw::kw_true) {
383 Ok(Expr::Literal(Literal::True(input.parse()?)))
384 } else if lookahead.peek(kw::nil) {
385 Ok(Expr::Literal(Literal::Nil(input.parse()?)))
386 } else if lookahead.peek(LitFloat) {
387 Ok(Expr::Literal(Literal::Float(input.parse()?)))
388 } else if lookahead.peek(LitInt) {
389 Ok(Expr::Literal(Literal::Int(input.parse()?)))
390 } else if lookahead.peek(LitStr) {
391 Ok(Expr::Literal(Literal::String(input.parse()?)))
392 } else if input.peek(kw::kw_super) {
393 Ok(Expr::Super {
394 keyword: input.parse()?,
395 distance: Cell::new(None),
396 dot: input.parse()?,
397 method: kw::ident(input)?,
398 })
399 } else if input.peek(kw::this) {
400 Ok(Expr::This {
401 keyword: input.parse()?,
402 distance: Cell::new(None),
403 })
404 } else if lookahead.peek(Ident) {
405 Ok(Expr::Variable {
406 name: kw::ident(input)?,
407 distance: Cell::new(None),
408 })
409 } else if lookahead.peek(Punct!["("]) {
410 let content;
411 let _: Parentheses = group!(content in input);
412 Ok(Expr::Group(Box::new(content.parse()?)))
413 } else {
414 Err(lookahead.error())
415 }
416 }
417}
418
419impl Parse for Expr {
420 fn parse(input: ParseStream) -> Result<Self> {
421 Expr::assignment(input)
422 }
423}
424
425#[derive(Debug, Clone, PartialEq)]
426struct Function {
427 name: Ident,
428 params: Vec<Ident>,
429 body: Vec<Stmt>,
430}
431
432impl Parse for Function {
433 fn parse(input: ParseStream) -> Result<Self> {
434 let name: Ident = input.parse()?;
435 let mut contents: Group<Parentheses> = input.parse()?;
436 contents.remove_whitespace();
437 let Parentheses(span) = contents.delimiters();
438 let tokens = contents.into_token_stream();
439 let params: Vec<Ident> = if tokens.is_empty() {
440 vec![]
441 } else {
442 let params: Punctuated<Ident, Punct![","]> =
443 Punctuated::parse_separated.parse(tokens)?;
444 params.into_iter().collect()
445 };
446 if params.len() >= 255 {
447 input.add_error(input.new_error(
448 "Can't have more than 254 parameters".to_string(),
449 span,
450 error_codes::TOO_MANY_ARGS,
451 ));
452 }
453 let mut contents: Group<Braces> = input.parse()?;
454 contents.remove_whitespace();
455 let body = block.parse(contents.into_token_stream())?;
456 Ok(Function { name, params, body })
457 }Sourcepub fn add_error(&self, error: Error)
pub fn add_error(&self, error: Error)
Adds a new error to this buffer’s storage.
Examples found in repository?
192 fn assignment(input: ParseStream) -> Result<Self> {
193 let expr = Expr::or(input)?;
194
195 if input.peek(Punct!["="]) {
196 let equals: Punct!["="] = input.parse()?;
197 let value = Box::new(Expr::assignment(input)?);
198
199 if let Expr::Variable { name, .. } = expr {
200 return Ok(Expr::Assign {
201 name,
202 value,
203 distance: Cell::new(None),
204 });
205 } else if let Expr::Get { object, name } = expr {
206 return Ok(Expr::Set {
207 object,
208 name,
209 value,
210 });
211 }
212
213 input.add_error(input.new_error(
214 "Invalid assignment target".to_string(),
215 &equals,
216 error_codes::INVALID_ASSIGN,
217 ));
218 }
219
220 Ok(expr)
221 }
222
223 fn or(input: ParseStream) -> Result<Self> {
224 let mut expr = Expr::and(input)?;
225
226 while input.peek(kw::or) {
227 expr = Expr::Logical(Box::new(Logical::Or(
228 expr,
229 input.parse()?,
230 Expr::and(input)?,
231 )));
232 }
233
234 Ok(expr)
235 }
236
237 fn and(input: ParseStream) -> Result<Self> {
238 let mut expr = Expr::equality(input)?;
239
240 while input.peek(kw::and) {
241 expr = Expr::Logical(Box::new(Logical::And(
242 expr,
243 input.parse()?,
244 Expr::equality(input)?,
245 )));
246 }
247
248 Ok(expr)
249 }
250
251 fn equality(input: ParseStream) -> Result<Self> {
252 let mut expr = Expr::comparison(input)?;
253
254 loop {
255 if input.peek(Punct!["=="]) {
256 expr = Expr::binary(Binary::Equal(
257 expr,
258 input.parse()?,
259 Expr::comparison(input)?,
260 ));
261 } else if input.peek(Punct!["!="]) {
262 expr = Expr::binary(Binary::NotEqual(
263 expr,
264 input.parse()?,
265 Expr::comparison(input)?,
266 ));
267 } else {
268 break Ok(expr);
269 }
270 }
271 }
272
273 fn comparison(input: ParseStream) -> Result<Self> {
274 let mut expr = Expr::term(input)?;
275
276 loop {
277 if input.peek(Punct![">"]) {
278 expr = Expr::binary(Binary::Greater(expr, input.parse()?, Expr::term(input)?));
279 } else if input.peek(Punct![">="]) {
280 expr = Expr::binary(Binary::GreaterEqual(
281 expr,
282 input.parse()?,
283 Expr::term(input)?,
284 ));
285 } else if input.peek(Punct!["<"]) {
286 expr = Expr::binary(Binary::Less(expr, input.parse()?, Expr::term(input)?));
287 } else if input.peek(Punct!["<="]) {
288 expr = Expr::binary(Binary::LessEqual(expr, input.parse()?, Expr::term(input)?));
289 } else {
290 break Ok(expr);
291 }
292 }
293 }
294
295 fn term(input: ParseStream) -> Result<Self> {
296 let mut expr = Expr::factor(input)?;
297
298 loop {
299 if input.peek(Punct!["+"]) {
300 expr = Expr::binary(Binary::Add(expr, input.parse()?, Expr::factor(input)?));
301 } else if input.peek(Punct!["-"]) {
302 expr = Expr::binary(Binary::Sub(expr, input.parse()?, Expr::factor(input)?));
303 } else {
304 break Ok(expr);
305 }
306 }
307 }
308
309 fn factor(input: ParseStream) -> Result<Self> {
310 let mut expr = Expr::unary(input)?;
311
312 loop {
313 if input.peek(Punct!["*"]) {
314 expr = Expr::binary(Binary::Mul(expr, input.parse()?, Expr::unary(input)?));
315 } else if input.peek(Punct!["/"]) {
316 expr = Expr::binary(Binary::Div(expr, input.parse()?, Expr::unary(input)?));
317 } else {
318 break Ok(expr);
319 }
320 }
321 }
322
323 fn unary(input: ParseStream) -> Result<Self> {
324 if input.peek(Punct!["-"]) {
325 Ok(Expr::Unary(Box::new(Unary::Neg(
326 input.parse()?,
327 Expr::unary(input)?,
328 ))))
329 } else if input.peek(Punct!["!"]) {
330 Ok(Expr::Unary(Box::new(Unary::Not(
331 input.parse()?,
332 Expr::unary(input)?,
333 ))))
334 } else {
335 Expr::call(input)
336 }
337 }
338
339 fn call(input: ParseStream) -> Result<Self> {
340 let mut expr = Expr::primary(input)?;
341
342 loop {
343 if input.peek(Punct!["("]) {
344 expr = Expr::finish_call(input, expr)?;
345 } else if input.peek(Punct!["."]) {
346 let _: Punct!["."] = input.parse()?;
347 let name: Ident = input.parse()?;
348 expr = Expr::Get {
349 object: Box::new(expr),
350 name,
351 };
352 } else {
353 break Ok(expr);
354 }
355 }
356 }
357
358 fn finish_call(input: ParseStream<'_>, callee: Expr) -> Result<Self> {
359 let content;
360 let paren: Parentheses = group!(content in input);
361 let arguments: Punctuated<Expr, Punct![","]> =
362 Punctuated::parse_separated_trailing(&content)?;
363 let arguments: Vec<_> = arguments.into_iter().collect();
364 if arguments.len() >= 255 {
365 input.add_error(input.new_error(
366 "Can't have more than 254 arguments".to_string(),
367 paren.0.clone(),
368 error_codes::TOO_MANY_ARGS,
369 ));
370 }
371 Ok(Expr::Call {
372 callee: Box::new(callee),
373 paren,
374 arguments,
375 })
376 }
377
378 fn primary(input: ParseStream) -> Result<Self> {
379 let lookahead = input.lookahead();
380 if lookahead.peek(kw::kw_false) {
381 Ok(Expr::Literal(Literal::False(input.parse()?)))
382 } else if lookahead.peek(kw::kw_true) {
383 Ok(Expr::Literal(Literal::True(input.parse()?)))
384 } else if lookahead.peek(kw::nil) {
385 Ok(Expr::Literal(Literal::Nil(input.parse()?)))
386 } else if lookahead.peek(LitFloat) {
387 Ok(Expr::Literal(Literal::Float(input.parse()?)))
388 } else if lookahead.peek(LitInt) {
389 Ok(Expr::Literal(Literal::Int(input.parse()?)))
390 } else if lookahead.peek(LitStr) {
391 Ok(Expr::Literal(Literal::String(input.parse()?)))
392 } else if input.peek(kw::kw_super) {
393 Ok(Expr::Super {
394 keyword: input.parse()?,
395 distance: Cell::new(None),
396 dot: input.parse()?,
397 method: kw::ident(input)?,
398 })
399 } else if input.peek(kw::this) {
400 Ok(Expr::This {
401 keyword: input.parse()?,
402 distance: Cell::new(None),
403 })
404 } else if lookahead.peek(Ident) {
405 Ok(Expr::Variable {
406 name: kw::ident(input)?,
407 distance: Cell::new(None),
408 })
409 } else if lookahead.peek(Punct!["("]) {
410 let content;
411 let _: Parentheses = group!(content in input);
412 Ok(Expr::Group(Box::new(content.parse()?)))
413 } else {
414 Err(lookahead.error())
415 }
416 }
417}
418
419impl Parse for Expr {
420 fn parse(input: ParseStream) -> Result<Self> {
421 Expr::assignment(input)
422 }
423}
424
425#[derive(Debug, Clone, PartialEq)]
426struct Function {
427 name: Ident,
428 params: Vec<Ident>,
429 body: Vec<Stmt>,
430}
431
432impl Parse for Function {
433 fn parse(input: ParseStream) -> Result<Self> {
434 let name: Ident = input.parse()?;
435 let mut contents: Group<Parentheses> = input.parse()?;
436 contents.remove_whitespace();
437 let Parentheses(span) = contents.delimiters();
438 let tokens = contents.into_token_stream();
439 let params: Vec<Ident> = if tokens.is_empty() {
440 vec![]
441 } else {
442 let params: Punctuated<Ident, Punct![","]> =
443 Punctuated::parse_separated.parse(tokens)?;
444 params.into_iter().collect()
445 };
446 if params.len() >= 255 {
447 input.add_error(input.new_error(
448 "Can't have more than 254 parameters".to_string(),
449 span,
450 error_codes::TOO_MANY_ARGS,
451 ));
452 }
453 let mut contents: Group<Braces> = input.parse()?;
454 contents.remove_whitespace();
455 let body = block.parse(contents.into_token_stream())?;
456 Ok(Function { name, params, body })
457 }
458}
459
460#[derive(Debug, Clone, PartialEq)]
461enum Stmt {
462 Block(Vec<Stmt>),
463 Class {
464 name: Ident,
465 superclass: Option<Ident>,
466 superclass_distance: Cell<Option<usize>>,
467 methods: Vec<Function>,
468 },
469 Expr(Expr),
470 Function(Function),
471 If {
472 condition: Expr,
473 then_branch: Box<Stmt>,
474 else_branch: Option<Box<Stmt>>,
475 },
476 Print(Expr),
477 Return {
478 keyword: kw::kw_return,
479 value: Option<Expr>,
480 },
481 Variable {
482 name: Ident,
483 initialiser: Option<Expr>,
484 },
485 While {
486 condition: Expr,
487 body: Box<Stmt>,
488 },
489}
490
491fn block(input: ParseStream) -> Result<Vec<Stmt>> {
492 let mut statements = vec![];
493
494 while !input.is_empty() {
495 statements.push(Stmt::declaration(input)?);
496 }
497
498 Ok(statements)
499}
500
501impl Stmt {
502 fn declaration(input: ParseStream) -> Result<Self> {
503 if input.peek(kw::class) {
504 Stmt::class_declaration(input)
505 } else if input.peek(kw::fun) {
506 let _: kw::fun = input.parse()?;
507 Ok(Stmt::Function(Function::parse(input)?))
508 } else if input.peek(kw::var) {
509 Stmt::var_declaration(input)
510 } else {
511 Stmt::statement(input)
512 }
513 }
514
515 fn class_declaration(input: ParseStream) -> Result<Self> {
516 let _: kw::class = input.parse()?;
517 let name: Ident = input.parse()?;
518
519 let superclass = if input.peek(Punct!["<"]) {
520 let _: Punct!["<"] = input.parse()?;
521 Some(input.parse()?)
522 } else {
523 None
524 };
525
526 let content;
527 let _: Braces = group!(content in input);
528 let methods = parse_repeated(&content)?;
529
530 Ok(Stmt::Class {
531 name,
532 superclass,
533 superclass_distance: Cell::new(None),
534 methods,
535 })
536 }
537
538 fn var_declaration(input: ParseStream) -> Result<Self> {
539 let _: kw::var = input.parse()?;
540
541 let name = kw::ident(input)?;
542
543 let initialiser = if input.peek(Punct!["="]) {
544 let _: Punct!["="] = input.parse()?;
545 Some(input.parse()?)
546 } else {
547 None
548 };
549
550 let _: Punct![";"] = input.parse()?;
551 Ok(Stmt::Variable { name, initialiser })
552 }
553
554 fn statement(input: ParseStream) -> Result<Self> {
555 if input.peek(kw::kw_if) {
556 Stmt::if_statement(input)
557 } else if input.peek(kw::kw_for) {
558 Stmt::for_statement(input)
559 } else if input.peek(kw::print) {
560 Stmt::print_statement(input)
561 } else if input.peek(kw::kw_return) {
562 Stmt::return_statement(input)
563 } else if input.peek(kw::kw_while) {
564 Stmt::while_statement(input)
565 } else if input.peek(Punct!["{"]) {
566 let content;
567 let _: Braces = group!(content in input);
568 Ok(Stmt::Block(block(&content)?))
569 } else {
570 Stmt::expression_statement(input)
571 }
572 }
573
574 fn for_statement(input: ParseStream) -> Result<Self> {
575 let _: kw::kw_for = input.parse()?;
576
577 let content;
578 let _: Parentheses = group!(content in input);
579
580 let initialiser = if content.peek(Punct![";"]) {
581 let _: Punct![";"] = content.parse()?;
582 None
583 } else if content.peek(kw::var) {
584 Some(Stmt::var_declaration(&content)?)
585 } else {
586 Some(Stmt::expression_statement(&content)?)
587 };
588
589 let condition = if content.peek(Punct![";"]) {
590 Expr::Literal(Literal::True(kw::kw_true::new(&content)))
591 } else {
592 content.parse()?
593 };
594 let _: Punct![";"] = content.parse()?;
595
596 let increment = if content.is_empty() {
597 None
598 } else {
599 Some(content.parse()?)
600 };
601
602 let mut body = Stmt::statement(input)?;
603
604 if let Some(increment) = increment {
605 body = Stmt::Block(vec![body, Stmt::Expr(increment)]);
606 }
607
608 body = Stmt::While {
609 condition,
610 body: Box::new(body),
611 };
612
613 if let Some(initialiser) = initialiser {
614 body = Stmt::Block(vec![initialiser, body]);
615 }
616
617 Ok(body)
618 }
619
620 fn if_statement(input: ParseStream) -> Result<Self> {
621 let _: kw::kw_if = input.parse()?;
622 let content;
623 let _: Parentheses = group!(content in input);
624 let condition = content.parse()?;
625
626 let then_branch = Box::new(Stmt::statement(input)?);
627 let else_branch = if input.peek(kw::kw_else) {
628 Some(Box::new(Stmt::statement(input)?))
629 } else {
630 None
631 };
632
633 Ok(Stmt::If {
634 condition,
635 then_branch,
636 else_branch,
637 })
638 }
639
640 fn print_statement(input: ParseStream) -> Result<Self> {
641 let _: kw::print = input.parse()?;
642 let value = input.parse()?;
643 let _: Punct![";"] = input.parse()?;
644 Ok(Self::Print(value))
645 }
646
647 fn return_statement(input: ParseStream) -> Result<Self> {
648 let keyword: kw::kw_return = input.parse()?;
649 let value = if input.peek(Punct![";"]) {
650 None
651 } else {
652 Some(input.parse()?)
653 };
654 let _: Punct![";"] = input.parse()?;
655 Ok(Stmt::Return { keyword, value })
656 }
657
658 fn while_statement(input: ParseStream) -> Result<Self> {
659 let _: kw::kw_while = input.parse()?;
660 let content;
661 let _: Parentheses = group!(content in input);
662 let condition = content.parse()?;
663 let body = Box::new(Stmt::statement(input)?);
664
665 Ok(Stmt::While { condition, body })
666 }
667
668 fn expression_statement(input: ParseStream) -> Result<Self> {
669 let expr = input.parse()?;
670 let _: Punct![";"] = input.parse()?;
671 Ok(Self::Expr(expr))
672 }
673}
674
675impl Parse for Stmt {
676 fn parse(input: ParseStream) -> Result<Self> {
677 Stmt::declaration(input)
678 }
679}
680
681struct Ast(Vec<Stmt>);
682
683impl Ast {
684 #[allow(clippy::wildcard_imports)]
685 fn synchronise(input: ParseStream) {
686 input.synchronise(|input| {
687 use kw::*;
688 input.peek(Punct![";"]) && !input.peek2(Punct!["}"])
689 || peek2_any!(input, class, kw_for, fun, kw_if, print, kw_return, var, kw_while)
690 });
691 }
692}
693
694impl Parse for Ast {
695 fn parse(input: ParseStream) -> Result<Self> {
696 let mut stmts = vec![];
697
698 while !input.is_empty() {
699 match input.parse() {
700 Ok(stmt) => stmts.push(stmt),
701 Err(err) => {
702 Ast::synchronise(input);
703 input.add_error(err);
704 }
705 }
706 }
707
708 input.get_error().map_or(Ok(Ast(stmts)), Err)
709 }Sourcepub fn get_error(&self) -> Option<Error>
pub fn get_error(&self) -> Option<Error>
Returns an error consisting of all errors from
ParseBuffer::add_error, if it has been called.
Examples found in repository?
695 fn parse(input: ParseStream) -> Result<Self> {
696 let mut stmts = vec![];
697
698 while !input.is_empty() {
699 match input.parse() {
700 Ok(stmt) => stmts.push(stmt),
701 Err(err) => {
702 Ast::synchronise(input);
703 input.add_error(err);
704 }
705 }
706 }
707
708 input.get_error().map_or(Ok(Ast(stmts)), Err)
709 }Sourcepub fn synchronise<F: FnMut(ParseStream<'_>) -> bool>(&self, function: F)
pub fn synchronise<F: FnMut(ParseStream<'_>) -> bool>(&self, function: F)
Repeatedly skips tokens until function returns true or self is
empty.
Sourcepub fn parse_joint<T1: Token, T2: Token>(&self) -> Result<(T1, T2)>
pub fn parse_joint<T1: Token, T2: Token>(&self) -> Result<(T1, T2)>
Parses T1 and T2, with no whitespace allowed between them.
§Errors
Returns an error if self does not start with the required tokens.
Sourcepub fn parse_repeated<T: Parse>(&self) -> Result<Vec<T>>
pub fn parse_repeated<T: Parse>(&self) -> Result<Vec<T>>
Attempts to parse self into Vec<T>, with no separating punctuation,
fully consuming self.
To parse separated instances of T, see
Punctuated.
§Errors
Returns an error if self is not a valid sequence of T.
Sourcepub fn peek<T: Peek>(&self, token: T) -> bool
pub fn peek<T: Peek>(&self, token: T) -> bool
Returns true if the next token is an instance of T.
Examples found in repository?
41 fn parse(input: ParseStream) -> Result<Self> {
42 let mut expr = factor(input)?;
43 loop {
44 if input.peek(Punct!["+"]) {
45 expr = Expr::Add(Box::new(expr), input.parse()?, Box::new(factor(input)?));
46 } else if input.peek(Punct!["-"]) {
47 expr = Expr::Sub(Box::new(expr), input.parse()?, Box::new(factor(input)?));
48 } else {
49 break;
50 }
51 }
52 Ok(expr)
53 }
54}
55
56fn factor(input: ParseStream) -> Result<Expr> {
57 let mut expr: Expr = unary(input)?;
58 loop {
59 if input.peek(Punct!["*"]) {
60 expr = Expr::Mul(Box::new(expr), input.parse()?, Box::new(unary(input)?));
61 } else if input.peek(Punct!["/"]) {
62 expr = Expr::Div(Box::new(expr), input.parse()?, Box::new(unary(input)?));
63 } else if input.peek(Punct!["%"]) {
64 expr = Expr::Mod(Box::new(expr), input.parse()?, Box::new(unary(input)?));
65 } else {
66 break;
67 }
68 }
69 Ok(expr)
70}
71
72fn unary(input: ParseStream) -> Result<Expr> {
73 if input.peek(Punct!["-"]) {
74 Ok(Expr::Neg(input.parse()?, Box::new(unary(input)?)))
75 } else {
76 primary(input)
77 }
78}More examples
192 fn assignment(input: ParseStream) -> Result<Self> {
193 let expr = Expr::or(input)?;
194
195 if input.peek(Punct!["="]) {
196 let equals: Punct!["="] = input.parse()?;
197 let value = Box::new(Expr::assignment(input)?);
198
199 if let Expr::Variable { name, .. } = expr {
200 return Ok(Expr::Assign {
201 name,
202 value,
203 distance: Cell::new(None),
204 });
205 } else if let Expr::Get { object, name } = expr {
206 return Ok(Expr::Set {
207 object,
208 name,
209 value,
210 });
211 }
212
213 input.add_error(input.new_error(
214 "Invalid assignment target".to_string(),
215 &equals,
216 error_codes::INVALID_ASSIGN,
217 ));
218 }
219
220 Ok(expr)
221 }
222
223 fn or(input: ParseStream) -> Result<Self> {
224 let mut expr = Expr::and(input)?;
225
226 while input.peek(kw::or) {
227 expr = Expr::Logical(Box::new(Logical::Or(
228 expr,
229 input.parse()?,
230 Expr::and(input)?,
231 )));
232 }
233
234 Ok(expr)
235 }
236
237 fn and(input: ParseStream) -> Result<Self> {
238 let mut expr = Expr::equality(input)?;
239
240 while input.peek(kw::and) {
241 expr = Expr::Logical(Box::new(Logical::And(
242 expr,
243 input.parse()?,
244 Expr::equality(input)?,
245 )));
246 }
247
248 Ok(expr)
249 }
250
251 fn equality(input: ParseStream) -> Result<Self> {
252 let mut expr = Expr::comparison(input)?;
253
254 loop {
255 if input.peek(Punct!["=="]) {
256 expr = Expr::binary(Binary::Equal(
257 expr,
258 input.parse()?,
259 Expr::comparison(input)?,
260 ));
261 } else if input.peek(Punct!["!="]) {
262 expr = Expr::binary(Binary::NotEqual(
263 expr,
264 input.parse()?,
265 Expr::comparison(input)?,
266 ));
267 } else {
268 break Ok(expr);
269 }
270 }
271 }
272
273 fn comparison(input: ParseStream) -> Result<Self> {
274 let mut expr = Expr::term(input)?;
275
276 loop {
277 if input.peek(Punct![">"]) {
278 expr = Expr::binary(Binary::Greater(expr, input.parse()?, Expr::term(input)?));
279 } else if input.peek(Punct![">="]) {
280 expr = Expr::binary(Binary::GreaterEqual(
281 expr,
282 input.parse()?,
283 Expr::term(input)?,
284 ));
285 } else if input.peek(Punct!["<"]) {
286 expr = Expr::binary(Binary::Less(expr, input.parse()?, Expr::term(input)?));
287 } else if input.peek(Punct!["<="]) {
288 expr = Expr::binary(Binary::LessEqual(expr, input.parse()?, Expr::term(input)?));
289 } else {
290 break Ok(expr);
291 }
292 }
293 }
294
295 fn term(input: ParseStream) -> Result<Self> {
296 let mut expr = Expr::factor(input)?;
297
298 loop {
299 if input.peek(Punct!["+"]) {
300 expr = Expr::binary(Binary::Add(expr, input.parse()?, Expr::factor(input)?));
301 } else if input.peek(Punct!["-"]) {
302 expr = Expr::binary(Binary::Sub(expr, input.parse()?, Expr::factor(input)?));
303 } else {
304 break Ok(expr);
305 }
306 }
307 }
308
309 fn factor(input: ParseStream) -> Result<Self> {
310 let mut expr = Expr::unary(input)?;
311
312 loop {
313 if input.peek(Punct!["*"]) {
314 expr = Expr::binary(Binary::Mul(expr, input.parse()?, Expr::unary(input)?));
315 } else if input.peek(Punct!["/"]) {
316 expr = Expr::binary(Binary::Div(expr, input.parse()?, Expr::unary(input)?));
317 } else {
318 break Ok(expr);
319 }
320 }
321 }
322
323 fn unary(input: ParseStream) -> Result<Self> {
324 if input.peek(Punct!["-"]) {
325 Ok(Expr::Unary(Box::new(Unary::Neg(
326 input.parse()?,
327 Expr::unary(input)?,
328 ))))
329 } else if input.peek(Punct!["!"]) {
330 Ok(Expr::Unary(Box::new(Unary::Not(
331 input.parse()?,
332 Expr::unary(input)?,
333 ))))
334 } else {
335 Expr::call(input)
336 }
337 }
338
339 fn call(input: ParseStream) -> Result<Self> {
340 let mut expr = Expr::primary(input)?;
341
342 loop {
343 if input.peek(Punct!["("]) {
344 expr = Expr::finish_call(input, expr)?;
345 } else if input.peek(Punct!["."]) {
346 let _: Punct!["."] = input.parse()?;
347 let name: Ident = input.parse()?;
348 expr = Expr::Get {
349 object: Box::new(expr),
350 name,
351 };
352 } else {
353 break Ok(expr);
354 }
355 }
356 }
357
358 fn finish_call(input: ParseStream<'_>, callee: Expr) -> Result<Self> {
359 let content;
360 let paren: Parentheses = group!(content in input);
361 let arguments: Punctuated<Expr, Punct![","]> =
362 Punctuated::parse_separated_trailing(&content)?;
363 let arguments: Vec<_> = arguments.into_iter().collect();
364 if arguments.len() >= 255 {
365 input.add_error(input.new_error(
366 "Can't have more than 254 arguments".to_string(),
367 paren.0.clone(),
368 error_codes::TOO_MANY_ARGS,
369 ));
370 }
371 Ok(Expr::Call {
372 callee: Box::new(callee),
373 paren,
374 arguments,
375 })
376 }
377
378 fn primary(input: ParseStream) -> Result<Self> {
379 let lookahead = input.lookahead();
380 if lookahead.peek(kw::kw_false) {
381 Ok(Expr::Literal(Literal::False(input.parse()?)))
382 } else if lookahead.peek(kw::kw_true) {
383 Ok(Expr::Literal(Literal::True(input.parse()?)))
384 } else if lookahead.peek(kw::nil) {
385 Ok(Expr::Literal(Literal::Nil(input.parse()?)))
386 } else if lookahead.peek(LitFloat) {
387 Ok(Expr::Literal(Literal::Float(input.parse()?)))
388 } else if lookahead.peek(LitInt) {
389 Ok(Expr::Literal(Literal::Int(input.parse()?)))
390 } else if lookahead.peek(LitStr) {
391 Ok(Expr::Literal(Literal::String(input.parse()?)))
392 } else if input.peek(kw::kw_super) {
393 Ok(Expr::Super {
394 keyword: input.parse()?,
395 distance: Cell::new(None),
396 dot: input.parse()?,
397 method: kw::ident(input)?,
398 })
399 } else if input.peek(kw::this) {
400 Ok(Expr::This {
401 keyword: input.parse()?,
402 distance: Cell::new(None),
403 })
404 } else if lookahead.peek(Ident) {
405 Ok(Expr::Variable {
406 name: kw::ident(input)?,
407 distance: Cell::new(None),
408 })
409 } else if lookahead.peek(Punct!["("]) {
410 let content;
411 let _: Parentheses = group!(content in input);
412 Ok(Expr::Group(Box::new(content.parse()?)))
413 } else {
414 Err(lookahead.error())
415 }
416 }
417}
418
419impl Parse for Expr {
420 fn parse(input: ParseStream) -> Result<Self> {
421 Expr::assignment(input)
422 }
423}
424
425#[derive(Debug, Clone, PartialEq)]
426struct Function {
427 name: Ident,
428 params: Vec<Ident>,
429 body: Vec<Stmt>,
430}
431
432impl Parse for Function {
433 fn parse(input: ParseStream) -> Result<Self> {
434 let name: Ident = input.parse()?;
435 let mut contents: Group<Parentheses> = input.parse()?;
436 contents.remove_whitespace();
437 let Parentheses(span) = contents.delimiters();
438 let tokens = contents.into_token_stream();
439 let params: Vec<Ident> = if tokens.is_empty() {
440 vec![]
441 } else {
442 let params: Punctuated<Ident, Punct![","]> =
443 Punctuated::parse_separated.parse(tokens)?;
444 params.into_iter().collect()
445 };
446 if params.len() >= 255 {
447 input.add_error(input.new_error(
448 "Can't have more than 254 parameters".to_string(),
449 span,
450 error_codes::TOO_MANY_ARGS,
451 ));
452 }
453 let mut contents: Group<Braces> = input.parse()?;
454 contents.remove_whitespace();
455 let body = block.parse(contents.into_token_stream())?;
456 Ok(Function { name, params, body })
457 }
458}
459
460#[derive(Debug, Clone, PartialEq)]
461enum Stmt {
462 Block(Vec<Stmt>),
463 Class {
464 name: Ident,
465 superclass: Option<Ident>,
466 superclass_distance: Cell<Option<usize>>,
467 methods: Vec<Function>,
468 },
469 Expr(Expr),
470 Function(Function),
471 If {
472 condition: Expr,
473 then_branch: Box<Stmt>,
474 else_branch: Option<Box<Stmt>>,
475 },
476 Print(Expr),
477 Return {
478 keyword: kw::kw_return,
479 value: Option<Expr>,
480 },
481 Variable {
482 name: Ident,
483 initialiser: Option<Expr>,
484 },
485 While {
486 condition: Expr,
487 body: Box<Stmt>,
488 },
489}
490
491fn block(input: ParseStream) -> Result<Vec<Stmt>> {
492 let mut statements = vec![];
493
494 while !input.is_empty() {
495 statements.push(Stmt::declaration(input)?);
496 }
497
498 Ok(statements)
499}
500
501impl Stmt {
502 fn declaration(input: ParseStream) -> Result<Self> {
503 if input.peek(kw::class) {
504 Stmt::class_declaration(input)
505 } else if input.peek(kw::fun) {
506 let _: kw::fun = input.parse()?;
507 Ok(Stmt::Function(Function::parse(input)?))
508 } else if input.peek(kw::var) {
509 Stmt::var_declaration(input)
510 } else {
511 Stmt::statement(input)
512 }
513 }
514
515 fn class_declaration(input: ParseStream) -> Result<Self> {
516 let _: kw::class = input.parse()?;
517 let name: Ident = input.parse()?;
518
519 let superclass = if input.peek(Punct!["<"]) {
520 let _: Punct!["<"] = input.parse()?;
521 Some(input.parse()?)
522 } else {
523 None
524 };
525
526 let content;
527 let _: Braces = group!(content in input);
528 let methods = parse_repeated(&content)?;
529
530 Ok(Stmt::Class {
531 name,
532 superclass,
533 superclass_distance: Cell::new(None),
534 methods,
535 })
536 }
537
538 fn var_declaration(input: ParseStream) -> Result<Self> {
539 let _: kw::var = input.parse()?;
540
541 let name = kw::ident(input)?;
542
543 let initialiser = if input.peek(Punct!["="]) {
544 let _: Punct!["="] = input.parse()?;
545 Some(input.parse()?)
546 } else {
547 None
548 };
549
550 let _: Punct![";"] = input.parse()?;
551 Ok(Stmt::Variable { name, initialiser })
552 }
553
554 fn statement(input: ParseStream) -> Result<Self> {
555 if input.peek(kw::kw_if) {
556 Stmt::if_statement(input)
557 } else if input.peek(kw::kw_for) {
558 Stmt::for_statement(input)
559 } else if input.peek(kw::print) {
560 Stmt::print_statement(input)
561 } else if input.peek(kw::kw_return) {
562 Stmt::return_statement(input)
563 } else if input.peek(kw::kw_while) {
564 Stmt::while_statement(input)
565 } else if input.peek(Punct!["{"]) {
566 let content;
567 let _: Braces = group!(content in input);
568 Ok(Stmt::Block(block(&content)?))
569 } else {
570 Stmt::expression_statement(input)
571 }
572 }
573
574 fn for_statement(input: ParseStream) -> Result<Self> {
575 let _: kw::kw_for = input.parse()?;
576
577 let content;
578 let _: Parentheses = group!(content in input);
579
580 let initialiser = if content.peek(Punct![";"]) {
581 let _: Punct![";"] = content.parse()?;
582 None
583 } else if content.peek(kw::var) {
584 Some(Stmt::var_declaration(&content)?)
585 } else {
586 Some(Stmt::expression_statement(&content)?)
587 };
588
589 let condition = if content.peek(Punct![";"]) {
590 Expr::Literal(Literal::True(kw::kw_true::new(&content)))
591 } else {
592 content.parse()?
593 };
594 let _: Punct![";"] = content.parse()?;
595
596 let increment = if content.is_empty() {
597 None
598 } else {
599 Some(content.parse()?)
600 };
601
602 let mut body = Stmt::statement(input)?;
603
604 if let Some(increment) = increment {
605 body = Stmt::Block(vec![body, Stmt::Expr(increment)]);
606 }
607
608 body = Stmt::While {
609 condition,
610 body: Box::new(body),
611 };
612
613 if let Some(initialiser) = initialiser {
614 body = Stmt::Block(vec![initialiser, body]);
615 }
616
617 Ok(body)
618 }
619
620 fn if_statement(input: ParseStream) -> Result<Self> {
621 let _: kw::kw_if = input.parse()?;
622 let content;
623 let _: Parentheses = group!(content in input);
624 let condition = content.parse()?;
625
626 let then_branch = Box::new(Stmt::statement(input)?);
627 let else_branch = if input.peek(kw::kw_else) {
628 Some(Box::new(Stmt::statement(input)?))
629 } else {
630 None
631 };
632
633 Ok(Stmt::If {
634 condition,
635 then_branch,
636 else_branch,
637 })
638 }
639
640 fn print_statement(input: ParseStream) -> Result<Self> {
641 let _: kw::print = input.parse()?;
642 let value = input.parse()?;
643 let _: Punct![";"] = input.parse()?;
644 Ok(Self::Print(value))
645 }
646
647 fn return_statement(input: ParseStream) -> Result<Self> {
648 let keyword: kw::kw_return = input.parse()?;
649 let value = if input.peek(Punct![";"]) {
650 None
651 } else {
652 Some(input.parse()?)
653 };
654 let _: Punct![";"] = input.parse()?;
655 Ok(Stmt::Return { keyword, value })
656 }
657
658 fn while_statement(input: ParseStream) -> Result<Self> {
659 let _: kw::kw_while = input.parse()?;
660 let content;
661 let _: Parentheses = group!(content in input);
662 let condition = content.parse()?;
663 let body = Box::new(Stmt::statement(input)?);
664
665 Ok(Stmt::While { condition, body })
666 }
667
668 fn expression_statement(input: ParseStream) -> Result<Self> {
669 let expr = input.parse()?;
670 let _: Punct![";"] = input.parse()?;
671 Ok(Self::Expr(expr))
672 }
673}
674
675impl Parse for Stmt {
676 fn parse(input: ParseStream) -> Result<Self> {
677 Stmt::declaration(input)
678 }
679}
680
681struct Ast(Vec<Stmt>);
682
683impl Ast {
684 #[allow(clippy::wildcard_imports)]
685 fn synchronise(input: ParseStream) {
686 input.synchronise(|input| {
687 use kw::*;
688 input.peek(Punct![";"]) && !input.peek2(Punct!["}"])
689 || peek2_any!(input, class, kw_for, fun, kw_if, print, kw_return, var, kw_while)
690 });
691 }Sourcepub fn peek2<T: Peek>(&self, token: T) -> bool
pub fn peek2<T: Peek>(&self, token: T) -> bool
Returns true if the next token is an instance of T.
Note that for the purposes of this function, multi-character punctuation
like += is considered to be two tokens, and float literals are
considered to be three tokens (start, ., end).
Sourcepub fn current_span(&self) -> Result<Span>
pub fn current_span(&self) -> Result<Span>
Sourcepub fn fork(&self) -> ParseBuffer<'a>
pub fn fork(&self) -> ParseBuffer<'a>
Creates a new ParseBuffer at the same position as self.
Changes to self will not affect the fork, and vice versa.
Sourcepub fn commit(&self, fork: &Self)
pub fn commit(&self, fork: &Self)
Commits a forked buffer into self, updating self to reflect fork.
§Panics
This function will panic if fork wasn’t forked from self or if
self is further ahead than fork.
Sourcepub fn unexpected_token(&self, expected: HashSet<String>) -> Error
pub fn unexpected_token(&self, expected: HashSet<String>) -> Error
Creates an error with the message Unexpected token and the given
expected tokens.
Use of this function is generally discouraged in favour of
Lookahead::error.
Sourcepub fn lookahead(&self) -> Lookahead<'a>
pub fn lookahead(&self) -> Lookahead<'a>
Creates a helper struct for peeking at the next token.
Examples found in repository?
81fn primary(input: ParseStream) -> Result<Expr> {
82 let lookahead = input.lookahead();
83 if lookahead.peek(token::LitFloat) {
84 Ok(Expr::Num(input.parse::<token::LitFloat>()?.value()))
85 } else if lookahead.peek(token::LitInt) {
86 Ok(Expr::Num(input.parse::<token::LitInt>()?.value() as f64))
87 } else if lookahead.peek(token::LeftParen) {
88 let group: Group<Parentheses> = input.parse()?;
89 parse(group.into_token_stream())
90 } else {
91 Err(lookahead.error())
92 }
93}More examples
378 fn primary(input: ParseStream) -> Result<Self> {
379 let lookahead = input.lookahead();
380 if lookahead.peek(kw::kw_false) {
381 Ok(Expr::Literal(Literal::False(input.parse()?)))
382 } else if lookahead.peek(kw::kw_true) {
383 Ok(Expr::Literal(Literal::True(input.parse()?)))
384 } else if lookahead.peek(kw::nil) {
385 Ok(Expr::Literal(Literal::Nil(input.parse()?)))
386 } else if lookahead.peek(LitFloat) {
387 Ok(Expr::Literal(Literal::Float(input.parse()?)))
388 } else if lookahead.peek(LitInt) {
389 Ok(Expr::Literal(Literal::Int(input.parse()?)))
390 } else if lookahead.peek(LitStr) {
391 Ok(Expr::Literal(Literal::String(input.parse()?)))
392 } else if input.peek(kw::kw_super) {
393 Ok(Expr::Super {
394 keyword: input.parse()?,
395 distance: Cell::new(None),
396 dot: input.parse()?,
397 method: kw::ident(input)?,
398 })
399 } else if input.peek(kw::this) {
400 Ok(Expr::This {
401 keyword: input.parse()?,
402 distance: Cell::new(None),
403 })
404 } else if lookahead.peek(Ident) {
405 Ok(Expr::Variable {
406 name: kw::ident(input)?,
407 distance: Cell::new(None),
408 })
409 } else if lookahead.peek(Punct!["("]) {
410 let content;
411 let _: Parentheses = group!(content in input);
412 Ok(Expr::Group(Box::new(content.parse()?)))
413 } else {
414 Err(lookahead.error())
415 }
416 }Sourcepub fn skip_whitespace(&self)
pub fn skip_whitespace(&self)
Skips over all whitespace tokens before the next non-whitespace token.
This method will not skip newlines.
Sourcepub fn empty_span(&self) -> Span
pub fn empty_span(&self) -> Span
Creates a new empty Span with this stream’s source file.