Amo/src/parser/pattern.rs

67 lines
1.6 KiB
Rust
Raw Normal View History

2022-04-06 13:23:46 +00:00
// <binding_pattern> ::= Symbol { <tight_binding_pattern> }
// <tight_binding_pattern> ::= Literal
// | Symbol
// | OpenParen <binding_pattern> CloseParen
use std::mem::{discriminant, Discriminant};
use crate::token::{Literal, Token};
use super::{Parsable, ParseError, WrappedLexer, absorb_token_or_error};
#[derive(Debug)]
pub enum TightBindingPattern {
Literal(Literal),
Symbol(String),
Group(BindingPattern),
}
impl Parsable for TightBindingPattern {
fn expected() -> (Vec<Discriminant<Token>>, bool) {
(
vec![
discriminant(&Token::Literal(Literal::Int(0))),
discriminant(&Token::Symbol(String::new())),
discriminant(&Token::OpenParen),
],
false,
)
}
fn parse(l: &mut WrappedLexer) -> Result<Self, ParseError> {
let location = l.span();
match l.curtok() {
Token::Literal(l) => Ok(TightBindingPattern::Literal(l.clone())),
Token::Symbol(name) => Ok(TightBindingPattern::Symbol(name.to_owned())),
Token::OpenParen => {
let patt = BindingPattern::parse(l)?;
absorb_token_or_error(l, discriminant(&Token::CloseParen))?;
Ok(TightBindingPattern::Group(patt))
},
_ => {
Err(ParseError {
expected: Self::expected().0,
location,
})
}
}
}
}
#[derive(Debug)]
pub struct BindingPattern(String, Vec<TightBindingPattern>);
impl Parsable for BindingPattern {
fn expected() -> (Vec<Discriminant<Token>>, bool) {
(
vec![
discriminant(&Token::Symbol(String::new())),
], false
)
}
fn parse(l: &mut WrappedLexer) -> Result<Self, ParseError> {
let name = String::parse(l)?;
let fields = Vec::parse(l)?;
Ok(Self(name, fields))
}
}