luaparser 0.1.1

Read Lua 5.1 code and produce an abstract syntax tree
Documentation
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)))
}