use crate::parser::{Parser, ParserError, ParserResult, PrefixParselet};
use crate::types::{Expression, ExpressionKind, Method, Pattern, Token, TokenKind, ValuePattern};
#[derive(Debug, Clone)]
pub struct MethodParselet;
impl MethodParselet {
fn pattern_or_value_pattern(
&self,
expression: Box<Expression>,
) -> Result<Pattern, ParserError> {
match expression.kind {
ExpressionKind::Pattern(pattern) => Ok(pattern),
_ => Ok(Pattern::Value(ValuePattern { expression })),
}
}
}
impl PrefixParselet for MethodParselet {
fn parse(&self, parser: &mut Parser, _token: Token) -> ParserResult {
let method_name = parser.consume_expect(TokenKind::Identifier)?;
parser.consume_expect(TokenKind::LeftParen)?;
let kind = match parser.peek()?.kind {
TokenKind::RightParen => {
parser.consume_expect(TokenKind::RightParen)?;
let body = Box::new(parser.parse_expression(0)?);
ExpressionKind::Method(Method {
name: parser.get_lexeme(method_name.start_pos, method_name.end_pos)?,
signature: None,
body,
})
}
_ => {
let signature =
Some(self.pattern_or_value_pattern(Box::new(parser.parse_expression(0)?))?);
parser.consume_expect(TokenKind::RightParen)?;
let body = Box::new(parser.parse_expression(0)?);
ExpressionKind::Method(Method {
name: parser.get_lexeme(method_name.start_pos, method_name.end_pos)?,
signature,
body,
})
}
};
Ok(Expression {
kind,
start_pos: 0,
end_pos: 0,
})
}
}