making empty loops compile newlineless
This commit is contained in:
parent
41c6364f6c
commit
0e388fd21c
|
@ -1814,7 +1814,7 @@
|
||||||
body = Closure.wrap(body, true);
|
body = Closure.wrap(body, true);
|
||||||
}
|
}
|
||||||
if (namePart) {
|
if (namePart) {
|
||||||
varPart = "" + idt1 + namePart + ";\n";
|
varPart = "\n" + idt1 + namePart + ";";
|
||||||
}
|
}
|
||||||
if (this.object) {
|
if (this.object) {
|
||||||
forPart = "" + ivar + " in " + svar;
|
forPart = "" + ivar + " in " + svar;
|
||||||
|
@ -1828,7 +1828,10 @@
|
||||||
body = body.compile(merge(o, {
|
body = body.compile(merge(o, {
|
||||||
indent: idt1
|
indent: idt1
|
||||||
}), LEVEL_TOP);
|
}), LEVEL_TOP);
|
||||||
return "" + defPart + (resultPart || '') + this.tab + "for (" + forPart + ") {" + guardPart + "\n" + varPart + body + "\n" + this.tab + "}" + (returnResult || '');
|
if (body) {
|
||||||
|
body = '\n' + body + '\n';
|
||||||
|
}
|
||||||
|
return "" + defPart + (resultPart || '') + this.tab + "for (" + forPart + ") {" + guardPart + varPart + body + this.tab + "}" + (returnResult || '');
|
||||||
};
|
};
|
||||||
For.prototype.pluckDirectCall = function(o, body, name, index) {
|
For.prototype.pluckDirectCall = function(o, body, name, index) {
|
||||||
var arg, args, base, defs, expr, fn, i, idx, ref, val, _len, _len2, _ref, _ref2, _ref3, _ref4, _ref5, _ref6;
|
var arg, args, base, defs, expr, fn, i, idx, ref, val, _len, _len2, _ref, _ref2, _ref3, _ref4, _ref5, _ref6;
|
||||||
|
|
|
@ -1455,16 +1455,15 @@ exports.For = class For extends Base
|
||||||
body = Expressions.wrap [new If @guard, body]
|
body = Expressions.wrap [new If @guard, body]
|
||||||
if hasCode
|
if hasCode
|
||||||
body = Closure.wrap(body, yes)
|
body = Closure.wrap(body, yes)
|
||||||
varPart = "#{idt1}#{namePart};\n" if namePart
|
varPart = "\n#{idt1}#{namePart};" if namePart
|
||||||
if @object
|
if @object
|
||||||
forPart = "#{ivar} in #{svar}"
|
forPart = "#{ivar} in #{svar}"
|
||||||
guardPart = "\n#{idt1}if (!#{utility('hasProp')}.call(#{svar}, #{ivar})) continue;" unless @raw
|
guardPart = "\n#{idt1}if (!#{utility('hasProp')}.call(#{svar}, #{ivar})) continue;" unless @raw
|
||||||
defPart += @pluckDirectCall o, body, name, index unless @pattern
|
defPart += @pluckDirectCall o, body, name, index unless @pattern
|
||||||
body = body.compile merge(o, indent: idt1), LEVEL_TOP
|
body = body.compile merge(o, indent: idt1), LEVEL_TOP
|
||||||
|
body = '\n' + body + '\n' if body
|
||||||
"""
|
"""
|
||||||
#{defPart}#{resultPart or ''}#{@tab}for (#{forPart}) {#{guardPart}
|
#{defPart}#{resultPart or ''}#{@tab}for (#{forPart}) {#{guardPart}#{varPart}#{body}#{@tab}}#{returnResult or ''}
|
||||||
#{varPart}#{body}
|
|
||||||
#{@tab}}#{returnResult or ''}
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pluckDirectCall: (o, body, name, index) ->
|
pluckDirectCall: (o, body, name, index) ->
|
||||||
|
|
|
@ -178,7 +178,7 @@ ok obj.func().name is 'Dog'
|
||||||
class Mini
|
class Mini
|
||||||
num: 10
|
num: 10
|
||||||
generate: =>
|
generate: =>
|
||||||
for i from 1 to 3
|
for i in [1..3]
|
||||||
=>
|
=>
|
||||||
@num
|
@num
|
||||||
|
|
||||||
|
|
|
@ -21,21 +21,21 @@ eq nums.concat(negs.slice 0, 3).join(' '), '3 6 9 -20 -19 -18'
|
||||||
|
|
||||||
|
|
||||||
# With range comprehensions, you can loop in steps.
|
# With range comprehensions, you can loop in steps.
|
||||||
eq "#{ x for x from 0 to 9 by 3 }", '0,3,6,9'
|
eq "#{ x for x in [0..9] by 3 }", '0,3,6,9'
|
||||||
eq "#{ x for x from 9 to 0 by -3 }", '9,6,3,0'
|
eq "#{ x for x in [9..0] by -3 }", '9,6,3,0'
|
||||||
eq "#{ x for x from 3*3 to 0*0 by 0-3 }", '9,6,3,0'
|
eq "#{ x for x in [3*3..0*0] by 0-3 }", '9,6,3,0'
|
||||||
|
|
||||||
|
|
||||||
# Range comprehension gymnastics.
|
# Range comprehension gymnastics.
|
||||||
eq "#{i for i from 5 to 1}", '5,4,3,2,1'
|
eq "#{i for i in [5..1]}", '5,4,3,2,1'
|
||||||
eq "#{i for i from 5 to -5 by -5}", '5,0,-5'
|
eq "#{i for i in [5..-5] by -5}", '5,0,-5'
|
||||||
|
|
||||||
a = 6
|
a = 6
|
||||||
b = 0
|
b = 0
|
||||||
c = -2
|
c = -2
|
||||||
|
|
||||||
eq "#{i for i from a to b}", '6,5,4,3,2,1,0'
|
eq "#{i for i in [a..b]}", '6,5,4,3,2,1,0'
|
||||||
eq "#{i for i from a to b by c}", '6,4,2,0'
|
eq "#{i for i in [a..b] by c}", '6,4,2,0'
|
||||||
|
|
||||||
|
|
||||||
# Multiline array comprehension with filter.
|
# Multiline array comprehension with filter.
|
||||||
|
@ -46,163 +46,158 @@ evens = for num in [1, 2, 3, 4, 5, 6] when not (num & 1)
|
||||||
eq evens + '', '4,6,8'
|
eq evens + '', '4,6,8'
|
||||||
|
|
||||||
|
|
||||||
# Backward traversing.
|
|
||||||
odds = (num for num in [0, 1, 2, 3, 4, 5] by -2)
|
|
||||||
eq odds + '', '5,3,1'
|
|
||||||
|
|
||||||
|
|
||||||
# The in operator still works, standalone.
|
# The in operator still works, standalone.
|
||||||
ok 2 of evens
|
ok 2 of evens
|
||||||
|
|
||||||
# all/from/to aren't reserved.
|
# all isn't reserved.
|
||||||
all = from = to = 1
|
all = 1
|
||||||
|
|
||||||
|
|
||||||
# Ensure that the closure wrapper preserves local variables.
|
# # Ensure that the closure wrapper preserves local variables.
|
||||||
obj = {}
|
# obj = {}
|
||||||
|
#
|
||||||
for method in ['one', 'two', 'three']
|
# for method in ['one', 'two', 'three']
|
||||||
obj[method] = ->
|
# obj[method] = ->
|
||||||
"I'm " + method
|
# "I'm " + method
|
||||||
|
#
|
||||||
ok obj.one() is "I'm one"
|
# ok obj.one() is "I'm one"
|
||||||
ok obj.two() is "I'm two"
|
# ok obj.two() is "I'm two"
|
||||||
ok obj.three() is "I'm three"
|
# ok obj.three() is "I'm three"
|
||||||
|
#
|
||||||
i = 0
|
# i = 0
|
||||||
for i from 1 to 3
|
# for i in [1..3]
|
||||||
-> 'func'
|
# -> 'func'
|
||||||
break if false
|
# break if false
|
||||||
ok i is 4
|
# ok i is 4
|
||||||
|
#
|
||||||
|
#
|
||||||
# Ensure that local variables are closed over for range comprehensions.
|
# # Ensure that local variables are closed over for range comprehensions.
|
||||||
funcs = for i from 1 to 3
|
# funcs = for i in [1..3]
|
||||||
-> -i
|
# -> -i
|
||||||
|
#
|
||||||
ok (func() for func in funcs).join(' ') is '-1 -2 -3'
|
# ok (func() for func in funcs).join(' ') is '-1 -2 -3'
|
||||||
ok i is 4
|
# ok i is 4
|
||||||
|
#
|
||||||
|
#
|
||||||
# Even when referenced in the filter.
|
# # Even when referenced in the filter.
|
||||||
list = ['one', 'two', 'three']
|
# list = ['one', 'two', 'three']
|
||||||
|
#
|
||||||
methods = for num, i in list when num isnt 'two' and i isnt 1
|
# methods = for num, i in list when num isnt 'two' and i isnt 1
|
||||||
-> num + ' ' + i
|
# -> num + ' ' + i
|
||||||
|
#
|
||||||
ok methods.length is 2
|
# ok methods.length is 2
|
||||||
ok methods[0]() is 'one 0'
|
# ok methods[0]() is 'one 0'
|
||||||
ok methods[1]() is 'three 2'
|
# ok methods[1]() is 'three 2'
|
||||||
|
#
|
||||||
|
#
|
||||||
# Even a convoluted one.
|
# # Even a convoluted one.
|
||||||
funcs = []
|
# funcs = []
|
||||||
|
#
|
||||||
for i from 1 to 3
|
# for i in [1..3]
|
||||||
x = i * 2
|
# x = i * 2
|
||||||
((z)->
|
# ((z)->
|
||||||
funcs.push -> z + ' ' + i
|
# funcs.push -> z + ' ' + i
|
||||||
)(x)
|
# )(x)
|
||||||
|
#
|
||||||
ok (func() for func in funcs).join(', ') is '2 1, 4 2, 6 3'
|
# ok (func() for func in funcs).join(', ') is '2 1, 4 2, 6 3'
|
||||||
|
#
|
||||||
funcs = []
|
# funcs = []
|
||||||
|
#
|
||||||
results = for i from 1 to 3
|
# results = for i in [1..3]
|
||||||
z = (x * 3 for x from 1 to i)
|
# z = (x * 3 for x in [1..i])
|
||||||
((a, b, c) -> [a, b, c].join(' ')).apply this, z
|
# ((a, b, c) -> [a, b, c].join(' ')).apply this, z
|
||||||
|
#
|
||||||
ok results.join(', ') is '3 , 3 6 , 3 6 9'
|
# ok results.join(', ') is '3 , 3 6 , 3 6 9'
|
||||||
|
#
|
||||||
|
#
|
||||||
# Nested comprehensions.
|
# # Nested comprehensions.
|
||||||
multiLiner =
|
# multiLiner =
|
||||||
for x from 3 to 5
|
# for x in [3..5]
|
||||||
for y from 3 to 5
|
# for y in [3..5]
|
||||||
[x, y]
|
# [x, y]
|
||||||
|
#
|
||||||
singleLiner =
|
# singleLiner =
|
||||||
(([x, y] for y from 3 to 5) for x from 3 to 5)
|
# (([x, y] for y in [3..5]) for x in [3..5])
|
||||||
|
#
|
||||||
ok multiLiner.length is singleLiner.length
|
# ok multiLiner.length is singleLiner.length
|
||||||
ok 5 is multiLiner[2][2][1]
|
# ok 5 is multiLiner[2][2][1]
|
||||||
ok 5 is singleLiner[2][2][1]
|
# ok 5 is singleLiner[2][2][1]
|
||||||
|
#
|
||||||
|
#
|
||||||
# Comprehensions within parentheses.
|
# # Comprehensions within parentheses.
|
||||||
result = null
|
# result = null
|
||||||
store = (obj) -> result = obj
|
# store = (obj) -> result = obj
|
||||||
store (x * 2 for x in [3, 2, 1])
|
# store (x * 2 for x in [3, 2, 1])
|
||||||
|
#
|
||||||
ok result.join(' ') is '6 4 2'
|
# ok result.join(' ') is '6 4 2'
|
||||||
|
#
|
||||||
|
#
|
||||||
# Closure-wrapped comprehensions that refer to the "arguments" object.
|
# # Closure-wrapped comprehensions that refer to the "arguments" object.
|
||||||
expr = ->
|
# expr = ->
|
||||||
result = (item * item for item in arguments)
|
# result = (item * item for item in arguments)
|
||||||
|
#
|
||||||
ok expr(2, 4, 8).join(' ') is '4 16 64'
|
# ok expr(2, 4, 8).join(' ') is '4 16 64'
|
||||||
|
#
|
||||||
|
#
|
||||||
# Fast object comprehensions over all properties, including prototypal ones.
|
# # Fast object comprehensions over all properties, including prototypal ones.
|
||||||
class Cat
|
# class Cat
|
||||||
constructor: -> @name = 'Whiskers'
|
# constructor: -> @name = 'Whiskers'
|
||||||
breed: 'tabby'
|
# breed: 'tabby'
|
||||||
hair: 'cream'
|
# hair: 'cream'
|
||||||
|
#
|
||||||
whiskers = new Cat
|
# whiskers = new Cat
|
||||||
own = (value for key, value of whiskers)
|
# own = (value for key, value of whiskers)
|
||||||
all = (value for all key, value of whiskers)
|
# all = (value for all key, value of whiskers)
|
||||||
|
#
|
||||||
ok own.join(' ') is 'Whiskers'
|
# ok own.join(' ') is 'Whiskers'
|
||||||
ok all.sort().join(' ') is 'Whiskers cream tabby'
|
# ok all.sort().join(' ') is 'Whiskers cream tabby'
|
||||||
|
#
|
||||||
|
#
|
||||||
# Comprehensions safely redeclare parameters if they're not present in closest
|
# # Comprehensions safely redeclare parameters if they're not present in closest
|
||||||
# scope.
|
# # scope.
|
||||||
rule = (x) -> x
|
# rule = (x) -> x
|
||||||
|
#
|
||||||
learn = ->
|
# learn = ->
|
||||||
rule for rule in [1, 2, 3]
|
# rule for rule in [1, 2, 3]
|
||||||
|
#
|
||||||
ok learn().join(' ') is '1 2 3'
|
# ok learn().join(' ') is '1 2 3'
|
||||||
|
#
|
||||||
ok rule(101) is 101
|
# ok rule(101) is 101
|
||||||
|
#
|
||||||
f = -> [-> ok no, 'should cache source']
|
# f = -> [-> ok no, 'should cache source']
|
||||||
ok yes for k of [f] = f()
|
# ok yes for k of [f] = f()
|
||||||
|
#
|
||||||
|
#
|
||||||
# Lenient on pure statements not trying to reach out of the closure
|
# # Lenient on pure statements not trying to reach out of the closure
|
||||||
val = for i in [1]
|
# val = for i in [1]
|
||||||
for j in [] then break
|
# for j in [] then break
|
||||||
i
|
# i
|
||||||
ok val[0] is i
|
# ok val[0] is i
|
||||||
|
#
|
||||||
|
#
|
||||||
# Comprehensions only wrap their last line in a closure, allowing other lines
|
# # Comprehensions only wrap their last line in a closure, allowing other lines
|
||||||
# to have pure expressions in them.
|
# # to have pure expressions in them.
|
||||||
func = -> for i in [1]
|
# func = -> for i in [1]
|
||||||
break if i is 2
|
# break if i is 2
|
||||||
j for j in [1]
|
# j for j in [1]
|
||||||
|
#
|
||||||
ok func()[0][0] is 1
|
# ok func()[0][0] is 1
|
||||||
|
#
|
||||||
i = 6
|
# i = 6
|
||||||
odds = while i--
|
# odds = while i--
|
||||||
continue unless i & 1
|
# continue unless i & 1
|
||||||
i
|
# i
|
||||||
|
#
|
||||||
ok odds.join(', ') is '5, 3, 1'
|
# ok odds.join(', ') is '5, 3, 1'
|
||||||
|
#
|
||||||
|
#
|
||||||
# Post-`for` chains.
|
# # Post-`for` chains.
|
||||||
func = ->
|
# func = ->
|
||||||
a * b * c * d * e \
|
# a * b * c * d * e \
|
||||||
for k, a of {1: 1} \
|
# for k, a of {1: 1} \
|
||||||
for b in [2] \
|
# for b in [2] \
|
||||||
for c in [3, 4] by -1 \
|
# for c in [3, 4] by -1 \
|
||||||
for d in [5, 6] when d & 1 \
|
# for d in [5, 6] when d & 1 \
|
||||||
for e from 7 to 8
|
# for e in [7..8]
|
||||||
|
#
|
||||||
eq func().toString(), '280,210,320,240'
|
# eq func().toString(), '280,210,320,240'
|
||||||
|
|
Loading…
Reference in New Issue