luaparser/parser/parse_expression/
parse_primary.rs

1use crate::parser::{
2    parse_function_expression,
3    parse_unary_expression,
4    try_parse_table_expression,
5    OptionParsingResult,
6};
7use crate::parser::token_utils::{
8    skip_first_token,
9    LuaKeyword,
10    LuaSymbol,
11};
12use crate::parser::node_types::NodeTypes;
13use crate::parser::node_types::builders::{
14    Expression,
15    UnaryOperator,
16};
17
18use lualexer::{Token, TokenType};
19use std::convert::TryFrom;
20
21pub fn try_parse_primary_expression<'a, T: NodeTypes>(
22    tokens: &'a [Token<'a>],
23) -> OptionParsingResult<'a, T::Expression> {
24    if let Some(token) = tokens.first() {
25        let expression_and_tokens = if let Ok(keyword) = LuaKeyword::try_from(token.get_content()) {
26            match keyword {
27                LuaKeyword::True => {
28                    let expression = T::Expression::true_expression();
29                    (expression, skip_first_token(tokens))
30                }
31                LuaKeyword::False => {
32                    let expression = T::Expression::false_expression();
33                    (expression, skip_first_token(tokens))
34                }
35                LuaKeyword::Nil => {
36                    let expression = T::Expression::nil_expression();
37                    (expression, skip_first_token(tokens))
38                }
39                LuaKeyword::Function => {
40                    return parse_function_expression::<T>(tokens)
41                        .map(|(function, next_tokens)| Some((function.into(), next_tokens)))
42                }
43                LuaKeyword::Not => {
44                    let (expression, tokens) = parse_unary_expression::<T>(
45                        T::UnaryOperator::not(),
46                        skip_first_token(tokens)
47                    )?;
48                    (expression.into(), tokens)
49                }
50                _ => return Ok(None),
51            }
52        } else if let Ok(symbol) = LuaSymbol::try_from(token.get_content()) {
53            match symbol {
54                LuaSymbol::OpenBrace => {
55                    return Ok(try_parse_table_expression::<T>(tokens)?
56                        .map(|(table, next_tokens)| (table.into(), next_tokens)))
57                }
58                LuaSymbol::Length => {
59                    let (expression, tokens) = parse_unary_expression::<T>(
60                        T::UnaryOperator::length(),
61                        skip_first_token(tokens)
62                    )?;
63                    (expression.into(), tokens)
64                }
65                LuaSymbol::Minus => {
66                    let (expression, tokens) = parse_unary_expression::<T>(
67                        T::UnaryOperator::minus(),
68                        skip_first_token(tokens)
69                    )?;
70                    (expression.into(), tokens)
71                }
72                LuaSymbol::VariableArguments => {
73                    (T::Expression::variable_arguments(), skip_first_token(tokens))
74                }
75                _ => return Ok(None),
76            }
77        } else {
78            match (token.get_type(), token.get_content()) {
79                (TokenType::Number, number) => {
80                    let expression = T::NumberExpression::from(number.to_owned());
81                    (expression.into(), skip_first_token(tokens))
82                }
83                (TokenType::String, string) => {
84                    let expression = T::StringExpression::from(string.to_owned());
85                    (expression.into(), skip_first_token(tokens))
86                }
87                _ => return Ok(None),
88            }
89        };
90
91        Ok(Some(expression_and_tokens))
92    } else {
93        Ok(None)
94    }
95}