diff --git a/lib/coffee-script/lexer.js b/lib/coffee-script/lexer.js index 717df9d7..05fe48aa 100644 --- a/lib/coffee-script/lexer.js +++ b/lib/coffee-script/lexer.js @@ -107,11 +107,14 @@ }; Lexer.prototype.numberToken = function() { - var match, number; + var is_binary, match, number, numlen; if (!(match = NUMBER.exec(this.chunk))) return 0; number = match[0]; + numlen = number.length; + is_binary = /0b([01]+)/.exec(number); + if (is_binary) number = (parseInt(is_binary[1], 2)).toString(); this.token('NUMBER', number); - return number.length; + return numlen; }; Lexer.prototype.stringToken = function() { @@ -620,7 +623,7 @@ IDENTIFIER = /^([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?!:))?/; - NUMBER = /^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i; + NUMBER = /^0x[\da-f]+|^0b[01]+|^\d*\.?\d+(?:e[+-]?\d+)?/i; HEREDOC = /^("""|''')([\s\S]*?)(?:\n[^\n\S]*)?\1/; diff --git a/src/lexer.coffee b/src/lexer.coffee index 0c03dd4b..d36dfd75 100644 --- a/src/lexer.coffee +++ b/src/lexer.coffee @@ -133,8 +133,14 @@ exports.Lexer = class Lexer numberToken: -> return 0 unless match = NUMBER.exec @chunk number = match[0] + numlen = number.length + # Now, since it is not JavaScript-descended, if it is binary, we will have + # to massage it into something similar and then hand it over. May the user + # forgive us. + is_binary = /0b([01]+)/.exec number + number = (parseInt is_binary[1], 2).toString() if is_binary @token 'NUMBER', number - number.length + numlen # Matches strings, including multi-line strings. Ensures that quotation marks # are balanced within the string's contents, and within nested interpolations. @@ -578,6 +584,7 @@ IDENTIFIER = /// ^ NUMBER = /// ^ 0x[\da-f]+ | # hex + ^ 0b[01]+ | # binary ^ \d*\.?\d+ (?:e[+-]?\d+)? # decimal ///i diff --git a/test/numbers.coffee b/test/numbers.coffee index 5598313f..5ea9331e 100644 --- a/test/numbers.coffee +++ b/test/numbers.coffee @@ -7,8 +7,17 @@ # * Scientific Notation Integer Literals # * Scientific Notation Non-Integer Literals # * Non-Integer Literals +# * Binary Integer Literals +# Binary Integer Literals +# Binary notation is understood as would be decimal notation. + +test "Parser recognises binary numbers", -> + eq 4, 0b100.valueOf() + eq '11', 0b100.toString 3 + eq '100', 0b100['toString'] 2 + # Decimal Integer Literals test "call methods directly on numbers", ->