luau_parser/impl/expression/
mod.rs1mod function;
4mod table;
5mod var;
6
7use luau_lexer::prelude::{
8 Keyword, Lexer, Literal, Operator, ParseError, Symbol, Token, TokenType,
9};
10
11use crate::{
12 handle_error_token, parse_bracketed, safe_unwrap,
13 types::{
14 Bracketed, Closure, ElseIfExpression, Expression, ExpressionWrap, FunctionArguments,
15 FunctionCall, FunctionCallInvoked, IfExpression, Parse, ParseWithArgs, Pointer, PrefixExp,
16 Table, TryParse, TypeValue, Var,
17 },
18 utils::get_token_type_display,
19};
20
21impl Parse for PrefixExp {
22 fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
23 let var: Option<Var> = Var::parse(token.clone(), lexer, errors);
24 if let Some(var) = var {
25 maybe_next_token!(lexer, colon, TokenType::Symbol(Symbol::Colon));
26 let invoked = if let Some(colon) = colon {
27 next_token_recoverable!(
28 lexer,
29 method,
30 TokenType::Identifier(_) | TokenType::PartialKeyword(_),
31 TokenType::Identifier("*error*".into(),),
32 errors,
33 "Expected ".to_string()
34 + get_token_type_display(&TokenType::Identifier("".into(),))
35 );
36
37 FunctionCallInvoked::TableMethod {
38 table: Pointer::new(PrefixExp::Var(var.clone())),
39 colon: Pointer::new(colon),
40 method: Pointer::new(method),
41 }
42 } else {
43 FunctionCallInvoked::Function(Pointer::new(PrefixExp::Var(var.clone())))
44 };
45
46 return FunctionCall::try_parse_with_invoked(lexer, errors, invoked)
47 .map(Self::FunctionCall)
48 .or(Some(Self::Var(var)));
49 }
50
51 if token == TokenType::Symbol(Symbol::OpeningParenthesis) {
52 let expression_wrap = Bracketed::<Pointer<Expression>>::parse_with(
53 token,
54 lexer,
55 errors,
56 ("Expected <expr>", Symbol::ClosingParenthesis),
57 );
58
59 if let Some(expression_wrap) = expression_wrap {
60 FunctionCall::try_parse_with_invoked(
61 lexer,
62 errors,
63 FunctionCallInvoked::Function(Pointer::new(PrefixExp::ExpressionWrap(
64 expression_wrap.clone(),
65 ))),
66 )
67 .map(Self::FunctionCall)
68 .or(Some(Self::ExpressionWrap(expression_wrap)))
69 } else {
70 None
71 }
72 } else {
73 None
74 }
75 }
76}
77impl TryParse for PrefixExp {}
78
79impl Expression {
80 pub fn parse_from_literal(token: Token) -> Option<Self> {
82 match &token.token_type {
83 TokenType::Literal(literal) => match literal {
84 Literal::Number(_) => Some(Self::Number(token)),
85 Literal::String(_) => Some(Self::String(token)),
86 Literal::Boolean(_) => Some(Self::Boolean(token)),
87 },
88 _ => None,
89 }
90 }
91
92 fn parse_inner(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
95 match token.token_type {
96 TokenType::Error(error) => handle_error_token!(errors, error),
97 TokenType::Literal(_) => Self::parse_from_literal(token),
98 TokenType::Identifier(_)
99 | TokenType::PartialKeyword(_)
100 | TokenType::Symbol(Symbol::OpeningParenthesis) => {
101 match PrefixExp::parse(token, lexer, errors) {
102 Some(PrefixExp::ExpressionWrap(wrap)) => Some(Self::ExpressionWrap(wrap)),
103 Some(PrefixExp::FunctionCall(function_call)) => {
104 Some(Self::FunctionCall(function_call))
105 }
106 Some(PrefixExp::Var(var)) => Some(Self::Var(var)),
107 None => None,
108 }
109 }
110 TokenType::Symbol(Symbol::OpeningCurlyBrackets) => {
111 Table::parse_with(token, lexer, errors, false).map(Self::Table)
112 }
113 TokenType::Keyword(Keyword::Function) | TokenType::Symbol(Symbol::At) => {
114 Closure::parse(token, lexer, errors).map(Self::Closure)
115 }
116 TokenType::Keyword(Keyword::Nil) => Some(Self::Nil(token)),
117 TokenType::Keyword(Keyword::If) => {
118 IfExpression::parse(token, lexer, errors).map(Self::IfExpression)
119 }
120 _ => None,
121 }
122 }
123}
124
125impl Parse for Expression {
126 fn parse(mut token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
127 let maybe_unary_operator = match token.token_type {
128 TokenType::Operator(Operator::Minus | Operator::Not | Operator::Length) => {
129 let temp = token;
130 token = lexer.next_token();
131
132 Some(temp)
133 }
134 _ => None,
135 };
136
137 let left = Self::parse_inner(token, lexer, errors)?;
138 let left = if let Some(operator) = maybe_unary_operator {
139 Self::UnaryExpression {
140 operator,
141 expression: Pointer::new(left),
142 }
143 } else {
144 left
145 };
146
147 let state = lexer.save_state();
148 let next_token = lexer.next_token();
149
150 match next_token.token_type {
151 TokenType::Operator(_)
152 | TokenType::CompoundOperator(_)
153 | TokenType::Symbol(Symbol::OpeningAngleBrackets)
154 | TokenType::Symbol(Symbol::ClosingAngleBrackets) => Some(Self::BinaryExpression {
155 left: Pointer::new(left),
156 operator: next_token,
157 right: safe_unwrap!(
158 lexer,
159 errors,
160 "Expected <expr>",
161 Self::try_parse(lexer, errors).map(Pointer::new)
162 ),
163 }),
164 TokenType::Symbol(Symbol::Typecast) => Some(Self::TypeCast {
165 expression: Pointer::new(left),
166 operator: next_token,
167 cast_to: safe_unwrap!(
168 lexer,
169 errors,
170 "Expected <type>",
171 TypeValue::try_parse(lexer, errors).map(Pointer::new)
172 ),
173 }),
174 _ => {
175 lexer.set_state(state);
176 Some(left)
177 }
178 }
179 }
180}
181impl TryParse for Expression {}
182
183impl Parse for IfExpression {
184 fn parse(if_keyword: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
185 if if_keyword != TokenType::Keyword(Keyword::If) {
186 return None;
187 }
188
189 let condition = safe_unwrap!(
190 lexer,
191 errors,
192 "Expected <expr>",
193 Pointer::<Expression>::try_parse(lexer, errors)
194 );
195
196 next_token_recoverable!(
197 lexer,
198 then_keyword,
199 TokenType::Keyword(Keyword::Then),
200 TokenType::Keyword(Keyword::Then),
201 errors,
202 "Expected `then`"
203 );
204
205 let if_expression = safe_unwrap!(
206 lexer,
207 errors,
208 "Expected <expr>",
209 Pointer::<Expression>::try_parse(lexer, errors)
210 );
211
212 let else_if_expressions =
213 Pointer::<Vec<ElseIfExpression>>::try_parse(lexer, errors).unwrap_or_default();
214
215 next_token_recoverable!(
216 lexer,
217 else_keyword,
218 TokenType::Keyword(Keyword::Else),
219 TokenType::Keyword(Keyword::Else),
220 errors,
221 "Expected `else`"
222 );
223 let else_expression = safe_unwrap!(
224 lexer,
225 errors,
226 "Expected <expr>",
227 Expression::try_parse(lexer, errors).map(Pointer::new)
228 );
229
230 Some(Self {
231 if_keyword,
232 condition,
233 then_keyword,
234 if_expression,
235 else_if_expressions,
236 else_keyword,
237 else_expression,
238 })
239 }
240}
241impl TryParse for IfExpression {}
242
243impl Parse for ElseIfExpression {
244 fn parse(
245 else_if_keyword: Token,
246 lexer: &mut Lexer,
247 errors: &mut Vec<ParseError>,
248 ) -> Option<Self> {
249 if else_if_keyword != TokenType::Keyword(Keyword::Elseif) {
250 return None;
251 }
252
253 let condition = safe_unwrap!(
254 lexer,
255 errors,
256 "Expected <expr>",
257 Pointer::<Expression>::try_parse(lexer, errors)
258 );
259
260 next_token_recoverable!(
261 lexer,
262 then_keyword,
263 TokenType::Keyword(Keyword::Then),
264 TokenType::Keyword(Keyword::Then),
265 errors,
266 "Expected `then`"
267 );
268
269 let expression = safe_unwrap!(
270 lexer,
271 errors,
272 "Expected <expr>",
273 Pointer::<Expression>::try_parse(lexer, errors)
274 );
275
276 Some(Self {
277 else_if_keyword,
278 condition,
279 then_keyword,
280 expression,
281 })
282 }
283}
284impl TryParse for ElseIfExpression {}