1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

Treat Infinity and NaN as reserved words

Fixes #4218.
This commit is contained in:
Simon Lydell 2016-03-05 21:32:20 +01:00
parent cbc72a29bf
commit 9a0babf5b1
11 changed files with 207 additions and 164 deletions

View file

@ -77,8 +77,6 @@
AlphaNumeric: [
o('NUMBER', function() {
return new NumberLiteral($1);
}), o('INFINITY', function() {
return new InfinityLiteral($1);
}), o('String')
],
String: [
@ -104,6 +102,10 @@
return new NullLiteral;
}), o('BOOL', function() {
return new BooleanLiteral($1);
}), o('INFINITY', function() {
return new InfinityLiteral($1);
}), o('NAN', function() {
return new NaNLiteral;
})
],
Assign: [

View file

@ -185,7 +185,7 @@
} else {
numberValue = parseFloat(number);
}
tag = numberValue === Infinity ? 'INFINITY' : 'NUMBER';
tag = numberValue === 2e308 ? 'INFINITY' : 'NUMBER';
this.token(tag, number, 0, lexedLength);
return lexedLength;
};
@ -907,7 +907,7 @@
JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'yield', 'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally', 'class', 'extends', 'super'];
COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when'];
COFFEE_KEYWORDS = ['undefined', 'Infinity', 'NaN', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when'];
COFFEE_ALIAS_MAP = {
and: '&&',
@ -1018,7 +1018,7 @@
CALLABLE = ['IDENTIFIER', 'PROPERTY', ')', ']', '?', '@', 'THIS', 'SUPER'];
INDEXABLE = CALLABLE.concat(['NUMBER', 'INFINITY', 'STRING', 'STRING_END', 'REGEX', 'REGEX_END', 'BOOL', 'NULL', 'UNDEFINED', '}', '::']);
INDEXABLE = CALLABLE.concat(['NUMBER', 'INFINITY', 'NAN', 'STRING', 'STRING_END', 'REGEX', 'REGEX_END', 'BOOL', 'NULL', 'UNDEFINED', '}', '::']);
NOT_REGEX = INDEXABLE.concat(['++', '--']);

View file

@ -1,12 +1,12 @@
// Generated by CoffeeScript 1.10.0
(function() {
var Access, Arr, Assign, Base, Block, BooleanLiteral, Call, Class, Code, CodeFragment, Comment, Existence, Expansion, Extends, For, IdentifierLiteral, If, In, Index, InfinityLiteral, JS_FORBIDDEN, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, NEGATE, NO, NullLiteral, NumberLiteral, Obj, Op, Param, Parens, PassthroughLiteral, PropertyName, Range, RegexLiteral, RegexWithInterpolations, Return, SIMPLENUM, Scope, Slice, Splat, StatementLiteral, StringLiteral, StringWithInterpolations, SuperCall, Switch, TAB, THIS, ThisLiteral, Throw, Try, UTILITIES, UndefinedLiteral, Value, While, YES, YieldReturn, addLocationDataFn, compact, del, ends, extend, flatten, fragmentsToText, isComplexOrAssignable, isLiteralArguments, isLiteralThis, isUnassignable, locationDataToString, merge, multident, ref1, ref2, some, starts, throwSyntaxError, unfoldSoak, utility,
var Access, Arr, Assign, Base, Block, BooleanLiteral, Call, Class, Code, CodeFragment, Comment, Existence, Expansion, Extends, For, IdentifierLiteral, If, In, Index, InfinityLiteral, JS_FORBIDDEN, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, NEGATE, NO, NaNLiteral, NullLiteral, NumberLiteral, Obj, Op, Param, Parens, PassthroughLiteral, PropertyName, Range, RegexLiteral, RegexWithInterpolations, Return, SIMPLENUM, Scope, Slice, Splat, StatementLiteral, StringLiteral, StringWithInterpolations, SuperCall, Switch, TAB, THIS, ThisLiteral, Throw, Try, UTILITIES, UndefinedLiteral, Value, While, YES, YieldReturn, addLocationDataFn, compact, del, ends, extend, flatten, fragmentsToText, isComplexOrAssignable, isLiteralArguments, isLiteralThis, isUnassignable, locationDataToString, merge, multident, ref1, ref2, some, starts, throwSyntaxError, unfoldSoak, utility,
extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
slice = [].slice;
Error.stackTraceLimit = Infinity;
Error.stackTraceLimit = 2e308;
Scope = require('./scope').Scope;
@ -568,6 +568,27 @@
})(NumberLiteral);
exports.NaNLiteral = NaNLiteral = (function(superClass1) {
extend1(NaNLiteral, superClass1);
function NaNLiteral() {
NaNLiteral.__super__.constructor.call(this, 'NaN');
}
NaNLiteral.prototype.compileNode = function(o) {
var code;
code = [this.makeCode('0/0')];
if (o.level >= LEVEL_OP) {
return this.wrapInBraces(code);
} else {
return code;
}
};
return NaNLiteral;
})(NumberLiteral);
exports.StringLiteral = StringLiteral = (function(superClass1) {
extend1(StringLiteral, superClass1);

File diff suppressed because one or more lines are too long

View file

@ -487,7 +487,7 @@
IMPLICIT_FUNC = ['IDENTIFIER', 'PROPERTY', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
IMPLICIT_CALL = ['IDENTIFIER', 'PROPERTY', 'NUMBER', 'INFINITY', 'STRING', 'STRING_START', 'JS', 'REGEX', 'REGEX_START', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY', 'YIELD', 'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'];
IMPLICIT_CALL = ['IDENTIFIER', 'PROPERTY', 'NUMBER', 'INFINITY', 'NAN', 'STRING', 'STRING_START', 'REGEX', 'REGEX_START', 'JS', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'UNDEFINED', 'NULL', 'BOOL', 'UNARY', 'YIELD', 'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'];
IMPLICIT_UNSPACED_CALL = ['+', '-'];

View file

@ -145,7 +145,6 @@ grammar =
# they can also serve as keys in object literals.
AlphaNumeric: [
o 'NUMBER', -> new NumberLiteral $1
o 'INFINITY', -> new InfinityLiteral $1
o 'String'
]
@ -168,6 +167,8 @@ grammar =
o 'UNDEFINED', -> new UndefinedLiteral
o 'NULL', -> new NullLiteral
o 'BOOL', -> new BooleanLiteral $1
o 'INFINITY', -> new InfinityLiteral $1
o 'NAN', -> new NaNLiteral
]
# Assignment of a variable, property, or index to a value.

View file

@ -777,7 +777,10 @@ JS_KEYWORDS = [
]
# CoffeeScript-only keywords.
COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when']
COFFEE_KEYWORDS = [
'undefined', 'Infinity', 'NaN'
'then', 'unless', 'until', 'loop', 'of', 'by', 'when'
]
COFFEE_ALIAS_MAP =
and : '&&'
@ -939,7 +942,7 @@ BOOL = ['TRUE', 'FALSE']
# of a function invocation or indexing operation.
CALLABLE = ['IDENTIFIER', 'PROPERTY', ')', ']', '?', '@', 'THIS', 'SUPER']
INDEXABLE = CALLABLE.concat [
'NUMBER', 'INFINITY', 'STRING', 'STRING_END', 'REGEX', 'REGEX_END'
'NUMBER', 'INFINITY', 'NAN', 'STRING', 'STRING_END', 'REGEX', 'REGEX_END'
'BOOL', 'NULL', 'UNDEFINED', '}', '::'
]

View file

@ -404,6 +404,14 @@ exports.InfinityLiteral = class InfinityLiteral extends NumberLiteral
compileNode: ->
[@makeCode '2e308']
exports.NaNLiteral = class NaNLiteral extends NumberLiteral
constructor: ->
super 'NaN'
compileNode: (o) ->
code = [@makeCode '0/0']
if o.level >= LEVEL_OP then @wrapInBraces code else code
exports.StringLiteral = class StringLiteral extends Literal
exports.RegexLiteral = class RegexLiteral extends Literal

View file

@ -483,9 +483,11 @@ IMPLICIT_FUNC = ['IDENTIFIER', 'PROPERTY', 'SUPER', ')', 'CALL_END', ']', 'IN
# If preceded by an `IMPLICIT_FUNC`, indicates a function invocation.
IMPLICIT_CALL = [
'IDENTIFIER', 'PROPERTY', 'NUMBER', 'INFINITY', 'STRING', 'STRING_START', 'JS', 'REGEX', 'REGEX_START'
'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL'
'UNDEFINED', 'UNARY', 'YIELD', 'UNARY_MATH', 'SUPER', 'THROW'
'IDENTIFIER', 'PROPERTY', 'NUMBER', 'INFINITY', 'NAN'
'STRING', 'STRING_START', 'REGEX', 'REGEX_START', 'JS'
'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS'
'UNDEFINED', 'NULL', 'BOOL'
'UNARY', 'YIELD', 'UNARY_MATH', 'SUPER', 'THROW'
'@', '->', '=>', '[', '(', '{', '--', '++'
]

View file

@ -83,3 +83,6 @@ test "Infinity", ->
eq Infinity, CoffeeScript.eval "0x#{Array(256 + 1).join('f')}"
eq Infinity, CoffeeScript.eval Array(500 + 1).join('9')
eq Infinity, 2e308
test "NaN", ->
ok isNaN 1/NaN

View file

@ -259,7 +259,7 @@ test "chained operations should evaluate each value only once", ->
test "#891: incorrect inversion of chained comparisons", ->
ok (true unless 0 > 1 > 2)
ok (true unless (NaN = 0/0) < 0/0 < NaN)
ok (true unless (this.NaN = 0/0) < 0/0 < this.NaN)
test "#1234: Applying a splat to :: applies the splat to the wrong object", ->
nonce = {}