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