mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
big commit -- adding back object comprehensions, using 'ino', versus 'in' for array comprehensions, fixing bug with dollar signs in identifiers
This commit is contained in:
parent
13fc8aea04
commit
902febb43a
18 changed files with 200 additions and 58 deletions
|
@ -2,5 +2,5 @@ alert(
|
|||
try
|
||||
nonexistent / undefined
|
||||
catch error
|
||||
"The error is: " + error
|
||||
"Caught an error: " + error
|
||||
)
|
3
documentation/coffee/object_comprehensions.coffee
Normal file
3
documentation/coffee/object_comprehensions.coffee
Normal file
|
@ -0,0 +1,3 @@
|
|||
years_old: {max: 10, ida: 9, tim: 11}
|
||||
|
||||
ages: child + " is " + age for child, age ino years_old
|
|
@ -1,3 +1,6 @@
|
|||
for i in [0...eggs.length] by 12
|
||||
countdown: num for num in [10..1]
|
||||
|
||||
egg_delivery: =>
|
||||
for i in [0...eggs.length] by 12
|
||||
dozen_eggs: eggs[i...i+12]
|
||||
deliver(new egg_carton(dozen))
|
||||
|
|
|
@ -399,12 +399,14 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
|
|||
<p>
|
||||
If you know the start and end of your loop, or would like to step through
|
||||
in fixed-size increments, you can use a range to specify the start and
|
||||
end of your comprehension:
|
||||
end of your comprehension. (The long line-breaking "for" definitions in
|
||||
the compiled JS below allow ranges to count downwards, as well as upwards).
|
||||
</p>
|
||||
<%= code_for('range_comprehensions') %>
|
||||
<%= code_for('range_comprehensions', 'countdown') %>
|
||||
<p>
|
||||
Comprehensions can also be used to iterate over the values and keys in
|
||||
an object:
|
||||
Comprehensions can also be used to iterate over the keys and values in
|
||||
an object. Use <tt>ino</tt> to signal comprehension over an object instead
|
||||
of an array.
|
||||
</p>
|
||||
<%= code_for('object_comprehensions', 'ages.join(", ")') %>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
(function(){
|
||||
var __a, __b, __c, __d, __e, __f, __g, lunch;
|
||||
var __a, __b, __c, __d, __e, __f, __g, food, lunch, roid, roid2;
|
||||
// Eat lunch.
|
||||
lunch = (function() {
|
||||
__c = []; __a = ['toast', 'cheese', 'wine'];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
(function(){
|
||||
var __a, __b, globals, name;
|
||||
var __a, __b, globals, name, property;
|
||||
// The first ten global properties.
|
||||
globals = ((function() {
|
||||
__b = []; __a = window;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
try {
|
||||
return nonexistent / undefined;
|
||||
} catch (error) {
|
||||
return "The error is: " + error;
|
||||
return "Caught an error: " + error;
|
||||
}
|
||||
})());
|
||||
})();
|
18
documentation/js/object_comprehensions.js
Normal file
18
documentation/js/object_comprehensions.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
(function(){
|
||||
var __a, __b, age, ages, child, years_old;
|
||||
years_old = {
|
||||
max: 10,
|
||||
ida: 9,
|
||||
tim: 11
|
||||
};
|
||||
ages = (function() {
|
||||
__b = []; __a = years_old;
|
||||
for (child in __a) {
|
||||
age = __a[child];
|
||||
if (__a.hasOwnProperty(child)) {
|
||||
__b.push(child + " is " + age);
|
||||
}
|
||||
}
|
||||
return __b;
|
||||
})();
|
||||
})();
|
|
@ -1,5 +1,5 @@
|
|||
(function(){
|
||||
var __a, __b, __c, cubed_list, list, math, number, opposite_day, race, square;
|
||||
var __a, __b, __c, cubed_list, list, math, num, number, opposite_day, race, square;
|
||||
// Assignment:
|
||||
number = 42;
|
||||
opposite_day = true;
|
||||
|
|
|
@ -1,8 +1,21 @@
|
|||
(function(){
|
||||
var __a, __b, __c, __d, dozen_eggs;
|
||||
__c = 0; __d = eggs.length;
|
||||
for (__b=0, i=__c; (__c <= __d ? i < __d : i > __d); (__c <= __d ? i += 12 : i -= 12), __b++) {
|
||||
dozen_eggs = eggs.slice(i, i + 12);
|
||||
deliver(new egg_carton(dozen));
|
||||
var __a, __b, __c, __d, __e, countdown, egg_delivery, num;
|
||||
countdown = (function() {
|
||||
__b = []; __d = 10; __e = 1;
|
||||
for (__c=0, num=__d; (__d <= __e ? num <= __e : num >= __e); (__d <= __e ? num += 1 : num -= 1), __c++) {
|
||||
__b.push(num);
|
||||
}
|
||||
return __b;
|
||||
})();
|
||||
egg_delivery = function egg_delivery() {
|
||||
var __f, __g, __h, __i, __j, dozen_eggs, i;
|
||||
__g = []; __i = 0; __j = eggs.length;
|
||||
for (__h=0, i=__i; (__i <= __j ? i < __j : i > __j); (__i <= __j ? i += 12 : i -= 12), __h++) {
|
||||
__g.push((function() {
|
||||
dozen_eggs = eggs.slice(i, i + 12);
|
||||
return deliver(new egg_carton(dozen));
|
||||
})());
|
||||
}
|
||||
return __g;
|
||||
};
|
||||
})();
|
|
@ -30,7 +30,7 @@
|
|||
breaker: if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration
|
||||
|
||||
|
||||
# Create a safe reference to the Underscore object for reference below.
|
||||
# Create a safe reference to the Underscore object forreference below.
|
||||
_: root._: obj => new wrapper(obj)
|
||||
|
||||
|
||||
|
@ -60,7 +60,7 @@
|
|||
return obj.forEach(iterator, context) if obj.forEach
|
||||
if _.isArray(obj) or _.isArguments(obj)
|
||||
return iterator.call(context, obj[i], i, obj) for i in [0...obj.length]
|
||||
iterator.call(context, val, key, obj) for val, key in obj
|
||||
iterator.call(context, val, key, obj) for key, val ino obj
|
||||
catch e
|
||||
throw e if e isnt breaker
|
||||
obj
|
||||
|
@ -148,7 +148,7 @@
|
|||
# based on '==='.
|
||||
_.include: obj, target =>
|
||||
return _.indexOf(obj, target) isnt -1 if _.isArray(obj)
|
||||
for val in obj
|
||||
for key, val ino obj
|
||||
return true if val is target
|
||||
false
|
||||
|
||||
|
@ -380,7 +380,7 @@
|
|||
# Retrieve the names of an object's properties.
|
||||
_.keys: obj =>
|
||||
return _.range(0, obj.length) if _.isArray(obj)
|
||||
key for val, key in obj
|
||||
key for key, val ino obj
|
||||
|
||||
|
||||
# Retrieve the values of an object's properties.
|
||||
|
@ -395,7 +395,7 @@
|
|||
|
||||
# Extend a given object with all of the properties in a source object.
|
||||
_.extend: destination, source =>
|
||||
for val, key in source
|
||||
for key, val ino source
|
||||
destination[key]: val
|
||||
destination
|
||||
|
||||
|
@ -564,8 +564,9 @@
|
|||
_.each(_.functions(_)) name =>
|
||||
method: _[name]
|
||||
wrapper.prototype[name]: =>
|
||||
unshift.call(arguments, this._wrapped)
|
||||
result(method.apply(_, arguments), this._chain)
|
||||
args: _.toArray(arguments)
|
||||
unshift.call(args, this._wrapped)
|
||||
result(method.apply(_, args), this._chain)
|
||||
|
||||
|
||||
# Add all mutator Array functions to the wrapper.
|
||||
|
|
108
index.html
108
index.html
|
@ -103,7 +103,7 @@ alert(<span class="String"><span class="String">"</span>I knew it!<span cla
|
|||
|
||||
<span class="Comment"><span class="Comment">#</span> Array comprehensions:</span>
|
||||
cubed_list<span class="Keyword">:</span> math.cube(num) <span class="Keyword">for</span> num <span class="Keyword">in</span> list
|
||||
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, __c, cubed_list, list, math, number, opposite_day, race, square;
|
||||
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, __c, cubed_list, list, math, num, number, opposite_day, race, square;
|
||||
<span class="Comment"><span class="Comment">//</span> Assignment:</span>
|
||||
number <span class="Keyword">=</span> <span class="Number">42</span>;
|
||||
opposite_day <span class="Keyword">=</span> <span class="BuiltInConstant">true</span>;
|
||||
|
@ -144,7 +144,7 @@ cubed_list <span class="Keyword">=</span> (<span class="Storage">function</span>
|
|||
}
|
||||
<span class="Keyword">return</span> __c;
|
||||
})();
|
||||
</pre><button onclick='javascript: var __a, __b, __c, cubed_list, list, math, number, opposite_day, race, square;
|
||||
</pre><button onclick='javascript: var __a, __b, __c, cubed_list, list, math, num, number, opposite_day, race, square;
|
||||
// Assignment:
|
||||
number = 42;
|
||||
opposite_day = true;
|
||||
|
@ -694,7 +694,7 @@ lunch<span class="Keyword">:</span> eat(food) <span class="Keyword">for</span> f
|
|||
<span class="Keyword">for</span> roid <span class="Keyword">in</span> asteroids
|
||||
<span class="Keyword">for</span> roid2 <span class="Keyword">in</span> asteroids <span class="Keyword">when</span> roid <span class="Keyword">isnt</span> roid2
|
||||
roid.explode() <span class="Keyword">if</span> roid.overlaps(roid2)
|
||||
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, __c, __d, __e, __f, __g, lunch;
|
||||
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, __c, __d, __e, __f, __g, food, lunch, roid, roid2;
|
||||
<span class="Comment"><span class="Comment">//</span> Eat lunch.</span>
|
||||
lunch <span class="Keyword">=</span> (<span class="Storage">function</span>() {
|
||||
__c <span class="Keyword">=</span> []; __a <span class="Keyword">=</span> [<span class="String"><span class="String">'</span>toast<span class="String">'</span></span>, <span class="String"><span class="String">'</span>cheese<span class="String">'</span></span>, <span class="String"><span class="String">'</span>wine<span class="String">'</span></span>];
|
||||
|
@ -722,23 +722,95 @@ __d <span class="Keyword">=</span> asteroids;
|
|||
<p>
|
||||
If you know the start and end of your loop, or would like to step through
|
||||
in fixed-size increments, you can use a range to specify the start and
|
||||
end of your comprehension:
|
||||
end of your comprehension. (The long line-breaking "for" definitions in
|
||||
the compiled JS below allow ranges to count downwards, as well as upwards).
|
||||
</p>
|
||||
<div class='code'><pre class="idle"><span class="Keyword">for</span> i <span class="Keyword">in</span> [<span class="Number">0</span>...eggs.length] <span class="Keyword">by</span> <span class="Number">12</span>
|
||||
<div class='code'><pre class="idle">countdown<span class="Keyword">:</span> num <span class="Keyword">for</span> num <span class="Keyword">in</span> [<span class="Number">10</span>..<span class="Number">1</span>]
|
||||
|
||||
<span class="FunctionName">egg_delivery</span><span class="Keyword">:</span> <span class="Storage">=></span>
|
||||
<span class="Keyword">for</span> i <span class="Keyword">in</span> [<span class="Number">0</span>...eggs.length] <span class="Keyword">by</span> <span class="Number">12</span>
|
||||
dozen_eggs<span class="Keyword">:</span> eggs[i...i<span class="Keyword">+</span><span class="Number">12</span>]
|
||||
deliver(<span class="Keyword">new</span> <span class="TypeName">egg_carton</span>(dozen))
|
||||
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, __c, __d, dozen_eggs;
|
||||
__c <span class="Keyword">=</span> <span class="Number">0</span>; __d <span class="Keyword">=</span> eggs.<span class="LibraryConstant">length</span>;
|
||||
<span class="Keyword">for</span> (__b<span class="Keyword">=</span><span class="Number">0</span>, i<span class="Keyword">=</span>__c; (__c <span class="Keyword"><=</span> __d ? i <span class="Keyword"><</span> __d : i <span class="Keyword">></span> __d); (__c <span class="Keyword"><=</span> __d ? i <span class="Keyword">+</span><span class="Keyword">=</span> <span class="Number">12</span> : i <span class="Keyword">-</span><span class="Keyword">=</span> <span class="Number">12</span>), __b<span class="Keyword">++</span>) {
|
||||
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, __c, __d, __e, countdown, egg_delivery, num;
|
||||
countdown <span class="Keyword">=</span> (<span class="Storage">function</span>() {
|
||||
__b <span class="Keyword">=</span> []; __d <span class="Keyword">=</span> <span class="Number">10</span>; __e <span class="Keyword">=</span> <span class="Number">1</span>;
|
||||
<span class="Keyword">for</span> (__c<span class="Keyword">=</span><span class="Number">0</span>, num<span class="Keyword">=</span>__d; (__d <span class="Keyword"><=</span> __e ? num <span class="Keyword"><=</span> __e : num <span class="Keyword">>=</span> __e); (__d <span class="Keyword"><=</span> __e ? num <span class="Keyword">+</span><span class="Keyword">=</span> <span class="Number">1</span> : num <span class="Keyword">-</span><span class="Keyword">=</span> <span class="Number">1</span>), __c<span class="Keyword">++</span>) {
|
||||
__b.<span class="LibraryFunction">push</span>(num);
|
||||
}
|
||||
<span class="Keyword">return</span> __b;
|
||||
})();
|
||||
egg_delivery <span class="Keyword">=</span> <span class="Storage">function</span> <span class="FunctionName">egg_delivery</span>() {
|
||||
<span class="Storage">var</span> __f, __g, __h, __i, __j, dozen_eggs, i;
|
||||
__g <span class="Keyword">=</span> []; __i <span class="Keyword">=</span> <span class="Number">0</span>; __j <span class="Keyword">=</span> eggs.<span class="LibraryConstant">length</span>;
|
||||
<span class="Keyword">for</span> (__h<span class="Keyword">=</span><span class="Number">0</span>, i<span class="Keyword">=</span>__i; (__i <span class="Keyword"><=</span> __j ? i <span class="Keyword"><</span> __j : i <span class="Keyword">></span> __j); (__i <span class="Keyword"><=</span> __j ? i <span class="Keyword">+</span><span class="Keyword">=</span> <span class="Number">12</span> : i <span class="Keyword">-</span><span class="Keyword">=</span> <span class="Number">12</span>), __h<span class="Keyword">++</span>) {
|
||||
__g.<span class="LibraryFunction">push</span>((<span class="Storage">function</span>() {
|
||||
dozen_eggs <span class="Keyword">=</span> eggs.<span class="LibraryFunction">slice</span>(i, i <span class="Keyword">+</span> <span class="Number">12</span>);
|
||||
deliver(<span class="Keyword">new</span> <span class="TypeName">egg_carton</span>(dozen));
|
||||
}
|
||||
</pre><br class='clear' /></div>
|
||||
<span class="Keyword">return</span> deliver(<span class="Keyword">new</span> <span class="TypeName">egg_carton</span>(dozen));
|
||||
})());
|
||||
}
|
||||
<span class="Keyword">return</span> __g;
|
||||
};
|
||||
</pre><button onclick='javascript: var __a, __b, __c, __d, __e, countdown, egg_delivery, num;
|
||||
countdown = (function() {
|
||||
__b = []; __d = 10; __e = 1;
|
||||
for (__c=0, num=__d; (__d <= __e ? num <= __e : num >= __e); (__d <= __e ? num += 1 : num -= 1), __c++) {
|
||||
__b.push(num);
|
||||
}
|
||||
return __b;
|
||||
})();
|
||||
egg_delivery = function egg_delivery() {
|
||||
var __f, __g, __h, __i, __j, dozen_eggs, i;
|
||||
__g = []; __i = 0; __j = eggs.length;
|
||||
for (__h=0, i=__i; (__i <= __j ? i < __j : i > __j); (__i <= __j ? i += 12 : i -= 12), __h++) {
|
||||
__g.push((function() {
|
||||
dozen_eggs = eggs.slice(i, i + 12);
|
||||
return deliver(new egg_carton(dozen));
|
||||
})());
|
||||
}
|
||||
return __g;
|
||||
};
|
||||
;alert(countdown);'>run: countdown</button><br class='clear' /></div>
|
||||
<p>
|
||||
Comprehensions can also be used to iterate over the values and keys in
|
||||
an object:
|
||||
Comprehensions can also be used to iterate over the keys and values in
|
||||
an object. Use <tt>ino</tt> to signal comprehension over an object instead
|
||||
of an array.
|
||||
</p>
|
||||
<div class='code'><pre class="idle">years_old<span class="Keyword">:</span> {max<span class="Keyword">:</span> <span class="Number">10</span>, ida<span class="Keyword">:</span> <span class="Number">9</span>, tim<span class="Keyword">:</span> <span class="Number">11</span>}
|
||||
|
||||
ages<span class="Keyword">:</span> child <span class="Keyword">+</span> <span class="String"><span class="String">"</span> is <span class="String">"</span></span> <span class="Keyword">+</span> age <span class="Keyword">for</span> child, age ino years_old
|
||||
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, age, ages, child, years_old;
|
||||
years_old <span class="Keyword">=</span> {
|
||||
max: <span class="Number">10</span>,
|
||||
ida: <span class="Number">9</span>,
|
||||
tim: <span class="Number">11</span>
|
||||
};
|
||||
ages <span class="Keyword">=</span> (<span class="Storage">function</span>() {
|
||||
__b <span class="Keyword">=</span> []; __a <span class="Keyword">=</span> years_old;
|
||||
<span class="Keyword">for</span> (child <span class="Keyword">in</span> __a) {
|
||||
age <span class="Keyword">=</span> __a[child];
|
||||
<span class="Keyword">if</span> (__a.hasOwnProperty(child)) {
|
||||
__b.<span class="LibraryFunction">push</span>(child <span class="Keyword">+</span> <span class="String"><span class="String">"</span> is <span class="String">"</span></span> <span class="Keyword">+</span> age);
|
||||
}
|
||||
}
|
||||
<span class="Keyword">return</span> __b;
|
||||
})();
|
||||
</pre><button onclick='javascript: var __a, __b, age, ages, child, years_old;
|
||||
years_old = {
|
||||
max: 10,
|
||||
ida: 9,
|
||||
tim: 11
|
||||
};
|
||||
ages = (function() {
|
||||
__b = []; __a = years_old;
|
||||
for (child in __a) {
|
||||
age = __a[child];
|
||||
if (__a.hasOwnProperty(child)) {
|
||||
__b.push(child + " is " + age);
|
||||
}
|
||||
}
|
||||
return __b;
|
||||
})();
|
||||
;alert(ages.join(", "));'>run: ages.join(", ")</button><br class='clear' /></div>
|
||||
|
||||
<p id="slice_splice">
|
||||
<b class="header">Array Slicing and Splicing with Ranges</b>
|
||||
|
@ -841,7 +913,7 @@ six = (one = 1) + (two = 2) + (three = 3);
|
|||
<div class='code'><pre class="idle"><span class="Comment"><span class="Comment">#</span> The first ten global properties.</span>
|
||||
|
||||
globals<span class="Keyword">:</span> (name <span class="Keyword">for</span> property, name <span class="Keyword">in</span> window)[<span class="Number">0</span>...<span class="Number">10</span>]
|
||||
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, globals, name;
|
||||
</pre><pre class="idle"><span class="Storage">var</span> __a, __b, globals, name, property;
|
||||
<span class="Comment"><span class="Comment">//</span> The first ten global properties.</span>
|
||||
globals <span class="Keyword">=</span> ((<span class="Storage">function</span>() {
|
||||
__b <span class="Keyword">=</span> []; __a <span class="Keyword">=</span> <span class="LibraryClassType">window</span>;
|
||||
|
@ -851,7 +923,7 @@ globals <span class="Keyword">=</span> ((<span class="Storage">function</span>()
|
|||
}
|
||||
<span class="Keyword">return</span> __b;
|
||||
})()).<span class="LibraryFunction">slice</span>(<span class="Number">0</span>, <span class="Number">10</span>);
|
||||
</pre><button onclick='javascript: var __a, __b, globals, name;
|
||||
</pre><button onclick='javascript: var __a, __b, globals, name, property;
|
||||
// The first ten global properties.
|
||||
globals = ((function() {
|
||||
__b = []; __a = window;
|
||||
|
@ -870,20 +942,20 @@ globals = ((function() {
|
|||
<span class="Keyword">try</span>
|
||||
nonexistent <span class="Keyword">/</span> <span class="BuiltInConstant">undefined</span>
|
||||
<span class="Keyword">catch</span> error
|
||||
<span class="String"><span class="String">"</span>The error is: <span class="String">"</span></span> <span class="Keyword">+</span> error
|
||||
<span class="String"><span class="String">"</span>Caught an error: <span class="String">"</span></span> <span class="Keyword">+</span> error
|
||||
)
|
||||
</pre><pre class="idle"><span class="LibraryFunction">alert</span>((<span class="Storage">function</span>() {
|
||||
<span class="Keyword">try</span> {
|
||||
<span class="Keyword">return</span> nonexistent / undefined;
|
||||
} <span class="Keyword">catch</span> (error) {
|
||||
<span class="Keyword">return</span> <span class="String"><span class="String">"</span>The error is: <span class="String">"</span></span> <span class="Keyword">+</span> error;
|
||||
<span class="Keyword">return</span> <span class="String"><span class="String">"</span>Caught an error: <span class="String">"</span></span> <span class="Keyword">+</span> error;
|
||||
}
|
||||
})());
|
||||
</pre><button onclick='javascript: alert((function() {
|
||||
try {
|
||||
return nonexistent / undefined;
|
||||
} catch (error) {
|
||||
return "The error is: " + error;
|
||||
return "Caught an error: " + error;
|
||||
}
|
||||
})());
|
||||
;'>run</button><br class='clear' /></div>
|
||||
|
|
|
@ -214,7 +214,7 @@
|
|||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>\b([a-zA-Z$_]\w*)(\:)\s</string>
|
||||
<string>\b([a-zA-Z$_](\w|\$)*)(\:)\s</string>
|
||||
<key>name</key>
|
||||
<string>variable.assignment.coffee</string>
|
||||
<key>captures</key>
|
||||
|
@ -224,7 +224,7 @@
|
|||
<key>name</key>
|
||||
<string>entity.name.function.coffee</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<key>3</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.coffee</string>
|
||||
|
@ -263,7 +263,7 @@
|
|||
</dict>
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<string>!|\$|%|&|\*|\/|\-\-|\-|\+\+|\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\?|\|\||\:|\*=|(?<!\()/=|%=|\+=|\-=|&=|\^=|\b(in|instanceof|new|delete|typeof|and|or|is|isnt|not)\b</string>
|
||||
<string>!|%|&|\*|\/|\-\-|\-|\+\+|\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\?|\|\||\:|\*=|(?<!\()/=|%=|\+=|\-=|&=|\^=|\b(in|ino|instanceof|new|delete|typeof|and|or|is|isnt|not)\b</string>
|
||||
<key>name</key>
|
||||
<string>keyword.operator.coffee</string>
|
||||
</dict>
|
||||
|
|
|
@ -8,7 +8,7 @@ token IDENTIFIER PROPERTY_ACCESS
|
|||
token CODE PARAM NEW RETURN
|
||||
token TRY CATCH FINALLY THROW
|
||||
token BREAK CONTINUE
|
||||
token FOR IN BY WHEN WHILE
|
||||
token FOR IN INO BY WHEN WHILE
|
||||
token SWITCH LEADING_WHEN
|
||||
token DELETE INSTANCEOF TYPEOF
|
||||
token SUPER EXTENDS
|
||||
|
@ -34,7 +34,7 @@ prechigh
|
|||
left '.'
|
||||
right INDENT
|
||||
left OUTDENT
|
||||
right WHEN LEADING_WHEN IN BY
|
||||
right WHEN LEADING_WHEN IN INO BY
|
||||
right THROW FOR NEW SUPER
|
||||
left EXTENDS
|
||||
left ASSIGN '||=' '&&='
|
||||
|
@ -360,6 +360,7 @@ rule
|
|||
# The source of the array comprehension can optionally be filtered.
|
||||
ForSource:
|
||||
IN Expression { result = {:source => val[1]} }
|
||||
| INO Expression { result = {:source => val[1], :object => true} }
|
||||
| ForSource
|
||||
WHEN Expression { result = val[0].merge(:filter => val[2]) }
|
||||
| ForSource
|
||||
|
|
|
@ -12,14 +12,14 @@ module CoffeeScript
|
|||
"new", "return",
|
||||
"try", "catch", "finally", "throw",
|
||||
"break", "continue",
|
||||
"for", "in", "by", "where", "while",
|
||||
"for", "in", "ino", "by", "where", "while",
|
||||
"switch", "when",
|
||||
"super", "extends",
|
||||
"arguments",
|
||||
"delete", "instanceof", "typeof"]
|
||||
|
||||
# Token matching regexes.
|
||||
IDENTIFIER = /\A([a-zA-Z$_]\w*)/
|
||||
IDENTIFIER = /\A([a-zA-Z$_](\w|\$)*)/
|
||||
NUMBER = /\A(\b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?(e[+\-]?[0-9]+)?)))\b/i
|
||||
STRING = /\A(""|''|"(.*?)([^\\]|\\\\)"|'(.*?)([^\\]|\\\\)')/m
|
||||
JS = /\A(``|`(.*?)([^\\]|\\\\)`)/m
|
||||
|
|
|
@ -153,6 +153,10 @@ module CoffeeScript
|
|||
|
||||
attr_reader :value
|
||||
|
||||
def self.wrap(string)
|
||||
self.new(Value.new(string))
|
||||
end
|
||||
|
||||
def initialize(value)
|
||||
@value = value
|
||||
end
|
||||
|
@ -384,7 +388,7 @@ module CoffeeScript
|
|||
# part of a comprehension, slice, or splice.
|
||||
# TODO: This generates pretty ugly code ... shrink it.
|
||||
def compile_array(o)
|
||||
body = Expressions.wrap(LiteralNode.new(Value.new('i')))
|
||||
body = Expressions.wrap(LiteralNode.wrap('i'))
|
||||
arr = Expressions.wrap(ForNode.new(body, {:source => ValueNode.new(self)}, Value.new('i')))
|
||||
ParentheticalNode.new(CallNode.new(CodeNode.new([], arr))).compile(o)
|
||||
end
|
||||
|
@ -629,6 +633,8 @@ module CoffeeScript
|
|||
@source = source[:source]
|
||||
@filter = source[:filter]
|
||||
@step = source[:step]
|
||||
@object = !!source[:object]
|
||||
@name, @index = @index, @name if @object
|
||||
end
|
||||
|
||||
def compile_node(o)
|
||||
|
@ -636,6 +642,7 @@ module CoffeeScript
|
|||
range = @source.is_a?(ValueNode) && @source.literal.is_a?(RangeNode) && @source.properties.empty?
|
||||
source = range ? @source.literal : @source
|
||||
scope = o[:scope]
|
||||
scope.find(@name)
|
||||
index_found = @index && scope.find(@index)
|
||||
body_dent = idt(1)
|
||||
svar = scope.free_variable
|
||||
|
@ -650,6 +657,7 @@ module CoffeeScript
|
|||
index_var = nil
|
||||
source_part = "#{svar} = #{source.compile(o)};\n#{idt}"
|
||||
for_part = "#{ivar}=0; #{ivar}<#{svar}.length; #{ivar}++"
|
||||
for_part = "#{@index} in #{svar}" if @object
|
||||
var_part = "#{body_dent}#{@name} = #{svar}[#{ivar}];\n"
|
||||
end
|
||||
body = @body
|
||||
|
@ -659,7 +667,7 @@ module CoffeeScript
|
|||
body = Expressions.wrap(body)
|
||||
else
|
||||
body = Expressions.wrap(CallNode.new(
|
||||
ValueNode.new(LiteralNode.new(rvar), [AccessorNode.new('push')]), [@body.unwrap]
|
||||
ValueNode.new(LiteralNode.new(rvar), [AccessorNode.new('push')]), [body.unwrap]
|
||||
))
|
||||
end
|
||||
if o[:return]
|
||||
|
@ -667,7 +675,15 @@ module CoffeeScript
|
|||
o.delete(:return)
|
||||
body = IfNode.new(@filter, body, nil, :statement => true) if @filter
|
||||
elsif @filter
|
||||
body = Expressions.wrap(IfNode.new(@filter, @body))
|
||||
body = Expressions.wrap(IfNode.new(@filter, body))
|
||||
end
|
||||
if @object
|
||||
body = Expressions.wrap(IfNode.new(
|
||||
CallNode.new(ValueNode.new(LiteralNode.wrap(svar), [AccessorNode.new(Value.new('hasOwnProperty'))]), [LiteralNode.wrap(@index)]),
|
||||
Expressions.wrap(body),
|
||||
nil,
|
||||
{:statement => true}
|
||||
))
|
||||
end
|
||||
|
||||
return_result = "\n#{idt}#{return_result};" unless top_level
|
||||
|
|
|
@ -4,6 +4,14 @@ results: n * 2 for n in nums
|
|||
print(results.join(',') is '2,18')
|
||||
|
||||
|
||||
obj: {one: 1, two: 2, three: 3}
|
||||
names: key + '!' for key, value ino obj
|
||||
odds: key + '!' for key, value ino obj when value % 2 isnt 0
|
||||
|
||||
print(names.join(' ') is "one! two! three!")
|
||||
print(odds.join(' ') is "one! three!")
|
||||
|
||||
|
||||
evens: for num in [1, 2, 3, 4, 5, 6] when num % 2 is 0
|
||||
num *= -1
|
||||
num -= 2
|
||||
|
|
5
test/fixtures/execution/test_literals.coffee
vendored
5
test/fixtures/execution/test_literals.coffee
vendored
|
@ -30,3 +30,8 @@ i: 10
|
|||
while i -= 1
|
||||
|
||||
print(i is 0)
|
||||
|
||||
|
||||
money$: 'dollars'
|
||||
|
||||
print(money$ is 'dollars')
|
Loading…
Add table
Add a link
Reference in a new issue