# HG changeset patch # User Rik # Date 1444441978 25200 # Node ID 7c0e10f035bd74dbfe9451c72bbd083f4917d418 # Parent e34692daf663ec52bd88dcb2d3a21253527220fe Extend parser to accept binary constants that begin with '0b' or '0B'. * NEWS: Announce change: * lex.ll: Define NUMBIN to be 0[bB] followed by 0,1, or '_'. Define NUMBER to be NUMREAL|NUMHEX|NUMBIN. *lex.ll (looks_like_bin): New function to detect 0[bB] prefix. *lex.ll (handle_numbe): Call looks_like_bin() and if found then convert binary string to double. * parser.tst: Add tests for new behavior. diff -r e34692daf663 -r 7c0e10f035bd NEWS --- a/NEWS Mon Oct 05 14:05:58 2015 -0700 +++ b/NEWS Fri Oct 09 18:52:58 2015 -0700 @@ -7,6 +7,13 @@ Examples: 1_000_000 == 1e6 or 0xDE_AD_BE_EF + ** The parser has been extended to understand binary numbers which begin + with the prefix '0b' or '0B'. The value returned is Octave's default + numeric class of double, not at unsigned integer class. Therefore numbers + greater than flintmax (2^53) will lose some precision. + + Examples: 0b101 == 5 or 0B1100_0001 == 0xC1 + ** The default colormap is now set to 'viridis' which is also the default colormap in matplotlib. This new colormap fixes some of the main issues with the old default colormap 'jet' diff -r e34692daf663 -r 7c0e10f035bd libinterp/parse-tree/lex.ll --- a/libinterp/parse-tree/lex.ll Mon Oct 05 14:05:58 2015 -0700 +++ b/libinterp/parse-tree/lex.ll Fri Oct 09 18:52:58 2015 -0700 @@ -64,6 +64,7 @@ #include #include +#include #include #include @@ -328,9 +329,10 @@ IDENT ([_$a-zA-Z][_$a-zA-Z0-9]*) FQIDENT ({IDENT}(\.{IDENT})*) EXPON ([DdEe][+-]?{D}{D_}*) -NUMREAL (({D}{D_}*\.?{D_}*{EXPON}?)|(\.{D}{D_}*{EXPON}?)) +NUMBIN (0[bB][01_]+) NUMHEX (0[xX][0-9a-fA-F][0-9a-fA-F_]*) -NUMBER ({NUMREAL}|{NUMHEX}) +NUMREAL (({D}{D_}*\.?{D_}*{EXPON}?)|(\.{D}{D_}*{EXPON}?)) +NUMBER ({NUMREAL}|{NUMHEX}|{NUMBIN}) ANY_EXCEPT_NL [^\r\n] ANY_INCLUDING_NL (.|{NL}) @@ -2658,6 +2660,12 @@ } static inline bool +looks_like_bin (const char *s, int len) +{ + return (len > 2 && s[0] == '0' && (s[1] == 'b' || s[1] == 'B')); +} + +static inline bool looks_like_hex (const char *s, int len) { return (len > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')); @@ -2690,6 +2698,19 @@ value = static_cast (ival); } + else if (looks_like_bin (tmptxt, strlen (tmptxt))) + { + uint64_t ivalue = 0; + + for (int i = 0; i < strlen (tmptxt); i++) + { + ivalue <<= 1; + ivalue += static_cast (tmptxt[i] == '1'); + } + + value = static_cast (ivalue); + nread = 1; // Just to pass the assert stmt below + } else { char *idx = strpbrk (tmptxt, "Dd"); diff -r e34692daf663 -r 7c0e10f035bd test/parser.tst --- a/test/parser.tst Mon Oct 05 14:05:58 2015 -0700 +++ b/test/parser.tst Fri Oct 09 18:52:58 2015 -0700 @@ -282,6 +282,11 @@ %!assert (0xAB_CD, 43981) %!assert (2e0_1, 20); +## Test binary constants +%!assert (0b101, 5) +%!assert (0B1100_0001, 0xC1) +%!assert (class (0b1), "double") + ## Test creation of anonymous functions %!test