diff --git a/lib/command.js b/lib/command.js index 0100c18b..35f16821 100644 --- a/lib/command.js +++ b/lib/command.js @@ -209,7 +209,7 @@ o = { source: source }; - o['no-wrap'] = options['no-wrap']; + o['no_wrap'] = options['no-wrap']; return o; }; // Print the `--help` usage message and exit. diff --git a/lib/nodes.js b/lib/nodes.js index cba69e39..0323e3d7 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -1009,7 +1009,7 @@ idt += TAB }).call(this); //### SplatNode // A splat, either as a parameter to a function, an argument to a call, - // or in a destructuring assignment. + // or as part of a destructuring assignment. exports.SplatNode = (function() { SplatNode = function SplatNode(name) { if (!(name.compile)) { @@ -1024,19 +1024,25 @@ idt += TAB var _a; return (typeof (_a = this.index) !== "undefined" && _a !== null) ? this.compile_param(o) : this.name.compile(o); }; + // Compiling a parameter splat means recovering the parameters that succeed + // the splat in the parameter list, by slicing the arguments object. SplatNode.prototype.compile_param = function compile_param(o) { var name; name = this.name.compile(o); o.scope.find(name); return name + " = Array.prototype.slice.call(arguments, " + this.index + ")"; }; + // A compiling a splat as a destructuring assignment means slicing arguments + // from the right-hand-side's corresponding array. SplatNode.prototype.compile_value = function compile_value(o, name, index) { return "Array.prototype.slice.call(" + name + ", " + index + ")"; }; return SplatNode; }).call(this); + //### WhileNode // A while loop, the only sort of low-level loop exposed by CoffeeScript. From - // it, all other loops can be manufactured. + // it, all other loops can be manufactured. Useful in cases where you need more + // flexibility or more speed than a comprehension can provide. exports.WhileNode = (function() { WhileNode = function WhileNode(condition, opts) { this.children = [(this.condition = condition)]; @@ -1052,6 +1058,9 @@ idt += TAB WhileNode.prototype.top_sensitive = function top_sensitive() { return true; }; + // The main difference from a JavaScript *while* is that the CoffeeScript + // *while* can be used as a part of a larger expression -- while loops may + // return an array containing the computed result of each iteration. WhileNode.prototype.compile_node = function compile_node(o) { var cond, post, pre, returns, rvar, set, top; returns = del(o, 'returns'); @@ -1080,6 +1089,7 @@ idt += TAB return WhileNode; }).call(this); statement(WhileNode); + //### OpNode // Simple Arithmetic and logical operations. Performs some conversion from // CoffeeScript operations into their JavaScript equivalents. exports.OpNode = (function() { @@ -1092,6 +1102,7 @@ idt += TAB }; __extends(OpNode, BaseNode); OpNode.prototype.type = 'Op'; + // The map of conversions from CoffeeScript to JavaScript symbols. OpNode.prototype.CONVERSIONS = { '==': '===', '!=': '!==', @@ -1101,8 +1112,12 @@ idt += TAB 'isnt': '!==', 'not': '!' }; + // The list of operators for which we perform + // [Python-style comparison chaining](http://docs.python.org/reference/expressions.html#notin). OpNode.prototype.CHAINABLE = ['<', '>', '>=', '<=', '===', '!==']; + // Our assignment operators that have no JavaScript equivalent. OpNode.prototype.ASSIGNMENT = ['||=', '&&=', '?=']; + // Operators must come before their operands with a space. OpNode.prototype.PREFIX_OPERATORS = ['typeof', 'delete']; OpNode.prototype.is_unary = function is_unary() { return !this.second; @@ -1126,8 +1141,8 @@ idt += TAB } return [this.first.compile(o), this.operator, this.second.compile(o)].join(' '); }; - // Mimic Python's chained comparisons. See: - // http://docs.python.org/reference/expressions.html#notin + // Mimic Python's chained comparisons when multiple comparison operators are + // used sequentially. For example: `50 < 65 > 10` OpNode.prototype.compile_chain = function compile_chain(o) { var _a, _b, first, second, shared; shared = this.first.unwrap().second; @@ -1142,6 +1157,9 @@ idt += TAB shared = _b[2]; return "(" + first + ") && (" + shared + " " + this.operator + " " + second + ")"; }; + // When compiling a conditional assignment, take care to ensure that the + // operands are only evaluated once, even though we have to reference them + // more than once. OpNode.prototype.compile_assignment = function compile_assignment(o) { var _a, first, second; _a = [this.first.compile(o), this.second.compile(o)]; diff --git a/src/command.coffee b/src/command.coffee index 899cd88c..9f17fbbb 100644 --- a/src/command.coffee +++ b/src/command.coffee @@ -146,7 +146,7 @@ parse_options: -> # The compile-time options to pass to the CoffeeScript compiler. compile_options: (source) -> o: {source: source} - o['no-wrap']: options['no-wrap'] + o['no_wrap']: options['no-wrap'] o # Print the `--help` usage message and exit.