ayin/src/parser/types.rs
2025-12-16 15:08:02 +02:00

146 lines
4 KiB
Rust

#[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<LocatedToken>);
impl From<Vec<LocatedToken>> for Tokens {
fn from(mut tokens: Vec<LocatedToken>) -> Tokens {
tokens.reverse();
Tokens(tokens)
}
}
impl Tokens {
pub fn peek(&mut self) -> Option<&LocatedToken> {
self.0.last()
}
pub fn next(&mut self) -> Option<LocatedToken> {
self.0.pop()
}
pub fn next_if(&mut self, token: &Token) -> Option<LocatedToken> {
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<T>(&mut self, start: &Token, end: &Token, parser: Parser<T>) -> ParseResult<T> {
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<T>(&mut self, parsers: Vec<Parser<T>>) -> ParseResult<T> {
for parser in parsers {
if let Some(result) = parser(self)? {
return Ok(Some(result));
}
}
Ok(None)
}
pub fn sep_by<T1, T2>(
&mut self,
separator: &Token,
parser1: Parser<T1>,
parser2: Parser<T2>,
) -> 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<T>(&mut self, separator: &Token, parser: Parser<T>) -> ParseResult<Vec<T>> {
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<T>(&mut self, parser: Parser<T>) -> ParseResult<Vec<T>> {
let mut results = vec![];
while let Some(result) = parser(self)? {
results.push(result);
}
Ok(Some(results))
}
}
pub type Parser<T> = fn(&mut Tokens) -> ParseResult<T>;
pub type ParseResult<T> = Result<Option<T>, Error>;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Error {
UnexpectedToken {
expected: Token,
got: Option<LocatedToken>,
},
UnexpectedEndOfInput(String),
UnexpectedTokenForParser(String, Option<LocatedToken>),
}