1mod 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, TableAccess, 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).map(Self::Closure)
140 }
141 TokenType::Keyword(Keyword::Nil) => Some(Self::Nil(token)),
142 TokenType::Keyword(Keyword::If) => {
143 IfExpression::parse(token, lexer, errors).map(Self::IfExpression)
144 }
145 _ => None,
146 }
147 }
148}
149
150impl Parse for Expression {
151 fn parse(mut token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
152 let maybe_unary_operator = match token.token_type {
153 TokenType::Operator(Operator::Minus | Operator::Not | Operator::Length) => {
154 let temp = token;
155 token = lexer.next_token();
156
157 Some(temp)
158 }
159 _ => None,
160 };
161
162 let left = Self::parse_inner(token, lexer, errors)?;
163 let left = if let Some(operator) = maybe_unary_operator {
164 Self::UnaryExpression {
165 operator,
166 expression: Pointer::new(left),
167 }
168 } else {
169 left
170 };
171
172 let state = lexer.save_state();
173 let next_token = lexer.next_token();
174
175 match next_token.token_type {
176 TokenType::Operator(_)
177 | TokenType::CompoundOperator(_)
178 | TokenType::Symbol(Symbol::OpeningAngleBrackets)
179 | TokenType::Symbol(Symbol::ClosingAngleBrackets) => Some(Self::BinaryExpression {
180 left: Pointer::new(left),
181 operator: next_token,
182 right: safe_unwrap!(
183 lexer,
184 errors,
185 "Expected <expr>",
186 Self::try_parse(lexer, errors).map(Pointer::new)
187 ),
188 }),
189 TokenType::Symbol(Symbol::Typecast) => Some(Self::TypeCast {
190 expression: Pointer::new(left),
191 operator: next_token,
192 cast_to: safe_unwrap!(
193 lexer,
194 errors,
195 "Expected <type>",
196 TypeValue::try_parse(lexer, errors).map(Pointer::new)
197 ),
198 }),
199 _ => {
200 lexer.set_state(state);
201 Some(left)
202 }
203 }
204 }
205}
206impl TryParse for Expression {}
207
208impl Parse for IfExpression {
209 fn parse(if_keyword: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
210 if if_keyword != TokenType::Keyword(Keyword::If) {
211 return None;
212 }
213
214 let condition = safe_unwrap!(
215 lexer,
216 errors,
217 "Expected <expr>",
218 Pointer::<Expression>::try_parse(lexer, errors)
219 );
220
221 next_token_recoverable!(
222 lexer,
223 then_keyword,
224 TokenType::Keyword(Keyword::Then),
225 TokenType::Keyword(Keyword::Then),
226 errors,
227 "Expected `then`"
228 );
229
230 let if_expression = safe_unwrap!(
231 lexer,
232 errors,
233 "Expected <expr>",
234 Pointer::<Expression>::try_parse(lexer, errors)
235 );
236
237 let else_if_expressions =
238 Pointer::<Vec<ElseIfExpression>>::try_parse(lexer, errors).unwrap_or_default();
239
240 next_token_recoverable!(
241 lexer,
242 else_keyword,
243 TokenType::Keyword(Keyword::Else),
244 TokenType::Keyword(Keyword::Else),
245 errors,
246 "Expected `else`"
247 );
248 let else_expression = safe_unwrap!(
249 lexer,
250 errors,
251 "Expected <expr>",
252 Expression::try_parse(lexer, errors).map(Pointer::new)
253 );
254
255 Some(Self {
256 if_keyword,
257 condition,
258 then_keyword,
259 if_expression,
260 else_if_expressions,
261 else_keyword,
262 else_expression,
263 })
264 }
265}
266impl TryParse for IfExpression {}
267
268impl Parse for ElseIfExpression {
269 fn parse(
270 else_if_keyword: Token,
271 lexer: &mut Lexer,
272 errors: &mut Vec<ParseError>,
273 ) -> Option<Self> {
274 if else_if_keyword != TokenType::Keyword(Keyword::Elseif) {
275 return None;
276 }
277
278 let condition = safe_unwrap!(
279 lexer,
280 errors,
281 "Expected <expr>",
282 Pointer::<Expression>::try_parse(lexer, errors)
283 );
284
285 next_token_recoverable!(
286 lexer,
287 then_keyword,
288 TokenType::Keyword(Keyword::Then),
289 TokenType::Keyword(Keyword::Then),
290 errors,
291 "Expected `then`"
292 );
293
294 let expression = safe_unwrap!(
295 lexer,
296 errors,
297 "Expected <expr>",
298 Pointer::<Expression>::try_parse(lexer, errors)
299 );
300
301 Some(Self {
302 else_if_keyword,
303 condition,
304 then_keyword,
305 expression,
306 })
307 }
308}
309impl TryParse for ElseIfExpression {}