| 555 | |
| 556 | // Okay, so we define a `parser` function that accepts our array of `tokens`. |
| 557 | function parser(tokens) { |
| 558 | |
| 559 | // Again we keep a `current` variable that we will use as a cursor. |
| 560 | let current = 0; |
| 561 | |
| 562 | // But this time we're going to use recursion instead of a `while` loop. So we |
| 563 | // define a `walk` function. |
| 564 | function walk() { |
| 565 | |
| 566 | // Inside the walk function we start by grabbing the `current` token. |
| 567 | let token = tokens[current]; |
| 568 | |
| 569 | // We're going to split each type of token off into a different code path, |
| 570 | // starting off with `number` tokens. |
| 571 | // |
| 572 | // We test to see if we have a `number` token. |
| 573 | if (token.type === 'number') { |
| 574 | |
| 575 | // If we have one, we'll increment `current`. |
| 576 | current++; |
| 577 | |
| 578 | // And we'll return a new AST node called `NumberLiteral` and setting its |
| 579 | // value to the value of our token. |
| 580 | return { |
| 581 | type: 'NumberLiteral', |
| 582 | value: token.value, |
| 583 | }; |
| 584 | } |
| 585 | |
| 586 | // If we have a string we will do the same as number and create a |
| 587 | // `StringLiteral` node. |
| 588 | if (token.type === 'string') { |
| 589 | current++; |
| 590 | |
| 591 | return { |
| 592 | type: 'StringLiteral', |
| 593 | value: token.value, |
| 594 | }; |
| 595 | } |
| 596 | |
| 597 | // Next we're going to look for CallExpressions. We start this off when we |
| 598 | // encounter an open parenthesis. |
| 599 | if ( |
| 600 | token.type === 'paren' && |
| 601 | token.value === '(' |
| 602 | ) { |
| 603 | |
| 604 | // We'll increment `current` to skip the parenthesis since we don't care |
| 605 | // about it in our AST. |
| 606 | token = tokens[++current]; |
| 607 | |
| 608 | // We create a base node with the type `CallExpression`, and we're going |
| 609 | // to set the name as the current token's value since the next token after |
| 610 | // the open parenthesis is the name of the function. |
| 611 | let node = { |
| 612 | type: 'CallExpression', |
| 613 | name: token.value, |
| 614 | params: [], |