mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
added the ability to print the parse tree
This commit is contained in:
parent
950d1199c2
commit
7c01bba4f4
6 changed files with 92 additions and 10 deletions
|
@ -185,6 +185,19 @@
|
|||
}
|
||||
return false;
|
||||
};
|
||||
// toString representation of the node, for inspecting the parse tree.
|
||||
Node.prototype.toString = function toString(idt) {
|
||||
var __a, __b, __c, child;
|
||||
idt = idt || '';
|
||||
return (this.type || 'anon') + "\n" + ((function() {
|
||||
__a = []; __b = this.children;
|
||||
for (__c = 0; __c < __b.length; __c++) {
|
||||
child = __b[__c];
|
||||
__a.push(idt + TAB + child.toString(idt + TAB));
|
||||
}
|
||||
return __a;
|
||||
}).call(this));
|
||||
};
|
||||
// Default implementations of the common node methods.
|
||||
Node.prototype.unwrap = function unwrap() {
|
||||
return this;
|
||||
|
@ -201,6 +214,7 @@
|
|||
};
|
||||
// A collection of nodes, each one representing an expression.
|
||||
Expressions = (exports.Expressions = inherit(Node, {
|
||||
type: 'Expressions',
|
||||
constructor: function constructor(nodes) {
|
||||
this.children = (this.expressions = compact(flatten(nodes)));
|
||||
return this;
|
||||
|
@ -310,6 +324,7 @@
|
|||
// Literals are static values that can be passed through directly into
|
||||
// JavaScript without translation, eg.: strings, numbers, true, false, null...
|
||||
LiteralNode = (exports.LiteralNode = inherit(Node, {
|
||||
type: 'Literal',
|
||||
constructor: function constructor(value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
|
@ -329,6 +344,7 @@
|
|||
LiteralNode.prototype.is_statement_only = LiteralNode.prototype.is_statement;
|
||||
// Return an expression, or wrap it in a closure and return it.
|
||||
ReturnNode = (exports.ReturnNode = inherit(Node, {
|
||||
type: 'Return',
|
||||
constructor: function constructor(expression) {
|
||||
this.children = [(this.expression = expression)];
|
||||
return this;
|
||||
|
@ -345,6 +361,7 @@
|
|||
statement(ReturnNode, true);
|
||||
// A value, indexed or dotted into, or vanilla.
|
||||
ValueNode = (exports.ValueNode = inherit(Node, {
|
||||
type: 'Value',
|
||||
SOAK: " == undefined ? undefined : ",
|
||||
constructor: function constructor(base, properties) {
|
||||
this.children = flatten((this.base = base), (this.properties = (properties || [])));
|
||||
|
@ -413,6 +430,7 @@
|
|||
// Pass through CoffeeScript comments into JavaScript comments at the
|
||||
// same position.
|
||||
CommentNode = (exports.CommentNode = inherit(Node, {
|
||||
type: 'Comment',
|
||||
constructor: function constructor(lines) {
|
||||
this.lines = lines;
|
||||
return this;
|
||||
|
@ -427,6 +445,7 @@
|
|||
// Node for a function invocation. Takes care of converting super() calls into
|
||||
// calls against the prototype's function of the same name.
|
||||
CallNode = (exports.CallNode = inherit(Node, {
|
||||
type: 'Call',
|
||||
constructor: function constructor(variable, args) {
|
||||
this.children = flatten([(this.variable = variable), (this.args = (args || []))]);
|
||||
this.prefix = '';
|
||||
|
@ -501,6 +520,7 @@
|
|||
// Node to extend an object's prototype with an ancestor object.
|
||||
// After goog.inherits from the Closure Library.
|
||||
ExtendsNode = (exports.ExtendsNode = inherit(Node, {
|
||||
type: 'Extends',
|
||||
constructor: function constructor(child, parent) {
|
||||
this.children = [(this.child = child), (this.parent = parent)];
|
||||
return this;
|
||||
|
@ -518,6 +538,7 @@
|
|||
// A dotted accessor into a part of a value, or the :: shorthand for
|
||||
// an accessor into the object's prototype.
|
||||
AccessorNode = (exports.AccessorNode = inherit(Node, {
|
||||
type: 'Accessor',
|
||||
constructor: function constructor(name, tag) {
|
||||
this.children = [(this.name = name)];
|
||||
this.prototype = tag === 'prototype';
|
||||
|
@ -530,6 +551,7 @@
|
|||
}));
|
||||
// An indexed accessor into a part of an array or object.
|
||||
IndexNode = (exports.IndexNode = inherit(Node, {
|
||||
type: 'Index',
|
||||
constructor: function constructor(index) {
|
||||
this.children = [(this.index = index)];
|
||||
return this;
|
||||
|
@ -540,6 +562,7 @@
|
|||
}));
|
||||
// A this-reference, using '@'.
|
||||
ThisNode = (exports.ThisNode = inherit(Node, {
|
||||
type: 'This',
|
||||
constructor: function constructor(property) {
|
||||
this.property = property || null;
|
||||
return this;
|
||||
|
@ -551,6 +574,7 @@
|
|||
// A range literal. Ranges can be used to extract portions (slices) of arrays,
|
||||
// or to specify a range for list comprehensions.
|
||||
RangeNode = (exports.RangeNode = inherit(Node, {
|
||||
type: 'Range',
|
||||
constructor: function constructor(from, to, exclusive) {
|
||||
this.children = [(this.from = from), (this.to = to)];
|
||||
this.exclusive = !!exclusive;
|
||||
|
@ -594,6 +618,7 @@
|
|||
// specifies the index of the end of the slice (just like the first parameter)
|
||||
// is the index of the beginning.
|
||||
SliceNode = (exports.SliceNode = inherit(Node, {
|
||||
type: 'Slice',
|
||||
constructor: function constructor(range) {
|
||||
this.children = [(this.range = range)];
|
||||
return this;
|
||||
|
@ -608,6 +633,7 @@
|
|||
}));
|
||||
// An object literal.
|
||||
ObjectNode = (exports.ObjectNode = inherit(Node, {
|
||||
type: 'Object',
|
||||
constructor: function constructor(props) {
|
||||
this.objects = (this.properties = props || []);
|
||||
return this;
|
||||
|
@ -652,6 +678,7 @@
|
|||
}));
|
||||
// An array literal.
|
||||
ArrayNode = (exports.ArrayNode = inherit(Node, {
|
||||
type: 'Array',
|
||||
constructor: function constructor(objects) {
|
||||
this.children = (this.objects = objects || []);
|
||||
return this;
|
||||
|
@ -706,6 +733,7 @@
|
|||
});
|
||||
// Setting the value of a local variable, or the value of an object property.
|
||||
AssignNode = (exports.AssignNode = inherit(Node, {
|
||||
type: 'Assign',
|
||||
PROTO_ASSIGN: /^(\S+)\.prototype/,
|
||||
LEADING_DOT: /^\.(prototype\.)?/,
|
||||
constructor: function constructor(variable, value, context) {
|
||||
|
@ -809,6 +837,7 @@
|
|||
// A function definition. The only node that creates a new Scope.
|
||||
// A CodeNode does not have any children -- they're within the new scope.
|
||||
CodeNode = (exports.CodeNode = inherit(Node, {
|
||||
type: 'Code',
|
||||
constructor: function constructor(params, body, tag) {
|
||||
this.params = params;
|
||||
this.body = body;
|
||||
|
@ -854,6 +883,7 @@
|
|||
// A splat, either as a parameter to a function, an argument to a call,
|
||||
// or in a destructuring assignment.
|
||||
SplatNode = (exports.SplatNode = inherit(Node, {
|
||||
type: 'Splat',
|
||||
constructor: function constructor(name) {
|
||||
this.children = [(this.name = name)];
|
||||
return this;
|
||||
|
@ -874,6 +904,7 @@
|
|||
// A while loop, the only sort of low-level loop exposed by CoffeeScript. From
|
||||
// it, all other loops can be manufactured.
|
||||
WhileNode = (exports.WhileNode = inherit(Node, {
|
||||
type: 'While',
|
||||
constructor: function constructor(condition, body) {
|
||||
this.children = [(this.condition = condition), (this.body = body)];
|
||||
return this;
|
||||
|
@ -906,6 +937,7 @@
|
|||
// Simple Arithmetic and logical operations. Performs some conversion from
|
||||
// CoffeeScript operations into their JavaScript equivalents.
|
||||
OpNode = (exports.OpNode = inherit(Node, {
|
||||
type: 'Op',
|
||||
CONVERSIONS: {
|
||||
'==': '===',
|
||||
'!=': '!==',
|
||||
|
@ -989,6 +1021,7 @@
|
|||
}));
|
||||
// A try/catch/finally block.
|
||||
TryNode = (exports.TryNode = inherit(Node, {
|
||||
type: 'Try',
|
||||
constructor: function constructor(attempt, error, recovery, ensure) {
|
||||
this.children = [(this.attempt = attempt), (this.recovery = recovery), (this.ensure = ensure)];
|
||||
this.error = error;
|
||||
|
@ -1009,6 +1042,7 @@
|
|||
statement(TryNode);
|
||||
// Throw an exception.
|
||||
ThrowNode = (exports.ThrowNode = inherit(Node, {
|
||||
type: 'Throw',
|
||||
constructor: function constructor(expression) {
|
||||
this.children = [(this.expression = expression)];
|
||||
return this;
|
||||
|
@ -1020,6 +1054,7 @@
|
|||
statement(ThrowNode, true);
|
||||
// Check an expression for existence (meaning not null or undefined).
|
||||
ExistenceNode = (exports.ExistenceNode = inherit(Node, {
|
||||
type: 'Existence',
|
||||
constructor: function constructor(expression) {
|
||||
this.children = [(this.expression = expression)];
|
||||
return this;
|
||||
|
@ -1042,6 +1077,7 @@
|
|||
};
|
||||
// An extra set of parentheses, specified explicitly in the source.
|
||||
ParentheticalNode = (exports.ParentheticalNode = inherit(Node, {
|
||||
type: 'Paren',
|
||||
constructor: function constructor(expressions) {
|
||||
this.children = [(this.expressions = expressions)];
|
||||
return this;
|
||||
|
@ -1061,6 +1097,7 @@
|
|||
// of the comprehenion. Unlike Python array comprehensions, it's able to pass
|
||||
// the current index of the loop as a second parameter.
|
||||
ForNode = (exports.ForNode = inherit(Node, {
|
||||
type: 'For',
|
||||
constructor: function constructor(body, source, name, index) {
|
||||
var __a;
|
||||
this.body = body;
|
||||
|
@ -1161,6 +1198,7 @@
|
|||
// Single-expression IfNodes are compiled into ternary operators if possible,
|
||||
// because ternaries are first-class returnable assignable expressions.
|
||||
IfNode = (exports.IfNode = inherit(Node, {
|
||||
type: 'If',
|
||||
constructor: function constructor(condition, body, else_body, tags) {
|
||||
this.condition = condition;
|
||||
this.body = body && body.unwrap();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue