luaparser/parser/parse_expression/
parse_primary.rs1use 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}