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