From 8cdee9c0f44c8544f4c4711923413418ae74a446 Mon Sep 17 00:00:00 2001 From: satyr Date: Sat, 2 Oct 2010 08:21:34 +0900 Subject: [PATCH] ensured `arguments` in each scope --- lib/scope.js | 70 +++++++++++++++++++++++++----------------------- src/scope.coffee | 20 +++++++------- 2 files changed, 47 insertions(+), 43 deletions(-) diff --git a/lib/scope.js b/lib/scope.js index 9c2d6e32..7b91d525 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -1,12 +1,15 @@ (function() { - var Scope, extend; + var Scope, _ref, extend, last; var __hasProp = Object.prototype.hasOwnProperty; - extend = require('./helpers').extend; + _ref = require('./helpers'), extend = _ref.extend, last = _ref.last; exports.Scope = (function() { - Scope = function(parent, expressions, method) { - var _ref; - _ref = [parent, expressions, method], this.parent = _ref[0], this.expressions = _ref[1], this.method = _ref[2]; - this.variables = {}; + Scope = function(_arg, _arg2, _arg3) { + this.method = _arg3; + this.expressions = _arg2; + this.parent = _arg; + this.variables = { + 'arguments': 'arguments' + }; if (this.parent) { this.garbage = this.parent.garbage; } else { @@ -20,12 +23,13 @@ return this.garbage.push([]); }; Scope.prototype.endLevel = function() { - var _i, _len, _ref, _result, name; - _result = []; _ref = this.garbage.pop(); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - name = _ref[_i]; - if (this.variables[name] === 'var') { - _result.push(this.variables[name] = 'reuse'); + var _i, _len, _ref2, _result, name, vars; + vars = this.variables; + _result = []; _ref2 = this.garbage.pop(); + for (_i = 0, _len = _ref2.length; _i < _len; _i++) { + name = _ref2[_i]; + if (vars[name] === 'var') { + _result.push(vars[name] = 'reuse'); } } return _result; @@ -38,11 +42,11 @@ return false; }; Scope.prototype.any = function(fn) { - var _ref, k, v; - _ref = this.variables; - for (v in _ref) { - if (!__hasProp.call(_ref, v)) continue; - k = _ref[v]; + var _ref2, k, v; + _ref2 = this.variables; + for (v in _ref2) { + if (!__hasProp.call(_ref2, v)) continue; + k = _ref2[v]; if (fn(v, k)) { return true; } @@ -53,12 +57,12 @@ return (this.variables[name] = 'param'); }; Scope.prototype.check = function(name, options) { - var immediate; + var _ref2, immediate; immediate = Object.prototype.hasOwnProperty.call(this.variables, name); - if (immediate || (options && options.immediate)) { + if (immediate || ((options != null) ? options.immediate : null)) { return immediate; } - return !!(this.parent && this.parent.check(name)); + return !!(((_ref2 = this.parent) != null) ? _ref2.check(name) : null); }; Scope.prototype.temporary = function(type, index) { return type.length > 1 ? '_' + type + (index > 1 ? index : '') : '_' + (index + parseInt(type, 36)).toString(36).replace(/\d/g, 'a'); @@ -71,7 +75,7 @@ } this.variables[temp] = 'var'; if (this.garbage.length) { - this.garbage[this.garbage.length - 1].push(temp); + last(this.garbage).push(temp); } return temp; }; @@ -83,7 +87,7 @@ }; Scope.prototype.hasDeclarations = function(body) { return body === this.expressions && this.any(function(k, val) { - return val === 'var' || val === 'reuse'; + return ('var' === val || 'reuse' === val); }); }; Scope.prototype.hasAssignments = function(body) { @@ -92,13 +96,13 @@ }); }; Scope.prototype.declaredVariables = function() { - var _ref, _result, key, val; + var _ref2, _result, key, val; return (function() { - _result = []; _ref = this.variables; - for (key in _ref) { - if (!__hasProp.call(_ref, key)) continue; - val = _ref[key]; - if (val === 'var' || val === 'reuse') { + _result = []; _ref2 = this.variables; + for (key in _ref2) { + if (!__hasProp.call(_ref2, key)) continue; + val = _ref2[key]; + if (('var' === val || 'reuse' === val)) { _result.push(key); } } @@ -106,11 +110,11 @@ }).call(this).sort(); }; Scope.prototype.assignedVariables = function() { - var _ref, _result, key, val; - _result = []; _ref = this.variables; - for (key in _ref) { - if (!__hasProp.call(_ref, key)) continue; - val = _ref[key]; + var _ref2, _result, key, val; + _result = []; _ref2 = this.variables; + for (key in _ref2) { + if (!__hasProp.call(_ref2, key)) continue; + val = _ref2[key]; if (val.assigned) { _result.push("" + (key) + " = " + (val.value)); } diff --git a/src/scope.coffee b/src/scope.coffee index b4256911..3a1aad31 100644 --- a/src/scope.coffee +++ b/src/scope.coffee @@ -6,7 +6,7 @@ # with the outside. # Import the helpers we plan to use. -{extend} = require './helpers' +{extend, last} = require './helpers' exports.Scope = class Scope @@ -17,9 +17,8 @@ exports.Scope = class Scope # as well as a reference to the **Expressions** node is belongs to, which is # where it should declare its variables, and a reference to the function that # it wraps. - constructor: (parent, expressions, method) -> - [@parent, @expressions, @method] = [parent, expressions, method] - @variables = {} + constructor: (@parent, @expressions, @method) -> + @variables = {'arguments'} if @parent @garbage = @parent.garbage else @@ -33,7 +32,8 @@ exports.Scope = class Scope # 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' + vars = @variables + (vars[name] = 'reuse') for name in @garbage.pop() when vars[name] is 'var' # Look up a variable name in lexical scope, and declare it if it does not # already exist. @@ -57,8 +57,8 @@ exports.Scope = class Scope # walks up to the root scope. check: (name, options) -> immediate = Object::hasOwnProperty.call @variables, name - return immediate if immediate or (options and options.immediate) - !!(@parent and @parent.check(name)) + return immediate if immediate or options?.immediate + !!@parent?.check name # Generate a temporary variable name at the given index. temporary: (type, index) -> @@ -73,7 +73,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 + last(@garbage).push temp if @garbage.length temp # Ensure that an assignment is made at the top of this scope @@ -84,7 +84,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' or val is 'reuse' + body is @expressions and @any (k, val) -> val in ['var', 'reuse'] # Does this scope reference any assignments that need to be declared at the # top of the given function body? @@ -93,7 +93,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' or val is 'reuse').sort() + (key for key, val of @variables when val in ['var', 'reuse']).sort() # Return the list of assignments that are supposed to be made at the top # of this scope.