#[derive(Debug, Clone, PartialEq, Eq)] pub struct LocatedToken { pub start: usize, pub end: usize, pub token: Token, } #[derive(Debug, Clone, PartialEq, Eq)] pub enum Token { Let, Fn, Return, Equals, OpenParen, CloseParen, OpenBracket, CloseBracket, OpenCurly, CloseCurly, Dot, Comma, Semicolon, Colon, True, False, Number(u32), String(String), Identifier(String), } #[derive(Debug, Clone, PartialEq, Eq)] pub struct Tokens(pub Vec); impl From> for Tokens { fn from(mut tokens: Vec) -> Tokens { tokens.reverse(); Tokens(tokens) } } impl Tokens { pub fn peek(&mut self) -> Option<&LocatedToken> { self.0.last() } pub fn next(&mut self) -> Option { self.0.pop() } pub fn next_if(&mut self, token: &Token) -> Option { self.0.pop_if(|t| match (t.token.clone(), token) { (a, b) if a == *b => true, (Token::Identifier(_), Token::Identifier(_)) => true, (Token::Number(_), Token::Number(_)) => true, (Token::String(_), Token::String(_)) => true, _ => false, }) } pub fn between(&mut self, start: &Token, end: &Token, parser: Parser) -> ParseResult { if let Some(_start) = self.next_if(start) { if let Some(result) = parser(self)? { if let Some(_end) = self.next_if(end) { Ok(Some(result)) } else { Err(Error::UnexpectedTokenForParser( "between".into(), self.next(), )) } } else { Err(Error::UnexpectedTokenForParser( "between".into(), self.next(), )) } } else { Ok(None) } } pub fn one_of(&mut self, parsers: Vec>) -> ParseResult { for parser in parsers { if let Some(result) = parser(self)? { return Ok(Some(result)); } } Ok(None) } pub fn sep_by( &mut self, separator: &Token, parser1: Parser, parser2: Parser, ) -> ParseResult<(T1, T2)> { if let Some(t1) = parser1(self)? { let _sep = self .next_if(separator) .ok_or(Error::UnexpectedEndOfInput("between".into()))?; if let Some(t2) = parser2(self)? { Ok(Some((t1, t2))) } else { Err(Error::UnexpectedTokenForParser( "sep_by".into(), self.next(), )) } } else { Ok(None) } } pub fn many_sep_by(&mut self, separator: &Token, parser: Parser) -> ParseResult> { if let Some(first) = parser(self)? { let mut results = vec![first]; while let Some(_) = self.next_if(&separator) { if let Some(result) = parser(self)? { results.push(result); } else { return Err(Error::UnexpectedTokenForParser( "sep_by_many".into(), self.next(), )); } } Ok(Some(results)) } else { Ok(None) } } pub fn many(&mut self, parser: Parser) -> ParseResult> { let mut results = vec![]; while let Some(result) = parser(self)? { results.push(result); } Ok(Some(results)) } } pub type Parser = fn(&mut Tokens) -> ParseResult; pub type ParseResult = Result, Error>; #[derive(Debug, Clone, PartialEq, Eq)] pub enum Error { UnexpectedToken { expected: Token, got: Option, }, UnexpectedEndOfInput(String), UnexpectedTokenForParser(String, Option), }