From dfc08ff2c6580bbeb3951b223e0332546ba3b0d9 Mon Sep 17 00:00:00 2001 From: Greg Brown Date: Thu, 6 May 2021 19:40:59 +0100 Subject: Introduce lambda expressions. --- src/nibble/mod.rs | 269 ++++++++++++++++++++++-------------------------------- 1 file changed, 111 insertions(+), 158 deletions(-) (limited to 'src/nibble/mod.rs') diff --git a/src/nibble/mod.rs b/src/nibble/mod.rs index dbb05b0..f5417db 100644 --- a/src/nibble/mod.rs +++ b/src/nibble/mod.rs @@ -2,82 +2,33 @@ pub mod convert; use std::fmt; -use proc_macro2::Span; +use proc_macro2::TokenStream; +use quote::{ToTokens, TokenStreamExt}; use syn::{ - bracketed, ext::IdentExt, parenthesized, parse::{Parse, ParseStream}, - punctuated::{Pair, Punctuated}, - token::{Bracket, Comma, Let, Match, Paren}, + punctuated::Punctuated, + token::{Let, Match, Paren}, LitStr, Token, }; -use crate::chomp::{Name, ast::{self, TopLevel}}; - -use convert::{Context, Convert, ConvertError}; - pub type Epsilon = Token![_]; pub type Ident = syn::Ident; pub type Literal = LitStr; -#[derive(Clone)] -pub struct ArgList { - paren_token: Paren, - args: Punctuated, -} - -impl ArgList { - pub fn span(&self) -> Span { - self.paren_token.span - } - - pub fn len(&self) -> usize { - self.args.len() - } - - pub fn is_empty(&self) -> bool { - self.args.is_empty() - } -} - -impl IntoIterator for ArgList { - type Item = T; - - type IntoIter = as IntoIterator>::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.args.into_iter() - } -} - -impl Parse for ArgList { - fn parse(input: ParseStream<'_>) -> syn::Result { - let args; - let paren_token = parenthesized!(args in input); - let args = args.call(Punctuated::parse_terminated)?; - Ok(Self { paren_token, args }) - } -} - -impl fmt::Debug for ArgList { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ArgList")?; - f.debug_list().entries(self.args.iter()).finish() - } -} - #[derive(Clone)] pub struct Fix { bang_token: Token![!], pub expr: Box, } -impl Fix { - pub fn span(&self) -> Option { - self.bang_token.span.join(self.expr.span()?) +impl ToTokens for Fix { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.bang_token.to_tokens(tokens); + self.expr.to_tokens(tokens); } } @@ -101,6 +52,12 @@ pub struct ParenExpression { pub expr: Expression, } +impl ToTokens for ParenExpression { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.paren_token.surround(tokens, |tokens| self.expr.to_tokens(tokens)) + } +} + impl Parse for ParenExpression { fn parse(input: ParseStream<'_>) -> syn::Result { let expr; @@ -127,14 +84,14 @@ pub enum Term { Parens(ParenExpression), } -impl Term { - pub fn span(&self) -> Option { +impl ToTokens for Term { + fn to_tokens(&self, tokens: &mut TokenStream) { match self { - Self::Epsilon(e) => Some(e.span), - Self::Ident(i) => Some(i.span()), - Self::Literal(l) => Some(l.span()), - Self::Fix(f) => f.span(), - Self::Parens(p) => Some(p.paren_token.span), + Self::Epsilon(e) => e.to_tokens(tokens), + Self::Ident(i) => i.to_tokens(tokens), + Self::Literal(l) => l.to_tokens(tokens), + Self::Fix(f) => f.to_tokens(tokens), + Self::Parens(p) => p.to_tokens(tokens), } } } @@ -174,18 +131,15 @@ impl fmt::Debug for Term { #[derive(Clone, Debug)] pub struct Call(pub Vec); -impl Call { - pub fn span(&self) -> Option { - let mut iter = self.0.iter(); - let first = iter.next()?.span()?; - iter.try_fold(first, |span, t| t.span().and_then(|s| span.join(s))) +impl ToTokens for Call { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append_all(&self.0) } } impl Parse for Call { fn parse(input: ParseStream<'_>) -> syn::Result { - let mut out = Vec::new(); - out.push(input.parse()?); + let mut out = vec![input.parse()?]; loop { let lookahead = input.lookahead1(); if lookahead.peek(Token![_]) @@ -207,34 +161,22 @@ impl Parse for Call { #[derive(Clone)] pub struct Cat(pub Punctuated); -impl Parse for Cat { - fn parse(input: ParseStream<'_>) -> syn::Result { - input.call(Punctuated::parse_separated_nonempty).map(Self) +impl ToTokens for Cat { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.0.to_tokens(tokens) } } -impl Cat { - pub fn span(&self) -> Option { - let mut iter = self.0.pairs(); - let span = match iter.next()? { - Pair::Punctuated(t, p) => t.span().and_then(|s| s.join(p.span)), - Pair::End(t) => t.span(), - }?; - - iter.try_fold(span, |span, pair| match pair { - Pair::Punctuated(t, p) => t - .span() - .and_then(|s| span.join(s)) - .and_then(|s| s.join(p.span)), - Pair::End(t) => t.span().and_then(|s| span.join(s)), - }) +impl Parse for Cat { + fn parse(input: ParseStream<'_>) -> syn::Result { + input.call(Punctuated::parse_separated_nonempty).map(Self) } } impl fmt::Debug for Cat { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Cat")?; - f.debug_list().entries(self.0.iter()).finish() + f.debug_list().entries(&self.0).finish() } } @@ -244,9 +186,10 @@ pub struct Label { pub label: Ident, } -impl Label { - pub fn span(&self) -> Option { - self.colon_tok.span.join(self.label.span()) +impl ToTokens for Label { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.colon_tok.to_tokens(tokens); + self.label.to_tokens(tokens); } } @@ -270,13 +213,12 @@ pub struct Labelled { pub label: Option