use crate::parser::{
try_parse_arguments,
try_parse_bracket,
try_parse_field,
try_parse_method,
try_parse_parenthese_expression,
OptionParsingResult,
ParsingError,
};
use crate::parser::token_utils::skip_first_token;
use crate::parser::node_types::NodeTypes;
use crate::parser::node_types::builders::Prefix;
use lualexer::{Token, TokenType};
pub fn try_parse_prefix_expression<'a, T: NodeTypes>(
tokens: &'a [Token<'a>],
) -> OptionParsingResult<'a, T::Prefix> {
let (mut prefix, mut next_tokens) = {
if let Some((sub_expression, next_tokens)) = try_parse_parenthese_expression::<T>(tokens)? {
(T::Prefix::from_parenthese(sub_expression), next_tokens)
} else if let Some(identifier) = tokens.first()
.filter(|token| token.is_type(TokenType::Identifier))
.map(Token::get_content)
{
(T::Prefix::from_name(identifier.to_owned()), skip_first_token(tokens))
} else {
return Ok(None)
}
};
loop {
next_tokens = if let Some((field, tokens)) = try_parse_field(next_tokens) {
let field_expression = T::FieldExpression::from((prefix, field.to_owned()));
prefix = T::Prefix::from_field(field_expression);
tokens
} else if let Some((expression, tokens)) = try_parse_bracket::<T>(next_tokens)? {
let index_expression = T::IndexExpression::from((prefix, expression));
prefix = T::Prefix::from_index(index_expression);
tokens
} else if let Some((arguments, tokens)) = try_parse_arguments::<T>(next_tokens)? {
let call_expression = T::CallExpression::from((
prefix,
arguments,
None,
));
prefix = T::Prefix::from_call(call_expression);
tokens
} else if let Some((method, tokens)) = try_parse_method(next_tokens) {
let (arguments, tokens) = try_parse_arguments::<T>(tokens)?
.ok_or(ParsingError::ArgumentsExpectedAfterMethod)?;
let call_expression = T::CallExpression::from((
prefix,
arguments,
Some(method),
));
prefix = T::Prefix::from_call(call_expression);
tokens
} else {
break
}
}
Ok(Some((prefix, next_tokens)))
}