From 499bc0d7a7928ac73568199403a5dfa5aa151a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20P=C3=A1nek?= Date: Mon, 26 Sep 2016 10:57:56 +0200 Subject: [PATCH] Pass through octal and binary literals as-is See https://github.com/coffeescript6/discuss/issues/45 --- src/lexer.coffee | 14 ++++++------ test/numbers.coffee | 56 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/src/lexer.coffee b/src/lexer.coffee index e0d3febd9b..19a86436f5 100644 --- a/src/lexer.coffee +++ b/src/lexer.coffee @@ -191,8 +191,10 @@ exports.Lexer = class Lexer # Be careful not to interfere with ranges-in-progress. numberToken: -> return 0 unless match = NUMBER.exec @chunk + number = match[0] lexedLength = number.length + if /^0[BOX]/.test number @error "radix prefix in '#{number}' must be lowercase", offset: 1 else if /E/.test(number) and not /^0x/.test number @@ -202,14 +204,12 @@ exports.Lexer = class Lexer @error "decimal literal '#{number}' must not be prefixed with '0'", length: lexedLength else if /^0\d+/.test number @error "octal literal '#{number}' must be prefixed with '0o'", length: lexedLength - if octalLiteral = /^0o([0-7]+)/.exec number - numberValue = parseInt(octalLiteral[1], 8) - number = "0x#{numberValue.toString 16}" - else if binaryLiteral = /^0b([01]+)/.exec number - numberValue = parseInt(binaryLiteral[1], 2) - number = "0x#{numberValue.toString 16}" - else + + numberValue = number + + unless /^(0o[0-7]+)/.test(number) or /^(0b[01]+)/.test(number) numberValue = parseFloat(number) + tag = if numberValue is Infinity then 'INFINITY' else 'NUMBER' @token tag, number, 0, lexedLength lexedLength diff --git a/test/numbers.coffee b/test/numbers.coffee index 4eccb6dc3c..75edf4826e 100644 --- a/test/numbers.coffee +++ b/test/numbers.coffee @@ -13,9 +13,26 @@ # Binary Integer Literals # Binary notation is understood as would be decimal notation. +toJS = (str) -> + CoffeeScript.compile str, bare: yes + .replace /^\s+|\s+$/g, '' # Trim leading/trailing whitespace + test "Parser recognises binary numbers", -> eq 4, 0b100 +test "Binary literals are compiled to binary literals", -> + input = """ + a = 0b100 + """ + + output = """ + var a; + + a = 0b100; + """ + + eq toJS(input), output + # Decimal Integer Literals test "call methods directly on numbers", -> @@ -24,6 +41,32 @@ test "call methods directly on numbers", -> eq -1, 3 -4 +test "Decimal literals are compiled to decimal literals", -> + input = """ + a = 10 + """ + + output = """ + var a; + + a = 10; + """ + + eq toJS(input), output + +test "Decimal literals are compiled to decimal literals", -> + input = """ + a = 10.1 + """ + + output = """ + var a; + + a = 10.1; + """ + + eq toJS(input), output + #764: Numbers should be indexable eq Number::toString, 42['toString'] @@ -66,6 +109,19 @@ test "Python-style octal literal notation '0o777'", -> eq Number::toString, 0o777['toString'] eq Number::toString, 0o777.toString +test "Octal literals are compiled to octal literals", -> + input = """ + a = 0o123 + """ + + output = """ + var a; + + a = 0o123; + """ + + eq toJS(input), output + test "#2060: Disallow uppercase radix prefixes and exponential notation", -> for char in ['b', 'o', 'x', 'e'] program = "0#{char}0"