| author | |
| committer | |
| log | aa5514fcf2305233c468b358d22ab171f377aef9 |
| tree | 7c85e4a710786963c5a05c0f3d62159c832c606b |
| parent | 0d0f277954e8809ac537d11ff536639aed8f2724 |
* Fix incorrect result when the first digit after the decimal point is not 0-9 - eg 0x0.ap0
* Fix compiler panic when the number starts with `0X` with a capital `X` - eg 0X0p0
* Fix compiler panic when the number has a decimal point immediately after `0x` - eg 0x.0p02 files changed, 35 insertions(+), 1 deletions(-)
src/translate_c.zig+19-1| ... | @@ -5603,7 +5603,25 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node { | ... | @@ -5603,7 +5603,25 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node { |
| 5603 | .FloatLiteral => |suffix| { | 5603 | .FloatLiteral => |suffix| { |
| 5604 | if (suffix != .none) lit_bytes = lit_bytes[0 .. lit_bytes.len - 1]; | 5604 | if (suffix != .none) lit_bytes = lit_bytes[0 .. lit_bytes.len - 1]; |
| 5605 | 5605 | ||
| 5606 | if (mem.indexOfScalar(u8, lit_bytes, '.')) |dot_index| { | 5606 | if (lit_bytes.len >= 2 and std.ascii.eqlIgnoreCase(lit_bytes[0..2], "0x")) { |
| 5607 | if (mem.indexOfScalar(u8, lit_bytes, '.')) |dot_index| { | ||
| 5608 | if (dot_index == 2) { | ||
| 5609 | lit_bytes = try std.fmt.allocPrint(c.arena, "0x0{s}", .{lit_bytes[2..]}); | ||
| 5610 | } else if (dot_index + 1 == lit_bytes.len or !std.ascii.isXDigit(lit_bytes[dot_index + 1])) { | ||
| 5611 | // If the literal lacks a digit after the `.`, we need to | ||
| 5612 | // add one since `0x1.p10` would be invalid syntax in Zig. | ||
| 5613 | lit_bytes = try std.fmt.allocPrint(c.arena, "0x{s}0{s}", .{ | ||
| 5614 | lit_bytes[2 .. dot_index + 1], | ||
| 5615 | lit_bytes[dot_index + 1 ..], | ||
| 5616 | }); | ||
| 5617 | } | ||
| 5618 | } | ||
| 5619 | |||
| 5620 | if (lit_bytes[1] == 'X') { | ||
| 5621 | // Hexadecimal with capital X, valid in C but not in Zig | ||
| 5622 | lit_bytes = try std.fmt.allocPrint(c.arena, "0x{s}", .{lit_bytes[2..]}); | ||
| 5623 | } | ||
| 5624 | } else if (mem.indexOfScalar(u8, lit_bytes, '.')) |dot_index| { | ||
| 5607 | if (dot_index == 0) { | 5625 | if (dot_index == 0) { |
| 5608 | lit_bytes = try std.fmt.allocPrint(c.arena, "0{s}", .{lit_bytes}); | 5626 | lit_bytes = try std.fmt.allocPrint(c.arena, "0{s}", .{lit_bytes}); |
| 5609 | } else if (dot_index + 1 == lit_bytes.len or !std.ascii.isDigit(lit_bytes[dot_index + 1])) { | 5627 | } else if (dot_index + 1 == lit_bytes.len or !std.ascii.isDigit(lit_bytes[dot_index + 1])) { |
test/translate_c.zig+16| ... | @@ -1137,6 +1137,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1137,6 +1137,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1137 | \\#define BAR .12345 | 1137 | \\#define BAR .12345 |
| 1138 | \\#define baz 1e1 | 1138 | \\#define baz 1e1 |
| 1139 | \\#define BAZ 42e-3f | 1139 | \\#define BAZ 42e-3f |
| 1140 | \\#define foobar -73.L | ||
| 1140 | , &[_][]const u8{ | 1141 | , &[_][]const u8{ |
| 1141 | "pub const foo = @as(f32, 3.14);", | 1142 | "pub const foo = @as(f32, 3.14);", |
| 1142 | "pub const bar = @as(c_longdouble, 16.0e-2);", | 1143 | "pub const bar = @as(c_longdouble, 16.0e-2);", |
| ... | @@ -1144,6 +1145,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1144,6 +1145,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1144 | "pub const BAR = 0.12345;", | 1145 | "pub const BAR = 0.12345;", |
| 1145 | "pub const baz = 1e1;", | 1146 | "pub const baz = 1e1;", |
| 1146 | "pub const BAZ = @as(f32, 42e-3);", | 1147 | "pub const BAZ = @as(f32, 42e-3);", |
| 1148 | "pub const foobar = -@as(c_longdouble, 73.0);", | ||
| 1149 | }); | ||
| 1150 | |||
| 1151 | cases.add("macro defines hexadecimal float", | ||
| 1152 | \\#define FOO 0xf7p38 | ||
| 1153 | \\#define BAR -0X8F.BP5F | ||
| 1154 | \\#define FOOBAR 0X0P+0 | ||
| 1155 | \\#define BAZ -0x.0a5dp+12 | ||
| 1156 | \\#define FOOBAZ 0xfE.P-1l | ||
| 1157 | , &[_][]const u8{ | ||
| 1158 | "pub const FOO = 0xf7p38;", | ||
| 1159 | "pub const BAR = -@as(f32, 0x8F.BP5);", | ||
| 1160 | "pub const FOOBAR = 0x0P+0;", | ||
| 1161 | "pub const BAZ = -0x0.0a5dp+12;", | ||
| 1162 | "pub const FOOBAZ = @as(c_longdouble, 0xfE.0P-1);", | ||
| 1147 | }); | 1163 | }); |
| 1148 | 1164 | ||
| 1149 | cases.add("comments", | 1165 | cases.add("comments", |