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