From 78ef41756edd3e6927436dcd8bc15a62598f6a3e Mon Sep 17 00:00:00 2001 From: Ryan Hendrickson Date: Wed, 10 Feb 2016 12:27:03 -0500 Subject: [PATCH] fix semiautovivification with slices --- lib/ast.js | 16 +++++++++++++--- src/ast.ls | 10 ++++++++-- test/chaining.ls | 5 +++++ 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/lib/ast.js b/lib/ast.js index 9ba2f4b05..37b4229eb 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -955,7 +955,7 @@ exports.Chain = Chain = (function(superclass){ } function ctor$(){} ctor$.prototype = prototype; prototype.children = ['head', 'tails']; prototype.add = function(it){ - var last, ref$, index, ref1$, bi, that, ref2$, logics, call, f; + var last, ref$, index, ref1$, bi, logics, call, f; if (this.tails.length) { last = (ref$ = this.tails)[ref$.length - 1]; if (last instanceof Call && ((ref$ = last.partialized) != null ? ref$.length : void 8) === 1 && it.args.length === 1) { @@ -981,8 +981,6 @@ exports.Chain = Chain = (function(superclass){ } else if (!this.tails[1] && ((ref1$ = it.key) != null ? ref1$.name : void 8) === 'prototype') { this.head.sproto = true; } - } else if (that = (ref2$ = it.vivify, delete it.vivify, ref2$)) { - this.head = Assign(Chain(this.head, this.tails.splice(0, 9e9)), that(), '=', '||'); } else if (it instanceof Call && this.tails.length === 1 && bi && in$(bi.op, logics = ['&&', '||', 'xor'])) { call = it; f = function(x, key){ @@ -1161,6 +1159,7 @@ exports.Chain = Chain = (function(superclass){ this.carp('invalid callee'); } this.expandSlice(o); + this.expandVivify(); this.expandBind(o); this.expandSplat(o); this.expandStar(o); @@ -1272,6 +1271,17 @@ exports.Chain = Chain = (function(superclass){ } } }; + prototype.expandVivify = function(){ + var tails, i, that, ref$, ref1$; + tails = this.tails; + i = 0; + while (i < tails.length) { + if (that = (ref1$ = (ref$ = tails[i++]).vivify, delete ref$.vivify, ref1$)) { + this.head = Assign(Chain(this.head, tails.splice(0, i)), that(), '=', '||'); + i = 0; + } + } + }; prototype.expandBind = function(o){ var tails, i, that, obj, key, call; tails = this.tails; diff --git a/src/ast.ls b/src/ast.ls index cb37e78d0..ea3d690b8 100644 --- a/src/ast.ls +++ b/src/ast.ls @@ -639,8 +639,6 @@ class exports.Chain extends Node @head.called = true else if not @tails.1 and it.key?name is \prototype @head.sproto = true - else if delete it.vivify - @head = Assign Chain(@head, @tails.splice 0, 9e9), that!, \= \|| else if it instanceof Call and @tails.length is 1 and bi and bi.op in logics = <[ && || xor ]> call = it @@ -759,6 +757,7 @@ class exports.Chain extends Node .add Call [context, Arr [this; Arr partial.args; Arr partial.partialized]]), post).compile o @carp 'invalid callee' if tails.0 instanceof Call and not head.is-callable! @expand-slice o + @expand-vivify! @expand-bind o @expand-splat o @expand-star o @@ -837,6 +836,13 @@ class exports.Chain extends Node i = 0 call <<< method: \.apply, args: [ctx or Literal \null; JS args] + expand-vivify: !-> + {tails} = this + i = 0 + while i < tails.length when delete tails[i++]vivify + @head = Assign Chain(@head, tails.splice 0, i), that!, \= \|| + i = 0 + expand-bind: !(o) -> {tails} = this i = -1 diff --git a/test/chaining.ls b/test/chaining.ls index ac78704a4..04686d424 100644 --- a/test/chaining.ls +++ b/test/chaining.ls @@ -214,6 +214,11 @@ eq '0,1' ''+o.a.b eq '2,3' ''+o.a.c.d eq 5 o.a.b.e.f.4 +a = [] +eq 2 a{}[0, 1].length +eq \object typeof a.0 +eq \object typeof a.1 + # Bang Call eq '' String! (-> ok true)!