Add traverser inline annotations

pull/11/head
James Kyle 8 years ago
parent d3a5ab209a
commit 7fa8ab691f

@ -329,9 +329,11 @@
*/
/**
* We're gonna start off with our first phase of parsing--lexical analysis--with the tokenizer.
* We're gonna start off with our first phase of parsing, lexical analysis, with
* the tokenizer.
*
* We're just going to take our string of code and break it down into an array of tokens.
* We're just going to take our string of code and break it down into an array
* of tokens.
*
* (add 2 (subtract 4 2)) => [{ type: 'paren', value: '(' }, ...]
*/
@ -621,14 +623,6 @@ function parser(tokens) {
return ast;
}
/**
* ----------------------------------------------------------------------------
* *Note:* This is all I've written so far, so the code below isn't annnotated
* yet. You can still read it all and it totally works, but I plan on improving
* this in the near future
* ----------------------------------------------------------------------------
*/
/**
* ============================================================================
* (><)
@ -636,38 +630,94 @@ function parser(tokens) {
* ============================================================================
*/
/**
* So now we have our AST, and we want to be able to visit different nodes with
* a visitor. We need to be able to call the methods on the visitor whenever we
* encounter a node with a matching type.
*
* traverse(ast, {
* Program(node, parent) {
* // ...
* },
*
* CallExpression(node, parent) {
* // ...
* },
*
* NumberLiteral(node, parent) {
* // ...
* }
* });
*/
// So we define a <code>traverser</code> function which accepts an AST and a
// visitor. Inside we're going to define two functions...
function traverser(ast, visitor) {
// A `traverseArray` function that will allow us to iterate over an array and
// call the next function that we will define: `traverseNode`.
function traverseArray(array, parent) {
array.forEach(function(child) {
traverseNode(child, parent);
});
}
// `traverseNode` will accept a `node` and its `parent` node. So that it can
// pass both to our visitor methods.
function traverseNode(node, parent) {
// We start by testing for the existance of a method on the visitor with a
// matching `type`.
var method = visitor[node.type];
// If it exists we'll call it with the `node` and its `parent`.
if (method) {
method(node, parent);
}
// Next we are going to split things up by the current node type.
switch (node.type) {
// We'll start with our top level `Program`. Since Program nodes have a
// property named body that has an array of nodes, we will call
// `traverseArray` to traverse down into them.
//
// (Remember that `traverseArray` will in turn call `traverseNode` so we
// are causing the tree to be traversed recursively)
case 'Program':
traverseArray(node.body, node);
break;
// Next we do the same will `CallExpressions` and traverse their `params`.
case 'CallExpression':
traverseArray(node.params, node);
break;
// In the case of `NumberLiterals` we don't have any child nodes to visit,
// so we'll just break.
case 'NumberLiteral':
break;
// And again, if we haven't recognized the node type then we'll throw an
// error.
default:
throw new TypeError(node.type);
}
}
// Finally we kickstart the traverser by calling `traverseNode` with our ast
// with no `parent` because the top level of the AST doesn't have a parent.
traverseNode(ast, null);
}
/**
* ----------------------------------------------------------------------------
* *Note:* This is all I've written so far, so the code below isn't annnotated
* yet. You can still read it all and it totally works, but I plan on improving
* this in the near future
* ----------------------------------------------------------------------------
*/
/**
* ============================================================================
* (˃̵͈̑˂̵͈̑)

Loading…
Cancel
Save