1use valua_diagnostics::Span;
8
9#[cfg(feature = "serde")]
10use serde::Serialize;
11
12#[cfg_attr(feature = "serde", derive(Serialize))]
16#[derive(Debug, Clone)]
17pub struct Block {
18 pub stmts: Vec<Statement>,
19 pub span: Span,
20}
21
22#[cfg_attr(feature = "serde", derive(Serialize))]
26#[derive(Debug, Clone)]
27pub enum Statement {
28 LocalDecl(LocalDecl),
30 Assign(Assign),
32 Do(Do),
34 While(While),
36 Repeat(Repeat),
38 If(If),
40 NumericFor(NumericFor),
42 GenericFor(GenericFor),
44 FunctionDecl(FunctionDecl),
46 LocalFunctionDecl(LocalFunctionDecl),
48 Return(Return),
50 Break(Span),
52 Goto(Goto),
54 Label(Label),
56 ExprStmt(Expression),
58}
59
60#[cfg_attr(feature = "serde", derive(Serialize))]
62#[derive(Debug, Clone)]
63pub struct LocalDecl {
64 pub names: Vec<LocalName>,
65 pub values: Vec<Expression>,
66 pub span: Span,
67}
68
69#[cfg_attr(feature = "serde", derive(Serialize))]
71#[derive(Debug, Clone)]
72pub struct LocalName {
73 pub name: String,
74 pub attribute: Option<Attribute>,
76 pub span: Span,
77}
78
79#[cfg_attr(feature = "serde", derive(Serialize))]
81#[derive(Debug, Clone, Copy, PartialEq, Eq)]
82pub enum Attribute {
83 Const,
85 Close,
87}
88
89#[cfg_attr(feature = "serde", derive(Serialize))]
91#[derive(Debug, Clone)]
92pub struct Assign {
93 pub targets: Vec<Expression>,
94 pub values: Vec<Expression>,
95 pub span: Span,
96}
97
98#[cfg_attr(feature = "serde", derive(Serialize))]
100#[derive(Debug, Clone)]
101pub struct Do {
102 pub body: Block,
103 pub span: Span,
104}
105
106#[cfg_attr(feature = "serde", derive(Serialize))]
108#[derive(Debug, Clone)]
109pub struct While {
110 pub condition: Box<Expression>,
111 pub body: Block,
112 pub span: Span,
113}
114
115#[cfg_attr(feature = "serde", derive(Serialize))]
117#[derive(Debug, Clone)]
118pub struct Repeat {
119 pub body: Block,
120 pub condition: Box<Expression>,
121 pub span: Span,
122}
123
124#[cfg_attr(feature = "serde", derive(Serialize))]
126#[derive(Debug, Clone)]
127pub struct If {
128 pub condition: Box<Expression>,
129 pub then_block: Block,
130 pub elseif_clauses: Vec<ElseIf>,
131 pub else_block: Option<Block>,
132 pub span: Span,
133}
134
135#[cfg_attr(feature = "serde", derive(Serialize))]
137#[derive(Debug, Clone)]
138pub struct ElseIf {
139 pub condition: Box<Expression>,
140 pub body: Block,
141 pub span: Span,
142}
143
144#[cfg_attr(feature = "serde", derive(Serialize))]
146#[derive(Debug, Clone)]
147pub struct NumericFor {
148 pub var: String,
149 pub start: Box<Expression>,
150 pub limit: Box<Expression>,
151 pub step: Option<Box<Expression>>,
152 pub body: Block,
153 pub span: Span,
154}
155
156#[cfg_attr(feature = "serde", derive(Serialize))]
158#[derive(Debug, Clone)]
159pub struct GenericFor {
160 pub vars: Vec<String>,
161 pub iterators: Vec<Expression>,
162 pub body: Block,
163 pub span: Span,
164}
165
166#[cfg_attr(feature = "serde", derive(Serialize))]
168#[derive(Debug, Clone)]
169pub struct FunctionDecl {
170 pub name: FunctionName,
171 pub func: FunctionBody,
172 pub span: Span,
173}
174
175#[cfg_attr(feature = "serde", derive(Serialize))]
177#[derive(Debug, Clone)]
178pub struct LocalFunctionDecl {
179 pub name: String,
180 pub func: FunctionBody,
181 pub span: Span,
182}
183
184#[cfg_attr(feature = "serde", derive(Serialize))]
186#[derive(Debug, Clone)]
187pub struct FunctionName {
188 pub parts: Vec<String>,
189 pub method: Option<String>,
191 pub span: Span,
192}
193
194#[cfg_attr(feature = "serde", derive(Serialize))]
196#[derive(Debug, Clone)]
197pub struct Return {
198 pub values: Vec<Expression>,
199 pub span: Span,
200}
201
202#[cfg_attr(feature = "serde", derive(Serialize))]
204#[derive(Debug, Clone)]
205pub struct Goto {
206 pub label: String,
207 pub span: Span,
208}
209
210#[cfg_attr(feature = "serde", derive(Serialize))]
212#[derive(Debug, Clone)]
213pub struct Label {
214 pub name: String,
215 pub span: Span,
216}
217
218#[cfg_attr(feature = "serde", derive(Serialize))]
222#[derive(Debug, Clone)]
223pub struct FunctionBody {
224 pub params: Vec<Param>,
225 pub is_vararg: bool,
226 pub body: Block,
227 pub span: Span,
228}
229
230#[cfg_attr(feature = "serde", derive(Serialize))]
232#[derive(Debug, Clone)]
233pub struct Param {
234 pub name: String,
235 pub span: Span,
236}
237
238#[cfg_attr(feature = "serde", derive(Serialize))]
242#[derive(Debug, Clone)]
243pub enum Expression {
244 Nil(Span),
245 True(Span),
246 False(Span),
247 Integer(i64, Span),
248 Float(f64, Span),
249 String(String, Span),
250 Vararg(Span),
251 Name(String, Span),
252 Index(Box<Expression>, String, Span),
254 IndexExpr(Box<Expression>, Box<Expression>, Span),
256 BinOp(Box<Expression>, BinaryOp, Box<Expression>, Span),
258 UnOp(UnaryOp, Box<Expression>, Span),
260 Call(Call),
262 Function(FunctionBody),
264 Table(TableConstructor),
266}
267
268impl Expression {
269 #[must_use]
271 #[allow(clippy::match_same_arms)]
272 pub fn span(&self) -> Span {
273 match self {
274 Expression::Nil(s)
275 | Expression::True(s)
276 | Expression::False(s)
277 | Expression::Vararg(s) => *s,
278 Expression::Integer(_, s) => *s,
279 Expression::Float(_, s) => *s,
280 Expression::String(_, s) => *s,
281 Expression::Name(_, s) => *s,
282 Expression::Index(_, _, s) => *s,
283 Expression::IndexExpr(_, _, s) => *s,
284 Expression::BinOp(_, _, _, s) => *s,
285 Expression::UnOp(_, _, s) => *s,
286 Expression::Call(c) => c.span(),
287 Expression::Function(f) => f.span,
288 Expression::Table(t) => t.span,
289 }
290 }
291}
292
293#[cfg_attr(feature = "serde", derive(Serialize))]
297#[derive(Debug, Clone, Copy, PartialEq, Eq)]
298pub enum BinaryOp {
299 Add,
301 Sub,
302 Mul,
303 Div,
304 Mod,
305 Pow,
306 IDiv,
308 Lt,
310 Le,
311 Gt,
312 Ge,
313 Eq,
314 Ne,
315 And,
317 Or,
318 BitwiseAnd,
321 BitwiseOr,
323 BitwiseXor,
325 Shl,
327 Shr,
329 Concat,
332}
333
334#[cfg_attr(feature = "serde", derive(Serialize))]
336#[derive(Debug, Clone, Copy, PartialEq, Eq)]
337pub enum UnaryOp {
338 Neg,
340 Not,
342 Len,
344 BitwiseNot,
346}
347
348#[cfg_attr(feature = "serde", derive(Serialize))]
352#[derive(Debug, Clone)]
353pub enum Call {
354 Call {
356 func: Box<Expression>,
357 args: Vec<Expression>,
358 span: Span,
359 },
360 MethodCall {
362 obj: Box<Expression>,
363 method: String,
364 args: Vec<Expression>,
365 span: Span,
366 },
367}
368
369impl Call {
370 #[must_use]
371 pub fn span(&self) -> Span {
372 match self {
373 Call::Call { span, .. } | Call::MethodCall { span, .. } => *span,
374 }
375 }
376}
377
378#[cfg_attr(feature = "serde", derive(Serialize))]
382#[derive(Debug, Clone)]
383pub struct TableConstructor {
384 pub fields: Vec<TableField>,
385 pub span: Span,
386}
387
388#[cfg_attr(feature = "serde", derive(Serialize))]
390#[derive(Debug, Clone)]
391pub enum TableField {
392 ExprKey {
394 key: Box<Expression>,
395 value: Box<Expression>,
396 span: Span,
397 },
398 NameKey {
400 key: String,
401 value: Box<Expression>,
402 span: Span,
403 },
404 Positional(Expression),
406}
407
408#[cfg(test)]
409mod tests {
410 use super::*;
411
412 #[test]
413 #[ignore = "TODO: verify Block can be constructed and iterated"]
414 fn test_block_construction() {
415 todo!()
416 }
417
418 #[test]
419 #[ignore = "TODO: verify Attribute variants are distinct"]
420 fn test_attribute_variants() {
421 todo!()
422 }
423
424 #[test]
425 #[ignore = "TODO: Expression::span() returns the correct span for each variant"]
426 fn test_expression_span() {
427 todo!()
428 }
429
430 #[test]
431 #[ignore = "TODO: BinaryOp includes all bitwise variants"]
432 fn test_binary_op_bitwise_variants() {
433 todo!()
434 }
435}
436
437#[cfg_attr(feature = "serde", derive(serde::Serialize))]
445#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
446pub enum LuaTarget {
447 #[default]
449 Lua51,
450 LuaJIT,
452}