Skip to content

Commit

Permalink
match_arm(s) refactor
Browse files Browse the repository at this point in the history
Use the `token_stream::FromIter` type to chain together the
Option<TokenStream> types that `match_arm` yields. There may be a way to
simplify this code. Refs lambda-fairy#121
  • Loading branch information
anxiousmodernman committed Apr 9, 2018
1 parent 3db89de commit fd43dde
Showing 1 changed file with 18 additions and 14 deletions.
32 changes: 18 additions & 14 deletions maud_macros/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ use proc_macro::{
use proc_macro::token_stream;
use std::iter;
use std::mem;
use std::iter::FromIterator;

use literalext::LiteralExt;


use super::build::Builder;
use super::ParseResult;

Expand Down Expand Up @@ -294,21 +296,21 @@ impl Parser {
}

fn match_arms(&mut self) -> ParseResult<TokenStream> {
let mut arms = Vec::new();
let mut arms: token_stream::IntoIter;
while let Some(arm) = self.match_arm()? {
arms.push(arm);
arms.chain(arm.into_iter());
}
Ok(arms.into_iter().collect())
Ok(TokenStream::from_iter(arms.into_iter()))
}

fn match_arm(&mut self) -> ParseResult<Option<TokenStream>> {
let mut pat = Vec::new();
let mut pat: Vec<TokenTree> = Vec::new();
loop {
match self.peek2() {
Some((
eq @ TokenTree { kind: TokenNode::Op('=', Spacing::Joint), .. },
Some(gt @ TokenTree { kind: TokenNode::Op('>', _), .. }),
)) => {
eq @ TokenTree::Op(o1),
Some(gt @ TokenTree::Op(o2)),
)) if o1.op() == '=' && o2.op() == '>' && o1.spacing() == Spacing::Joint => {
self.advance2();
pat.push(eq);
pat.push(gt);
Expand All @@ -328,23 +330,25 @@ impl Parser {
}
let body = match self.next() {
// $pat => { $stmts }
Some(TokenTree { kind: TokenNode::Group(Delimiter::Brace, body), span }) => {
let body = self.block(body, span)?;
Some(TokenTree::Group(body)) if body.delimiter() == Delimiter::Brace => {
let body: TokenTree = self.block(body.stream(), body.span())?;
// Trailing commas are optional if the match arm is a braced block
if let Some(TokenTree { kind: TokenNode::Op(',', _), .. }) = self.peek() {
self.advance();
if let Some(TokenTree::Op(o)) = self.peek() {
if o.op() == ',' {
self.advance();
}
}
body
},
// $pat => $expr
Some(first_token) => {
let mut span = first_token.span;
let mut span = first_token.span();
let mut body = vec![first_token];
loop {
match self.next() {
Some(TokenTree { kind: TokenNode::Op(',', _), .. }) => break,
Some(TokenTree::Op(o)) if o.op() == ',' => break,
Some(token) => {
if let Some(bigger_span) = span.join(token.span) {
if let Some(bigger_span) = span.join(token.span()) {
span = bigger_span;
}
body.push(token);
Expand Down

0 comments on commit fd43dde

Please sign in to comment.