Merge branch 'master' of github.com:michaelficarra/coffee-script into refactorTests
This commit is contained in:
commit
1e080cc258
|
@ -0,0 +1,6 @@
|
|||
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
|
||||
copy = numbers[0...numbers.length]
|
||||
|
||||
middle = copy[3..6]
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
|
||||
numbers[3..6] = [-3, -4, -5, -6]
|
||||
|
||||
|
|
@ -46,6 +46,7 @@
|
|||
<a href="#splats">Splats...</a>
|
||||
<a href="#while">While, Until, and Loop</a>
|
||||
<a href="#comprehensions">Comprehensions (Arrays, Objects, and Ranges)</a>
|
||||
<a href="#slices">Array Slicing and Splicing</a>
|
||||
<a href="#expressions">Everything is an Expression</a>
|
||||
<a href="#existence">The Existential Operator</a>
|
||||
<a href="#classes">Classes, Inheritance, and Super</a>
|
||||
|
@ -529,6 +530,22 @@ coffee --bare --print --stdio</pre>
|
|||
loop, for speed or for another reason, you can use <br />
|
||||
<tt>for all key, value of object</tt> in CoffeeScript.
|
||||
</p>
|
||||
<p>
|
||||
<span id="slices" class="bookmark"></span>
|
||||
<b class="header">Array Slicing and Splicing with Ranges</b>
|
||||
Ranges can also be used to extract slices of arrays.
|
||||
With two dots (<tt>3..6</tt>), the range is inclusive (<tt>3, 4, 5, 6</tt>);
|
||||
with three docs (<tt>3...6</tt>), the range excludes the end (<tt>3, 4, 5</tt>).
|
||||
</p>
|
||||
<%= code_for('slices', 'middle') %>
|
||||
<p>
|
||||
The same syntax can be used with assignment to replace a segment of an array
|
||||
with new values, splicing it.
|
||||
</p>
|
||||
<%= code_for('splices', 'numbers') %>
|
||||
<p>
|
||||
Note that JavaScript strings are immutable, and can't be spliced.
|
||||
</p>
|
||||
<p>
|
||||
<span id="expressions" class="bookmark"></span>
|
||||
<b class="header">Everything is an Expression (at least, as much as possible)</b>
|
||||
|
@ -1019,7 +1036,7 @@ coffee --bare --print --stdio</pre>
|
|||
Improved syntax errors for invalid CoffeeScript. <tt>undefined</tt> now
|
||||
works like <tt>null</tt>, and cannot be assigned a new value.
|
||||
There was a precedence change with respect to single-line comprehensions:
|
||||
<tt>result = i for i in list</tt><br /> used to parse as <tt>result = (i for i in list)</tt>
|
||||
<tt>result = i for i in list</tt><br /> used to parse as <tt>result = (i for i in list)</tt>
|
||||
by default ... it now parses as <br /><tt>(result = i) for i in list</tt>.
|
||||
</p>
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
var cholesterol, healthy;
|
||||
cholesterol = 127;
|
||||
healthy = 200 > cholesterol && cholesterol > 60;
|
||||
healthy = (200 > cholesterol && cholesterol > 60);
|
|
@ -0,0 +1,4 @@
|
|||
var copy, middle, numbers;
|
||||
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
copy = numbers.slice(0, numbers.length);
|
||||
middle = copy.slice(3, 6 + 1);
|
|
@ -0,0 +1,3 @@
|
|||
var numbers, _ref;
|
||||
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
([].splice.apply(numbers, [3, 6 - 3 + 1].concat(_ref = [-3, -4, -5, -6])), _ref);
|
|
@ -3,7 +3,7 @@ if (this.studyingEconomics) {
|
|||
while (supply > demand) {
|
||||
buy();
|
||||
}
|
||||
while (supply <= demand) {
|
||||
while (!(supply > demand)) {
|
||||
sell();
|
||||
}
|
||||
}
|
||||
|
|
52
index.html
52
index.html
|
@ -33,6 +33,7 @@
|
|||
<a href="#splats">Splats...</a>
|
||||
<a href="#while">While, Until, and Loop</a>
|
||||
<a href="#comprehensions">Comprehensions (Arrays, Objects, and Ranges)</a>
|
||||
<a href="#slices">Array Slicing and Splicing</a>
|
||||
<a href="#expressions">Everything is an Expression</a>
|
||||
<a href="#existence">The Existential Operator</a>
|
||||
<a href="#classes">Classes, Inheritance, and Super</a>
|
||||
|
@ -804,7 +805,7 @@ lyrics <span class="Keyword">=</span> <span class="Keyword">while</span> num <sp
|
|||
<span class="Keyword">while</span> (supply <span class="Keyword">></span> demand) {
|
||||
buy();
|
||||
}
|
||||
<span class="Keyword">while</span> (supply <span class="Keyword"><=</span> demand) {
|
||||
<span class="Keyword">while</span> (<span class="Keyword">!</span>(supply <span class="Keyword">></span> demand)) {
|
||||
sell();
|
||||
}
|
||||
}
|
||||
|
@ -821,7 +822,7 @@ if (this.studyingEconomics) {
|
|||
while (supply > demand) {
|
||||
buy();
|
||||
}
|
||||
while (supply <= demand) {
|
||||
while (!(supply > demand)) {
|
||||
sell();
|
||||
}
|
||||
}
|
||||
|
@ -944,6 +945,45 @@ ages = function() {
|
|||
loop, for speed or for another reason, you can use <br />
|
||||
<tt>for all key, value of object</tt> in CoffeeScript.
|
||||
</p>
|
||||
<p>
|
||||
<span id="slices" class="bookmark"></span>
|
||||
<b class="header">Array Slicing and Splicing with Ranges</b>
|
||||
Ranges can also be used to extract slices of arrays.
|
||||
With two dots (<tt>3..6</tt>), the range is inclusive (<tt>3, 4, 5, 6</tt>);
|
||||
with three docs (<tt>3...6</tt>), the range excludes the end (<tt>3, 4, 5</tt>).
|
||||
</p>
|
||||
<div class='code'><pre class="idle">numbers <span class="Keyword">=</span> [<span class="Number">0</span>, <span class="Number">1</span>, <span class="Number">2</span>, <span class="Number">3</span>, <span class="Number">4</span>, <span class="Number">5</span>, <span class="Number">6</span>, <span class="Number">7</span>, <span class="Number">8</span>, <span class="Number">9</span>]
|
||||
|
||||
copy <span class="Keyword">=</span> numbers[<span class="Number">0</span>...numbers.length]
|
||||
|
||||
middle <span class="Keyword">=</span> copy[<span class="Number">3</span>..<span class="Number">6</span>]
|
||||
|
||||
</pre><pre class="idle"><span class="Storage">var</span> copy, middle, numbers;
|
||||
numbers <span class="Keyword">=</span> [<span class="Number">0</span>, <span class="Number">1</span>, <span class="Number">2</span>, <span class="Number">3</span>, <span class="Number">4</span>, <span class="Number">5</span>, <span class="Number">6</span>, <span class="Number">7</span>, <span class="Number">8</span>, <span class="Number">9</span>];
|
||||
copy <span class="Keyword">=</span> numbers.<span class="LibraryFunction">slice</span>(<span class="Number">0</span>, numbers.<span class="LibraryConstant">length</span>);
|
||||
middle <span class="Keyword">=</span> copy.<span class="LibraryFunction">slice</span>(<span class="Number">3</span>, <span class="Number">6</span> <span class="Keyword">+</span> <span class="Number">1</span>);
|
||||
</pre><button onclick='javascript: var copy, middle, numbers;
|
||||
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
copy = numbers.slice(0, numbers.length);
|
||||
middle = copy.slice(3, 6 + 1);;alert(middle);'>run: middle</button><br class='clear' /></div>
|
||||
<p>
|
||||
The same syntax can be used with assignment to replace a segment of an array
|
||||
with new values, splicing it.
|
||||
</p>
|
||||
<div class='code'><pre class="idle">numbers <span class="Keyword">=</span> [<span class="Number">0</span>, <span class="Number">1</span>, <span class="Number">2</span>, <span class="Number">3</span>, <span class="Number">4</span>, <span class="Number">5</span>, <span class="Number">6</span>, <span class="Number">7</span>, <span class="Number">8</span>, <span class="Number">9</span>]
|
||||
|
||||
numbers[<span class="Number">3</span>..<span class="Number">6</span>] <span class="Keyword">=</span> [<span class="Keyword">-</span><span class="Number">3</span>, <span class="Keyword">-</span><span class="Number">4</span>, <span class="Keyword">-</span><span class="Number">5</span>, <span class="Keyword">-</span><span class="Number">6</span>]
|
||||
|
||||
|
||||
</pre><pre class="idle"><span class="Storage">var</span> numbers, _ref;
|
||||
numbers <span class="Keyword">=</span> [<span class="Number">0</span>, <span class="Number">1</span>, <span class="Number">2</span>, <span class="Number">3</span>, <span class="Number">4</span>, <span class="Number">5</span>, <span class="Number">6</span>, <span class="Number">7</span>, <span class="Number">8</span>, <span class="Number">9</span>];
|
||||
([].splice.<span class="LibraryFunction">apply</span>(numbers, [<span class="Number">3</span>, <span class="Number">6</span> <span class="Keyword">-</span> <span class="Number">3</span> <span class="Keyword">+</span> <span class="Number">1</span>].<span class="LibraryFunction">concat</span>(_ref <span class="Keyword">=</span> [<span class="Keyword">-</span><span class="Number">3</span>, <span class="Keyword">-</span><span class="Number">4</span>, <span class="Keyword">-</span><span class="Number">5</span>, <span class="Keyword">-</span><span class="Number">6</span>])), _ref);
|
||||
</pre><button onclick='javascript: var numbers, _ref;
|
||||
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
([].splice.apply(numbers, [3, 6 - 3 + 1].concat(_ref = [-3, -4, -5, -6])), _ref);;alert(numbers);'>run: numbers</button><br class='clear' /></div>
|
||||
<p>
|
||||
Note that JavaScript strings are immutable, and can't be spliced.
|
||||
</p>
|
||||
<p>
|
||||
<span id="expressions" class="bookmark"></span>
|
||||
<b class="header">Everything is an Expression (at least, as much as possible)</b>
|
||||
|
@ -1523,10 +1563,10 @@ healthy <span class="Keyword">=</span> <span class="Number">200</span> <span cla
|
|||
|
||||
</pre><pre class="idle"><span class="Storage">var</span> cholesterol, healthy;
|
||||
cholesterol <span class="Keyword">=</span> <span class="Number">127</span>;
|
||||
healthy <span class="Keyword">=</span> <span class="Number">200</span> <span class="Keyword">></span> cholesterol <span class="Keyword">&</span><span class="Keyword">&</span> cholesterol <span class="Keyword">></span> <span class="Number">60</span>;
|
||||
healthy <span class="Keyword">=</span> (<span class="Number">200</span> <span class="Keyword">></span> cholesterol <span class="Keyword">&</span><span class="Keyword">&</span> cholesterol <span class="Keyword">></span> <span class="Number">60</span>);
|
||||
</pre><button onclick='javascript: var cholesterol, healthy;
|
||||
cholesterol = 127;
|
||||
healthy = 200 > cholesterol && cholesterol > 60;;alert(healthy);'>run: healthy</button><br class='clear' /></div>
|
||||
healthy = (200 > cholesterol && cholesterol > 60);;alert(healthy);'>run: healthy</button><br class='clear' /></div>
|
||||
|
||||
<p>
|
||||
<span id="strings" class="bookmark"></span>
|
||||
|
@ -1879,8 +1919,8 @@ task(<span class="String"><span class="String">'</span>build:parser<span class="
|
|||
Improved syntax errors for invalid CoffeeScript. <tt>undefined</tt> now
|
||||
works like <tt>null</tt>, and cannot be assigned a new value.
|
||||
There was a precedence change with respect to single-line comprehensions:
|
||||
<tt>result = i for i in list</tt><br /> used to parse as <tt>result = (i for i in list)</tt>
|
||||
by default ... it now parses as <br /><tt>(result = i) for i in list</tt>.
|
||||
<tt>result = i for i in list</tt><br /> used to parse as <tt>result = (i for i in list)</tt>
|
||||
by default ... it now parses as <br /ea><tt>(result = i) for i in list</tt>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
|
@ -208,7 +208,7 @@
|
|||
return regex.length;
|
||||
};
|
||||
Lexer.prototype.heregexToken = function(match) {
|
||||
var body, flags, heregex, re, tag, tokens, value, _i, _len, _ref, _ref2, _ref3;
|
||||
var body, flags, heregex, re, tag, tokens, value, _i, _len, _ref, _ref2, _ref3, _ref4;
|
||||
heregex = match[0], body = match[1], flags = match[2];
|
||||
if (0 > body.indexOf('#{')) {
|
||||
re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/');
|
||||
|
@ -238,7 +238,7 @@
|
|||
if (((_ref3 = tokens[0]) != null ? _ref3[0] : void 0) !== 'STRING') {
|
||||
this.tokens.push(['STRING', '""'], ['+', '+']);
|
||||
}
|
||||
(_ref = this.tokens).push.apply(_ref, tokens);
|
||||
(_ref4 = this.tokens).push.apply(_ref4, tokens);
|
||||
if (flags) {
|
||||
this.tokens.push([',', ','], ['STRING', '"' + flags + '"']);
|
||||
}
|
||||
|
@ -478,7 +478,7 @@
|
|||
throw new Error("unterminated " + (stack.pop()[0]) + " on line " + (this.line + 1));
|
||||
};
|
||||
Lexer.prototype.interpolateString = function(str, options) {
|
||||
var expr, heredoc, i, inner, interpolated, letter, nested, pi, regex, tag, tokens, value, _len, _ref, _ref2;
|
||||
var expr, heredoc, i, inner, interpolated, letter, nested, pi, regex, tag, tokens, value, _len, _ref, _ref2, _ref3;
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
|
@ -537,7 +537,7 @@
|
|||
this.token('+', '+');
|
||||
}
|
||||
if (tag === 'TOKENS') {
|
||||
(_ref = this.tokens).push.apply(_ref, value);
|
||||
(_ref3 = this.tokens).push.apply(_ref3, value);
|
||||
} else {
|
||||
this.token('STRING', this.makeString(value, '"', heredoc));
|
||||
}
|
||||
|
|
22
lib/nodes.js
22
lib/nodes.js
|
@ -625,7 +625,7 @@
|
|||
}
|
||||
base = new Value(this.variable);
|
||||
if ((name = base.properties.pop()) && base.isComplex()) {
|
||||
ref = o.scope.temporary('ref');
|
||||
ref = o.scope.freeVariable('ref');
|
||||
fun = "(" + ref + " = " + (base.compile(o, LEVEL_LIST)) + ")" + (name.compile(o));
|
||||
} else {
|
||||
fun = base.compile(o, LEVEL_ACCESS);
|
||||
|
@ -1163,15 +1163,23 @@
|
|||
return new Op(this.context.slice(0, -1), left, new Assign(rite, this.value, '=')).compile(o);
|
||||
};
|
||||
Assign.prototype.compileSplice = function(o) {
|
||||
var from, name, plus, range, ref, to, val;
|
||||
var from, name, plus, range, to, val;
|
||||
range = this.variable.properties.pop().range;
|
||||
name = this.variable.compile(o);
|
||||
plus = range.exclusive ? '' : ' + 1';
|
||||
from = range.from ? range.from.compile(o) : '0';
|
||||
to = range.to ? range.to.compile(o) + ' - ' + from + plus : "" + name + ".length";
|
||||
ref = o.scope.freeVariable('ref');
|
||||
if (!range.to) {
|
||||
to = "" + name + ".length";
|
||||
}
|
||||
if (!to) {
|
||||
if (range.from && range.from.isSimpleNumber() && range.to.isSimpleNumber()) {
|
||||
to = (+range.to.compile(o)) - +from + +plus;
|
||||
} else {
|
||||
to = range.to.compile(o) + ' - ' + from + plus;
|
||||
}
|
||||
}
|
||||
val = this.value.compile(o);
|
||||
return "([].splice.apply(" + name + ", [" + from + ", " + to + "].concat(" + ref + " = " + val + ")), " + ref + ")";
|
||||
return "[].splice.apply(" + name + ", [" + from + ", " + to + "].concat(" + val + "))";
|
||||
};
|
||||
return Assign;
|
||||
}();
|
||||
|
@ -1190,7 +1198,7 @@
|
|||
return !!this.ctor;
|
||||
};
|
||||
Code.prototype.compileNode = function(o) {
|
||||
var code, exprs, i, idt, lit, p, param, ref, scope, sharedScope, splats, v, val, vars, wasEmpty, _i, _j, _k, _len, _len2, _len3, _len4, _ref, _ref2, _ref3, _results;
|
||||
var code, exprs, i, idt, lit, p, param, ref, scope, sharedScope, splats, v, val, vars, wasEmpty, _i, _j, _k, _len, _len2, _len3, _len4, _ref, _ref2, _ref3, _ref4, _results;
|
||||
sharedScope = del(o, 'sharedScope');
|
||||
o.scope = scope = sharedScope || new Scope(o.scope, this.body, this);
|
||||
o.indent += TAB;
|
||||
|
@ -1240,7 +1248,7 @@
|
|||
exprs.unshift(splats);
|
||||
}
|
||||
if (exprs.length) {
|
||||
(_ref = this.body.expressions).unshift.apply(_ref, exprs);
|
||||
(_ref4 = this.body.expressions).unshift.apply(_ref4, exprs);
|
||||
}
|
||||
if (!splats) {
|
||||
for (i = 0, _len4 = vars.length; i < _len4; i++) {
|
||||
|
|
|
@ -513,7 +513,7 @@ exports.Call = class Call extends Base
|
|||
"""
|
||||
base = new Value @variable
|
||||
if (name = base.properties.pop()) and base.isComplex()
|
||||
ref = o.scope.temporary 'ref'
|
||||
ref = o.scope.freeVariable 'ref'
|
||||
fun = "(#{ref} = #{ base.compile o, LEVEL_LIST })#{ name.compile o }"
|
||||
else
|
||||
fun = base.compile o, LEVEL_ACCESS
|
||||
|
@ -944,13 +944,17 @@ exports.Assign = class Assign extends Base
|
|||
# `Array#splice` method.
|
||||
compileSplice: (o) ->
|
||||
{range} = @variable.properties.pop()
|
||||
name = @variable.compile o
|
||||
plus = if range.exclusive then '' else ' + 1'
|
||||
from = if range.from then range.from.compile(o) else '0'
|
||||
to = if range.to then range.to.compile(o) + ' - ' + from + plus else "#{name}.length"
|
||||
ref = o.scope.freeVariable 'ref'
|
||||
val = @value.compile(o)
|
||||
"([].splice.apply(#{name}, [#{from}, #{to}].concat(#{ref} = #{val})), #{ref})"
|
||||
name = @variable.compile o
|
||||
plus = if range.exclusive then '' else ' + 1'
|
||||
from = if range.from then range.from.compile(o) else '0'
|
||||
to = "#{name}.length" unless range.to
|
||||
unless to
|
||||
if range.from and range.from.isSimpleNumber() and range.to.isSimpleNumber()
|
||||
to = (+range.to.compile(o)) - +from + +plus
|
||||
else
|
||||
to = range.to.compile(o) + ' - ' + from + plus
|
||||
val = @value.compile(o)
|
||||
"[].splice.apply(#{name}, [#{from}, #{to}].concat(#{val}))"
|
||||
|
||||
#### Code
|
||||
|
||||
|
|
|
@ -123,3 +123,13 @@ try
|
|||
failed = false
|
||||
catch err
|
||||
ok failed
|
||||
|
||||
|
||||
# multiple generated references
|
||||
(->
|
||||
a = {b: []}
|
||||
a.b[true] = -> this == a.b
|
||||
c = 0
|
||||
d = []
|
||||
ok a.b[0<++c<2] d...
|
||||
)()
|
||||
|
|
Loading…
Reference in New Issue