Browse Source

Add support for binary literal (#11627)

* Add support for binary literal

* [tests] add tests for binary literal
Rudy Ges 1 year ago
parent
commit
8ec4f09bed

+ 1 - 0
src/core/texpr.ml

@@ -612,6 +612,7 @@ let type_constant basic c p =
 	match c with
 	| Int (s,_) ->
 		if String.length s > 10 && String.sub s 0 2 = "0x" then raise_typing_error "Invalid hexadecimal integer" p;
+		if String.length s > 34 && String.sub s 0 2 = "0b" then raise_typing_error "Invalid binary integer" p;
 		(try mk (TConst (TInt (Int32.of_string s))) basic.tint p
 		with _ -> mk (TConst (TFloat s)) basic.tfloat p)
 	| Float (f,_) -> mk (TConst (TFloat f)) basic.tfloat p

+ 5 - 0
src/syntax/lexer.ml

@@ -360,6 +360,9 @@ let integer_digits = [%sedlex.regexp? (digit, Star sep_digit)]
 let hex_digit = [%sedlex.regexp? '0'..'9'|'a'..'f'|'A'..'F']
 let sep_hex_digit = [%sedlex.regexp? Opt '_', hex_digit]
 let hex_digits = [%sedlex.regexp? (hex_digit, Star sep_hex_digit)]
+let bin_digit = [%sedlex.regexp? '0'|'1']
+let sep_bin_digit = [%sedlex.regexp? Opt '_', bin_digit]
+let bin_digits = [%sedlex.regexp? (bin_digit, Star sep_bin_digit)]
 let integer = [%sedlex.regexp? ('1'..'9', Star sep_digit) | '0']
 
 let integer_suffix = [%sedlex.regexp? Opt '_', ('i'|'u'), Plus integer]
@@ -386,6 +389,8 @@ let rec token lexbuf =
 	| '\n' | '\r' -> newline lexbuf; token lexbuf
 	| "0x", Plus hex_digits, Opt integer_suffix ->
 		mk lexbuf (split_int_suffix (lexeme lexbuf))
+	| "0b", Plus bin_digits, Opt integer_suffix ->
+		mk lexbuf (split_int_suffix (lexeme lexbuf))
 	| integer, Opt integer_suffix ->
 		mk lexbuf (split_int_suffix (lexeme lexbuf))
 	| integer, float_suffix ->

+ 13 - 0
tests/unit/src/unit/TestMisc.hx

@@ -613,4 +613,17 @@ class TestMisc extends Test {
 		var values = AbstractEnumTools.getValues(MyEnumAbstract);
 		eq(values.join(","), "1,2,3");
 	}
+
+	function testIntLiterals() {
+		eq(15, 0xF);
+		eq(255, 0xFF);
+		eq(305419896, 0x12345678);
+		eq(162254319, 0x09ABCDEF);
+
+		eq(0, 0b0);
+		eq(1, 0b1);
+		eq(2, 0b10);
+		eq(8, 0b1000);
+		eq(0xFFFFFFFF, 0b11111111111111111111111111111111);
+	}
 }

+ 12 - 0
tests/unit/src/unit/TestNumericSeparator.hx

@@ -10,6 +10,10 @@ class TestNumericSeparator extends Test {
 		eq(0x12_0, 0x120);
 		eq(0x1_2_0, 0x120);
 
+		// bin int
+		eq(0b11_0, 0b110);
+		eq(0b1_1_0, 0b110);
+
 		// normal float
 		feq(12.3_4, 12.34);
 		feq(1_2.34, 12.34);
@@ -36,6 +40,10 @@ class TestNumericSeparator extends Test {
 		eq(0x12_0i32, 0x120i32);
 		eq(0x1_2_0i32, 0x120i32);
 
+		// bin int
+		eq(0b11_0i32, 0b110i32);
+		eq(0b1_1_0i32, 0b110i32);
+
 		// normal float
 		feq(12.3_4f64, 12.34f64);
 		feq(1_2.34f64, 12.34f64);
@@ -59,6 +67,10 @@ class TestNumericSeparator extends Test {
 		eq(0x12_0_i32, 0x120i32);
 		eq(0x1_2_0_i32, 0x120i32);
 
+		// bin int
+		eq(0b11_0_i32, 0b110i32);
+		eq(0b1_1_0_i32, 0b110i32);
+
 		// normal float
 		feq(12.3_4_f64, 12.34f64);
 		feq(1_2.34_f64, 12.34f64);

+ 9 - 1
tests/unit/src/unit/TestNumericSuffixes.hx

@@ -26,4 +26,12 @@ class TestNumericSuffixes extends Test {
         eq(0xFFFFFFFFFFFFFFFFi64 + "", "-1");
         eq(0x7FFFFFFFFFFFFFFFi64 + "", "9223372036854775807");
     }
-}
+
+    public function testBinSuffixes() {
+        eq(0b11111111111111111111111111111111i32, -1);
+        eq(0b11111111111111111111111111111111u32, (0b11111111111111111111111111111111i32 : UInt));
+        eq(0b11111111111111111111111111111111i64 + "", "4294967295");
+        eq(0b1111111111111111111111111111111111111111111111111111111111111111i64 + "", "-1");
+        eq(0b0111111111111111111111111111111111111111111111111111111111111111i64 + "", "9223372036854775807");
+    }
+}