diff --git a/lib/coffee-script/nodes.js b/lib/coffee-script/nodes.js index 91d01e1329..a506e19994 100644 --- a/lib/coffee-script/nodes.js +++ b/lib/coffee-script/nodes.js @@ -1,5 +1,5 @@ (function() { - var Access, Arr, Assign, Await, Base, Block, CALL_CONTINUATION, Call, Class, Closure, Code, Comment, CpsCascade, Defer, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, starts, tame, unfoldSoak, utility, _ref; + var Access, Arr, Assign, Await, Base, Block, CALL_CONTINUATION, Call, Class, Closure, Code, Comment, CpsCascade, Defer, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, Scope, Slice, Slot, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, starts, tame, unfoldSoak, utility, _ref; var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }, __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (__hasProp.call(this, i) && this[i] === item) return i; } return -1; }; Scope = require('./scope').Scope; @@ -727,6 +727,14 @@ } }; + Value.prototype.toSlot = function() { + var props, slotLoc; + slotLoc = null; + props = this.properties; + if (props && props.length) slotLoc = props.pop(); + return new Slot(this.base, props, slotLoc); + }; + Value.prototype.cacheReference = function(o) { var base, bref, name, nref; name = last(this.properties); @@ -2189,17 +2197,42 @@ })(); + exports.Slot = Slot = (function() { + + __extends(Slot, Base); + + function Slot(base, props, loc) { + this.base = base; + this.props = props; + this.loc = loc; + console.log("at Last! " + loc); + } + + Slot.prototype.children = ['base', 'props', 'loc']; + + return Slot; + + })(); + exports.Defer = Defer = (function() { __extends(Defer, Base); function Defer(args) { - this.args = args; + var a, _i, _len; + for (_i = 0, _len = args.length; _i < _len; _i++) { + a = args[_i]; + this.slots = a.toSlot(); + } } - Defer.prototype.children = ['args']; + Defer.prototype.children = ['slots']; Defer.prototype.compileNode = function(p) { + var call, meth; + call = new Value(new Literal(tame["const"].deferrals)); + meth = new Value(new Literal(tame["const"].defer_method)); + call.add(new Access(meth)); return "defer()"; }; diff --git a/lib/coffee-script/tame.js b/lib/coffee-script/tame.js index 1c238f0810..f53d1139fd 100644 --- a/lib/coffee-script/tame.js +++ b/lib/coffee-script/tame.js @@ -26,7 +26,8 @@ k_while: "_kw", b_while: "_break", t_while: "_while", - c_while: "_continue" + c_while: "_continue", + defer_method: "defer" }; }).call(this); diff --git a/src/nodes.coffee b/src/nodes.coffee index d6c126daed..cac47e3ba4 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -583,6 +583,15 @@ exports.Value = class Value extends Base unwrap: -> if @properties.length then this else @base + # If this value is being used as a slot for the purposes of a defer + # then export it here + toSlot : -> + slotLoc = null + props = @properties + if props and props.length + slotLoc = props.pop() + return new Slot @base, props, slotLoc + # A reference has base part (`this` value) and name part. # We cache them separately for compiling complex expressions. # `a()[b()] ?= c` -> `(_base = a())[_name = b()] ? _base[_name] = c` @@ -1780,13 +1789,23 @@ exports.In = class In extends Base toString: (idt) -> super idt, @constructor.name + if @negated then '!' else '' +#### Slot + +exports.Slot = class Slot extends Base + constructor : (base, props, loc) -> + @base = base + @props = props + @loc = loc + + children : [ 'base', 'props', 'loc' ] + #### Defer exports.Defer = class Defer extends Base constructor : (args) -> - @args = args + @slots = a.toSlot() for a in args - children : ['args'] + children : ['slots'] compileNode : (p) -> call = new Value new Literal tame.const.deferrals