From 2d9cff3af67771139ee83af49084df72fa3f0740 Mon Sep 17 00:00:00 2001 From: satyr Date: Thu, 7 Oct 2010 12:41:09 +0900 Subject: [PATCH] nodes: removed `literal` helper --- lib/nodes.js | 81 +++++++++++++++++++++++------------------------- src/nodes.coffee | 79 +++++++++++++++++++++++----------------------- 2 files changed, 77 insertions(+), 83 deletions(-) diff --git a/lib/nodes.js b/lib/nodes.js index 29e4cf5e..c836589a 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -1,5 +1,5 @@ (function() { - var Accessor, ArrayLiteral, Assign, Base, Call, Class, Closure, Code, Comment, Existence, Expressions, Extends, For, IDENTIFIER, IS_STRING, If, In, Index, Literal, NO, NUMBER, ObjectLiteral, Op, Param, Parenthetical, Push, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, TRAILING_WHITESPACE, Throw, Try, UTILITIES, Value, While, YES, _ref, compact, del, ends, flatten, include, indexOf, last, literal, merge, starts, utility; + var Accessor, ArrayLiteral, Assign, Base, Call, Class, Closure, Code, Comment, Existence, Expressions, Extends, For, IDENTIFIER, IS_STRING, If, In, Index, Literal, NO, NUMBER, ObjectLiteral, Op, Param, Parenthetical, Push, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, TRAILING_WHITESPACE, Throw, Try, UTILITIES, Value, While, YES, _ref, compact, del, ends, flatten, include, indexOf, last, merge, starts, utility; var __extends = function(child, parent) { var ctor = function() {}; ctor.prototype = parent.prototype; @@ -46,7 +46,7 @@ if (!(this.isComplex())) { return [this, this]; } else { - reference = literal(o.scope.freeVariable('ref')); + reference = new Literal(o.scope.freeVariable('ref')); compiled = new Assign(reference, this); return [compiled, reference]; } @@ -359,14 +359,14 @@ } base = new Value(this.base, this.properties.slice(0, -1)); if (base.isComplex()) { - bref = literal(o.scope.freeVariable('base')); + bref = new Literal(o.scope.freeVariable('base')); base = new Value(new Parenthetical(new Assign(bref, base))); } if (!(name)) { return [base, bref]; } if (name.isComplex()) { - nref = literal(o.scope.freeVariable('name')); + nref = new Literal(o.scope.freeVariable('name')); name = new Index(new Assign(nref, name.index)); nref = new Index(nref); } @@ -407,7 +407,7 @@ fst = new Value(this.base, this.properties.slice(0, i)); snd = new Value(this.base, this.properties.slice(i)); if (fst.isComplex()) { - ref = literal(o.scope.freeVariable('ref')); + ref = new Literal(o.scope.freeVariable('ref')); fst = new Parenthetical(new Assign(ref, fst)); snd.base = ref; } @@ -534,7 +534,7 @@ _ref2 = val.cacheReference(o), left = _ref2[0], rite = _ref2[1]; rite = new Call(rite, this.args); } else { - left = literal(this.superReference(o)); + left = new Literal(this.superReference(o)); rite = new Call(new Value(left), this.args); rite.isNew = this.isNew; } @@ -613,7 +613,7 @@ Extends.prototype.children = ['child', 'parent']; Extends.prototype.compileNode = function(o) { var ref; - ref = new Value(literal(utility('extends'))); + ref = new Value(new Literal(utility('extends'))); return (new Call(ref, [this.child, this.parent])).compile(o); }; return Extends; @@ -866,7 +866,7 @@ this.properties = _arg2; this.parent = _arg; Class.__super__.constructor.call(this); - this.variable = variable === '__temp__' ? literal(variable) : variable; + this.variable = variable === '__temp__' ? new Literal(variable) : variable; this.properties || (this.properties = []); this.returns = false; return this; @@ -883,7 +883,7 @@ var _i, _len, _ref2, _ref3, _ref4, access, applied, apply, className, constScope, construct, constructor, extension, func, me, pname, prop, props, pvar, ref, returns, val, variable; variable = this.variable; if (variable.value === '__temp__') { - variable = literal(o.scope.freeVariable('ctor')); + variable = new Literal(o.scope.freeVariable('ctor')); } extension = this.parent && new Extends(variable, this.parent); props = new Expressions; @@ -892,8 +892,8 @@ className = variable.compile(o); constScope = null; if (this.parent) { - applied = new Value(this.parent, [new Accessor(literal('apply'))]); - constructor = new Code([], new Expressions([new Call(applied, [literal('this'), literal('arguments')])])); + applied = new Value(this.parent, [new Accessor(new Literal('apply'))]); + constructor = new Code([], new Expressions([new Call(applied, [new Literal('this'), new Literal('arguments')])])); } else { constructor = new Code; } @@ -906,14 +906,14 @@ if (func !== ref) { props.push(func); } - apply = new Call(new Value(ref, [new Accessor(literal('apply'))]), [literal('this'), literal('arguments')]); + apply = new Call(new Value(ref, [new Accessor(new Literal('apply'))]), [new Literal('this'), new Literal('arguments')]); func = new Code([], new Expressions([apply])); } if (func.bound) { throw new Error("cannot define a constructor as a bound function."); } func.name = className; - func.body.push(new Return(literal('this'))); + func.body.push(new Return(new Literal('this'))); variable = new Value(variable); variable.namespaced = include(func.name, '.'); constructor = func; @@ -928,9 +928,9 @@ me || (me = constScope.freeVariable('this')); pname = pvar.compile(o); if (constructor.body.empty()) { - constructor.body.push(new Return(literal('this'))); + constructor.body.push(new Return(new Literal('this'))); } - constructor.body.unshift(literal("this." + pname + " = function(){ return " + className + ".prototype." + pname + ".apply(" + me + ", arguments); }")); + constructor.body.unshift(new Literal("this." + pname + " = function(){ return " + className + ".prototype." + pname + ".apply(" + me + ", arguments); }")); } } if (pvar) { @@ -942,7 +942,7 @@ } constructor.className = className.match(/[\w\d\$_]+$/); if (me) { - constructor.body.unshift(literal("" + me + " = this")); + constructor.body.unshift(new Literal("" + me + " = this")); } construct = this.idt() + new Assign(variable, constructor).compile(merge(o, { sharedScope: constScope @@ -1018,7 +1018,7 @@ if (obj instanceof Assign) { _ref2 = obj, idx = _ref2.variable.base, obj = _ref2.value; } else { - idx = isObject ? (obj.tags["this"] ? obj.properties[0].name : obj) : literal(0); + idx = isObject ? (obj.tags["this"] ? obj.properties[0].name : obj) : new Literal(0); } if (!(value instanceof Value)) { value = new Value(value); @@ -1049,13 +1049,13 @@ } accessClass = isObject && IDENTIFIER.test(idx.value) ? Accessor : Index; if (!splat && obj instanceof Splat) { - val = literal(obj.compileValue(o, valVar, i, olength - i - 1)); + val = new Literal(obj.compileValue(o, valVar, i, olength - i - 1)); splat = true; } else { if (typeof idx !== 'object') { - idx = literal(splat ? ("" + valVar + ".length - " + (olength - idx)) : idx); + idx = new Literal(splat ? ("" + valVar + ".length - " + (olength - idx)) : idx); } - val = new Value(literal(valVar), [new accessClass(idx)]); + val = new Value(new Literal(valVar), [new accessClass(idx)]); } assigns.push(new Assign(obj, val).compile(otop)); } @@ -1111,15 +1111,15 @@ param = _ref2[i]; if (splat) { if (param.attach) { - param.assign = new Assign(new Value(literal('this'), [new Accessor(param.value)])); + param.assign = new Assign(new Value(new Literal('this'), [new Accessor(param.value)])); this.body.expressions.splice(splat.index + 1, 0, param.assign); } splat.trailings.push(param); } else { if (param.attach) { value = param.value; - _ref3 = [literal(o.scope.freeVariable('arg')), param.splat], param = _ref3[0], param.splat = _ref3[1]; - this.body.unshift(new Assign(new Value(literal('this'), [new Accessor(value)]), param)); + _ref3 = [new Literal(o.scope.freeVariable('arg')), param.splat], param = _ref3[0], param.splat = _ref3[1]; + this.body.unshift(new Assign(new Value(new Literal('this'), [new Accessor(value)]), param)); } if (param.splat) { splat = new Splat(param.value); @@ -1174,7 +1174,7 @@ this.attach = _arg2; this.name = _arg; Param.__super__.constructor.call(this); - this.value = literal(this.name); + this.value = new Literal(this.name); return this; }; })(); @@ -1192,7 +1192,7 @@ if (this.splat) { name += '...'; } - return literal(name).toString(); + return new Literal(name).toString(); }; return Param; })(); @@ -1201,7 +1201,7 @@ return function Splat(name) { Splat.__super__.constructor.call(this); if (!(name.compile)) { - name = literal(name); + name = new Literal(name); } this.name = name; return this; @@ -1227,7 +1227,7 @@ trailing = _ref2[idx]; if (trailing.attach) { assign = trailing.assign; - trailing = literal(o.scope.freeVariable('arg')); + trailing = new Literal(o.scope.freeVariable('arg')); assign.value = trailing; } pos = this.trailings.length - idx; @@ -1313,7 +1313,7 @@ this.body = Expressions.wrap([new If(this.guard, this.body)]); } if (this.returns) { - post = '\n' + new Return(literal(rvar)).compile(merge(o, { + post = '\n' + new Return(new Literal(rvar)).compile(merge(o, { indent: this.idt() })); } else { @@ -1423,7 +1423,7 @@ var fst, ref; if (this.first.isComplex()) { ref = o.scope.freeVariable('ref'); - fst = new Parenthetical(new Assign(literal(ref), this.first)); + fst = new Parenthetical(new Assign(new Literal(ref), this.first)); } else { fst = this.first; ref = fst.compile(o); @@ -1625,7 +1625,7 @@ }; For.prototype.compileReturnValue = function(val, o) { if (this.returns) { - return '\n' + new Return(literal(val)).compile(o); + return '\n' + new Return(new Literal(val)).compile(o); } if (val) { return '\n' + val; @@ -1682,7 +1682,7 @@ } svar = ref; } - namePart = this.pattern ? new Assign(this.name, literal("" + svar + "[" + ivar + "]")).compile(merge(o, { + namePart = this.pattern ? new Assign(this.name, new Literal("" + svar + "[" + ivar + "]")).compile(merge(o, { top: true })) : (name ? ("" + name + " = " + svar + "[" + ivar + "]") : undefined); if (!(this.object)) { @@ -1701,13 +1701,13 @@ } if (codeInBody) { if (range) { - body.unshift(literal("var " + name + " = " + ivar)); + body.unshift(new Literal("var " + name + " = " + ivar)); } if (namePart) { - body.unshift(literal("var " + namePart)); + body.unshift(new Literal("var " + namePart)); } if (index) { - body.unshift(literal("var " + index + " = " + ivar)); + body.unshift(new Literal("var " + index + " = " + ivar)); } body = Closure.wrap(body, true); } else { @@ -1738,7 +1738,7 @@ this.subject = _arg; Switch.__super__.constructor.call(this); this.tags.subjectless = !this.subject; - this.subject || (this.subject = literal('true')); + this.subject || (this.subject = new Literal('true')); return this; }; })(); @@ -1895,7 +1895,7 @@ if (expressions.empty() || expressions.containsPureStatement()) { return expressions; } - return Expressions.wrap([new Call(new Value(literal(name), [new Accessor(literal('push'))]), [expressions.unwrap()])]); + return Expressions.wrap([new Call(new Value(new Literal(name), [new Accessor(new Literal('push'))]), [expressions.unwrap()])]); } }; Closure = { @@ -1907,10 +1907,10 @@ func = new Parenthetical(new Code([], Expressions.wrap([expressions]))); args = []; if ((mentionsArgs = expressions.contains(this.literalArgs)) || (expressions.contains(this.literalThis))) { - meth = literal(mentionsArgs ? 'apply' : 'call'); - args = [literal('this')]; + meth = new Literal(mentionsArgs ? 'apply' : 'call'); + args = [new Literal('this')]; if (mentionsArgs) { - args.push(literal('arguments')); + args.push(new Literal('arguments')); } func = new Value(func, [new Accessor(meth)]); } @@ -1936,9 +1936,6 @@ NUMBER = /^0x[\da-f]+|^(?:\d+(\.\d+)?|\.\d+)(?:e[+-]?\d+)?$/i; SIMPLENUM = /^-?\d+$/; IS_STRING = /^['"]/; - literal = function(name) { - return new Literal(name); - }; utility = function(name) { var ref; ref = ("__" + name); diff --git a/src/nodes.coffee b/src/nodes.coffee index 828489e1..27492cee 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -63,7 +63,7 @@ exports.Base = class Base pair = unless @isComplex() [this, this] else - reference = literal o.scope.freeVariable 'ref' + reference = new Literal o.scope.freeVariable 'ref' compiled = new Assign reference, this [compiled, reference] (pair[i] = node.compile o) for node, i in pair if options?.precompile @@ -352,11 +352,11 @@ exports.Value = class Value extends Base return [this, this] # `a` `a.b` base = new Value @base, @properties.slice 0, -1 if base.isComplex() # `a().b` - bref = literal o.scope.freeVariable 'base' + bref = new Literal o.scope.freeVariable 'base' base = new Value new Parenthetical new Assign bref, base return [base, bref] unless name # `a()` if name.isComplex() # `a[b()]` - nref = literal o.scope.freeVariable 'name' + nref = new Literal o.scope.freeVariable 'name' name = new Index new Assign nref, name.index nref = new Index nref [base.push(name), new Value(bref or base.base, [nref or name])] @@ -390,7 +390,7 @@ exports.Value = class Value extends Base fst = new Value @base, @properties.slice 0, i snd = new Value @base, @properties.slice i if fst.isComplex() - ref = literal o.scope.freeVariable 'ref' + ref = new Literal o.scope.freeVariable 'ref' fst = new Parenthetical new Assign ref, fst snd.base = ref ifn = new If new Existence(fst), snd, operation: yes @@ -493,7 +493,7 @@ exports.Call = class Call extends Base [left, rite] = val.cacheReference o rite = new Call rite, @args else - left = literal @superReference o + left = new Literal @superReference o rite = new Call new Value(left), @args rite.isNew = @isNew left = "typeof #{ left.compile o } !== \"function\"" @@ -558,7 +558,7 @@ exports.Extends = class Extends extends Base # Hooks one constructor into another's prototype chain. compileNode: (o) -> - ref = new Value literal utility 'extends' + ref = new Value new Literal utility 'extends' (new Call ref, [@child, @parent]).compile o #### Accessor @@ -765,7 +765,7 @@ exports.Class = class Class extends Base # list of prototype property assignments. constructor: (variable, @parent, @properties) -> super() - @variable = if variable is '__temp__' then literal variable else variable + @variable = if variable is '__temp__' then new Literal variable else variable @properties or= [] @returns = false @@ -778,7 +778,7 @@ exports.Class = class Class extends Base # constructor, property assignments, and inheritance getting built out below. compileNode: (o) -> {variable} = this - variable = literal o.scope.freeVariable 'ctor' if variable.value is '__temp__' + variable = new Literal o.scope.freeVariable 'ctor' if variable.value is '__temp__' extension = @parent and new Extends variable, @parent props = new Expressions o.top = true @@ -787,9 +787,9 @@ exports.Class = class Class extends Base constScope = null if @parent - applied = new Value(@parent, [new Accessor(literal('apply'))]) + applied = new Value @parent, [new Accessor new Literal 'apply'] constructor = new Code([], new Expressions([ - new Call(applied, [literal('this'), literal('arguments')]) + new Call applied, [new Literal('this'), new Literal('arguments')] ])) else constructor = new Code @@ -800,11 +800,11 @@ exports.Class = class Class extends Base if func not instanceof Code [func, ref] = func.compileReference o props.push func if func isnt ref - apply = new Call(new Value(ref, [new Accessor literal 'apply']), [literal('this'), literal('arguments')]) + apply = new Call(new Value(ref, [new Accessor new Literal 'apply']), [new Literal('this'), new Literal('arguments')]) func = new Code [], new Expressions([apply]) throw new Error "cannot define a constructor as a bound function." if func.bound func.name = className - func.body.push new Return literal 'this' + func.body.push new Return new Literal 'this' variable = new Value variable variable.namespaced = include func.name, '.' constructor = func @@ -817,8 +817,8 @@ exports.Class = class Class extends Base constScope or= new Scope(o.scope, constructor.body, constructor) me or= constScope.freeVariable 'this' pname = pvar.compile(o) - constructor.body.push new Return literal 'this' if constructor.body.empty() - constructor.body.unshift literal "this.#{pname} = function(){ return #{className}.prototype.#{pname}.apply(#{me}, arguments); }" + constructor.body.push new Return new Literal 'this' if constructor.body.empty() + constructor.body.unshift new Literal "this.#{pname} = function(){ return #{className}.prototype.#{pname}.apply(#{me}, arguments); }" if pvar access = if prop.context is 'this' then pvar.base.properties[0] else new Accessor(pvar, 'prototype') val = new Value variable, [access] @@ -826,7 +826,7 @@ exports.Class = class Class extends Base props.push prop constructor.className = className.match /[\w\d\$_]+$/ - constructor.body.unshift literal "#{me} = this" if me + constructor.body.unshift new Literal "#{me} = this" if me construct = @idt() + new Assign(variable, constructor).compile(merge o, sharedScope: constScope) + ';' props = if !props.empty() then '\n' + props.compile(o) else '' extension = if extension then '\n' + @idt() + extension.compile(o) + ';' else '' @@ -890,7 +890,7 @@ exports.Assign = class Assign extends Base else idx = if isObject if obj.tags.this then obj.properties[0].name else obj - else literal 0 + else new Literal 0 value = new Value value unless value instanceof Value accessClass = if IDENTIFIER.test idx.value then Accessor else Index value.properties.push new accessClass idx @@ -914,11 +914,11 @@ exports.Assign = class Assign extends Base throw new Error 'pattern matching must use only identifiers on the left-hand side.' accessClass = if isObject and IDENTIFIER.test(idx.value) then Accessor else Index if not splat and obj instanceof Splat - val = literal obj.compileValue o, valVar, i, olength - i - 1 + val = new Literal obj.compileValue o, valVar, i, olength - i - 1 splat = true else - idx = literal(if splat then "#{valVar}.length - #{olength - idx}" else idx) if typeof idx isnt 'object' - val = new Value literal(valVar), [new accessClass idx] + idx = new Literal(if splat then "#{valVar}.length - #{olength - idx}" else idx) if typeof idx isnt 'object' + val = new Value new Literal(valVar), [new accessClass idx] assigns.push new Assign(obj, val).compile otop assigns.push valVar unless top code = assigns.join ', ' @@ -971,14 +971,14 @@ exports.Code = class Code extends Base for param, i in @params if splat if param.attach - param.assign = new Assign new Value literal('this'), [new Accessor param.value] + param.assign = new Assign new Value new Literal('this'), [new Accessor param.value] @body.expressions.splice splat.index + 1, 0, param.assign splat.trailings.push param else if param.attach {value} = param - [param, param.splat] = [literal(o.scope.freeVariable 'arg'), param.splat] - @body.unshift new Assign new Value(literal('this'), [new Accessor value]), param + [param, param.splat] = [new Literal(o.scope.freeVariable 'arg'), param.splat] + @body.unshift new Assign new Value(new Literal('this'), [new Accessor value]), param if param.splat splat = new Splat param.value splat.index = i @@ -1017,7 +1017,7 @@ exports.Param = class Param extends Base constructor: (@name, @attach, @splat) -> super() - @value = literal @name + @value = new Literal @name compileNode: (o) -> @value.compile o @@ -1026,7 +1026,7 @@ exports.Param = class Param extends Base {name} = @ name = '@' + name if @attach name += '...' if @splat - literal(name).toString() + new Literal(name).toString() #### Splat @@ -1038,7 +1038,7 @@ exports.Splat = class Splat extends Base constructor: (name) -> super() - name = literal(name) unless name.compile + name = new Literal name unless name.compile @name = name compileNode: (o) -> @@ -1059,7 +1059,7 @@ exports.Splat = class Splat extends Base for trailing, idx in @trailings if trailing.attach assign = trailing.assign - trailing = literal o.scope.freeVariable 'arg' + trailing = new Literal o.scope.freeVariable 'arg' assign.value = trailing pos = @trailings.length - idx o.scope.assign(trailing.compile(o), "arguments[#{variadic} ? #{len} - #{pos} : #{@index + idx}]") @@ -1135,7 +1135,7 @@ exports.While = class While extends Base pre = "#{set}#{@tab}while (#{cond})" @body = Expressions.wrap([new If(@guard, @body)]) if @guard if @returns - post = '\n' + new Return(literal(rvar)).compile(merge(o, indent: @idt())) + post = '\n' + new Return(new Literal rvar).compile(merge(o, indent: @idt())) else post = '' "#{pre} {\n#{ @body.compile(o) }\n#{@tab}}#{post}" @@ -1233,7 +1233,7 @@ exports.Op = class Op extends Base compileExistence: (o) -> if @first.isComplex() ref = o.scope.freeVariable 'ref' - fst = new Parenthetical new Assign literal(ref), @first + fst = new Parenthetical new Assign new Literal(ref), @first else fst = @first ref = fst.compile o @@ -1405,7 +1405,7 @@ exports.For = class For extends Base this compileReturnValue: (val, o) -> - return '\n' + new Return(literal(val)).compile(o) if @returns + return '\n' + new Return(new Literal val).compile(o) if @returns return '\n' + val if val '' @@ -1441,7 +1441,7 @@ exports.For = class For extends Base sourcePart = "(#{sourcePart})" unless @object svar = ref namePart = if @pattern - new Assign(@name, literal "#{svar}[#{ivar}]").compile merge o, top: on + new Assign(@name, new Literal "#{svar}[#{ivar}]").compile merge o, top: on else if name "#{name} = #{svar}[#{ivar}]" unless @object @@ -1454,9 +1454,9 @@ exports.For = class For extends Base if @guard body = Expressions.wrap([new If(@guard, body)]) if codeInBody - body.unshift literal "var #{name} = #{ivar}" if range - body.unshift literal "var #{namePart}" if namePart - body.unshift literal "var #{index} = #{ivar}" if index + body.unshift new Literal "var #{name} = #{ivar}" if range + body.unshift new Literal "var #{namePart}" if namePart + body.unshift new Literal "var #{index} = #{ivar}" if index body = Closure.wrap(body, true) else varPart = "#{idt1}#{namePart};\n" if namePart @@ -1483,7 +1483,7 @@ exports.Switch = class Switch extends Base constructor: (@subject, @cases, @otherwise) -> super() @tags.subjectless = !@subject - @subject or= literal 'true' + @subject or= new Literal 'true' makeReturn: -> pair[1].makeReturn() for pair in @cases @@ -1607,7 +1607,7 @@ Push = wrap: (name, expressions) -> return expressions if expressions.empty() or expressions.containsPureStatement() Expressions.wrap [new Call( - new Value literal(name), [new Accessor literal 'push'] + new Value new Literal(name), [new Accessor new Literal 'push'] [expressions.unwrap()] )] @@ -1625,9 +1625,9 @@ Closure = args = [] if (mentionsArgs = expressions.contains @literalArgs) or ( expressions.contains @literalThis) - meth = literal if mentionsArgs then 'apply' else 'call' - args = [literal 'this'] - args.push literal 'arguments' if mentionsArgs + meth = new Literal if mentionsArgs then 'apply' else 'call' + args = [new Literal 'this'] + args.push new Literal 'arguments' if mentionsArgs func = new Value func, [new Accessor meth] call = new Call func, args if statement then Expressions.wrap [call] else call @@ -1683,9 +1683,6 @@ IS_STRING = /^['"]/ # Utility Functions # ----------------- -# Handy helper for generating a Literal. -literal = (name) -> new Literal name - # Helper for ensuring that utility functions are assigned at the top level. utility = (name) -> ref = "__#{name}"