Skip to content

Commit

Permalink
Merge pull request #4741 from momumi/master
Browse files Browse the repository at this point in the history
allow `_` separators in number literals (stage 1)
  • Loading branch information
andrewrk authored Mar 23, 2020
2 parents 7ffdf59 + 2d18178 commit 13d04f9
Show file tree
Hide file tree
Showing 10 changed files with 901 additions and 158 deletions.
11 changes: 11 additions & 0 deletions doc/langref.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,12 @@ const hex_int = 0xff;
const another_hex_int = 0xFF;
const octal_int = 0o755;
const binary_int = 0b11110000;

// underscores may be placed between two digits as a visual separator
const one_billion = 1_000_000_000;
const binary_mask = 0b1_1111_1111;
const permissions = 0o7_5_5;
const big_address = 0xFF80_0000_0000_0000;
{#code_end#}
{#header_close#}
{#header_open|Runtime Integer Values#}
Expand Down Expand Up @@ -947,6 +953,11 @@ const yet_another = 123.0e+77;
const hex_floating_point = 0x103.70p-5;
const another_hex_float = 0x103.70;
const yet_another_hex_float = 0x103.70P-5;

// underscores may be placed between two digits as a visual separator
const lightspeed = 299_792_458.000_000;
const nanosecond = 0.000_000_001;
const more_hex = 0x1234_5678.9ABC_CDEFp-10;
{#code_end#}
<p>
There is no syntax for NaN, infinity, or negative infinity. For these special values,
Expand Down
25 changes: 23 additions & 2 deletions lib/std/math/big/int.zig
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ pub const Int = struct {
const d = switch (ch) {
'0'...'9' => ch - '0',
'a'...'f' => (ch - 'a') + 0xa,
'A'...'F' => (ch - 'A') + 0xa,
else => return error.InvalidCharForDigit,
};

Expand All @@ -393,8 +394,9 @@ pub const Int = struct {

/// Set self from the string representation `value`.
///
/// value must contain only digits <= `base`. Base prefixes are not allowed (e.g. 0x43 should
/// simply be 43).
/// `value` must contain only digits <= `base` and is case insensitive. Base prefixes are
/// not allowed (e.g. 0x43 should simply be 43). Underscores in the input string are
/// ignored and can be used as digit separators.
///
/// Returns an error if memory could not be allocated or `value` has invalid digits for the
/// requested base.
Expand All @@ -415,6 +417,9 @@ pub const Int = struct {
try self.set(0);

for (value[i..]) |ch| {
if (ch == '_') {
continue;
}
const d = try charToDigit(ch, base);

const ap_d = Int.initFixed(([_]Limb{d})[0..]);
Expand Down Expand Up @@ -1582,6 +1587,22 @@ test "big.int string negative" {
testing.expect((try a.to(i32)) == -1023);
}

test "big.int string set number with underscores" {
var a = try Int.init(testing.allocator);
defer a.deinit();

try a.setString(10, "__1_2_0_3_1_7_2_4_1_2_0_____9_1__2__4_7_8_1_2_4_1_2_9_0_8_4_7_1_2_4___");
testing.expect((try a.to(u128)) == 120317241209124781241290847124);
}

test "big.int string set case insensitive number" {
var a = try Int.init(testing.allocator);
defer a.deinit();

try a.setString(16, "aB_cD_eF");
testing.expect((try a.to(u32)) == 0xabcdef);
}

test "big.int string set bad char error" {
var a = try Int.init(testing.allocator);
defer a.deinit();
Expand Down
38 changes: 19 additions & 19 deletions lib/std/special/compiler_rt/floatundisf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -69,23 +69,23 @@ test "floatundisf" {
test__floatundisf(0, 0.0);
test__floatundisf(1, 1.0);
test__floatundisf(2, 2.0);
test__floatundisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62F);
test__floatundisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62F);
test__floatundisf(0x8000008000000000, 0x1p+63F);
test__floatundisf(0x8000010000000000, 0x1.000002p+63F);
test__floatundisf(0x8000000000000000, 0x1p+63F);
test__floatundisf(0x8000000000000001, 0x1p+63F);
test__floatundisf(0xFFFFFFFFFFFFFFFE, 0x1p+64F);
test__floatundisf(0xFFFFFFFFFFFFFFFF, 0x1p+64F);
test__floatundisf(0x0007FB72E8000000, 0x1.FEDCBAp+50F);
test__floatundisf(0x0007FB72EA000000, 0x1.FEDCBAp+50F);
test__floatundisf(0x0007FB72EB000000, 0x1.FEDCBAp+50F);
test__floatundisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50F);
test__floatundisf(0x0007FB72EC000000, 0x1.FEDCBCp+50F);
test__floatundisf(0x0007FB72E8000001, 0x1.FEDCBAp+50F);
test__floatundisf(0x0007FB72E6000000, 0x1.FEDCBAp+50F);
test__floatundisf(0x0007FB72E7000000, 0x1.FEDCBAp+50F);
test__floatundisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50F);
test__floatundisf(0x0007FB72E4000001, 0x1.FEDCBAp+50F);
test__floatundisf(0x0007FB72E4000000, 0x1.FEDCB8p+50F);
test__floatundisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
test__floatundisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
test__floatundisf(0x8000008000000000, 0x1p+63);
test__floatundisf(0x8000010000000000, 0x1.000002p+63);
test__floatundisf(0x8000000000000000, 0x1p+63);
test__floatundisf(0x8000000000000001, 0x1p+63);
test__floatundisf(0xFFFFFFFFFFFFFFFE, 0x1p+64);
test__floatundisf(0xFFFFFFFFFFFFFFFF, 0x1p+64);
test__floatundisf(0x0007FB72E8000000, 0x1.FEDCBAp+50);
test__floatundisf(0x0007FB72EA000000, 0x1.FEDCBAp+50);
test__floatundisf(0x0007FB72EB000000, 0x1.FEDCBAp+50);
test__floatundisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
test__floatundisf(0x0007FB72EC000000, 0x1.FEDCBCp+50);
test__floatundisf(0x0007FB72E8000001, 0x1.FEDCBAp+50);
test__floatundisf(0x0007FB72E6000000, 0x1.FEDCBAp+50);
test__floatundisf(0x0007FB72E7000000, 0x1.FEDCBAp+50);
test__floatundisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
test__floatundisf(0x0007FB72E4000001, 0x1.FEDCBAp+50);
test__floatundisf(0x0007FB72E4000000, 0x1.FEDCB8p+50);
}
69 changes: 69 additions & 0 deletions lib/std/zig/parser_test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2815,6 +2815,75 @@ test "zig fmt: extern without container keyword returns error" {
);
}

test "zig fmt: integer literals with underscore separators" {
try testTransform(
\\const
\\ x =
\\ 1_234_567
\\ +(0b0_1-0o7_0+0xff_FF ) + 0_0;
,
\\const x = 1_234_567 + (0b0_1 - 0o7_0 + 0xff_FF) + 0_0;
\\
);
}

test "zig fmt: hex literals with underscore separators" {
try testTransform(
\\pub fn orMask(a: [ 1_000 ]u64, b: [ 1_000] u64) [1_000]u64 {
\\ var c: [1_000]u64 = [1]u64{ 0xFFFF_FFFF_FFFF_FFFF}**1_000;
\\ for (c [ 0_0 .. ]) |_, i| {
\\ c[i] = (a[i] | b[i]) & 0xCCAA_CCAA_CCAA_CCAA;
\\ }
\\ return c;
\\}
\\
\\
,
\\pub fn orMask(a: [1_000]u64, b: [1_000]u64) [1_000]u64 {
\\ var c: [1_000]u64 = [1]u64{0xFFFF_FFFF_FFFF_FFFF} ** 1_000;
\\ for (c[0_0..]) |_, i| {
\\ c[i] = (a[i] | b[i]) & 0xCCAA_CCAA_CCAA_CCAA;
\\ }
\\ return c;
\\}
\\
);
}

test "zig fmt: decimal float literals with underscore separators" {
try testTransform(
\\pub fn main() void {
\\ const a:f64=(10.0e-0+(10.e+0))+10_00.00_00e-2+00_00.00_10e+4;
\\ const b:f64=010.0--0_10.+0_1_0.0_0+1e2;
\\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b });
\\}
,
\\pub fn main() void {
\\ const a: f64 = (10.0e-0 + (10.e+0)) + 10_00.00_00e-2 + 00_00.00_10e+4;
\\ const b: f64 = 010.0 - -0_10. + 0_1_0.0_0 + 1e2;
\\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b });
\\}
\\
);
}

test "zig fmt: hexadeciaml float literals with underscore separators" {
try testTransform(
\\pub fn main() void {
\\ const a: f64 = (0x10.0p-0+(0x10.p+0))+0x10_00.00_00p-8+0x00_00.00_10p+16;
\\ const b: f64 = 0x0010.0--0x00_10.+0x10.00+0x1p4;
\\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b });
\\}
,
\\pub fn main() void {
\\ const a: f64 = (0x10.0p-0 + (0x10.p+0)) + 0x10_00.00_00p-8 + 0x00_00.00_10p+16;
\\ const b: f64 = 0x0010.0 - -0x00_10. + 0x10.00 + 0x1p4;
\\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b });
\\}
\\
);
}

const std = @import("std");
const mem = std.mem;
const warn = std.debug.warn;
Expand Down
Loading

0 comments on commit 13d04f9

Please sign in to comment.