From 3ab0c12bf1acf8128f31040f1ce8d18046c4467e Mon Sep 17 00:00:00 2001 From: Stan Angeloff Date: Sun, 19 Sep 2010 17:03:45 +0300 Subject: [PATCH 1/4] Don't store `tempVars` as we can get the next available one from scope. --- lib/scope.js | 21 +++++++-------------- src/scope.coffee | 11 ++++------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/lib/scope.js b/lib/scope.js index 27b20219..66af2231 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -6,21 +6,13 @@ } exports.Scope = (function() { Scope = function(parent, expressions, method) { - var _cache, _cache2, k, val; + var _cache; _cache = [parent, expressions, method]; this.parent = _cache[0]; this.expressions = _cache[1]; this.method = _cache[2]; this.variables = {}; - this.tempVars = {}; - if (this.parent) { - _cache2 = this.parent.tempVars; - for (k in _cache2) { - if (!__hasProp.call(_cache2, k)) continue; - val = _cache2[k]; - (this.tempVars[k] = val); - } - } else { + if (!this.parent) { Scope.root = this; } return this; @@ -57,12 +49,13 @@ return !!(this.parent && this.parent.check(name)); }; Scope.prototype.temporary = function(type, index) { - return '_' + type + ((index) > 1 ? index : ''); + return '_' + type + (index ? (index + 1) : ''); }; Scope.prototype.freeVariable = function(type) { - var temp; - while (this.check(temp = this.temporary(type, this.tempVars[type] || (this.tempVars[type] = 1)))) { - this.tempVars[type]++; + var index, temp; + index = 0; + while (this.check(temp = this.temporary(type, index))) { + index++; } this.variables[temp] = 'var'; return temp; diff --git a/src/scope.coffee b/src/scope.coffee index 9e8da7e6..46d73c1a 100644 --- a/src/scope.coffee +++ b/src/scope.coffee @@ -20,11 +20,7 @@ exports.Scope = class Scope constructor: (parent, expressions, method) -> [@parent, @expressions, @method] = [parent, expressions, method] @variables = {} - @tempVars = {} - if @parent - (@tempVars[k] = val) for k, val of @parent.tempVars - else - Scope.root = this + Scope.root = this if not @parent # Look up a variable name in lexical scope, and declare it if it does not # already exist. @@ -53,12 +49,13 @@ exports.Scope = class Scope # Generate a temporary variable name at the given index. temporary: (type, index) -> - '_' + type + (if (index) > 1 then index else '') + '_' + type + (if index then (index + 1) else '') # If we need to store an intermediate result, find an available name for a # compiler-generated variable. `_var`, `_var2`, and so on... freeVariable: (type) -> - @tempVars[type]++ while @check temp = @temporary type, @tempVars[type] or= 1 + index = 0 + index++ while @check temp = @temporary type, index @variables[temp] = 'var' temp From d568b56c5e5d7b1b6df8eb70a618b52de812ed8c Mon Sep 17 00:00:00 2001 From: Stan Angeloff Date: Sun, 19 Sep 2010 17:47:26 +0300 Subject: [PATCH 2/4] First attempt at allowing temporary variables to be reused. --- lib/nodes.js | 17 +++++++++++------ lib/scope.js | 18 ++++++++++++++---- src/nodes.coffee | 12 +++++++----- src/scope.coffee | 11 ++++++++--- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/lib/nodes.js b/lib/nodes.js index b0c230b7..9dfc8da8 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -47,7 +47,7 @@ return ClosureNode.wrap(this).compile(o); }; BaseNode.prototype.compileReference = function(o, options) { - var compiled, pair, reference; + var compiled, pair, reference, temp; options || (options = {}); pair = (function() { if (!(this.containsType(CallNode) || (this instanceof ValueNode && (!(this.base instanceof LiteralNode) || this.hasProperties())))) { @@ -55,13 +55,13 @@ } else if (this instanceof ValueNode && options.assignment) { return this.cacheIndexes(o); } else { - reference = literal(o.scope.freeVariable('cache')); + reference = literal(temp = o.scope.freeVariable('cache')); compiled = new AssignNode(reference, this); - return [compiled, reference]; + return [compiled, reference, temp]; } }).call(this); if (options.precompile) { - return [pair[0].compile(o), pair[1].compile(o)]; + return [pair[0].compile(o), pair[1].compile(o), pair[2]]; } return pair; }; @@ -1377,18 +1377,23 @@ return [this.first.compile(o), this.operator, this.second.compile(o)].join(' '); }; OpNode.prototype.compileChain = function(o) { - var _cache2, _cache3, first, second, shared; + var _cache2, _cache3, first, js, second, shared, temp; shared = this.first.unwrap().second; if (shared.containsType(CallNode)) { _cache2 = shared.compileReference(o); this.first.second = _cache2[0]; shared = _cache2[1]; + temp = _cache2[2]; } _cache3 = [this.first.compile(o), this.second.compile(o), shared.compile(o)]; first = _cache3[0]; second = _cache3[1]; shared = _cache3[2]; - return "(" + (first) + ") && (" + (shared) + " " + (this.operator) + " " + (second) + ")"; + js = ("(" + (first) + ") && (" + (shared) + " " + (this.operator) + " " + (second) + ")"); + if (temp) { + o.scope.reuse(temp); + } + return js; }; OpNode.prototype.compileAssignment = function(o) { var _cache2, first, firstVar, second; diff --git a/lib/scope.js b/lib/scope.js index 66af2231..c3a34a9b 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -1,6 +1,6 @@ (function() { var Scope; - var __hasProp = Object.prototype.hasOwnProperty; + var __slice = Array.prototype.slice, __hasProp = Object.prototype.hasOwnProperty; if (!(typeof process !== "undefined" && process !== null)) { this.exports = this; } @@ -25,6 +25,16 @@ this.variables[name] = 'var'; return false; }; + Scope.prototype.reuse = function() { + var _cache, _cache2, _index, _result, names, val; + names = __slice.call(arguments, 0); + _result = []; _cache = names; + for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { + val = _cache[_index]; + _result.push(this.variables[val] = 'reuse'); + } + return _result; + }; Scope.prototype.any = function(fn) { var _cache, k, v; _cache = this.variables; @@ -54,7 +64,7 @@ Scope.prototype.freeVariable = function(type) { var index, temp; index = 0; - while (this.check(temp = this.temporary(type, index))) { + while ((this.check(temp = this.temporary(type, index))) && this.variables[temp] !== 'reuse') { index++; } this.variables[temp] = 'var'; @@ -68,7 +78,7 @@ }; Scope.prototype.hasDeclarations = function(body) { return body === this.expressions && this.any(function(k, val) { - return val === 'var'; + return val === 'var' || val === 'reuse'; }); }; Scope.prototype.hasAssignments = function(body) { @@ -83,7 +93,7 @@ for (key in _cache) { if (!__hasProp.call(_cache, key)) continue; val = _cache[key]; - if (val === 'var') { + if (val === 'var' || val === 'reuse') { _result.push(key); } } diff --git a/src/nodes.coffee b/src/nodes.coffee index 6dbd2ed4..6f2c7b03 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -70,10 +70,10 @@ exports.BaseNode = class BaseNode else if this instanceof ValueNode and options.assignment this.cacheIndexes(o) else - reference = literal o.scope.freeVariable 'cache' + reference = literal temp = o.scope.freeVariable 'cache' compiled = new AssignNode reference, this - [compiled, reference] - return [pair[0].compile(o), pair[1].compile(o)] if options.precompile + [compiled, reference, temp] + return [pair[0].compile(o), pair[1].compile(o), pair[2]] if options.precompile pair # Convenience method to grab the current indentation level, plus tabbing in. @@ -1176,9 +1176,11 @@ exports.OpNode = class OpNode extends BaseNode # true compileChain: (o) -> shared = @first.unwrap().second - [@first.second, shared] = shared.compileReference(o) if shared.containsType CallNode + [@first.second, shared, temp] = shared.compileReference(o) if shared.containsType CallNode [first, second, shared] = [@first.compile(o), @second.compile(o), shared.compile(o)] - "(#{first}) && (#{shared} #{@operator} #{second})" + js = "(#{first}) && (#{shared} #{@operator} #{second})" + o.scope.reuse temp if temp + js # When compiling a conditional assignment, take care to ensure that the # operands are only evaluated once, even though we have to reference them diff --git a/src/scope.coffee b/src/scope.coffee index 46d73c1a..bf1d62aa 100644 --- a/src/scope.coffee +++ b/src/scope.coffee @@ -29,6 +29,11 @@ exports.Scope = class Scope @variables[name] = 'var' false + # Erase a variable from scope. This is usually carried when we are done + # working with a list of temporary variables and we want to flag them for reuse. + reuse: (names...) -> + (@variables[val] = 'reuse') for val in names + # Test variables and return true the first time fn(v, k) returns true any: (fn) -> for v, k of @variables when fn(v, k) @@ -55,7 +60,7 @@ exports.Scope = class Scope # compiler-generated variable. `_var`, `_var2`, and so on... freeVariable: (type) -> index = 0 - index++ while @check temp = @temporary type, index + index++ while (@check temp = @temporary type, index) and @variables[temp] isnt 'reuse' @variables[temp] = 'var' temp @@ -67,7 +72,7 @@ exports.Scope = class Scope # Does this scope reference any variables that need to be declared in the # given function body? hasDeclarations: (body) -> - body is @expressions and @any (k, val) -> val is 'var' + body is @expressions and @any (k, val) -> val is 'var' or val is 'reuse' # Does this scope reference any assignments that need to be declared at the # top of the given function body? @@ -76,7 +81,7 @@ exports.Scope = class Scope # Return the list of variables first declared in this scope. declaredVariables: -> - (key for key, val of @variables when val is 'var').sort() + (key for key, val of @variables when val is 'var' or val is 'reuse').sort() # Return the list of assignments that are supposed to be made at the top # of this scope. From 31441868e019e01ce51912eb62b4d722fcbe2b20 Mon Sep 17 00:00:00 2001 From: Stan Angeloff Date: Sun, 19 Sep 2010 19:34:27 +0300 Subject: [PATCH 3/4] Allowing temporary variables to be reused. --- lib/command.js | 50 ++++++++-------- lib/helpers.js | 8 +-- lib/lexer.js | 68 ++++++++++----------- lib/nodes.js | 151 ++++++++++++++++++++++++----------------------- lib/rewriter.js | 120 ++++++++++++++++++------------------- lib/scope.js | 34 +++++++---- src/nodes.coffee | 19 +++--- src/scope.coffee | 21 +++++-- 8 files changed, 247 insertions(+), 224 deletions(-) diff --git a/lib/command.js b/lib/command.js index f1bffcb9..b2617b0b 100644 --- a/lib/command.js +++ b/lib/command.js @@ -1,16 +1,16 @@ (function() { - var BANNER, CoffeeScript, EventEmitter, SWITCHES, _cache, _cache2, _cache3, compileOptions, compileScript, compileScripts, compileStdio, exec, fs, helpers, lint, optionParser, optparse, opts, parseOptions, path, printTokens, sources, spawn, usage, version, watch, writeJs; + var BANNER, CoffeeScript, EventEmitter, SWITCHES, _cache, compileOptions, compileScript, compileScripts, compileStdio, exec, fs, helpers, lint, optionParser, optparse, opts, parseOptions, path, printTokens, sources, spawn, usage, version, watch, writeJs; fs = require('fs'); path = require('path'); optparse = require('./optparse'); CoffeeScript = require('./coffee-script'); _cache = require('./helpers'); helpers = _cache.helpers; - _cache2 = require('child_process'); - spawn = _cache2.spawn; - exec = _cache2.exec; - _cache3 = require('events'); - EventEmitter = _cache3.EventEmitter; + _cache = require('child_process'); + spawn = _cache.spawn; + exec = _cache.exec; + _cache = require('events'); + EventEmitter = _cache.EventEmitter; helpers.extend(CoffeeScript, new EventEmitter()); global.CoffeeScript = CoffeeScript; BANNER = 'coffee compiles CoffeeScript source files into JavaScript.\n\nUsage:\n coffee path/to/script.coffee'; @@ -53,12 +53,12 @@ return compileScripts(); }; compileScripts = function() { - var _cache4, _cache5, _index, _result; - _result = []; _cache4 = sources; - for (_index = 0, _cache5 = _cache4.length; _index < _cache5; _index++) { + var _cache2, _cache3, _index, _result; + _result = []; _cache2 = sources; + for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { (function() { var base, compile; - var source = _cache4[_index]; + var source = _cache2[_index]; return _result.push((function() { base = source; compile = function(source, topLevel) { @@ -69,10 +69,10 @@ return fs.stat(source, function(err, stats) { if (stats.isDirectory()) { return fs.readdir(source, function(err, files) { - var _cache6, _cache7, _index2, _result2, file; - _result2 = []; _cache6 = files; - for (_index2 = 0, _cache7 = _cache6.length; _index2 < _cache7; _index2++) { - file = _cache6[_index2]; + var _cache4, _cache5, _index2, _result2, file; + _result2 = []; _cache4 = files; + for (_index2 = 0, _cache5 = _cache4.length; _index2 < _cache5; _index2++) { + file = _cache4[_index2]; _result2.push(compile(path.join(source, file))); } return _result2; @@ -95,13 +95,13 @@ return _result; }; compileScript = function(file, input, base) { - var _cache4, _cache5, _index, o, options, req, t, task; + var _cache2, _cache3, _index, o, options, req, t, task; o = opts; options = compileOptions(file); if (o.require) { - _cache4 = o.require; - for (_index = 0, _cache5 = _cache4.length; _index < _cache5; _index++) { - req = _cache4[_index]; + _cache2 = o.require; + for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + req = _cache2[_index]; require(helpers.starts(req, '.') ? fs.realpathSync(req) : req); } } @@ -204,15 +204,15 @@ return jsl.stdin.end(); }; printTokens = function(tokens) { - var _cache4, _cache5, _cache6, _index, _result, strings, tag, token, value; + var _cache2, _cache3, _cache4, _index, _result, strings, tag, token, value; strings = (function() { - _result = []; _cache4 = tokens; - for (_index = 0, _cache5 = _cache4.length; _index < _cache5; _index++) { - token = _cache4[_index]; + _result = []; _cache2 = tokens; + for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + token = _cache2[_index]; _result.push((function() { - _cache6 = [token[0], token[1].toString().replace(/\n/, '\\n')]; - tag = _cache6[0]; - value = _cache6[1]; + _cache4 = [token[0], token[1].toString().replace(/\n/, '\\n')]; + tag = _cache4[0]; + value = _cache4[1]; return "[" + (tag) + " " + (value) + "]"; })()); } diff --git a/lib/helpers.js b/lib/helpers.js index 79810ef6..1c80eb7e 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -51,7 +51,7 @@ return num; }); helpers.merge = (merge = function(options, overrides) { - var _cache, _cache2, fresh, key, val; + var _cache, fresh, key, val; fresh = {}; _cache = options; for (key in _cache) { @@ -59,9 +59,9 @@ (fresh[key] = val); } if (overrides) { - _cache2 = overrides; - for (key in _cache2) { - val = _cache2[key]; + _cache = overrides; + for (key in _cache) { + val = _cache[key]; (fresh[key] = val); } } diff --git a/lib/lexer.js b/lib/lexer.js index 26b93871..4973e59e 100644 --- a/lib/lexer.js +++ b/lib/lexer.js @@ -1,21 +1,21 @@ (function() { - var ASSIGNED, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, CONVERSIONS, HEREDOC, HEREDOC_INDENT, IDENTIFIER, JS_CLEANER, JS_FORBIDDEN, JS_KEYWORDS, LAST_DENT, LAST_DENTS, LINE_BREAK, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NEXT_CHARACTER, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX_END, REGEX_ESCAPE, REGEX_INTERPOLATION, REGEX_START, RESERVED, Rewriter, SHIFT, UNARY, WHITESPACE, _cache, _cache2, _cache3, compact, count, helpers, include, starts; + var ASSIGNED, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, CONVERSIONS, HEREDOC, HEREDOC_INDENT, IDENTIFIER, JS_CLEANER, JS_FORBIDDEN, JS_KEYWORDS, LAST_DENT, LAST_DENTS, LINE_BREAK, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NEXT_CHARACTER, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX_END, REGEX_ESCAPE, REGEX_INTERPOLATION, REGEX_START, RESERVED, Rewriter, SHIFT, UNARY, WHITESPACE, _cache, compact, count, helpers, include, starts; var __slice = Array.prototype.slice; if (typeof process !== "undefined" && process !== null) { _cache = require('./rewriter'); Rewriter = _cache.Rewriter; - _cache2 = require('./helpers'); - helpers = _cache2.helpers; + _cache = require('./helpers'); + helpers = _cache.helpers; } else { this.exports = this; Rewriter = this.Rewriter; helpers = this.helpers; } - _cache3 = helpers; - include = _cache3.include; - count = _cache3.count; - starts = _cache3.starts; - compact = _cache3.compact; + _cache = helpers; + include = _cache.include; + count = _cache.count; + starts = _cache.starts; + compact = _cache.compact; exports.Lexer = (function() { Lexer = function() {}; Lexer.prototype.tokenize = function(code, options) { @@ -192,11 +192,11 @@ return true; }; Lexer.prototype.regexToken = function() { - var _cache4, end, first, flags, regex, str; + var _cache2, end, first, flags, regex, str; if (!(first = this.chunk.match(REGEX_START))) { return false; } - if (first[1] === ' ' && !('CALL_START' === (_cache4 = this.tag()) || '=' === _cache4)) { + if (first[1] === ' ' && !('CALL_START' === (_cache2 = this.tag()) || '=' === _cache2)) { return false; } if (include(NOT_REGEX, this.tag())) { @@ -320,7 +320,7 @@ return true; }; Lexer.prototype.literalToken = function() { - var _cache4, match, prev, space, spaced, tag, value; + var _cache2, match, prev, space, spaced, tag, value; match = this.chunk.match(OPERATOR); value = match && match[1]; space = match && match[2]; @@ -335,7 +335,7 @@ if (include(JS_FORBIDDEN, this.value())) { this.assignmentError(); } - if (('or' === (_cache4 = this.value()) || 'and' === _cache4)) { + if (('or' === (_cache2 = this.value()) || 'and' === _cache2)) { this.tokens.splice(this.tokens.length - 1, 1, ['COMPOUND_ASSIGN', CONVERSIONS[this.value()] + '=', prev[2]]); return true; } @@ -395,14 +395,14 @@ return accessor ? 'accessor' : false; }; Lexer.prototype.sanitizeHeredoc = function(doc, options) { - var _cache4, attempt, indent, match; + var _cache2, attempt, indent, match; indent = options.indent; if (options.herecomment && !include(doc, '\n')) { return doc; } if (!(options.herecomment)) { while ((match = HEREDOC_INDENT.exec(doc)) !== null) { - attempt = (typeof (_cache4 = match[2]) !== "undefined" && _cache4 !== null) ? match[2] : match[3]; + attempt = (typeof (_cache2 = match[2]) !== "undefined" && _cache2 !== null) ? match[2] : match[3]; if (!(typeof indent !== "undefined" && indent !== null) || attempt.length < indent.length) { indent = attempt; } @@ -451,7 +451,7 @@ throw new Error("SyntaxError: Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned"); }; Lexer.prototype.balancedString = function(str, delimited, options) { - var _cache4, _cache5, _cache6, _index, close, i, levels, open, pair, slash; + var _cache2, _cache3, _cache4, _index, close, i, levels, open, pair, slash; options || (options = {}); slash = delimited[0][0] === '/'; levels = []; @@ -460,12 +460,12 @@ if (levels.length && starts(str, '\\', i)) { i += 1; } else { - _cache4 = delimited; - for (_index = 0, _cache5 = _cache4.length; _index < _cache5; _index++) { - pair = _cache4[_index]; - _cache6 = pair; - open = _cache6[0]; - close = _cache6[1]; + _cache2 = delimited; + for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + pair = _cache2[_index]; + _cache4 = pair; + open = _cache4[0]; + close = _cache4[1]; if (levels.length && starts(str, close, i) && levels[levels.length - 1] === pair) { levels.pop(); i += close.length - 1; @@ -494,7 +494,7 @@ return !i ? false : str.substring(0, i); }; Lexer.prototype.interpolateString = function(str, options) { - var _cache4, _cache5, _cache6, _cache7, _cache8, _cache9, escaped, expr, i, idx, inner, interpolated, lexer, nested, pi, quote, tag, tok, token, tokens, value; + var _cache2, _cache3, _cache4, escaped, expr, i, idx, inner, interpolated, lexer, nested, pi, quote, tag, tok, token, tokens, value; options || (options = {}); if (str.length < 3 || !starts(str, '"')) { return this.token('STRING', str); @@ -502,9 +502,9 @@ lexer = new Lexer(); tokens = []; quote = str.substring(0, 1); - _cache4 = [1, 1]; - i = _cache4[0]; - pi = _cache4[1]; + _cache2 = [1, 1]; + i = _cache2[0]; + pi = _cache2[1]; while (i < str.length - 1) { if (starts(str, '\\', i)) { i += 1; @@ -520,9 +520,9 @@ nested = lexer.tokenize("(" + (inner) + ")", { line: this.line }); - _cache5 = nested; - for (idx = 0, _cache6 = _cache5.length; idx < _cache6; idx++) { - tok = _cache5[idx]; + _cache2 = nested; + for (idx = 0, _cache3 = _cache2.length; idx < _cache3; idx++) { + tok = _cache2[idx]; if (tok[0] === 'CALL_END') { (tok[0] = ')'); } @@ -547,12 +547,12 @@ if (interpolated) { this.token('(', '('); } - _cache7 = tokens; - for (i = 0, _cache8 = _cache7.length; i < _cache8; i++) { - token = _cache7[i]; - _cache9 = token; - tag = _cache9[0]; - value = _cache9[1]; + _cache2 = tokens; + for (i = 0, _cache3 = _cache2.length; i < _cache3; i++) { + token = _cache2[i]; + _cache4 = token; + tag = _cache4[0]; + value = _cache4[1]; if (tag === 'TOKENS') { this.tokens = this.tokens.concat(value); } else if (tag === 'STRING' && options.escapeQuotes) { diff --git a/lib/nodes.js b/lib/nodes.js index 9dfc8da8..5571a923 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -31,7 +31,7 @@ return this; }; BaseNode.prototype.compile = function(o) { - var closure, top; + var closure, code, top; this.options = merge(o || {}); this.tab = o.indent; if (!(this instanceof AccessorNode || this instanceof IndexNode)) { @@ -39,7 +39,14 @@ } top = this.topSensitive() ? this.options.top : del(this.options, 'top'); closure = this.isStatement(o) && !this.isPureStatement() && !top && !this.options.asStatement && !(this instanceof CommentNode) && !this.containsPureStatement(); - return closure ? this.compileClosure(this.options) : this.compileNode(this.options); + if (!o.keepLevel) { + o.scope.startLevel(); + } + code = closure ? this.compileClosure(this.options) : this.compileNode(this.options); + if (!o.keepLevel) { + o.scope.endLevel(); + } + return code; }; BaseNode.prototype.compileClosure = function(o) { this.tab = o.indent; @@ -47,7 +54,7 @@ return ClosureNode.wrap(this).compile(o); }; BaseNode.prototype.compileReference = function(o, options) { - var compiled, pair, reference, temp; + var compiled, pair, reference; options || (options = {}); pair = (function() { if (!(this.containsType(CallNode) || (this instanceof ValueNode && (!(this.base instanceof LiteralNode) || this.hasProperties())))) { @@ -55,13 +62,13 @@ } else if (this instanceof ValueNode && options.assignment) { return this.cacheIndexes(o); } else { - reference = literal(temp = o.scope.freeVariable('cache')); + reference = literal(o.scope.freeVariable('cache')); compiled = new AssignNode(reference, this); - return [compiled, reference, temp]; + return [compiled, reference]; } }).call(this); if (options.precompile) { - return [pair[0].compile(o), pair[1].compile(o), pair[2]]; + return [pair[0].compile(o), pair[1].compile(o)]; } return pair; }; @@ -355,25 +362,25 @@ return this.base instanceof LiteralNode && this.base.value.match(NUMBER); }; ValueNode.prototype.cacheIndexes = function(o) { - var _cache2, _cache3, _cache4, _index, copy, i; + var _cache2, _cache3, _index, copy, i; copy = new ValueNode(this.base, this.properties.slice(0)); if (this.base instanceof CallNode) { _cache2 = this.base.compileReference(o); this.base = _cache2[0]; copy.base = _cache2[1]; } - _cache3 = copy.properties; - for (_index = 0, _cache4 = _cache3.length; _index < _cache4; _index++) { + _cache2 = copy.properties; + for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { (function() { - var _cache5, index, indexVar; + var _cache4, index, indexVar; var i = _index; - var prop = _cache3[_index]; + var prop = _cache2[_index]; if (prop instanceof IndexNode && prop.contains(function(n) { return n instanceof CallNode; })) { - _cache5 = prop.index.compileReference(o); - index = _cache5[0]; - indexVar = _cache5[1]; + _cache4 = prop.index.compileReference(o); + index = _cache4[0]; + indexVar = _cache4[1]; this.properties[i] = new IndexNode(index); return (copy.properties[i] = new IndexNode(indexVar)); } @@ -385,7 +392,7 @@ return !o.top || this.properties.length ? ValueNode.__super__.compile.call(this, o) : this.base.compile(o); }; ValueNode.prototype.compileNode = function(o) { - var _cache2, _cache3, _cache4, _cache5, _cache6, _index, baseline, complete, copy, hasSoak, i, me, only, op, part, prop, props, temp; + var _cache2, _cache3, _index, baseline, complete, copy, hasSoak, i, me, only, op, part, prop, props, temp; only = del(o, 'onlyFirst'); op = this.tags.operation; props = only ? this.properties.slice(0, this.properties.length - 1) : this.properties; @@ -398,9 +405,9 @@ } } if (hasSoak && this.containsType(CallNode)) { - _cache4 = this.cacheIndexes(o); - me = _cache4[0]; - copy = _cache4[1]; + _cache2 = this.cacheIndexes(o); + me = _cache2[0]; + copy = _cache2[1]; } if (this.parenthetical && !props.length) { this.base.parenthetical = true; @@ -410,9 +417,9 @@ baseline = ("(" + (baseline) + ")"); } complete = (this.last = baseline); - _cache5 = props; - for (i = 0, _cache6 = _cache5.length; i < _cache6; i++) { - prop = _cache5[i]; + _cache2 = props; + for (i = 0, _cache3 = _cache2.length; i < _cache3; i++) { + prop = _cache2[i]; this.source = baseline; if (prop.soakNode) { if (this.base.containsType(CallNode) && i === 0) { @@ -497,7 +504,7 @@ })()); }; CallNode.prototype.compileNode = function(o) { - var _cache2, _cache3, _cache4, _cache5, _cache6, _cache7, _index, _index2, _result, arg, args, code, first, meth, methodAccessor, op; + var _cache2, _cache3, _index, _result, arg, args, code, first, meth, methodAccessor, op; if (!(o.chainRoot)) { o.chainRoot = this; } @@ -511,29 +518,29 @@ this.first = new ValueNode(first, [methodAccessor]).compile(o); this.meth = new ValueNode(meth, [methodAccessor]).compile(o); } else { - _cache3 = this.variable.compileReference(o, { + _cache2 = this.variable.compileReference(o, { precompile: true }); - this.first = _cache3[0]; - this.meth = _cache3[1]; + this.first = _cache2[0]; + this.meth = _cache2[1]; } this.first = ("(typeof " + (this.first) + " === \"function\" ? "); this.last = " : undefined)"; } else if (this.variable) { this.meth = this.variable.compile(o); } - _cache4 = this.args; - for (_index = 0, _cache5 = _cache4.length; _index < _cache5; _index++) { - arg = _cache4[_index]; + _cache2 = this.args; + for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + arg = _cache2[_index]; if (arg instanceof SplatNode) { code = this.compileSplat(o); } } if (!code) { args = (function() { - _result = []; _cache6 = this.args; - for (_index2 = 0, _cache7 = _cache6.length; _index2 < _cache7; _index2++) { - arg = _cache6[_index2]; + _result = []; _cache2 = this.args; + for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + arg = _cache2[_index]; _result.push((function() { arg.parenthetical = true; return arg.compile(o); @@ -647,7 +654,7 @@ RangeNode.prototype["class"] = 'RangeNode'; RangeNode.prototype.children = ['from', 'to']; RangeNode.prototype.compileVariables = function(o) { - var _cache2, _cache3, _cache4, parts; + var _cache2, parts; o = merge(o, { top: true }); @@ -656,14 +663,14 @@ }); this.from = _cache2[0]; this.fromVar = _cache2[1]; - _cache3 = this.to.compileReference(o, { + _cache2 = this.to.compileReference(o, { precompile: true }); - this.to = _cache3[0]; - this.toVar = _cache3[1]; - _cache4 = [this.fromVar.match(SIMPLENUM), this.toVar.match(SIMPLENUM)]; - this.fromNum = _cache4[0]; - this.toNum = _cache4[1]; + this.to = _cache2[0]; + this.toVar = _cache2[1]; + _cache2 = [this.fromVar.match(SIMPLENUM), this.toVar.match(SIMPLENUM)]; + this.fromNum = _cache2[0]; + this.toNum = _cache2[1]; parts = []; if (this.from !== this.fromVar) { parts.push(this.from); @@ -766,7 +773,7 @@ return true; }; ObjectNode.prototype.compileNode = function(o) { - var _cache2, _cache3, _cache4, _cache5, _index, _result, _result2, i, indent, join, lastNoncom, nonComments, obj, prop, props, top; + var _cache2, _cache3, _index, _result, i, indent, join, lastNoncom, nonComments, obj, prop, props, top; top = del(o, 'top'); o.indent = this.idt(1); nonComments = (function() { @@ -781,10 +788,10 @@ }).call(this); lastNoncom = nonComments[nonComments.length - 1]; props = (function() { - _result2 = []; _cache4 = this.properties; - for (i = 0, _cache5 = _cache4.length; i < _cache5; i++) { - prop = _cache4[i]; - _result2.push((function() { + _result = []; _cache2 = this.properties; + for (i = 0, _cache3 = _cache2.length; i < _cache3; i++) { + prop = _cache2[i]; + _result.push((function() { join = ",\n"; if ((prop === lastNoncom) || (prop instanceof CommentNode)) { join = "\n"; @@ -799,7 +806,7 @@ return indent + prop.compile(o) + join; }).call(this)); } - return _result2; + return _result; }).call(this); props = props.join(''); obj = '{' + (props ? '\n' + props + '\n' + this.idt() : '') + '}'; @@ -1067,7 +1074,7 @@ CodeNode.prototype["class"] = 'CodeNode'; CodeNode.prototype.children = ['params', 'body']; CodeNode.prototype.compileNode = function(o) { - var _cache2, _cache3, _cache4, _cache5, _cache6, _cache7, _cache8, _cache9, _index, _index2, _result, code, empty, func, i, param, params, sharedScope, splat, top, value; + var _cache2, _cache3, _cache4, _index, _result, code, empty, func, i, param, params, sharedScope, splat, top, value; sharedScope = del(o, 'sharedScope'); top = del(o, 'top'); o.scope = sharedScope || new Scope(o.scope, this.body, this); @@ -1091,9 +1098,9 @@ if (param.attach) { _cache4 = param; value = _cache4.value; - _cache5 = [literal(o.scope.freeVariable('arg')), param.splat]; - param = _cache5[0]; - param.splat = _cache5[1]; + _cache4 = [literal(o.scope.freeVariable('arg')), param.splat]; + param = _cache4[0]; + param.splat = _cache4[1]; this.body.unshift(new AssignNode(new ValueNode(literal('this'), [new AccessorNode(value)]), param)); } if (param.splat) { @@ -1108,9 +1115,9 @@ } } params = (function() { - _result = []; _cache6 = params; - for (_index = 0, _cache7 = _cache6.length; _index < _cache7; _index++) { - param = _cache6[_index]; + _result = []; _cache2 = params; + for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + param = _cache2[_index]; _result.push(param.compile(o)); } return _result; @@ -1118,9 +1125,9 @@ if (!(empty)) { this.body.makeReturn(); } - _cache8 = params; - for (_index2 = 0, _cache9 = _cache8.length; _index2 < _cache9; _index2++) { - param = _cache8[_index2]; + _cache2 = params; + for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + param = _cache2[_index]; (o.scope.parameter(param)); } code = this.body.expressions.length ? ("\n" + (this.body.compileWithDeclarations(o)) + "\n") : ''; @@ -1377,23 +1384,18 @@ return [this.first.compile(o), this.operator, this.second.compile(o)].join(' '); }; OpNode.prototype.compileChain = function(o) { - var _cache2, _cache3, first, js, second, shared, temp; + var _cache2, first, second, shared; shared = this.first.unwrap().second; if (shared.containsType(CallNode)) { _cache2 = shared.compileReference(o); this.first.second = _cache2[0]; shared = _cache2[1]; - temp = _cache2[2]; } - _cache3 = [this.first.compile(o), this.second.compile(o), shared.compile(o)]; - first = _cache3[0]; - second = _cache3[1]; - shared = _cache3[2]; - js = ("(" + (first) + ") && (" + (shared) + " " + (this.operator) + " " + (second) + ")"); - if (temp) { - o.scope.reuse(temp); - } - return js; + _cache2 = [this.first.compile(o), this.second.compile(o), shared.compile(o)]; + first = _cache2[0]; + second = _cache2[1]; + shared = _cache2[2]; + return "(" + (first) + ") && (" + (shared) + " " + (this.operator) + " " + (second) + ")"; }; OpNode.prototype.compileAssignment = function(o) { var _cache2, first, firstVar, second; @@ -1468,15 +1470,15 @@ return "(" + (tests.join(' || ')) + ")"; }; InNode.prototype.compileLoopTest = function(o) { - var _cache2, _cache3, i, l, prefix; + var _cache2, i, l, prefix; _cache2 = this.array.compileReference(o, { precompile: true }); this.arr1 = _cache2[0]; this.arr2 = _cache2[1]; - _cache3 = [o.scope.freeVariable('index'), o.scope.freeVariable('cache')]; - i = _cache3[0]; - l = _cache3[1]; + _cache2 = [o.scope.freeVariable('index'), o.scope.freeVariable('cache')]; + i = _cache2[0]; + l = _cache2[1]; prefix = this.obj1 !== this.obj2 ? this.obj1 + '; ' : ''; return "(function(){ " + (prefix) + "for (var " + (i) + "=0, " + (l) + "=" + (this.arr1) + ".length; " + (i) + "<" + (l) + "; " + (i) + "++) { if (" + (this.arr2) + "[" + (i) + "] === " + (this.obj2) + ") return true; } return false; }).call(this)"; }; @@ -1691,7 +1693,8 @@ if (this.pattern) { namePart = new AssignNode(this.name, literal("" + (svar) + "[" + (ivar) + "]")).compile(merge(o, { indent: this.idt(1), - top: true + top: true, + keepLevel: true })) + '\n'; } else { if (name) { @@ -1771,7 +1774,7 @@ return this; }; SwitchNode.prototype.compileNode = function(o) { - var _cache2, _cache3, _cache4, _cache5, _cache6, _index, _index2, block, code, condition, conditions, exprs, idt, pair; + var _cache2, _cache3, _cache4, _cache5, _index, _index2, block, code, condition, conditions, exprs, idt, pair; idt = (o.indent = this.idt(1)); o.top = true; code = ("" + (this.tab) + "switch (" + (this.subject.compile(o)) + ") {"); @@ -1782,9 +1785,9 @@ conditions = _cache4[0]; block = _cache4[1]; exprs = block.expressions; - _cache5 = flatten([conditions]); - for (_index2 = 0, _cache6 = _cache5.length; _index2 < _cache6; _index2++) { - condition = _cache5[_index2]; + _cache4 = flatten([conditions]); + for (_index2 = 0, _cache5 = _cache4.length; _index2 < _cache5; _index2++) { + condition = _cache4[_index2]; if (this.tags.subjectless) { condition = new OpNode('!!', new ParentheticalNode(condition)); } diff --git a/lib/rewriter.js b/lib/rewriter.js index c7d8be2c..467efe67 100644 --- a/lib/rewriter.js +++ b/lib/rewriter.js @@ -1,5 +1,5 @@ (function() { - var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, INVERSES, LINEBREAKS, Rewriter, SINGLE_CLOSERS, SINGLE_LINERS, _cache, _cache2, _cache3, _cache4, _cache5, _cache6, _cache7, _cache8, _index, _index2, _index3, _result, _result2, helpers, include, pair; + var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, INVERSES, LINEBREAKS, Rewriter, SINGLE_CLOSERS, SINGLE_LINERS, _cache, _cache2, _index, _result, helpers, include, pair; var __hasProp = Object.prototype.hasOwnProperty; if (typeof process !== "undefined" && process !== null) { _cache = require('./helpers'); @@ -8,8 +8,8 @@ this.exports = this; helpers = this.helpers; } - _cache2 = helpers; - include = _cache2.include; + _cache = helpers; + include = _cache.include; exports.Rewriter = (function() { Rewriter = function() {}; Rewriter.prototype.rewrite = function(tokens) { @@ -62,15 +62,15 @@ }; Rewriter.prototype.adjustComments = function() { return this.scanTokens(function(token, i) { - var _cache3, _cache4, after, before, post, prev; + var _cache2, after, before, post, prev; if (token[0] !== 'HERECOMMENT') { return 1; } - _cache3 = [this.tokens[i - 2], this.tokens[i - 1], this.tokens[i + 1], this.tokens[i + 2]]; - before = _cache3[0]; - prev = _cache3[1]; - post = _cache3[2]; - after = _cache3[3]; + _cache2 = [this.tokens[i - 2], this.tokens[i - 1], this.tokens[i + 1], this.tokens[i + 2]]; + before = _cache2[0]; + prev = _cache2[1]; + post = _cache2[2]; + after = _cache2[3]; if (after && after[0] === 'INDENT') { this.tokens.splice(i + 2, 1); if (before && before[0] === 'OUTDENT' && post && (prev[0] === post[0]) && (post[0] === 'TERMINATOR')) { @@ -78,7 +78,7 @@ } else { this.tokens.splice(i, 0, after); } - } else if (prev && !('TERMINATOR' === (_cache4 = prev[0]) || 'INDENT' === _cache4 || 'OUTDENT' === _cache4)) { + } else if (prev && !('TERMINATOR' === (_cache2 = prev[0]) || 'INDENT' === _cache2 || 'OUTDENT' === _cache2)) { if (post && post[0] === 'TERMINATOR' && after && after[0] === 'OUTDENT') { this.tokens.splice.apply(this.tokens, [i + 2, 0].concat(this.tokens.splice(i, 2))); if (this.tokens[i + 2][0] !== 'TERMINATOR') { @@ -114,8 +114,8 @@ var action, condition; if (token[0] === 'CALL_START') { condition = function(token, i) { - var _cache3; - return ((')' === (_cache3 = token[0]) || 'CALL_END' === _cache3)) || (token[0] === 'OUTDENT' && this.tokens[i - 1][0] === ')'); + var _cache2; + return ((')' === (_cache2 = token[0]) || 'CALL_END' === _cache2)) || (token[0] === 'OUTDENT' && this.tokens[i - 1][0] === ')'); }; action = function(token, i) { var idx; @@ -132,8 +132,8 @@ var action, condition; if (token[0] === 'INDEX_START') { condition = function(token, i) { - var _cache3; - return (']' === (_cache3 = token[0]) || 'INDEX_END' === _cache3); + var _cache2; + return (']' === (_cache2 = token[0]) || 'INDEX_END' === _cache2); }; action = function(token, i) { return (token[0] = 'INDEX_END'); @@ -162,15 +162,15 @@ tok.generated = true; this.tokens.splice(idx, 0, tok); condition = function(token, i) { - var _cache3, _cache4, _cache5, one, three, two; - _cache3 = this.tokens.slice(i + 1, i + 4); - one = _cache3[0]; - two = _cache3[1]; - three = _cache3[2]; + var _cache2, one, three, two; + _cache2 = this.tokens.slice(i + 1, i + 4); + one = _cache2[0]; + two = _cache2[1]; + three = _cache2[2]; if ((this.tag(i + 1) === 'HERECOMMENT' || this.tag(i - 1) === 'HERECOMMENT')) { return false; } - return ((('TERMINATOR' === (_cache4 = token[0]) || 'OUTDENT' === _cache4)) && !((two && two[0] === ':') || (one && one[0] === '@' && three && three[0] === ':'))) || (token[0] === ',' && one && (!('IDENTIFIER' === (_cache5 = one[0]) || 'STRING' === _cache5 || '@' === _cache5 || 'TERMINATOR' === _cache5 || 'OUTDENT' === _cache5))); + return ((('TERMINATOR' === (_cache2 = token[0]) || 'OUTDENT' === _cache2)) && !((two && two[0] === ':') || (one && one[0] === '@' && three && three[0] === ':'))) || (token[0] === ',' && one && (!('IDENTIFIER' === (_cache2 = one[0]) || 'STRING' === _cache2 || '@' === _cache2 || 'TERMINATOR' === _cache2 || 'OUTDENT' === _cache2))); }; action = function(token, i) { return this.tokens.splice(i, 0, ['}', '}', token[2]]); @@ -185,7 +185,7 @@ var classLine; classLine = false; return this.scanTokens(function(token, i) { - var _cache3, action, callObject, condition, idx, next, prev, seenSingle; + var _cache2, action, callObject, condition, idx, next, prev, seenSingle; if (token[0] === 'CLASS') { classLine = true; } @@ -203,14 +203,14 @@ if (prev && !prev.spaced && token[0] === '?') { token.call = true; } - if (prev && (prev.spaced && (include(IMPLICIT_FUNC, prev[0]) || prev.call) && include(IMPLICIT_CALL, token[0]) && !(token[0] === 'UNARY' && (('IN' === (_cache3 = this.tag(i + 1)) || 'OF' === _cache3 || 'INSTANCEOF' === _cache3)))) || callObject) { + if (prev && (prev.spaced && (include(IMPLICIT_FUNC, prev[0]) || prev.call) && include(IMPLICIT_CALL, token[0]) && !(token[0] === 'UNARY' && (('IN' === (_cache2 = this.tag(i + 1)) || 'OF' === _cache2 || 'INSTANCEOF' === _cache2)))) || callObject) { this.tokens.splice(i, 0, ['CALL_START', '(', token[2]]); condition = function(token, i) { - var _cache3; + var _cache2; if (!seenSingle && token.fromThen) { return true; } - if (('IF' === (_cache3 = token[0]) || 'ELSE' === _cache3 || 'UNLESS' === _cache3 || '->' === _cache3 || '=>' === _cache3)) { + if (('IF' === (_cache2 = token[0]) || 'ELSE' === _cache2 || 'UNLESS' === _cache2 || '->' === _cache2 || '=>' === _cache2)) { seenSingle = true; } return (!token.generated && this.tokens[i - 1][0] !== ',' && include(IMPLICIT_END, token[0]) && !(token[0] === 'INDENT' && (include(IMPLICIT_BLOCK, this.tag(i - 1)) || this.tag(i - 2) === 'CLASS' || this.tag(i + 1) === '{'))) || token[0] === 'PROPERTY_ACCESS' && this.tag(i - 1) === 'OUTDENT'; @@ -230,7 +230,7 @@ }; Rewriter.prototype.addImplicitIndentation = function() { return this.scanTokens(function(token, i) { - var _cache3, action, condition, indent, outdent, starter; + var _cache2, action, condition, indent, outdent, starter; if (token[0] === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') { this.tokens.splice.apply(this.tokens, [i, 0].concat(this.indentation(token))); return 2; @@ -241,9 +241,9 @@ } if (include(SINGLE_LINERS, token[0]) && this.tag(i + 1) !== 'INDENT' && !(token[0] === 'ELSE' && this.tag(i + 1) === 'IF')) { starter = token[0]; - _cache3 = this.indentation(token); - indent = _cache3[0]; - outdent = _cache3[1]; + _cache2 = this.indentation(token); + indent = _cache2[0]; + outdent = _cache2[1]; if (starter === 'THEN') { indent.fromThen = true; } @@ -268,12 +268,12 @@ }; Rewriter.prototype.tagPostfixConditionals = function() { return this.scanTokens(function(token, i) { - var _cache3, action, condition, original; - if (('IF' === (_cache3 = token[0]) || 'UNLESS' === _cache3)) { + var _cache2, action, condition, original; + if (('IF' === (_cache2 = token[0]) || 'UNLESS' === _cache2)) { original = token; condition = function(token, i) { - var _cache3; - return ('TERMINATOR' === (_cache3 = token[0]) || 'INDENT' === _cache3); + var _cache2; + return ('TERMINATOR' === (_cache2 = token[0]) || 'INDENT' === _cache2); }; action = function(token, i) { if (token[0] !== 'INDENT') { @@ -287,17 +287,17 @@ }); }; Rewriter.prototype.ensureBalance = function(pairs) { - var _cache3, _result, key, levels, line, open, openLine, unclosed, value; + var _cache2, _result, key, levels, line, open, openLine, unclosed, value; levels = {}; openLine = {}; this.scanTokens(function(token, i) { - var _cache3, _cache4, _cache5, _index, close, open, pair; - _cache3 = pairs; - for (_index = 0, _cache4 = _cache3.length; _index < _cache4; _index++) { - pair = _cache3[_index]; - _cache5 = pair; - open = _cache5[0]; - close = _cache5[1]; + var _cache2, _cache3, _cache4, _index, close, open, pair; + _cache2 = pairs; + for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + pair = _cache2[_index]; + _cache4 = pair; + open = _cache4[0]; + close = _cache4[1]; levels[open] || (levels[open] = 0); if (token[0] === open) { if (levels[open] === 0) { @@ -315,10 +315,10 @@ return 1; }); unclosed = (function() { - _result = []; _cache3 = levels; - for (key in _cache3) { - if (!__hasProp.call(_cache3, key)) continue; - value = _cache3[key]; + _result = []; _cache2 = levels; + for (key in _cache2) { + if (!__hasProp.call(_cache2, key)) continue; + value = _cache2[key]; if (value > 0) { _result.push(key); } @@ -332,13 +332,13 @@ } }; Rewriter.prototype.rewriteClosingParens = function() { - var _cache3, debt, key, stack, val; + var _cache2, debt, key, stack, val; stack = []; debt = {}; - _cache3 = INVERSES; - for (key in _cache3) { - if (!__hasProp.call(_cache3, key)) continue; - val = _cache3[key]; + _cache2 = INVERSES; + for (key in _cache2) { + if (!__hasProp.call(_cache2, key)) continue; + val = _cache2[key]; (debt[key] = 0); } return this.scanTokens(function(token, i) { @@ -385,27 +385,27 @@ })(); BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['PARAM_START', 'PARAM_END'], ['CALL_START', 'CALL_END'], ['INDEX_START', 'INDEX_END']]; INVERSES = {}; - _cache3 = BALANCED_PAIRS; - for (_index = 0, _cache4 = _cache3.length; _index < _cache4; _index++) { - pair = _cache3[_index]; + _cache = BALANCED_PAIRS; + for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { + pair = _cache[_index]; INVERSES[pair[0]] = pair[1]; INVERSES[pair[1]] = pair[0]; } EXPRESSION_START = (function() { - _result = []; _cache5 = BALANCED_PAIRS; - for (_index2 = 0, _cache6 = _cache5.length; _index2 < _cache6; _index2++) { - pair = _cache5[_index2]; + _result = []; _cache = BALANCED_PAIRS; + for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { + pair = _cache[_index]; _result.push(pair[0]); } return _result; })(); EXPRESSION_END = (function() { - _result2 = []; _cache7 = BALANCED_PAIRS; - for (_index3 = 0, _cache8 = _cache7.length; _index3 < _cache8; _index3++) { - pair = _cache7[_index3]; - _result2.push(pair[1]); + _result = []; _cache = BALANCED_PAIRS; + for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { + pair = _cache[_index]; + _result.push(pair[1]); } - return _result2; + return _result; })(); EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END); IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS']; diff --git a/lib/scope.js b/lib/scope.js index c3a34a9b..22e2c52b 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -1,6 +1,6 @@ (function() { var Scope; - var __slice = Array.prototype.slice, __hasProp = Object.prototype.hasOwnProperty; + var __hasProp = Object.prototype.hasOwnProperty; if (!(typeof process !== "undefined" && process !== null)) { this.exports = this; } @@ -12,12 +12,29 @@ this.expressions = _cache[1]; this.method = _cache[2]; this.variables = {}; - if (!this.parent) { + if (this.parent) { + this.garbage = this.parent.garbage; + } else { + this.garbage = []; Scope.root = this; } return this; }; Scope.root = null; + Scope.prototype.startLevel = function() { + return this.garbage.push([]); + }; + Scope.prototype.endLevel = function() { + var _cache, _cache2, _index, _result, name; + _result = []; _cache = this.garbage.pop(); + for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { + name = _cache[_index]; + if (this.variables[name] === 'var') { + _result.push(this.variables[name] = 'reuse'); + } + } + return _result; + }; Scope.prototype.find = function(name, options) { if (this.check(name, options)) { return true; @@ -25,16 +42,6 @@ this.variables[name] = 'var'; return false; }; - Scope.prototype.reuse = function() { - var _cache, _cache2, _index, _result, names, val; - names = __slice.call(arguments, 0); - _result = []; _cache = names; - for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { - val = _cache[_index]; - _result.push(this.variables[val] = 'reuse'); - } - return _result; - }; Scope.prototype.any = function(fn) { var _cache, k, v; _cache = this.variables; @@ -68,6 +75,9 @@ index++; } this.variables[temp] = 'var'; + if (this.garbage.length) { + this.garbage[this.garbage.length - 1].push(temp); + } return temp; }; Scope.prototype.assign = function(name, value) { diff --git a/src/nodes.coffee b/src/nodes.coffee index 6f2c7b03..45660672 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -50,7 +50,10 @@ exports.BaseNode = class BaseNode closure = @isStatement(o) and not @isPureStatement() and not top and not @options.asStatement and this not instanceof CommentNode and not @containsPureStatement() - if closure then @compileClosure(@options) else @compileNode(@options) + o.scope.startLevel() if not o.keepLevel + code = if closure then @compileClosure(@options) else @compileNode(@options) + o.scope.endLevel() if not o.keepLevel + code # Statements converted into expressions via closure-wrapping share a scope # object with their parent closure, to preserve the expected lexical scope. @@ -70,10 +73,10 @@ exports.BaseNode = class BaseNode else if this instanceof ValueNode and options.assignment this.cacheIndexes(o) else - reference = literal temp = o.scope.freeVariable 'cache' + reference = literal o.scope.freeVariable 'cache' compiled = new AssignNode reference, this - [compiled, reference, temp] - return [pair[0].compile(o), pair[1].compile(o), pair[2]] if options.precompile + [compiled, reference] + return [pair[0].compile(o), pair[1].compile(o)] if options.precompile pair # Convenience method to grab the current indentation level, plus tabbing in. @@ -1176,11 +1179,9 @@ exports.OpNode = class OpNode extends BaseNode # true compileChain: (o) -> shared = @first.unwrap().second - [@first.second, shared, temp] = shared.compileReference(o) if shared.containsType CallNode + [@first.second, shared] = shared.compileReference(o) if shared.containsType CallNode [first, second, shared] = [@first.compile(o), @second.compile(o), shared.compile(o)] - js = "(#{first}) && (#{shared} #{@operator} #{second})" - o.scope.reuse temp if temp - js + "(#{first}) && (#{shared} #{@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 @@ -1403,7 +1404,7 @@ exports.ForNode = class ForNode extends BaseNode svar = scope.freeVariable 'cache' sourcePart = "#{svar} = #{ @source.compile(o) };" if @pattern - namePart = new AssignNode(@name, literal("#{svar}[#{ivar}]")).compile(merge o, {indent: @idt(1), top: true}) + '\n' + namePart = new AssignNode(@name, literal("#{svar}[#{ivar}]")).compile(merge o, {indent: @idt(1), top: true, keepLevel: yes}) + '\n' else namePart = "#{name} = #{svar}[#{ivar}]" if name unless @object diff --git a/src/scope.coffee b/src/scope.coffee index bf1d62aa..5a4fbb44 100644 --- a/src/scope.coffee +++ b/src/scope.coffee @@ -20,7 +20,20 @@ exports.Scope = class Scope constructor: (parent, expressions, method) -> [@parent, @expressions, @method] = [parent, expressions, method] @variables = {} - Scope.root = this if not @parent + if @parent + @garbage = @parent.garbage + else + @garbage = [] + Scope.root = this + + # Create a new garbage level + startLevel: -> + @garbage.push [] + + # Return to the previous garbage level and erase referenced temporary + # variables in current level from scope. + endLevel: -> + (@variables[name] = 'reuse') for name in @garbage.pop() when @variables[name] is 'var' # Look up a variable name in lexical scope, and declare it if it does not # already exist. @@ -29,11 +42,6 @@ exports.Scope = class Scope @variables[name] = 'var' false - # Erase a variable from scope. This is usually carried when we are done - # working with a list of temporary variables and we want to flag them for reuse. - reuse: (names...) -> - (@variables[val] = 'reuse') for val in names - # Test variables and return true the first time fn(v, k) returns true any: (fn) -> for v, k of @variables when fn(v, k) @@ -62,6 +70,7 @@ exports.Scope = class Scope index = 0 index++ while (@check temp = @temporary type, index) and @variables[temp] isnt 'reuse' @variables[temp] = 'var' + @garbage[@garbage.length - 1].push temp if @garbage.length temp # Ensure that an assignment is made at the top of this scope From 99a06ce4ead1ecc9c5acd00851f644fd1a94a7e0 Mon Sep 17 00:00:00 2001 From: Stan Angeloff Date: Mon, 20 Sep 2010 08:42:31 +0300 Subject: [PATCH 4/4] Updating name for cached length temporary variables to '_length', 'length2', and so on. --- lib/browser.js | 4 +- lib/cake.js | 4 +- lib/command.js | 26 ++++----- lib/grammar.js | 10 ++-- lib/helpers.js | 12 ++-- lib/lexer.js | 22 ++++---- lib/nodes.js | 140 +++++++++++++++++++++++------------------------ lib/optparse.js | 28 +++++----- lib/rewriter.js | 18 +++--- lib/scope.js | 4 +- src/nodes.coffee | 6 +- 11 files changed, 137 insertions(+), 137 deletions(-) diff --git a/lib/browser.js b/lib/browser.js index a5db05c2..07b9424f 100644 --- a/lib/browser.js +++ b/lib/browser.js @@ -19,9 +19,9 @@ return xhr.send(null); }; processScripts = function() { - var _cache, _cache2, _index, script; + var _cache, _index, _length, script; _cache = document.getElementsByTagName('script'); - for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { + for (_index = 0, _length = _cache.length; _index < _length; _index++) { script = _cache[_index]; if (script.type === 'text/coffeescript') { if (script.src) { diff --git a/lib/cake.js b/lib/cake.js index cd6b49dc..594ad8d2 100755 --- a/lib/cake.js +++ b/lib/cake.js @@ -35,7 +35,7 @@ }); exports.run = function() { return path.exists('Cakefile', function(exists) { - var _cache, _cache2, _index, _result, arg, args; + var _cache, _index, _length, _result, arg, args; if (!(exists)) { throw new Error("Cakefile not found in " + (process.cwd())); } @@ -49,7 +49,7 @@ } options = oparse.parse(args); _result = []; _cache = options.arguments; - for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { + for (_index = 0, _length = _cache.length; _index < _length; _index++) { arg = _cache[_index]; _result.push(invoke(arg)); } diff --git a/lib/command.js b/lib/command.js index b2617b0b..88fa96e4 100644 --- a/lib/command.js +++ b/lib/command.js @@ -53,9 +53,9 @@ return compileScripts(); }; compileScripts = function() { - var _cache2, _cache3, _index, _result; + var _cache2, _index, _length, _result; _result = []; _cache2 = sources; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { (function() { var base, compile; var source = _cache2[_index]; @@ -69,10 +69,10 @@ return fs.stat(source, function(err, stats) { if (stats.isDirectory()) { return fs.readdir(source, function(err, files) { - var _cache4, _cache5, _index2, _result2, file; - _result2 = []; _cache4 = files; - for (_index2 = 0, _cache5 = _cache4.length; _index2 < _cache5; _index2++) { - file = _cache4[_index2]; + var _cache3, _index2, _length2, _result2, file; + _result2 = []; _cache3 = files; + for (_index2 = 0, _length2 = _cache3.length; _index2 < _length2; _index2++) { + file = _cache3[_index2]; _result2.push(compile(path.join(source, file))); } return _result2; @@ -95,12 +95,12 @@ return _result; }; compileScript = function(file, input, base) { - var _cache2, _cache3, _index, o, options, req, t, task; + var _cache2, _index, _length, o, options, req, t, task; o = opts; options = compileOptions(file); if (o.require) { _cache2 = o.require; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { req = _cache2[_index]; require(helpers.starts(req, '.') ? fs.realpathSync(req) : req); } @@ -204,15 +204,15 @@ return jsl.stdin.end(); }; printTokens = function(tokens) { - var _cache2, _cache3, _cache4, _index, _result, strings, tag, token, value; + var _cache2, _cache3, _index, _length, _result, strings, tag, token, value; strings = (function() { _result = []; _cache2 = tokens; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { token = _cache2[_index]; _result.push((function() { - _cache4 = [token[0], token[1].toString().replace(/\n/, '\\n')]; - tag = _cache4[0]; - value = _cache4[1]; + _cache3 = [token[0], token[1].toString().replace(/\n/, '\\n')]; + tag = _cache3[0]; + value = _cache3[1]; return "[" + (tag) + " " + (value) + "]"; })()); } diff --git a/lib/grammar.js b/lib/grammar.js index 99c3f798..998c9339 100644 --- a/lib/grammar.js +++ b/lib/grammar.js @@ -1,5 +1,5 @@ (function() { - var Parser, _cache, _cache2, _cache3, _cache4, _cache5, _index, _index2, _result, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap; + var Parser, _cache, _cache2, _cache3, _index, _index2, _length, _length2, _result, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap; var __hasProp = Object.prototype.hasOwnProperty; Parser = require('jison').Parser; unwrap = /function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/; @@ -618,12 +618,12 @@ alternatives = _cache[name]; grammar[name] = (function() { _result = []; _cache2 = alternatives; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { alt = _cache2[_index]; _result.push((function() { - _cache4 = alt[0].split(' '); - for (_index2 = 0, _cache5 = _cache4.length; _index2 < _cache5; _index2++) { - token = _cache4[_index2]; + _cache3 = alt[0].split(' '); + for (_index2 = 0, _length2 = _cache3.length; _index2 < _length2; _index2++) { + token = _cache3[_index2]; if (!(grammar[token])) { tokens.push(token); } diff --git a/lib/helpers.js b/lib/helpers.js index 1c80eb7e..8e2f0eb2 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -5,12 +5,12 @@ } helpers = (exports.helpers = {}); helpers.indexOf = (indexOf = function(array, item, from) { - var _cache, _cache2, index, other; + var _cache, _length, index, other; if (array.indexOf) { return array.indexOf(item, from); } _cache = array; - for (index = 0, _cache2 = _cache.length; index < _cache2; index++) { + for (index = 0, _length = _cache.length; index < _length; index++) { other = _cache[index]; if (other === item && (!from || (from <= index))) { return index; @@ -30,9 +30,9 @@ return string.substring(start, start + literal.length) === literal; }); helpers.compact = (compact = function(array) { - var _cache, _cache2, _index, _result, item; + var _cache, _index, _length, _result, item; _result = []; _cache = array; - for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { + for (_index = 0, _length = _cache.length; _index < _length; _index++) { item = _cache[_index]; if (item) { _result.push(item); @@ -77,10 +77,10 @@ return _result; }); helpers.flatten = (flatten = function(array) { - var _cache, _cache2, _index, item, memo; + var _cache, _index, _length, item, memo; memo = []; _cache = array; - for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { + for (_index = 0, _length = _cache.length; _index < _length; _index++) { item = _cache[_index]; if (item instanceof Array) { memo = memo.concat(item); diff --git a/lib/lexer.js b/lib/lexer.js index 4973e59e..66951465 100644 --- a/lib/lexer.js +++ b/lib/lexer.js @@ -451,7 +451,7 @@ throw new Error("SyntaxError: Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned"); }; Lexer.prototype.balancedString = function(str, delimited, options) { - var _cache2, _cache3, _cache4, _index, close, i, levels, open, pair, slash; + var _cache2, _cache3, _index, _length, close, i, levels, open, pair, slash; options || (options = {}); slash = delimited[0][0] === '/'; levels = []; @@ -461,11 +461,11 @@ i += 1; } else { _cache2 = delimited; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { pair = _cache2[_index]; - _cache4 = pair; - open = _cache4[0]; - close = _cache4[1]; + _cache3 = pair; + open = _cache3[0]; + close = _cache3[1]; if (levels.length && starts(str, close, i) && levels[levels.length - 1] === pair) { levels.pop(); i += close.length - 1; @@ -494,7 +494,7 @@ return !i ? false : str.substring(0, i); }; Lexer.prototype.interpolateString = function(str, options) { - var _cache2, _cache3, _cache4, escaped, expr, i, idx, inner, interpolated, lexer, nested, pi, quote, tag, tok, token, tokens, value; + var _cache2, _cache3, _length, escaped, expr, i, idx, inner, interpolated, lexer, nested, pi, quote, tag, tok, token, tokens, value; options || (options = {}); if (str.length < 3 || !starts(str, '"')) { return this.token('STRING', str); @@ -521,7 +521,7 @@ line: this.line }); _cache2 = nested; - for (idx = 0, _cache3 = _cache2.length; idx < _cache3; idx++) { + for (idx = 0, _length = _cache2.length; idx < _length; idx++) { tok = _cache2[idx]; if (tok[0] === 'CALL_END') { (tok[0] = ')'); @@ -548,11 +548,11 @@ this.token('(', '('); } _cache2 = tokens; - for (i = 0, _cache3 = _cache2.length; i < _cache3; i++) { + for (i = 0, _length = _cache2.length; i < _length; i++) { token = _cache2[i]; - _cache4 = token; - tag = _cache4[0]; - value = _cache4[1]; + _cache3 = token; + tag = _cache3[0]; + value = _cache3[1]; if (tag === 'TOKENS') { this.tokens = this.tokens.concat(value); } else if (tag === 'STRING' && options.escapeQuotes) { diff --git a/lib/nodes.js b/lib/nodes.js index 5571a923..d1b0cabe 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -109,11 +109,11 @@ return this.traverseChildren(true, block); }; BaseNode.prototype.toString = function(idt, override) { - var _cache2, _cache3, _index, _result, child, children; + var _cache2, _index, _length, _result, child, children; idt || (idt = ''); children = (function() { _result = []; _cache2 = this.collectChildren(); - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { child = _cache2[_index]; _result.push(child.toString(idt + TAB)); } @@ -122,17 +122,17 @@ return '\n' + idt + (override || this["class"]) + children; }; BaseNode.prototype.eachChild = function(func) { - var _cache2, _cache3, _cache4, _cache5, _index, _index2, _result, attr, child; + var _cache2, _cache3, _index, _index2, _length, _length2, _result, attr, child; if (!(this.children)) { return null; } _result = []; _cache2 = this.children; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { attr = _cache2[_index]; if (this[attr]) { - _cache4 = flatten([this[attr]]); - for (_index2 = 0, _cache5 = _cache4.length; _index2 < _cache5; _index2++) { - child = _cache4[_index2]; + _cache3 = flatten([this[attr]]); + for (_index2 = 0, _length2 = _cache3.length; _index2 < _length2; _index2++) { + child = _cache3[_index2]; if (func(child) === false) { return null; } @@ -217,10 +217,10 @@ return o.scope ? Expressions.__super__.compile.call(this, o) : this.compileRoot(o); }; Expressions.prototype.compileNode = function(o) { - var _cache2, _cache3, _index, _result, node; + var _cache2, _index, _length, _result, node; return (function() { _result = []; _cache2 = this.expressions; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { node = _cache2[_index]; _result.push(this.compileExpression(node, merge(o))); } @@ -362,7 +362,7 @@ return this.base instanceof LiteralNode && this.base.value.match(NUMBER); }; ValueNode.prototype.cacheIndexes = function(o) { - var _cache2, _cache3, _index, copy, i; + var _cache2, _index, _length, copy, i; copy = new ValueNode(this.base, this.properties.slice(0)); if (this.base instanceof CallNode) { _cache2 = this.base.compileReference(o); @@ -370,17 +370,17 @@ copy.base = _cache2[1]; } _cache2 = copy.properties; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { (function() { - var _cache4, index, indexVar; + var _cache3, index, indexVar; var i = _index; var prop = _cache2[_index]; if (prop instanceof IndexNode && prop.contains(function(n) { return n instanceof CallNode; })) { - _cache4 = prop.index.compileReference(o); - index = _cache4[0]; - indexVar = _cache4[1]; + _cache3 = prop.index.compileReference(o); + index = _cache3[0]; + indexVar = _cache3[1]; this.properties[i] = new IndexNode(index); return (copy.properties[i] = new IndexNode(indexVar)); } @@ -392,13 +392,13 @@ return !o.top || this.properties.length ? ValueNode.__super__.compile.call(this, o) : this.base.compile(o); }; ValueNode.prototype.compileNode = function(o) { - var _cache2, _cache3, _index, baseline, complete, copy, hasSoak, i, me, only, op, part, prop, props, temp; + var _cache2, _index, _length, baseline, complete, copy, hasSoak, i, me, only, op, part, prop, props, temp; only = del(o, 'onlyFirst'); op = this.tags.operation; props = only ? this.properties.slice(0, this.properties.length - 1) : this.properties; o.chainRoot || (o.chainRoot = this); _cache2 = props; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { prop = _cache2[_index]; if (prop.soakNode) { hasSoak = true; @@ -418,7 +418,7 @@ } complete = (this.last = baseline); _cache2 = props; - for (i = 0, _cache3 = _cache2.length; i < _cache3; i++) { + for (i = 0, _length = _cache2.length; i < _length; i++) { prop = _cache2[i]; this.source = baseline; if (prop.soakNode) { @@ -504,7 +504,7 @@ })()); }; CallNode.prototype.compileNode = function(o) { - var _cache2, _cache3, _index, _result, arg, args, code, first, meth, methodAccessor, op; + var _cache2, _index, _length, _result, arg, args, code, first, meth, methodAccessor, op; if (!(o.chainRoot)) { o.chainRoot = this; } @@ -530,7 +530,7 @@ this.meth = this.variable.compile(o); } _cache2 = this.args; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { arg = _cache2[_index]; if (arg instanceof SplatNode) { code = this.compileSplat(o); @@ -539,7 +539,7 @@ if (!code) { args = (function() { _result = []; _cache2 = this.args; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { arg = _cache2[_index]; _result.push((function() { arg.parenthetical = true; @@ -556,7 +556,7 @@ return "" + (this.superReference(o)) + ".call(this" + (args.length ? ', ' : '') + (args) + ")"; }; CallNode.prototype.compileSplat = function(o) { - var _cache2, _cache3, _index, a, b, c, mentionsArgs, meth, obj, temp; + var _cache2, _index, _length, a, b, c, mentionsArgs, meth, obj, temp; meth = this.meth || this.superReference(o); obj = this.variable && this.variable.source || 'this'; if (obj.match(/\(/)) { @@ -567,7 +567,7 @@ if (this.isNew) { mentionsArgs = false; _cache2 = this.args; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { (function() { var arg = _cache2[_index]; return arg.contains(function(n) { @@ -773,12 +773,12 @@ return true; }; ObjectNode.prototype.compileNode = function(o) { - var _cache2, _cache3, _index, _result, i, indent, join, lastNoncom, nonComments, obj, prop, props, top; + var _cache2, _index, _length, _result, i, indent, join, lastNoncom, nonComments, obj, prop, props, top; top = del(o, 'top'); o.indent = this.idt(1); nonComments = (function() { _result = []; _cache2 = this.properties; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { prop = _cache2[_index]; if (!(prop instanceof CommentNode)) { _result.push(prop); @@ -789,7 +789,7 @@ lastNoncom = nonComments[nonComments.length - 1]; props = (function() { _result = []; _cache2 = this.properties; - for (i = 0, _cache3 = _cache2.length; i < _cache3; i++) { + for (i = 0, _length = _cache2.length; i < _length; i++) { prop = _cache2[i]; _result.push((function() { join = ",\n"; @@ -828,11 +828,11 @@ ArrayNode.prototype["class"] = 'ArrayNode'; ArrayNode.prototype.children = ['objects']; ArrayNode.prototype.compileNode = function(o) { - var _cache2, _cache3, code, i, obj, objects; + var _cache2, _length, code, i, obj, objects; o.indent = this.idt(1); objects = []; _cache2 = this.objects; - for (i = 0, _cache3 = _cache2.length; i < _cache3; i++) { + for (i = 0, _length = _cache2.length; i < _length; i++) { obj = _cache2[i]; code = obj.compile(o); if (obj instanceof SplatNode) { @@ -871,7 +871,7 @@ return this; }; ClassNode.prototype.compileNode = function(o) { - var _cache2, _cache3, _cache4, _index, access, applied, className, constScope, construct, constructor, extension, func, me, pname, prop, props, pvar, returns, val; + var _cache2, _cache3, _index, _length, access, applied, className, constScope, construct, constructor, extension, func, me, pname, prop, props, pvar, returns, val; if (this.variable === '__temp__') { this.variable = literal(o.scope.freeVariable('klass')); } @@ -888,11 +888,11 @@ constructor = new CodeNode(); } _cache2 = this.properties; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { prop = _cache2[_index]; - _cache4 = [prop.variable, prop.value]; - pvar = _cache4[0]; - func = _cache4[1]; + _cache3 = [prop.variable, prop.value]; + pvar = _cache3[0]; + func = _cache3[1]; if (pvar && pvar.base.value === 'constructor' && func instanceof CodeNode) { if (func.bound) { throw new Error("cannot define a constructor as a bound function."); @@ -1003,7 +1003,7 @@ return top || this.parenthetical ? val : ("(" + (val) + ")"); }; AssignNode.prototype.compilePatternMatch = function(o) { - var _cache2, _cache3, _cache4, accessClass, assigns, code, i, idx, isString, obj, oindex, olength, splat, val, valVar, value; + var _cache2, _cache3, _length, accessClass, assigns, code, i, idx, isString, obj, oindex, olength, splat, val, valVar, value; valVar = o.scope.freeVariable('cache'); value = this.value.isStatement(o) ? ClosureNode.wrap(this.value) : this.value; assigns = [("" + (this.tab) + (valVar) + " = " + (value.compile(o)) + ";")]; @@ -1011,14 +1011,14 @@ o.asStatement = true; splat = false; _cache2 = this.variable.base.objects; - for (i = 0, _cache3 = _cache2.length; i < _cache3; i++) { + for (i = 0, _length = _cache2.length; i < _length; i++) { obj = _cache2[i]; idx = i; if (this.variable.isObject()) { if (obj instanceof AssignNode) { - _cache4 = [obj.value, obj.variable.base]; - obj = _cache4[0]; - idx = _cache4[1]; + _cache3 = [obj.value, obj.variable.base]; + obj = _cache3[0]; + idx = _cache3[1]; } else { idx = obj; } @@ -1074,7 +1074,7 @@ CodeNode.prototype["class"] = 'CodeNode'; CodeNode.prototype.children = ['params', 'body']; CodeNode.prototype.compileNode = function(o) { - var _cache2, _cache3, _cache4, _index, _result, code, empty, func, i, param, params, sharedScope, splat, top, value; + var _cache2, _cache3, _index, _length, _result, code, empty, func, i, param, params, sharedScope, splat, top, value; sharedScope = del(o, 'sharedScope'); top = del(o, 'top'); o.scope = sharedScope || new Scope(o.scope, this.body, this); @@ -1086,7 +1086,7 @@ splat = undefined; params = []; _cache2 = this.params; - for (i = 0, _cache3 = _cache2.length; i < _cache3; i++) { + for (i = 0, _length = _cache2.length; i < _length; i++) { param = _cache2[i]; if (splat) { if (param.attach) { @@ -1096,11 +1096,11 @@ splat.trailings.push(param); } else { if (param.attach) { - _cache4 = param; - value = _cache4.value; - _cache4 = [literal(o.scope.freeVariable('arg')), param.splat]; - param = _cache4[0]; - param.splat = _cache4[1]; + _cache3 = param; + value = _cache3.value; + _cache3 = [literal(o.scope.freeVariable('arg')), param.splat]; + param = _cache3[0]; + param.splat = _cache3[1]; this.body.unshift(new AssignNode(new ValueNode(literal('this'), [new AccessorNode(value)]), param)); } if (param.splat) { @@ -1116,7 +1116,7 @@ } params = (function() { _result = []; _cache2 = params; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { param = _cache2[_index]; _result.push(param.compile(o)); } @@ -1126,7 +1126,7 @@ this.body.makeReturn(); } _cache2 = params; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { param = _cache2[_index]; (o.scope.parameter(param)); } @@ -1146,11 +1146,11 @@ } }; CodeNode.prototype.toString = function(idt) { - var _cache2, _cache3, _index, _result, child, children; + var _cache2, _index, _length, _result, child, children; idt || (idt = ''); children = (function() { _result = []; _cache2 = this.collectChildren(); - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { child = _cache2[_index]; _result.push(child.toString(idt + TAB)); } @@ -1197,18 +1197,18 @@ return (typeof (_cache2 = this.index) !== "undefined" && _cache2 !== null) ? this.compileParam(o) : this.name.compile(o); }; SplatNode.prototype.compileParam = function(o) { - var _cache2, _cache3, assign, end, idx, len, name, pos, trailing, variadic; + var _cache2, _length, assign, end, idx, len, name, pos, trailing, variadic; name = this.name.compile(o); o.scope.find(name); end = ''; if (this.trailings.length) { - len = o.scope.freeVariable('cache'); + len = o.scope.freeVariable('length'); o.scope.assign(len, "arguments.length"); variadic = o.scope.freeVariable('result'); o.scope.assign(variadic, len + ' >= ' + this.arglength); end = this.trailings.length ? (", " + (len) + " - " + (this.trailings.length)) : null; _cache2 = this.trailings; - for (idx = 0, _cache3 = _cache2.length; idx < _cache3; idx++) { + for (idx = 0, _length = _cache2.length; idx < _length; idx++) { trailing = _cache2[idx]; if (trailing.attach) { assign = trailing.assign; @@ -1227,10 +1227,10 @@ return "" + (utility('slice')) + ".call(" + (name) + ", " + (index) + (trail) + ")"; }; SplatNode.compileSplattedArray = function(list, o) { - var _cache2, _cache3, arg, args, code, i, last, prev; + var _cache2, _length, arg, args, code, i, last, prev; args = []; _cache2 = list; - for (i = 0, _cache3 = _cache2.length; i < _cache3; i++) { + for (i = 0, _length = _cache2.length; i < _length; i++) { arg = _cache2[i]; code = arg.compile(o); prev = args[(last = args.length - 1)]; @@ -1458,10 +1458,10 @@ return this.isArray() ? this.compileOrTest(o) : this.compileLoopTest(o); }; InNode.prototype.compileOrTest = function(o) { - var _cache2, _cache3, _result, i, item, tests; + var _cache2, _length, _result, i, item, tests; tests = (function() { _result = []; _cache2 = this.array.base.objects; - for (i = 0, _cache3 = _cache2.length; i < _cache3; i++) { + for (i = 0, _length = _cache2.length; i < _length; i++) { item = _cache2[i]; _result.push("" + (item.compile(o)) + " === " + (i ? this.obj2 : this.obj1)); } @@ -1476,7 +1476,7 @@ }); this.arr1 = _cache2[0]; this.arr2 = _cache2[1]; - _cache2 = [o.scope.freeVariable('index'), o.scope.freeVariable('cache')]; + _cache2 = [o.scope.freeVariable('index'), o.scope.freeVariable('length')]; i = _cache2[0]; l = _cache2[1]; prefix = this.obj1 !== this.obj2 ? this.obj1 + '; ' : ''; @@ -1702,7 +1702,7 @@ } } if (!(this.object)) { - lvar = scope.freeVariable('cache'); + lvar = scope.freeVariable('length'); stepPart = this.step ? ("" + (ivar) + " += " + (this.step.compile(o))) : ("" + (ivar) + "++"); forPart = ("" + (ivar) + " = 0, " + (lvar) + " = " + (svar) + ".length; " + (ivar) + " < " + (lvar) + "; " + (stepPart)); } @@ -1762,9 +1762,9 @@ return true; }; SwitchNode.prototype.makeReturn = function() { - var _cache2, _cache3, _index, pair; + var _cache2, _index, _length, pair; _cache2 = this.cases; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { pair = _cache2[_index]; pair[1].makeReturn(); } @@ -1774,20 +1774,20 @@ return this; }; SwitchNode.prototype.compileNode = function(o) { - var _cache2, _cache3, _cache4, _cache5, _index, _index2, block, code, condition, conditions, exprs, idt, pair; + var _cache2, _cache3, _index, _index2, _length, _length2, block, code, condition, conditions, exprs, idt, pair; idt = (o.indent = this.idt(1)); o.top = true; code = ("" + (this.tab) + "switch (" + (this.subject.compile(o)) + ") {"); _cache2 = this.cases; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { pair = _cache2[_index]; - _cache4 = pair; - conditions = _cache4[0]; - block = _cache4[1]; + _cache3 = pair; + conditions = _cache3[0]; + block = _cache3[1]; exprs = block.expressions; - _cache4 = flatten([conditions]); - for (_index2 = 0, _cache5 = _cache4.length; _index2 < _cache5; _index2++) { - condition = _cache4[_index2]; + _cache3 = flatten([conditions]); + for (_index2 = 0, _length2 = _cache3.length; _index2 < _length2; _index2++) { + condition = _cache3[_index2]; if (this.tags.subjectless) { condition = new OpNode('!!', new ParentheticalNode(condition)); } @@ -1852,14 +1852,14 @@ return this.statement || (this.statement = (!!((o && o.top) || this.tags.statement || this.bodyNode().isStatement(o) || (this.elseBody && this.elseBodyNode().isStatement(o))))); }; IfNode.prototype.compileCondition = function(o) { - var _cache2, _cache3, _index, _result, cond, conditions; + var _cache2, _index, _length, _result, cond, conditions; conditions = flatten([this.condition]); if (conditions.length === 1) { conditions[0].parenthetical = true; } return (function() { _result = []; _cache2 = conditions; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { cond = _cache2[_index]; _result.push(cond.compile(o)); } diff --git a/lib/optparse.js b/lib/optparse.js index 581fa70c..7eb03e7c 100755 --- a/lib/optparse.js +++ b/lib/optparse.js @@ -7,19 +7,19 @@ return this; }; OptionParser.prototype.parse = function(args) { - var _cache, _cache2, _cache3, _cache4, _index, arg, i, isOption, matchedRule, options, rule, value; + var _cache, _cache2, _index, _length, _length2, arg, i, isOption, matchedRule, options, rule, value; options = { arguments: [] }; args = normalizeArguments(args); _cache = args; - for (i = 0, _cache2 = _cache.length; i < _cache2; i++) { + for (i = 0, _length = _cache.length; i < _length; i++) { arg = _cache[i]; isOption = !!(arg.match(LONG_FLAG) || arg.match(SHORT_FLAG)); matchedRule = false; - _cache3 = this.rules; - for (_index = 0, _cache4 = _cache3.length; _index < _cache4; _index++) { - rule = _cache3[_index]; + _cache2 = this.rules; + for (_index = 0, _length2 = _cache2.length; _index < _length2; _index++) { + rule = _cache2[_index]; if (rule.shortFlag === arg || rule.longFlag === arg) { value = rule.hasArgument ? args[i += 1] : true; options[rule.name] = rule.isList ? (options[rule.name] || []).concat(value) : value; @@ -38,13 +38,13 @@ return options; }; OptionParser.prototype.help = function() { - var _cache, _cache2, _index, _result, i, letPart, lines, rule, spaces; + var _cache, _index, _length, _result, i, letPart, lines, rule, spaces; lines = ['Available options:']; if (this.banner) { lines.unshift("" + (this.banner) + "\n"); } _cache = this.rules; - for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { + for (_index = 0, _length = _cache.length; _index < _length; _index++) { rule = _cache[_index]; spaces = 15 - rule.longFlag.length; spaces = spaces > 0 ? (function() { @@ -66,9 +66,9 @@ MULTI_FLAG = /^-(\w{2,})/; OPTIONAL = /\[(\w+(\*?))\]/; buildRules = function(rules) { - var _cache, _cache2, _index, _result, tuple; + var _cache, _index, _length, _result, tuple; _result = []; _cache = rules; - for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { + for (_index = 0, _length = _cache.length; _index < _length; _index++) { tuple = _cache[_index]; _result.push((function() { if (tuple.length < 3) { @@ -94,16 +94,16 @@ }; }; normalizeArguments = function(args) { - var _cache, _cache2, _cache3, _cache4, _index, _index2, arg, l, match, result; + var _cache, _cache2, _index, _index2, _length, _length2, arg, l, match, result; args = args.slice(0); result = []; _cache = args; - for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { + for (_index = 0, _length = _cache.length; _index < _length; _index++) { arg = _cache[_index]; if (match = arg.match(MULTI_FLAG)) { - _cache3 = match[1].split(''); - for (_index2 = 0, _cache4 = _cache3.length; _index2 < _cache4; _index2++) { - l = _cache3[_index2]; + _cache2 = match[1].split(''); + for (_index2 = 0, _length2 = _cache2.length; _index2 < _length2; _index2++) { + l = _cache2[_index2]; result.push('-' + l); } } else { diff --git a/lib/rewriter.js b/lib/rewriter.js index 467efe67..5b390fc4 100644 --- a/lib/rewriter.js +++ b/lib/rewriter.js @@ -1,5 +1,5 @@ (function() { - var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, INVERSES, LINEBREAKS, Rewriter, SINGLE_CLOSERS, SINGLE_LINERS, _cache, _cache2, _index, _result, helpers, include, pair; + var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, INVERSES, LINEBREAKS, Rewriter, SINGLE_CLOSERS, SINGLE_LINERS, _cache, _index, _length, _result, helpers, include, pair; var __hasProp = Object.prototype.hasOwnProperty; if (typeof process !== "undefined" && process !== null) { _cache = require('./helpers'); @@ -291,13 +291,13 @@ levels = {}; openLine = {}; this.scanTokens(function(token, i) { - var _cache2, _cache3, _cache4, _index, close, open, pair; + var _cache2, _cache3, _index, _length, close, open, pair; _cache2 = pairs; - for (_index = 0, _cache3 = _cache2.length; _index < _cache3; _index++) { + for (_index = 0, _length = _cache2.length; _index < _length; _index++) { pair = _cache2[_index]; - _cache4 = pair; - open = _cache4[0]; - close = _cache4[1]; + _cache3 = pair; + open = _cache3[0]; + close = _cache3[1]; levels[open] || (levels[open] = 0); if (token[0] === open) { if (levels[open] === 0) { @@ -386,14 +386,14 @@ BALANCED_PAIRS = [['(', ')'], ['[', ']'], ['{', '}'], ['INDENT', 'OUTDENT'], ['PARAM_START', 'PARAM_END'], ['CALL_START', 'CALL_END'], ['INDEX_START', 'INDEX_END']]; INVERSES = {}; _cache = BALANCED_PAIRS; - for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { + for (_index = 0, _length = _cache.length; _index < _length; _index++) { pair = _cache[_index]; INVERSES[pair[0]] = pair[1]; INVERSES[pair[1]] = pair[0]; } EXPRESSION_START = (function() { _result = []; _cache = BALANCED_PAIRS; - for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { + for (_index = 0, _length = _cache.length; _index < _length; _index++) { pair = _cache[_index]; _result.push(pair[0]); } @@ -401,7 +401,7 @@ })(); EXPRESSION_END = (function() { _result = []; _cache = BALANCED_PAIRS; - for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { + for (_index = 0, _length = _cache.length; _index < _length; _index++) { pair = _cache[_index]; _result.push(pair[1]); } diff --git a/lib/scope.js b/lib/scope.js index 22e2c52b..92a1ad55 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -25,9 +25,9 @@ return this.garbage.push([]); }; Scope.prototype.endLevel = function() { - var _cache, _cache2, _index, _result, name; + var _cache, _index, _length, _result, name; _result = []; _cache = this.garbage.pop(); - for (_index = 0, _cache2 = _cache.length; _index < _cache2; _index++) { + for (_index = 0, _length = _cache.length; _index < _length; _index++) { name = _cache[_index]; if (this.variables[name] === 'var') { _result.push(this.variables[name] = 'reuse'); diff --git a/src/nodes.coffee b/src/nodes.coffee index 45660672..e929ac6d 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -1014,7 +1014,7 @@ exports.SplatNode = class SplatNode extends BaseNode o.scope.find name end = '' if @trailings.length - len = o.scope.freeVariable 'cache' + len = o.scope.freeVariable 'length' o.scope.assign len, "arguments.length" variadic = o.scope.freeVariable 'result' o.scope.assign variadic, len + ' >= ' + @arglength @@ -1230,7 +1230,7 @@ exports.InNode = class InNode extends BaseNode compileLoopTest: (o) -> [@arr1, @arr2] = @array.compileReference o, precompile: yes - [i, l] = [o.scope.freeVariable('index'), o.scope.freeVariable('cache')] + [i, l] = [o.scope.freeVariable('index'), o.scope.freeVariable('length')] prefix = if @obj1 isnt @obj2 then @obj1 + '; ' else '' "(function(){ #{prefix}for (var #{i}=0, #{l}=#{@arr1}.length; #{i}<#{l}; #{i}++) { if (#{@arr2}[#{i}] === #{@obj2}) return true; } return false; }).call(this)" @@ -1408,7 +1408,7 @@ exports.ForNode = class ForNode extends BaseNode else namePart = "#{name} = #{svar}[#{ivar}]" if name unless @object - lvar = scope.freeVariable 'cache' + lvar = scope.freeVariable 'length' stepPart = if @step then "#{ivar} += #{ @step.compile(o) }" else "#{ivar}++" forPart = "#{ivar} = 0, #{lvar} = #{svar}.length; #{ivar} < #{lvar}; #{stepPart}" sourcePart = (if rvar then "#{rvar} = []; " else '') + sourcePart