esr/parser/
nested.rs

1use toolshed::list::ListBuilder;
2use crate::parser::Parser;
3use crate::lexer::Token;
4use crate::lexer::Token::*;
5use crate::ast::{NodeList, Expression, ExpressionNode};
6use crate::ast::expression::*;
7use crate::ast::OperatorKind::*;
8use crate::lexer::Asi;
9
10const TOTAL_TOKENS: usize = 108;
11
12type NestedHandler = Option<for<'ast> fn(&mut Parser<'ast>, ExpressionNode<'ast>) -> ExpressionNode<'ast>>;
13
14pub trait BindingPower {
15    const LUT: [NestedHandler; TOTAL_TOKENS];
16
17    #[inline]
18    fn handler(asi: Asi, token: Token) -> NestedHandler {
19        // TODO: find a cleaner solution, roll it the ASI check into lookup table somehow?
20        if asi == Asi::ImplicitSemicolon {
21            match token {
22                OperatorIncrement | OperatorDecrement => return None,
23                _ => {}
24            }
25        }
26
27        Self::LUT[token as usize]
28    }
29}
30
31macro_rules! bp {
32    ($name:ident, $table:tt) => {
33        pub struct $name;
34
35        impl BindingPower for $name {
36            const LUT: [NestedHandler; TOTAL_TOKENS] = $table;
37        }
38    }
39}
40
41/// All potential tokens, including Comma for sequence expressions
42bp!(ANY, [
43    ____, ____, ____, SEQ,  CALL, ____, CMEM, ____, ____, ____, ARRW, ____,
44//  EOF   ;     :     ,     (     )     [     ]     {     }     =>    NEW
45
46    INC,  DEC,  ____, ____, ____, ____, ____, MUL,  DIV,  REM,  EXPN, ADD,
47//  ++    --    !     ~     TYPOF VOID  DELET *     /     %     **    +
48
49    SUB,  BSL,  BSR,  UBSR, LESS, LSEQ, GRTR, GREQ, INOF, IN,   STEQ, SIEQ,
50//  -     <<    >>    >>>   <     <=    >     >=    INSOF IN    ===   !==
51
52    EQ,   INEQ, BWAN, BWXO, BWOR, AND,  OR,   COND, ASGN, ADDA, SUBA, EXPA,
53//  ==    !=    &     ^     |     &&    ||    ?     =     +=    -=    **=
54
55    MULA, DIVA, REMA, BSLA, BSRA, UBSA, BWAA, XORA, BORA, ____, ____, ____,
56//  *=    /=    %=    <<=   >>=   >>>=  &=    ^=    |=    ...   VAR   LET
57
58    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
59//  CONST BREAK DO    CASE  ELSE  CATCH EXPRT CLASS EXTND RET   WHILE FINLY
60
61    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
62//  SUPER WITH  CONT  FOR   SWTCH YIELD DBGGR FUNCT THIS  DEFLT IF    THROW
63
64    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
65//  IMPRT TRY   STATI TRUE  FALSE NULL  UNDEF STR   NUM   BIN   REGEX ENUM
66
67    ____, ____, ____, ____, ____, ____, ____, ACCS, TPLE, TPLS, ____, ____,
68//  IMPL  PCKG  PROT  IFACE PRIV  PUBLI IDENT ACCSS TPL_O TPL_C ERR_T ERR_E
69]);
70
71bp!(B0, [
72    ____, ____, ____, ____, CALL, ____, CMEM, ____, ____, ____, ARRW, ____,
73    INC,  DEC,  ____, ____, ____, ____, ____, MUL,  DIV,  REM,  EXPN, ADD,
74    SUB,  BSL,  BSR,  UBSR, LESS, LSEQ, GRTR, GREQ, INOF, IN,   STEQ, SIEQ,
75    EQ,   INEQ, BWAN, BWXO, BWOR, AND,  OR,   COND, ASGN, ADDA, SUBA, EXPA,
76    MULA, DIVA, REMA, BSLA, BSRA, UBSA, BWAA, XORA, BORA, ____, ____, ____,
77    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
78    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
79    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
80    ____, ____, ____, ____, ____, ____, ____, ACCS, TPLE, TPLS, ____, ____,
81]);
82
83bp!(B1, [
84    ____, ____, ____, ____, CALL, ____, CMEM, ____, ____, ____, ARRW, ____,
85    INC,  DEC,  ____, ____, ____, ____, ____, MUL,  DIV,  REM,  EXPN, ADD,
86    SUB,  BSL,  BSR,  UBSR, LESS, LSEQ, GRTR, GREQ, INOF, IN,   STEQ, SIEQ,
87    EQ,   INEQ, BWAN, BWXO, BWOR, AND,  OR,   COND, ASGN, ADDA, SUBA, EXPA,
88    MULA, DIVA, REMA, BSLA, BSRA, UBSA, BWAA, XORA, BORA, ____, ____, ____,
89    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
90    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
91    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
92    ____, ____, ____, ____, ____, ____, ____, ACCS, TPLE, TPLS, ____, ____,
93]);
94
95bp!(B5, [
96    ____, ____, ____, ____, CALL, ____, CMEM, ____, ____, ____, ARRW, ____,
97    INC,  DEC,  ____, ____, ____, ____, ____, MUL,  DIV,  REM,  EXPN, ADD,
98    SUB,  BSL,  BSR,  UBSR, LESS, LSEQ, GRTR, GREQ, INOF, IN,   STEQ, SIEQ,
99    EQ,   INEQ, BWAN, BWXO, BWOR, AND,  ____, ____, ____, ____, ____, ____,
100    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
101    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
102    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
103    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
104    ____, ____, ____, ____, ____, ____, ____, ACCS, TPLE, TPLS, ____, ____,
105]);
106
107bp!(B6, [
108    ____, ____, ____, ____, CALL, ____, CMEM, ____, ____, ____, ARRW, ____,
109    INC,  DEC,  ____, ____, ____, ____, ____, MUL,  DIV,  REM,  EXPN, ADD,
110    SUB,  BSL,  BSR,  UBSR, LESS, LSEQ, GRTR, GREQ, INOF, IN,   STEQ, SIEQ,
111    EQ,   INEQ, BWAN, BWXO, BWOR, ____, ____, ____, ____, ____, ____, ____,
112    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
113    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
114    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
115    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
116    ____, ____, ____, ____, ____, ____, ____, ACCS, TPLE, TPLS, ____, ____,
117]);
118
119bp!(B7, [
120    ____, ____, ____, ____, CALL, ____, CMEM, ____, ____, ____, ARRW, ____,
121    INC,  DEC,  ____, ____, ____, ____, ____, MUL,  DIV,  REM,  EXPN, ADD,
122    SUB,  BSL,  BSR,  UBSR, LESS, LSEQ, GRTR, GREQ, INOF, IN,   STEQ, SIEQ,
123    EQ,   INEQ, BWAN, BWXO, ____, ____, ____, ____, ____, ____, ____, ____,
124    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
125    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
126    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
127    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
128    ____, ____, ____, ____, ____, ____, ____, ACCS, TPLE, TPLS, ____, ____,
129]);
130
131bp!(B8, [
132    ____, ____, ____, ____, CALL, ____, CMEM, ____, ____, ____, ARRW, ____,
133    INC,  DEC,  ____, ____, ____, ____, ____, MUL,  DIV,  REM,  EXPN, ADD,
134    SUB,  BSL,  BSR,  UBSR, LESS, LSEQ, GRTR, GREQ, INOF, IN,   STEQ, SIEQ,
135    EQ,   INEQ, BWAN, ____, ____, ____, ____, ____, ____, ____, ____, ____,
136    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
137    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
138    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
139    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
140    ____, ____, ____, ____, ____, ____, ____, ACCS, TPLE, TPLS, ____, ____,
141]);
142
143bp!(B9, [
144    ____, ____, ____, ____, CALL, ____, CMEM, ____, ____, ____, ARRW, ____,
145    INC,  DEC,  ____, ____, ____, ____, ____, MUL,  DIV,  REM,  EXPN, ADD,
146    SUB,  BSL,  BSR,  UBSR, LESS, LSEQ, GRTR, GREQ, INOF, IN,   STEQ, SIEQ,
147    EQ,   INEQ, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
148    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
149    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
150    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
151    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
152    ____, ____, ____, ____, ____, ____, ____, ACCS, TPLE, TPLS, ____, ____,
153]);
154
155bp!(B10, [
156    ____, ____, ____, ____, CALL, ____, CMEM, ____, ____, ____, ARRW, ____,
157    INC,  DEC,  ____, ____, ____, ____, ____, MUL,  DIV,  REM,  EXPN, ADD,
158    SUB,  BSL,  BSR,  UBSR, LESS, LSEQ, GRTR, GREQ, INOF, IN,   ____, ____,
159    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
160    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
161    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
162    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
163    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
164    ____, ____, ____, ____, ____, ____, ____, ACCS, TPLE, TPLS, ____, ____,
165]);
166
167bp!(B11, [
168    ____, ____, ____, ____, CALL, ____, CMEM, ____, ____, ____, ARRW, ____,
169    INC,  DEC,  ____, ____, ____, ____, ____, MUL,  DIV,  REM,  EXPN, ADD,
170    SUB,  BSL,  BSR,  UBSR, ____, ____, ____, ____, ____, ____, ____, ____,
171    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
172    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
173    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
174    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
175    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
176    ____, ____, ____, ____, ____, ____, ____, ACCS, TPLE, TPLS, ____, ____,
177]);
178
179bp!(B12, [
180    ____, ____, ____, ____, CALL, ____, CMEM, ____, ____, ____, ARRW, ____,
181    INC,  DEC,  ____, ____, ____, ____, ____, MUL,  DIV,  REM,  EXPN, ADD,
182    SUB,  ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
183    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
184    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
185    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
186    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
187    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
188    ____, ____, ____, ____, ____, ____, ____, ACCS, TPLE, TPLS, ____, ____,
189]);
190
191bp!(B13, [
192    ____, ____, ____, ____, CALL, ____, CMEM, ____, ____, ____, ARRW, ____,
193    INC,  DEC,  ____, ____, ____, ____, ____, MUL,  DIV,  REM,  EXPN, ____,
194    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
195    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
196    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
197    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
198    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
199    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
200    ____, ____, ____, ____, ____, ____, ____, ACCS, TPLE, TPLS, ____, ____,
201]);
202
203bp!(B14, [
204    ____, ____, ____, ____, CALL, ____, CMEM, ____, ____, ____, ARRW, ____,
205    INC,  DEC,  ____, ____, ____, ____, ____, ____, ____, ____, EXPN, ____,
206    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
207    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
208    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
209    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
210    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
211    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
212    ____, ____, ____, ____, ____, ____, ____, ACCS, TPLE, TPLS, ____, ____,
213]);
214
215bp!(B15, [
216    ____, ____, ____, ____, CALL, ____, CMEM, ____, ____, ____, ARRW, ____,
217    INC,  DEC,  ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
218    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
219    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
220    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
221    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
222    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
223    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
224    ____, ____, ____, ____, ____, ____, ____, ACCS, TPLE, TPLS, ____, ____,
225]);
226
227const ____: NestedHandler = None;
228
229const SEQ: NestedHandler = Some(|par, left| {
230    par.lexer.consume();
231
232    let builder = ListBuilder::new(par.arena, left);
233    builder.push(par.arena, par.expression::<B0>());
234
235    while let Comma = par.lexer.token {
236        par.lexer.consume();
237        builder.push(par.arena, par.expression::<B0>());
238    }
239    let end = par.lexer.end();
240    par.alloc_at_loc(left.start, end, SequenceExpression {
241        body: builder.as_list()
242    })
243});
244
245
246const COND: NestedHandler = Some(|par, left| {
247    par.lexer.consume();
248
249    let consequent = par.expression::<B1>();
250    expect!(par, Colon);
251    let alternate = par.expression::<B1>();
252
253    par.alloc_at_loc(left.start, alternate.end, ConditionalExpression {
254        test: left,
255        consequent,
256        alternate,
257    })
258});
259
260const ARRW: NestedHandler = Some(|par, left| {
261    par.lexer.consume();
262
263    let params = match left.item {
264        Expression::Sequence(SequenceExpression { body }) => body,
265        _ => NodeList::from(par.arena, left)
266    };
267
268    let expression = par.arrow_function_expression(params);
269    let start = left.start;
270    let end = par.lexer.end();
271    par.alloc_at_loc(start, end, expression)
272});
273
274const ACCS: NestedHandler = Some(|par, left| {
275    let member = par.lexer.accessor_as_str();
276    par.lexer.consume();
277
278    let right = par.alloc_in_loc(member);
279
280    par.alloc_at_loc(left.start, right.end, MemberExpression {
281        object: left,
282        property: right,
283    })
284});
285
286const CALL: NestedHandler = Some(|par, left| {
287    let start = par.lexer.start_then_consume();
288    let arguments = par.call_arguments();
289    let end = par.lexer.end_then_consume();
290
291    par.alloc_at_loc(start, end, CallExpression {
292        callee: left,
293        arguments,
294    })
295});
296
297const CMEM: NestedHandler = Some(|par, left| {
298    par.lexer.consume();
299    let property = par.expression::<ANY>();
300
301    expect!(par, BracketClose);
302    let end = par.lexer.end();
303
304    par.alloc_at_loc(left.start, end, ComputedMemberExpression {
305        object: left,
306        property,
307    })
308});
309
310const TPLS: NestedHandler = Some(|par, left| {
311    let quasi = par.template_string();
312
313    par.alloc_at_loc(left.start, quasi.end, TaggedTemplateExpression {
314        tag: left,
315        quasi,
316    })
317});
318
319const TPLE: NestedHandler = Some(|par, left| {
320    par.tagged_template_expression(left)
321});
322
323macro_rules! postfix {
324    ($name:ident => $op:ident) => {
325        const $name: NestedHandler = {
326            fn handler<'ast>(par: &mut Parser<'ast>, left: ExpressionNode<'ast>) -> ExpressionNode<'ast> {
327                let end = par.lexer.end();
328                par.lexer.consume();
329
330                if !left.is_lvalue() {
331                    par.error::<()>();
332                }
333
334                par.alloc_at_loc(left.start, end, PostfixExpression {
335                    operator: $op,
336                    operand: left,
337                })
338            }
339
340            Some(handler)
341        };
342    }
343}
344
345macro_rules! assign {
346    ($name:ident => $op:ident) => {
347        const $name: NestedHandler = {
348            fn handler<'ast>(par: &mut Parser<'ast>, left: ExpressionNode<'ast>) -> ExpressionNode<'ast> {
349                par.lexer.consume();
350
351                if !left.is_lvalue() {
352                    par.error::<()>();
353                }
354
355                let right = par.expression::<B1>();
356
357                par.alloc_at_loc(left.start, right.end, BinaryExpression {
358                    operator: $op,
359                    left,
360                    right,
361                })
362            }
363
364            Some(handler)
365        };
366    }
367}
368
369macro_rules! binary {
370    ($name:ident, $bp:ident => $op:ident) => {
371        const $name: NestedHandler = {
372            fn handler<'ast>(par: &mut Parser<'ast>, left: ExpressionNode<'ast>) -> ExpressionNode<'ast> {
373                par.lexer.consume();
374
375                let right = par.expression::<$bp>();
376
377                par.alloc_at_loc(left.start, right.end, BinaryExpression {
378                    operator: $op,
379                    left,
380                    right,
381                })
382            }
383
384            Some(handler)
385        };
386    }
387}
388
389postfix!(INC => Increment);
390postfix!(DEC => Decrement);
391
392assign!(ASGN => Assign);
393assign!(ADDA => AddAssign);
394assign!(SUBA => SubtractAssign);
395assign!(EXPA => ExponentAssign);
396assign!(MULA => MultiplyAssign);
397assign!(DIVA => DivideAssign);
398assign!(REMA => RemainderAssign);
399assign!(BSLA => BSLAssign);
400assign!(BSRA => BSRAssign);
401assign!(UBSA => UBSRAssign);
402assign!(BWAA => BitAndAssign);
403assign!(XORA => BitXorAssign);
404assign!(BORA => BitOrAssign);
405
406binary!(OR   , B5  => LogicalOr);
407binary!(AND  , B6  => LogicalAnd);
408binary!(BWOR , B7  => BitwiseOr);
409binary!(BWXO , B8  => BitwiseXor);
410binary!(BWAN , B9  => BitwiseAnd);
411binary!(STEQ , B10 => StrictEquality);
412binary!(SIEQ , B10 => StrictInequality);
413binary!(EQ   , B10 => Equality);
414binary!(INEQ , B10 => Inequality);
415binary!(LESS , B11 => Lesser);
416binary!(LSEQ , B11 => LesserEquals);
417binary!(GRTR , B11 => Greater);
418binary!(GREQ , B11 => GreaterEquals);
419binary!(INOF , B11 => Instanceof);
420binary!(IN   , B11 => In);
421binary!(BSL  , B12 => BitShiftLeft);
422binary!(BSR  , B12 => BitShiftRight);
423binary!(UBSR , B12 => UBitShiftRight);
424binary!(ADD  , B13 => Addition);
425binary!(SUB  , B13 => Subtraction);
426binary!(MUL  , B14 => Multiplication);
427binary!(DIV  , B14 => Division);
428binary!(REM  , B14 => Remainder);
429binary!(EXPN , B15 => Exponent);
430
431
432impl<'ast> Parser<'ast> {
433    #[inline]
434    pub fn nested_expression<B>(&mut self, mut left: ExpressionNode<'ast>) -> ExpressionNode<'ast>
435    where
436        B: BindingPower
437    {
438        while let Some(handler) = B::handler(self.asi(), self.lexer.token) {
439            left = handler(self, left);
440        }
441
442        left
443    }
444}