| author | |
| committer | |
| log | e1f5ad3cc875d255946cafc92e0b415a285919c9 |
| tree | 863d200a241b44b3a1bc2bd030ff91fa7bc87970 |
| parent | 49c1384bac75a908c347a74e75e9b9e0110b0700 |
| signature |
3 files changed, 20 insertions(+), 9 deletions(-)
lib/std/zig/number_literal.zig+3-7| ... | ... | @@ -44,8 +44,6 @@ pub const Error = union(enum) { |
| 44 | 44 | duplicate_period, |
| 45 | 45 | /// Float literal has multiple exponents. |
| 46 | 46 | duplicate_exponent: usize, |
| 47 | /// Decimal float has hexadecimal exponent. | |
| 48 | invalid_hex_exponent: usize, | |
| 49 | 47 | /// Exponent comes directly after '_' digit separator. |
| 50 | 48 | exponent_after_underscore: usize, |
| 51 | 49 | /// Special character (+-.) comes directly after exponent. |
| ... | ... | @@ -103,7 +101,6 @@ pub fn parseNumberLiteral(bytes: []const u8) Result { |
| 103 | 101 | }, |
| 104 | 102 | 'e', 'E' => if (base == 10) { |
| 105 | 103 | float = true; |
| 106 | if (base != 10 and base != 16) return .{ .failure = .{ .invalid_float_base = 2 } }; | |
| 107 | 104 | if (exponent) return .{ .failure = .{ .duplicate_exponent = i } }; |
| 108 | 105 | if (underscore) return .{ .failure = .{ .exponent_after_underscore = i } }; |
| 109 | 106 | special = c; |
| ... | ... | @@ -112,10 +109,8 @@ pub fn parseNumberLiteral(bytes: []const u8) Result { |
| 112 | 109 | }, |
| 113 | 110 | 'p', 'P' => if (base == 16) { |
| 114 | 111 | float = true; |
| 115 | if (base != 10 and base != 16) return .{ .failure = .{ .invalid_float_base = 2 } }; | |
| 116 | 112 | if (exponent) return .{ .failure = .{ .duplicate_exponent = i } }; |
| 117 | 113 | if (underscore) return .{ .failure = .{ .exponent_after_underscore = i } }; |
| 118 | if (base != 16) return .{ .failure = .{ .invalid_hex_exponent = i } }; | |
| 119 | 114 | special = c; |
| 120 | 115 | exponent = true; |
| 121 | 116 | continue; |
| ... | ... | @@ -123,7 +118,7 @@ pub fn parseNumberLiteral(bytes: []const u8) Result { |
| 123 | 118 | '.' => { |
| 124 | 119 | float = true; |
| 125 | 120 | if (base != 10 and base != 16) return .{ .failure = .{ .invalid_float_base = 2 } }; |
| 126 | if (period) return .{ .failure = .{ .duplicate_exponent = i } }; | |
| 121 | if (period) return .{ .failure = .duplicate_period }; | |
| 127 | 122 | period = true; |
| 128 | 123 | if (underscore) return .{ .failure = .{ .special_after_underscore = i } }; |
| 129 | 124 | special = c; |
| ... | ... | @@ -131,7 +126,8 @@ pub fn parseNumberLiteral(bytes: []const u8) Result { |
| 131 | 126 | }, |
| 132 | 127 | '+', '-' => { |
| 133 | 128 | switch (special) { |
| 134 | 'p', 'P', 'e', 'E' => {}, | |
| 129 | 'p', 'P' => {}, | |
| 130 | 'e', 'E' => if (base != 10) return .{ .failure = .{ .invalid_exponent_sign = i } }, | |
| 135 | 131 | else => return .{ .failure = .{ .invalid_exponent_sign = i } }, |
| 136 | 132 | } |
| 137 | 133 | special = c; |
src/AstGen.zig+4-2| ... | ... | @@ -7622,14 +7622,16 @@ fn failWithNumberError(astgen: *AstGen, err: std.zig.number_literal.Error, token |
| 7622 | 7622 | .invalid_digit => |info| return astgen.failOff(token, @intCast(u32, info.i), "invalid digit '{c}' for {s} base", .{ bytes[info.i], @tagName(info.base) }), |
| 7623 | 7623 | .invalid_digit_exponent => |i| return astgen.failOff(token, @intCast(u32, i), "invalid digit '{c}' in exponent", .{bytes[i]}), |
| 7624 | 7624 | .duplicate_exponent => |i| return astgen.failOff(token, @intCast(u32, i), "duplicate exponent", .{}), |
| 7625 | .invalid_hex_exponent => |i| return astgen.failOff(token, @intCast(u32, i), "hex exponent in decimal float", .{}), | |
| 7626 | 7625 | .exponent_after_underscore => |i| return astgen.failOff(token, @intCast(u32, i), "expected digit before exponent", .{}), |
| 7627 | 7626 | .special_after_underscore => |i| return astgen.failOff(token, @intCast(u32, i), "expected digit before '{c}'", .{bytes[i]}), |
| 7628 | 7627 | .trailing_special => |i| return astgen.failOff(token, @intCast(u32, i), "expected digit after '{c}'", .{bytes[i - 1]}), |
| 7629 | 7628 | .trailing_underscore => |i| return astgen.failOff(token, @intCast(u32, i), "trailing digit separator", .{}), |
| 7630 | 7629 | .duplicate_period => unreachable, // Validated by tokenizer |
| 7631 | 7630 | .invalid_character => unreachable, // Validated by tokenizer |
| 7632 | .invalid_exponent_sign => unreachable, // Validated by tokenizer | |
| 7631 | .invalid_exponent_sign => |i| { | |
| 7632 | assert(bytes.len >= 2 and bytes[0] == '0' and bytes[1] == 'x'); // Validated by tokenizer | |
| 7633 | return astgen.failOff(token, @intCast(u32, i), "sign '{c}' cannot follow digit '{c}' in hex base", .{ bytes[i], bytes[i - 1] }); | |
| 7634 | }, | |
| 7633 | 7635 | } |
| 7634 | 7636 | } |
| 7635 | 7637 |
test/cases/compile_errors/number_literal_bad_exponent.zig created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | const a = 0x1e-4; | |
| 2 | const b = 0x1e+4; | |
| 3 | const c = 0x1E-4; | |
| 4 | const d = 0x1E+4; | |
| 5 | ||
| 6 | // error | |
| 7 | // backend=stage2 | |
| 8 | // target=native | |
| 9 | // | |
| 10 | // :1:15: error: sign '-' cannot follow digit 'e' in hex base | |
| 11 | // :2:15: error: sign '+' cannot follow digit 'e' in hex base | |
| 12 | // :3:15: error: sign '-' cannot follow digit 'E' in hex base | |
| 13 | // :4:15: error: sign '+' cannot follow digit 'E' in hex base |