mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 08:45:52 +00:00
Fix parsing of hexadecimal literals
This commit is contained in:
parent
49c1384bac
commit
e1f5ad3cc8
@ -44,8 +44,6 @@ pub const Error = union(enum) {
|
||||
duplicate_period,
|
||||
/// Float literal has multiple exponents.
|
||||
duplicate_exponent: usize,
|
||||
/// Decimal float has hexadecimal exponent.
|
||||
invalid_hex_exponent: usize,
|
||||
/// Exponent comes directly after '_' digit separator.
|
||||
exponent_after_underscore: usize,
|
||||
/// Special character (+-.) comes directly after exponent.
|
||||
@ -103,7 +101,6 @@ pub fn parseNumberLiteral(bytes: []const u8) Result {
|
||||
},
|
||||
'e', 'E' => if (base == 10) {
|
||||
float = true;
|
||||
if (base != 10 and base != 16) return .{ .failure = .{ .invalid_float_base = 2 } };
|
||||
if (exponent) return .{ .failure = .{ .duplicate_exponent = i } };
|
||||
if (underscore) return .{ .failure = .{ .exponent_after_underscore = i } };
|
||||
special = c;
|
||||
@ -112,10 +109,8 @@ pub fn parseNumberLiteral(bytes: []const u8) Result {
|
||||
},
|
||||
'p', 'P' => if (base == 16) {
|
||||
float = true;
|
||||
if (base != 10 and base != 16) return .{ .failure = .{ .invalid_float_base = 2 } };
|
||||
if (exponent) return .{ .failure = .{ .duplicate_exponent = i } };
|
||||
if (underscore) return .{ .failure = .{ .exponent_after_underscore = i } };
|
||||
if (base != 16) return .{ .failure = .{ .invalid_hex_exponent = i } };
|
||||
special = c;
|
||||
exponent = true;
|
||||
continue;
|
||||
@ -123,7 +118,7 @@ pub fn parseNumberLiteral(bytes: []const u8) Result {
|
||||
'.' => {
|
||||
float = true;
|
||||
if (base != 10 and base != 16) return .{ .failure = .{ .invalid_float_base = 2 } };
|
||||
if (period) return .{ .failure = .{ .duplicate_exponent = i } };
|
||||
if (period) return .{ .failure = .duplicate_period };
|
||||
period = true;
|
||||
if (underscore) return .{ .failure = .{ .special_after_underscore = i } };
|
||||
special = c;
|
||||
@ -131,7 +126,8 @@ pub fn parseNumberLiteral(bytes: []const u8) Result {
|
||||
},
|
||||
'+', '-' => {
|
||||
switch (special) {
|
||||
'p', 'P', 'e', 'E' => {},
|
||||
'p', 'P' => {},
|
||||
'e', 'E' => if (base != 10) return .{ .failure = .{ .invalid_exponent_sign = i } },
|
||||
else => return .{ .failure = .{ .invalid_exponent_sign = i } },
|
||||
}
|
||||
special = c;
|
||||
|
||||
@ -7622,14 +7622,16 @@ fn failWithNumberError(astgen: *AstGen, err: std.zig.number_literal.Error, token
|
||||
.invalid_digit => |info| return astgen.failOff(token, @intCast(u32, info.i), "invalid digit '{c}' for {s} base", .{ bytes[info.i], @tagName(info.base) }),
|
||||
.invalid_digit_exponent => |i| return astgen.failOff(token, @intCast(u32, i), "invalid digit '{c}' in exponent", .{bytes[i]}),
|
||||
.duplicate_exponent => |i| return astgen.failOff(token, @intCast(u32, i), "duplicate exponent", .{}),
|
||||
.invalid_hex_exponent => |i| return astgen.failOff(token, @intCast(u32, i), "hex exponent in decimal float", .{}),
|
||||
.exponent_after_underscore => |i| return astgen.failOff(token, @intCast(u32, i), "expected digit before exponent", .{}),
|
||||
.special_after_underscore => |i| return astgen.failOff(token, @intCast(u32, i), "expected digit before '{c}'", .{bytes[i]}),
|
||||
.trailing_special => |i| return astgen.failOff(token, @intCast(u32, i), "expected digit after '{c}'", .{bytes[i - 1]}),
|
||||
.trailing_underscore => |i| return astgen.failOff(token, @intCast(u32, i), "trailing digit separator", .{}),
|
||||
.duplicate_period => unreachable, // Validated by tokenizer
|
||||
.invalid_character => unreachable, // Validated by tokenizer
|
||||
.invalid_exponent_sign => unreachable, // Validated by tokenizer
|
||||
.invalid_exponent_sign => |i| {
|
||||
assert(bytes.len >= 2 and bytes[0] == '0' and bytes[1] == 'x'); // Validated by tokenizer
|
||||
return astgen.failOff(token, @intCast(u32, i), "sign '{c}' cannot follow digit '{c}' in hex base", .{ bytes[i], bytes[i - 1] });
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
13
test/cases/compile_errors/number_literal_bad_exponent.zig
Normal file
13
test/cases/compile_errors/number_literal_bad_exponent.zig
Normal file
@ -0,0 +1,13 @@
|
||||
const a = 0x1e-4;
|
||||
const b = 0x1e+4;
|
||||
const c = 0x1E-4;
|
||||
const d = 0x1E+4;
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :1:15: error: sign '-' cannot follow digit 'e' in hex base
|
||||
// :2:15: error: sign '+' cannot follow digit 'e' in hex base
|
||||
// :3:15: error: sign '-' cannot follow digit 'E' in hex base
|
||||
// :4:15: error: sign '+' cannot follow digit 'E' in hex base
|
||||
Loading…
x
Reference in New Issue
Block a user