diff --git a/CHANGELOG.md b/CHANGELOG.md index 7491ed8a9..4751092e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # [unreleased] +## New features + +- Support more integer notations + ([PR#897](https://github.com/jasmin-lang/jasmin/pull/897)): + * Octal: `0O777`, `0o52` + * Binary: `0b11101`, `0B11100` + * `_` characters: `100_000_00___111` + ## Bug fixes - Easycrypt extraction for CT : fix decreasing for loops diff --git a/compiler/src/lexer.mll b/compiler/src/lexer.mll index 3ce849dfa..3354b0e59 100644 --- a/compiler/src/lexer.mll +++ b/compiler/src/lexer.mll @@ -108,6 +108,8 @@ let blank = [' ' '\t' '\r'] let newline = ['\n'] let digit = ['0'-'9'] +let octdigit = ['0'-'7'] +let bindigit = ['0'-'1'] let hexdigit = ['0'-'9' 'a'-'f' 'A'-'F'] let lower = ['a'-'z'] let upper = ['A'-'Z'] @@ -133,11 +135,13 @@ rule main = parse | '"' (([^'"' '\\']|'\\' _)* as s) '"' { STRING (unescape (L.of_lexbuf lexbuf) s) } - (* Why this is needed *) - | ((*'-'?*) digit+) as s - {INT s} + | (digit+(('_')+ digit+)*) as s - | ('0' ['x' 'X'] hexdigit+) as s + | ('0' ['x' 'X'] hexdigit+(('_')+hexdigit+)*) as s + + | ('0' ['b' 'B'] bindigit+(('_')+bindigit+)*) as s + + | ('0' ['o' 'O'] octdigit+(('_')+octdigit+)*) as s {INT s} | ident as s diff --git a/compiler/src/syntax.ml b/compiler/src/syntax.ml index ee509f085..4911d7eaf 100644 --- a/compiler/src/syntax.ml +++ b/compiler/src/syntax.ml @@ -1,4 +1,5 @@ open Annotations +open Utils (* -------------------------------------------------------------------- *) module L = Location @@ -24,7 +25,9 @@ type castop1 = CSS of sowsize | CVS of svsize type castop = castop1 L.located option type int_representation = string -let parse_int = Z.of_string +let parse_int (i: int_representation) : Z.t = + let s = String.filter (( <> ) '_') i in + Z.of_string s let bits_of_wsize : wsize -> int = Annotations.int_of_ws diff --git a/compiler/tests/success/common/integer_notation.jazz b/compiler/tests/success/common/integer_notation.jazz new file mode 100644 index 000000000..6ac12464a --- /dev/null +++ b/compiler/tests/success/common/integer_notation.jazz @@ -0,0 +1,22 @@ +/* +Test for all valid integer syntaxes +*/ +export fn test () -> reg u32 { + reg u32 y; + y = 0b11110000; + y = 0b111_111_11; + y = 0B111_00_11; + + y = 0o01234567; + y = 0o765_4_321; + y = 0O76543210; + + y = 1000000000; + y = 1000_0000_000; + + y = 0x01234567; + y = 0x765_b_32aac; + y = 0X76aab3210; + + return y; +}