use crate::parser::{InfixParselet, Parser, ParserError, ParserResult, PREC_CALL};
use crate::types::{
Call, Expression, ExpressionKind, Pattern, Token, TokenKind, ValuePattern, VariablePattern,
};
#[derive(Debug, Clone)]
pub struct CallParselet;
impl CallParselet {
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 })),
}
}
fn expect_typeless_variable_pattern(
&self,
expression: Box<Expression>,
) -> Result<String, ParserError> {
match expression.kind {
ExpressionKind::Pattern(Pattern::Variable(pattern)) => {
if let VariablePattern {
name: Some(name),
type_id: None,
} = pattern
{
Ok(name)
} else {
Err(ParserError::ExpectedPattern)
}
}
_ => Err(ParserError::ExpectedPattern),
}
}
}
impl InfixParselet for CallParselet {
fn parse(&self, parser: &mut Parser, left: Box<Expression>, token: Token) -> ParserResult {
let name = self.expect_typeless_variable_pattern(left)?;
parser.consume_expect(TokenKind::LeftParen)?;
let t = parser.peek()?;
match t.kind {
TokenKind::RightParen => parser.consume_expect(TokenKind::RightParen)?,
_ => {
let expr = parser.parse_expression(0)?;
parser.consume_expect(TokenKind::RightParen)?;
return Ok(Expression {
kind: ExpressionKind::Call(Call {
name,
signature: Some(self.pattern_or_value_pattern(Box::new(expr))?),
}),
start_pos: token.start_pos,
end_pos: token.end_pos,
});
}
};
Ok(Expression {
kind: ExpressionKind::Call(Call {
name,
signature: None,
}),
start_pos: token.start_pos,
end_pos: token.end_pos,
})
}
fn get_precedence(&self) -> usize {
PREC_CALL
}
}