Merge branch 'master' of github.com:michaelficarra/coffee-script into refactorTests

This commit is contained in:
Michael Ficarra 2010-12-05 13:37:34 -05:00
commit 1e080cc258
12 changed files with 125 additions and 28 deletions

View File

@ -0,0 +1,6 @@
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
copy = numbers[0...numbers.length]
middle = copy[3..6]

View File

@ -0,0 +1,5 @@
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
numbers[3..6] = [-3, -4, -5, -6]

View File

@ -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>

View File

@ -1,3 +1,3 @@
var cholesterol, healthy;
cholesterol = 127;
healthy = 200 > cholesterol && cholesterol > 60;
healthy = (200 > cholesterol && cholesterol > 60);

View File

@ -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);

View File

@ -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);

View File

@ -3,7 +3,7 @@ if (this.studyingEconomics) {
while (supply > demand) {
buy();
}
while (supply <= demand) {
while (!(supply > demand)) {
sell();
}
}

View File

@ -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">&gt;</span> demand) {
buy();
}
<span class="Keyword">while</span> (supply <span class="Keyword">&lt;=</span> demand) {
<span class="Keyword">while</span> (<span class="Keyword">!</span>(supply <span class="Keyword">&gt;</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">&gt;</span> cholesterol <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> cholesterol <span class="Keyword">&gt;</span> <span class="Number">60</span>;
healthy <span class="Keyword">=</span> (<span class="Number">200</span> <span class="Keyword">&gt;</span> cholesterol <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> cholesterol <span class="Keyword">&gt;</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>

View File

@ -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));
}

View File

@ -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++) {

View File

@ -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

View File

@ -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...
)()