authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-04 11:06:28+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-04 11:06:28+01:00
log51e430fac01a4b36a61d4c626d7c25158898e216
treee3ab74a8aa91b9e33e81eeaace59a7436e0e123d
parent6ea193946da13a42ecd8f8d46e4a140f9937d1e5

Fix edge case in hex-literal translation


3 files changed, 37 insertions(+), 12 deletions(-)

src-self-hosted/c_tokenizer.zig+10
...@@ -659,6 +659,16 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:...@@ -659,6 +659,16 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*:
659 try failDecl(ctx, loc, name, "macro tokenizing failed: invalid digit '{c}' in octal number", .{c});659 try failDecl(ctx, loc, name, "macro tokenizing failed: invalid digit '{c}' in octal number", .{c});
660 return error.TokenizingFailed;660 return error.TokenizingFailed;
661 },661 },
662 'u', 'U' => {
663 state = .NumLitIntSuffixU;
664 result.num_lit_suffix = .U;
665 result.bytes = chars[begin_index..i.*];
666 },
667 'l', 'L' => {
668 state = .NumLitIntSuffixL;
669 result.num_lit_suffix = .L;
670 result.bytes = chars[begin_index..i.*];
671 },
662 else => {672 else => {
663 result.bytes = chars[begin_index..i.*];673 result.bytes = chars[begin_index..i.*];
664 return result;674 return result;
src-self-hosted/translate_c.zig+21-12
...@@ -2125,7 +2125,8 @@ fn transForLoop(...@@ -2125,7 +2125,8 @@ fn transForLoop(
2125 block_scope = try Scope.Block.init(rp.c, scope, null);2125 block_scope = try Scope.Block.init(rp.c, scope, null);
2126 block_scope.?.block_node = try transCreateNodeBlock(rp.c, null);2126 block_scope.?.block_node = try transCreateNodeBlock(rp.c, null);
2127 loop_scope.parent = &block_scope.?.base;2127 loop_scope.parent = &block_scope.?.base;
2128 _ = try transStmt(rp, &loop_scope, init, .unused, .r_value);2128 const init_stmt = try transStmt(rp, &loop_scope, init, .unused, .r_value);
2129 try block_scope.?.block_node.statements.push(init_stmt);
2129 }2130 }
2130 var cond_scope = Scope{2131 var cond_scope = Scope{
2131 .parent = scope,2132 .parent = scope,
...@@ -4720,18 +4721,26 @@ fn parseCExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigClangSou...@@ -4720,18 +4721,26 @@ fn parseCExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: ZigClangSou
47204721
4721fn parseCNumLit(c: *Context, tok: *CToken, source_loc: ZigClangSourceLocation) ParseError!*ast.Node {4722fn parseCNumLit(c: *Context, tok: *CToken, source_loc: ZigClangSourceLocation) ParseError!*ast.Node {
4722 if (tok.id == .NumLitInt) {4723 if (tok.id == .NumLitInt) {
4723 if (tok.num_lit_suffix == .None) {4724 var lit_bytes = tok.bytes;
4724 if (tok.bytes.len > 2 and tok.bytes[0] == '0') {4725
4725 switch (tok.bytes[1]) {4726 if (tok.bytes.len > 2 and tok.bytes[0] == '0') {
4726 '0'...'7' => {4727 switch (tok.bytes[1]) {
4727 // octal4728 '0'...'7' => {
4728 return transCreateNodeInt(c, try std.fmt.allocPrint(c.a(), "0o{}", .{tok.bytes}));4729 // Octal
4729 },4730 lit_bytes = try std.fmt.allocPrint(c.a(), "0o{}", .{tok.bytes});
4730 else => {},4731 },
4731 }4732 'X' => {
4733 // Hexadecimal with capital X, valid in C but not in Zig
4734 lit_bytes = try std.fmt.allocPrint(c.a(), "0x{}", .{tok.bytes[2..]});
4735 },
4736 else => {},
4732 }4737 }
4733 return transCreateNodeInt(c, tok.bytes);
4734 }4738 }
4739
4740 if (tok.num_lit_suffix == .None) {
4741 return transCreateNodeInt(c, lit_bytes);
4742 }
4743
4735 const cast_node = try transCreateNodeBuiltinFnCall(c, "@as");4744 const cast_node = try transCreateNodeBuiltinFnCall(c, "@as");
4736 try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.num_lit_suffix) {4745 try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.num_lit_suffix) {
4737 .U => "c_uint",4746 .U => "c_uint",
...@@ -4742,7 +4751,7 @@ fn parseCNumLit(c: *Context, tok: *CToken, source_loc: ZigClangSourceLocation) P...@@ -4742,7 +4751,7 @@ fn parseCNumLit(c: *Context, tok: *CToken, source_loc: ZigClangSourceLocation) P
4742 else => unreachable,4751 else => unreachable,
4743 }));4752 }));
4744 _ = try appendToken(c, .Comma, ",");4753 _ = try appendToken(c, .Comma, ",");
4745 try cast_node.params.push(try transCreateNodeInt(c, tok.bytes));4754 try cast_node.params.push(try transCreateNodeInt(c, lit_bytes));
4746 cast_node.rparen_token = try appendToken(c, .RParen, ")");4755 cast_node.rparen_token = try appendToken(c, .RParen, ")");
4747 return &cast_node.base;4756 return &cast_node.base;
4748 } else if (tok.id == .NumLitFloat) {4757 } else if (tok.id == .NumLitFloat) {
test/translate_c.zig+6
...@@ -2,6 +2,12 @@ const tests = @import("tests.zig");...@@ -2,6 +2,12 @@ const tests = @import("tests.zig");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub fn addCases(cases: *tests.TranslateCContext) void {4pub fn addCases(cases: *tests.TranslateCContext) void {
5 cases.add("#define hex literal with capital X",
6 \\#define VAL 0XF00D
7 , &[_][]const u8{
8 \\pub const VAL = 0xF00D;
9 });
10
5 cases.add("union initializer",11 cases.add("union initializer",
6 \\union { int x; char c[4]; }12 \\union { int x; char c[4]; }
7 \\ ua = {1},13 \\ ua = {1},