Skip to main content

full_moon_compat_luaparse/
stream.rs

1use {
2    super::{
3        Body, CallExpression, ElseClause, ElseifClause, Expr, ExprList, ExprRef,
4        FunctionIdentifier, FunctionParameters, Identifier, IfClause, IfClauses, LastStatement,
5        NameList, Null, Param, Statement, TableConsField, TableConstructorExpr,
6        TableConstructorFields, Token, VarExpr, VarList, Variable,
7    },
8    full_moon::{
9        ast::{
10            punctuated::Iter as PIter, ElseIf, Expression, Parameter, Stmt, TableConstructorField,
11            Var,
12        },
13        tokenizer::TokenReference,
14    },
15    miniserde::{
16        ser::{Map, Seq},
17        Serialize,
18    },
19    std::borrow::Cow,
20};
21
22macro_rules! impl_Map(
23    ($name:ident : $type:literal {
24        $($s:literal: $key:literal = $field:ident,)*
25    }) => (
26        impl<'a, 'b> Map for $name<'a, 'b> {
27            next_Map!($type {
28                $($s: $key = $field,)*
29            });
30        }
31    );
32);
33
34macro_rules! next_Map(
35    ($type:literal {
36        $($s:literal: $key:literal = $field:ident,)*
37    }) => (
38        fn next(&mut self) -> Option<(Cow<str>, &dyn Serialize)> {
39            match self.state {
40                0 => type_Map!(self, $type),
41                $(
42                    $s => step_Map!($s: $key = self.$field),
43                )*
44                _ => None,
45            }
46        }
47    );
48);
49
50macro_rules! type_Map(
51    ($self:ident, $type:literal) => ({
52        $self.state = 1;
53        Some((Cow::Borrowed("type"), &$type))
54    })
55);
56macro_rules! step_Map(
57    ($s:literal: $key:literal = $self:ident.$field:ident) => ({
58        $self.state = $s + 1;
59        Some((Cow::Borrowed($key), &$self.$field))
60    });
61);
62
63pub struct ChunkStream<'a, 'b> {
64    pub(crate) state: u8,
65    pub(crate) body: Body<'a, 'b>,
66}
67
68impl_Map!(ChunkStream: "Chunk" {
69    1: "body" = body,
70});
71
72pub struct BodyStream<'a, 'b, Iter: Iterator<Item = &'b Stmt<'a>>> {
73    pub(crate) state: u8,
74    pub(crate) stmts: Iter,
75    pub(crate) curr: Option<Statement<'a, 'b>>,
76    pub(crate) last: Option<LastStatement<'a, 'b>>,
77}
78
79impl<'a, 'b, Iter> Seq for BodyStream<'a, 'b, Iter>
80where
81    Iter: Iterator<Item = &'b Stmt<'a>>,
82{
83    fn next(&mut self) -> Option<&dyn Serialize> {
84        match self.state {
85            // ignore curr, fetch next
86            0 => {
87                self.curr = self.stmts.next().map(Statement);
88                if let Some(stmt) = &self.curr {
89                    Some(stmt)
90                } else if let Some(last) = &self.last {
91                    self.state = 1;
92                    Some(last)
93                } else {
94                    self.state = 1;
95                    None
96                }
97            }
98            _ => None,
99        }
100    }
101}
102
103pub struct CallStatementStream<'a, 'b> {
104    pub(crate) state: u8,
105    pub(crate) expression: CallExpression<'a, 'b>,
106}
107impl_Map!(CallStatementStream: "CallStatement" {
108    1: "expression" = expression,
109});
110
111pub struct ForGenericStatementStream<'a, 'b> {
112    pub(crate) state: u8,
113    pub(crate) variables: NameList<'a, 'b>,
114    pub(crate) iterators: ExprList<'a, 'b>,
115    pub(crate) body: Body<'a, 'b>,
116}
117impl_Map!(ForGenericStatementStream: "ForGenericStatement" {
118    1: "variables" = variables,
119    2: "iterators" = iterators,
120    3: "body" = body,
121});
122
123pub struct ForNumericStatementStream<'a, 'b> {
124    pub(crate) state: u8,
125    pub(crate) variable: Identifier<'a, 'b>,
126    pub(crate) start: Expr<'a, 'b>,
127    pub(crate) end: Expr<'a, 'b>,
128    pub(crate) step: Option<Expr<'a, 'b>>,
129    pub(crate) body: Body<'a, 'b>,
130}
131impl_Map!(ForNumericStatementStream: "ForNumericStatement" {
132    1: "variable" = variable,
133    2: "start" = start,
134    3: "end" = end,
135    4: "step" = step,
136    5: "body" = body,
137});
138
139pub struct WhileStatementStream<'a, 'b> {
140    pub(crate) state: u8,
141    pub(crate) condition: Expr<'a, 'b>,
142    pub(crate) body: Body<'a, 'b>,
143}
144impl_Map!(WhileStatementStream: "WhileStatement" {
145    1: "condition" = condition,
146    2: "body" = body,
147});
148
149pub struct IfStatementStream<'a, 'b> {
150    pub(crate) state: u8,
151    pub(crate) clauses: IfClauses<'a, 'b>,
152}
153impl_Map!(IfStatementStream: "IfStatement" {
154    1: "clauses" = clauses,
155});
156
157pub struct IfClausesStream<'a, 'b> {
158    pub(crate) state: u8,
159    pub(crate) if_clause: IfClause<'a, 'b>,
160    pub(crate) elseif_iter: Option<std::slice::Iter<'b, ElseIf<'a>>>,
161    pub(crate) elseif_clause: Option<ElseifClause<'a, 'b>>,
162    pub(crate) else_clause: Option<ElseClause<'a, 'b>>,
163}
164impl<'a, 'b> Seq for IfClausesStream<'a, 'b> {
165    fn next(&mut self) -> Option<&dyn Serialize> {
166        match self.state {
167            0 => {
168                self.state = 1;
169                Some(&self.if_clause)
170            }
171            // ignore curr, fetch next
172            1 => {
173                if let Some(iter) = &mut self.elseif_iter {
174                    if let Some(elseif) = iter.next() {
175                        self.elseif_clause = Some(ElseifClause(elseif));
176                        return Some(&self.elseif_clause);
177                    }
178                }
179                self.state = 2;
180                self.next()
181            }
182            2 => {
183                self.state = 3;
184                self.else_clause.as_ref().map(|c| c as &dyn Serialize)
185            }
186            _ => None,
187        }
188    }
189}
190
191pub struct IfClauseStream<'a, 'b> {
192    pub(crate) state: u8,
193    pub(crate) condition: Expr<'a, 'b>,
194    pub(crate) body: Body<'a, 'b>,
195}
196pub struct ElseifClauseStream<'a, 'b> {
197    pub(crate) state: u8,
198    pub(crate) condition: Expr<'a, 'b>,
199    pub(crate) body: Body<'a, 'b>,
200}
201pub struct ElseClauseStream<'a, 'b> {
202    pub(crate) state: u8,
203    pub(crate) body: Body<'a, 'b>,
204}
205impl_Map!(IfClauseStream: "IfClause" {
206    1: "condition" = condition,
207    2: "body" = body,
208});
209impl_Map!(ElseifClauseStream: "ElseifClause" {
210    1: "condition" = condition,
211    2: "body" = body,
212});
213impl_Map!(ElseClauseStream: "ElseClause" {
214    1: "body" = body,
215});
216
217pub struct FunctionDeclarationStream<'a, 'b> {
218    pub(crate) state: u8,
219    pub(crate) is_local: bool,
220    pub(crate) identifier: FunctionIdentifier<'a, 'b>,
221    pub(crate) parameters: FunctionParameters<'a, 'b>,
222    pub(crate) body: Body<'a, 'b>,
223}
224impl_Map!(FunctionDeclarationStream: "FunctionDeclaration" {
225    1: "identifier" = identifier,
226    2: "isLocal" = is_local,
227    3: "parameters" = parameters,
228    4: "body" = body,
229});
230
231pub struct FunctionParameterStream<'a, 'b, Iter> {
232    pub(crate) iter: Iter,
233    pub(crate) place: Option<Param<'a, 'b>>,
234}
235impl<'a, 'b, Iter> Seq for FunctionParameterStream<'a, 'b, Iter>
236where
237    Iter: Iterator<Item = &'b Parameter<'a>>,
238{
239    fn next(&mut self) -> Option<&dyn Serialize> {
240        self.place = self.iter.next().map(Param);
241        self.place.as_ref().map(|r| r as &dyn Serialize)
242    }
243}
244
245pub struct AssignmentStmtStream<'a, 'b> {
246    pub(crate) state: u8,
247    pub(crate) variables: VarList<'a, 'b>,
248    pub(crate) init: ExprList<'a, 'b>,
249}
250impl_Map!(AssignmentStmtStream: "AssignmentStatement" {
251    1: "variables" = variables,
252    2: "init" = init,
253});
254pub struct LocalStatementStream<'a, 'b> {
255    pub(crate) state: u8,
256    pub(crate) variables: NameList<'a, 'b>,
257    pub(crate) init: ExprList<'a, 'b>,
258}
259impl_Map!(LocalStatementStream: "LocalStatement" {
260    1: "variables" = variables,
261    2: "init" = init,
262});
263
264pub struct NameStream<'a, 'b> {
265    pub(crate) iter: PIter<'a, 'b, Cow<'b, TokenReference<'a>>>,
266    pub(crate) curr: Option<Identifier<'a, 'b>>,
267}
268impl<'a, 'b> Seq for NameStream<'a, 'b> {
269    fn next(&mut self) -> Option<&dyn Serialize> {
270        self.curr = self.iter.next().map(|tr| Identifier(tr.clone()));
271        self.curr.as_ref().map(|r| r as &dyn Serialize)
272    }
273}
274
275pub struct VarStream<'a, 'b> {
276    pub(crate) iter: PIter<'a, 'b, Var<'a>>,
277    pub(crate) curr: Option<Variable<'a, 'b>>,
278}
279impl<'a, 'b> Seq for VarStream<'a, 'b> {
280    fn next(&mut self) -> Option<&dyn Serialize> {
281        self.curr = self.iter.next().map(Variable);
282        self.curr.as_ref().map(|r| r as &dyn Serialize)
283    }
284}
285
286pub struct CallExpressionStream<'a, 'b, Base> {
287    pub(crate) state: u8,
288    pub(crate) base: Base,
289    pub(crate) arguments: ExprList<'a, 'b>,
290}
291impl<'a, 'b, Base: Serialize> Map for CallExpressionStream<'a, 'b, Base> {
292    next_Map!("CallExpression" {
293        1: "base" = base,
294        2: "arguments" = arguments,
295    });
296}
297
298pub struct StringCallExpressionStream<'a, 'b, Base> {
299    pub(crate) state: u8,
300    pub(crate) base: Base,
301    pub(crate) argument: Token<'a, 'b>,
302}
303impl<'a, 'b, Base: Serialize> Map for StringCallExpressionStream<'a, 'b, Base> {
304    next_Map!("StringCallExpression" {
305        1: "base" = base,
306        2: "argument" = argument,
307    });
308}
309
310pub struct TableCallExpressionStream<'a, 'b, Base> {
311    pub(crate) state: u8,
312    pub(crate) base: Base,
313    pub(crate) arguments: TableConstructorExpr<'a, 'b>,
314}
315impl<'a, 'b, Base: Serialize> Map for TableCallExpressionStream<'a, 'b, Base> {
316    next_Map!("TableCallExpression" {
317        1: "base" = base,
318        2: "arguments" = arguments,
319    });
320}
321
322pub struct VarIndexExprStream<'a, 'b> {
323    pub(crate) state: u8,
324    pub(crate) base: VarExpr<'a, 'b>,
325    pub(crate) index: Expr<'a, 'b>,
326}
327impl<'a, 'b> Map for VarIndexExprStream<'a, 'b> {
328    next_Map!("IndexExpression" {
329        1: "base" = base,
330        2: "index" = index,
331    });
332}
333
334pub struct MemberExprStream<'a, 'b, Base: Serialize> {
335    pub(crate) state: u8,
336    pub(crate) base: Base,
337    pub(crate) indexer: Cow<'a, str>,
338    pub(crate) identifier: Identifier<'a, 'b>,
339}
340impl<'a, 'b, Base: Serialize> Map for MemberExprStream<'a, 'b, Base> {
341    next_Map!("MemberExpression" {
342        1: "indexer" = indexer,
343        2: "identifier" = identifier,
344        3: "base" = base,
345    });
346}
347
348pub struct IdentifierStream {
349    pub(crate) name: String,
350    pub(crate) state: u8,
351}
352impl Map for IdentifierStream {
353    next_Map!("Identifier" {
354        1: "name" = name,
355    });
356}
357
358pub struct ExprStream<'a, 'b> {
359    pub(crate) iter: PIter<'a, 'b, Expression<'a>>,
360    pub(crate) curr: Option<Expr<'a, 'b>>,
361}
362impl<'a, 'b> Seq for ExprStream<'a, 'b> {
363    fn next(&mut self) -> Option<&dyn Serialize> {
364        self.curr = self.iter.next().map(Expr);
365        self.curr.as_ref().map(|r| r as &dyn Serialize)
366    }
367}
368
369pub struct TableConstructorStream<'a, 'b> {
370    pub(crate) fields: TableConstructorFields<'a, 'b>,
371    pub(crate) state: u8,
372}
373impl_Map!(TableConstructorStream : "TableConstructorExpression" {
374    1: "fields" = fields,
375});
376
377pub struct TableConstructorFieldsStream<'a, 'b, T> {
378    pub(crate) iter: T,
379    pub(crate) curr: Option<TableConsField<'a, 'b>>,
380}
381impl<'a, 'b, T> Seq for TableConstructorFieldsStream<'a, 'b, T>
382where
383    T: Iterator<Item = &'b TableConstructorField<'a>>,
384{
385    fn next(&mut self) -> Option<&dyn Serialize> {
386        self.curr = self.iter.next().map(TableConsField);
387        self.curr.as_ref().map(|r| r as &dyn Serialize)
388    }
389}
390
391pub struct TableKeyStringStream<'a, 'b> {
392    pub(crate) state: u8,
393    pub(crate) key: Identifier<'a, 'b>,
394    pub(crate) value: Expr<'a, 'b>,
395}
396impl_Map!(TableKeyStringStream : "TableKeyString" {
397    1: "key" = key,
398    2: "value" = value,
399});
400
401pub struct TableKeyStream<'a, 'b> {
402    pub(crate) state: u8,
403    pub(crate) key: Expr<'a, 'b>,
404    pub(crate) value: Expr<'a, 'b>,
405}
406impl_Map!(TableKeyStream : "TableKey" {
407    1: "key" = key,
408    2: "value" = value,
409});
410
411pub struct TableValueStream<'a, 'b> {
412    pub(crate) state: u8,
413    pub(crate) value: Expr<'a, 'b>,
414}
415impl_Map!(TableValueStream : "TableValue" {
416    1: "value" = value,
417});
418
419pub struct StringLiteralStream<'a> {
420    pub(crate) state: u8,
421    pub(crate) value: Cow<'a, str>,
422    pub(crate) raw: String,
423}
424impl<'a> Map for StringLiteralStream<'a> {
425    next_Map!("StringLiteral" {
426        1: "value" = value,
427        2: "raw" = raw,
428    });
429}
430
431pub struct NumericLiteralStream<'a, Val: Serialize> {
432    pub(crate) state: u8,
433    pub(crate) value: Val,
434    pub(crate) raw: Cow<'a, str>,
435}
436impl<'a, Val: Serialize> Map for NumericLiteralStream<'a, Val> {
437    next_Map!("NumericLiteral" {
438        1: "value" = value,
439        2: "raw" = raw,
440    });
441}
442pub struct VarargLiteralStream {
443    pub(crate) state: u8,
444}
445impl Map for VarargLiteralStream {
446    fn next(&mut self) -> Option<(Cow<str>, &dyn Serialize)> {
447        match self.state {
448            0 => type_Map!(self, "VarargLiteral"),
449            1 => {
450                self.state = 2;
451                Some((Cow::Borrowed("value"), &"..."))
452            }
453            2 => {
454                self.state = 3;
455                Some((Cow::Borrowed("raw"), &"..."))
456            }
457            _ => None,
458        }
459    }
460}
461
462pub struct NilLiteralStream<'a> {
463    pub(crate) state: u8,
464    pub(crate) value: Null,
465    pub(crate) raw: Cow<'a, str>,
466}
467impl<'a> Map for NilLiteralStream<'a> {
468    next_Map!("NilLiteral" {
469        1: "value" = value,
470        2: "raw" = raw,
471    });
472}
473
474pub struct BooleanLiteralStream<'a> {
475    pub(crate) state: u8,
476    pub(crate) value: bool,
477    pub(crate) raw: Cow<'a, str>,
478}
479impl<'a> Map for BooleanLiteralStream<'a> {
480    next_Map!("BooleanLiteral" {
481        1: "value" = value,
482        2: "raw" = raw,
483    });
484}
485
486pub struct UnaryExprStream<'a, 'b, 'c> {
487    pub(crate) state: u8,
488    pub(crate) operator: String,
489    pub(crate) argument: ExprRef<'a, 'b, 'c>,
490    pub(crate) in_parens: bool,
491}
492impl<'a, 'b, 'c> Map for UnaryExprStream<'a, 'b, 'c> {
493    fn next(&mut self) -> Option<(Cow<str>, &dyn Serialize)> {
494        match self.state {
495            0 => type_Map!(self, "UnaryExpression"),
496            1 => step_Map!(1: "operator" = self.operator),
497            2 => step_Map!(2: "argument" = self.argument),
498            3 if self.in_parens => {
499                self.state = 4;
500                Some((Cow::Borrowed("inParens"), &self.in_parens))
501            }
502            _ => None,
503        }
504    }
505}
506
507pub struct BinaryExprStream<'a, 'b, 'c> {
508    pub(crate) state: u8,
509    pub(crate) operator: String,
510    pub(crate) left: ExprRef<'a, 'b, 'c>,
511    pub(crate) right: ExprRef<'a, 'b, 'c>,
512    pub(crate) in_parens: bool,
513    pub(crate) is_logical: bool,
514}
515impl<'a, 'b, 'c> Map for BinaryExprStream<'a, 'b, 'c> {
516    fn next(&mut self) -> Option<(Cow<str>, &dyn Serialize)> {
517        match self.state {
518            0 => {
519                self.state = 1;
520                if self.is_logical {
521                    Some((Cow::Borrowed("type"), &"LogicalExpression"))
522                } else {
523                    Some((Cow::Borrowed("type"), &"BinaryExpression"))
524                }
525            }
526            1 => step_Map!(1: "operator" = self.operator),
527            2 => step_Map!(2: "left" = self.left),
528            3 => step_Map!(3: "right" = self.right),
529            4 if self.in_parens => {
530                self.state = 5;
531                Some((Cow::Borrowed("inParens"), &self.in_parens))
532            }
533            _ => None,
534        }
535    }
536}
537
538pub struct ReturnStatementStream<'a, 'b> {
539    pub(crate) state: u8,
540    pub(crate) arguments: ExprList<'a, 'b>,
541}
542impl_Map!(ReturnStatementStream: "ReturnStatement" {
543    1: "arguments" = arguments,
544});
545
546pub struct BreakStatementStream {
547    pub(crate) state: u8,
548}
549impl Map for BreakStatementStream {
550    next_Map!("BreakStatement" {});
551}