Issue #1547 'use strict' Python-style octal literal notation 0o777

Allows octals in the form '0o777' and '0O777'

Case insensitive

Disallows decimals prefixed with '0'
This commit is contained in:
Gerald Lewis
2012-01-12 15:32:14 -05:00
parent 8b179fb391
commit 4372138fdd
4 changed files with 34 additions and 8 deletions

View File

@@ -109,10 +109,18 @@
};
Lexer.prototype.numberToken = function() {
var binaryLiteral, lexedLength, match, number;
var binaryLiteral, dec, lexedLength, match, nonStrictOctalLiteral, number, oct, octalLiteral;
if (!(match = NUMBER.exec(this.chunk))) return 0;
number = match[0];
lexedLength = number.length;
if (nonStrictOctalLiteral = /^0\d+/.test(number)) {
dec = /[89]/.test(number) ? "\"" + number + "\" " : '';
oct = dec ? '' : "\"" + number + "\" ";
this.error("decimal literals " + dec + "must not be prefixed with '0'; octal literals " + oct + "must be prefixed with '0o'");
}
if (octalLiteral = /0o([0-7]+)/i.exec(number)) {
number = (parseInt(octalLiteral[1], 8)).toString();
}
if (binaryLiteral = /0b([01]+)/i.exec(number)) {
number = (parseInt(binaryLiteral[1], 2)).toString();
}
@@ -630,7 +638,7 @@
IDENTIFIER = /^([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?!:))?/;
NUMBER = /^0x[\da-f]+|^0b[01]+|^\d*\.?\d+(?:e[+-]?\d+)?/i;
NUMBER = /^0x[\da-f]+|^0b[01]+|^0o[0-7]+|^\d*\.?\d+(?:e[+-]?\d+)?/i;
HEREDOC = /^("""|''')([\s\S]*?)(?:\n[^\n\S]*)?\1/;

View File

@@ -134,8 +134,12 @@ exports.Lexer = class Lexer
return 0 unless match = NUMBER.exec @chunk
number = match[0]
lexedLength = number.length
if octalLiteral = /^0[0-7]+$/.test number
@error "octal literals \"#{number}\" are not allowed"
if nonStrictOctalLiteral = /^0\d+/.test number
dec = if /[89]/.test number then "\"#{number}\" " else ''
oct = if dec then '' else "\"#{number}\" "
@error "decimal literals #{dec}must not be prefixed with '0'; octal literals #{oct}must be prefixed with '0o'"
if octalLiteral = /0o([0-7]+)/i.exec number
number = (parseInt octalLiteral[1], 8).toString()
if binaryLiteral = /0b([01]+)/i.exec number
number = (parseInt binaryLiteral[1], 2).toString()
@token 'NUMBER', number
@@ -592,8 +596,9 @@ IDENTIFIER = /// ^
///
NUMBER = ///
^ 0x[\da-f]+ | # hex
^ 0b[01]+ | # binary
^ 0x[\da-f]+ | # hex
^ 0b[01]+ | # binary
^ 0o[0-7]+ | # octal
^ \d*\.?\d+ (?:e[+-]?\d+)? # decimal
///i

View File

@@ -54,3 +54,15 @@ test '#1168: leading floating point suppresses newline', ->
eq 1, do ->
1
.5 + 0.5
test "Python-style octal literal notation '0o777'", ->
eq 511, 0o777
eq 511, 0O777
eq 1, 0o1
eq 1, 0O1
eq 1, 0o00001
eq parseInt('0777', 8), 0o777
eq '777', 0o777.toString 8
eq 4, 0o4.valueOf()
eq Number::toString, 0o777['toString']
eq Number::toString, 0o777.toString

View File

@@ -26,8 +26,9 @@ strictOk = (code, msg) ->
test "Octal Integer Literals prohibited", ->
strict '01'
strict '07777'
strictOk '09'
strictOk '079'
# decimals with a leading '0' are also prohibited
strict '09'
strict '079'
strictOk '`01`'
test "Octal Escape Sequences prohibited", ->