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.