authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-23 21:58:28-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-23 22:21:25-05:00
log00878a15d703a668970c7869276d33b21464714a
treed84e68f83d2b484e04494e3b36d76a6beb34e443
parentf25182f46dd672eb5b10533c67ed462a3e5df999
signaturelock-open Commit is signed but in an unrecognized format.

zig fmt: support sentinel-terminated pointer syntax


5 files changed, 202 insertions(+), 192 deletions(-)

lib/std/zig/ast.zig+16-11
...@@ -137,7 +137,6 @@ pub const Error = union(enum) {...@@ -137,7 +137,6 @@ pub const Error = union(enum) {
137 ExpectedCallOrFnProto: ExpectedCallOrFnProto,137 ExpectedCallOrFnProto: ExpectedCallOrFnProto,
138 ExpectedSliceOrRBracket: ExpectedSliceOrRBracket,138 ExpectedSliceOrRBracket: ExpectedSliceOrRBracket,
139 ExtraAlignQualifier: ExtraAlignQualifier,139 ExtraAlignQualifier: ExtraAlignQualifier,
140 ExtraNullQualifier: ExtraNullQualifier,
141 ExtraConstQualifier: ExtraConstQualifier,140 ExtraConstQualifier: ExtraConstQualifier,
142 ExtraVolatileQualifier: ExtraVolatileQualifier,141 ExtraVolatileQualifier: ExtraVolatileQualifier,
143 ExtraAllowZeroQualifier: ExtraAllowZeroQualifier,142 ExtraAllowZeroQualifier: ExtraAllowZeroQualifier,
...@@ -185,7 +184,6 @@ pub const Error = union(enum) {...@@ -185,7 +184,6 @@ pub const Error = union(enum) {
185 .ExpectedCallOrFnProto => |*x| return x.render(tokens, stream),184 .ExpectedCallOrFnProto => |*x| return x.render(tokens, stream),
186 .ExpectedSliceOrRBracket => |*x| return x.render(tokens, stream),185 .ExpectedSliceOrRBracket => |*x| return x.render(tokens, stream),
187 .ExtraAlignQualifier => |*x| return x.render(tokens, stream),186 .ExtraAlignQualifier => |*x| return x.render(tokens, stream),
188 .ExtraNullQualifier => |*x| return x.render(tokens, stream),
189 .ExtraConstQualifier => |*x| return x.render(tokens, stream),187 .ExtraConstQualifier => |*x| return x.render(tokens, stream),
190 .ExtraVolatileQualifier => |*x| return x.render(tokens, stream),188 .ExtraVolatileQualifier => |*x| return x.render(tokens, stream),
191 .ExtraAllowZeroQualifier => |*x| return x.render(tokens, stream),189 .ExtraAllowZeroQualifier => |*x| return x.render(tokens, stream),
...@@ -235,7 +233,6 @@ pub const Error = union(enum) {...@@ -235,7 +233,6 @@ pub const Error = union(enum) {
235 .ExpectedCallOrFnProto => |x| return x.node.firstToken(),233 .ExpectedCallOrFnProto => |x| return x.node.firstToken(),
236 .ExpectedSliceOrRBracket => |x| return x.token,234 .ExpectedSliceOrRBracket => |x| return x.token,
237 .ExtraAlignQualifier => |x| return x.token,235 .ExtraAlignQualifier => |x| return x.token,
238 .ExtraNullQualifier => |x| return x.token,
239 .ExtraConstQualifier => |x| return x.token,236 .ExtraConstQualifier => |x| return x.token,
240 .ExtraVolatileQualifier => |x| return x.token,237 .ExtraVolatileQualifier => |x| return x.token,
241 .ExtraAllowZeroQualifier => |x| return x.token,238 .ExtraAllowZeroQualifier => |x| return x.token,
...@@ -296,7 +293,6 @@ pub const Error = union(enum) {...@@ -296,7 +293,6 @@ pub const Error = union(enum) {
296 pub const ExpectedPubItem = SimpleError("Expected function or variable declaration after pub");293 pub const ExpectedPubItem = SimpleError("Expected function or variable declaration after pub");
297 pub const UnattachedDocComment = SimpleError("Unattached documentation comment");294 pub const UnattachedDocComment = SimpleError("Unattached documentation comment");
298 pub const ExtraAlignQualifier = SimpleError("Extra align qualifier");295 pub const ExtraAlignQualifier = SimpleError("Extra align qualifier");
299 pub const ExtraNullQualifier = SimpleError("Extra null qualifier");
300 pub const ExtraConstQualifier = SimpleError("Extra const qualifier");296 pub const ExtraConstQualifier = SimpleError("Extra const qualifier");
301 pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier");297 pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier");
302 pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");298 pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");
...@@ -1535,7 +1531,7 @@ pub const Node = struct {...@@ -1535,7 +1531,7 @@ pub const Node = struct {
1535 };1531 };
15361532
1537 pub const PrefixOp = struct {1533 pub const PrefixOp = struct {
1538 base: Node,1534 base: Node = Node{ .id = .PrefixOp },
1539 op_token: TokenIndex,1535 op_token: TokenIndex,
1540 op: Op,1536 op: Op,
1541 rhs: *Node,1537 rhs: *Node,
...@@ -1558,15 +1554,15 @@ pub const Node = struct {...@@ -1558,15 +1554,15 @@ pub const Node = struct {
15581554
1559 pub const ArrayInfo = struct {1555 pub const ArrayInfo = struct {
1560 len_expr: *Node,1556 len_expr: *Node,
1561 null_token: ?TokenIndex,1557 sentinel: ?*Node,
1562 };1558 };
15631559
1564 pub const PtrInfo = struct {1560 pub const PtrInfo = struct {
1565 allowzero_token: ?TokenIndex,1561 allowzero_token: ?TokenIndex = null,
1566 align_info: ?Align,1562 align_info: ?Align = null,
1567 const_token: ?TokenIndex,1563 const_token: ?TokenIndex = null,
1568 volatile_token: ?TokenIndex,1564 volatile_token: ?TokenIndex = null,
1569 null_token: ?TokenIndex,1565 sentinel: ?*Node = null,
15701566
1571 pub const Align = struct {1567 pub const Align = struct {
1572 node: *Node,1568 node: *Node,
...@@ -1585,6 +1581,11 @@ pub const Node = struct {...@@ -1585,6 +1581,11 @@ pub const Node = struct {
1585 switch (self.op) {1581 switch (self.op) {
1586 // TODO https://github.com/ziglang/zig/issues/11071582 // TODO https://github.com/ziglang/zig/issues/1107
1587 Op.SliceType => |addr_of_info| {1583 Op.SliceType => |addr_of_info| {
1584 if (addr_of_info.sentinel) |sentinel| {
1585 if (i < 1) return sentinel;
1586 i -= 1;
1587 }
1588
1588 if (addr_of_info.align_info) |align_info| {1589 if (addr_of_info.align_info) |align_info| {
1589 if (i < 1) return align_info.node;1590 if (i < 1) return align_info.node;
1590 i -= 1;1591 i -= 1;
...@@ -1601,6 +1602,10 @@ pub const Node = struct {...@@ -1601,6 +1602,10 @@ pub const Node = struct {
1601 Op.ArrayType => |array_info| {1602 Op.ArrayType => |array_info| {
1602 if (i < 1) return array_info.len_expr;1603 if (i < 1) return array_info.len_expr;
1603 i -= 1;1604 i -= 1;
1605 if (array_info.sentinel) |sentinel| {
1606 if (i < 1) return sentinel;
1607 i -= 1;
1608 }
1604 },1609 },
16051610
1606 Op.AddressOf,1611 Op.AddressOf,
lib/std/zig/parse.zig+127-109
...@@ -2246,73 +2246,6 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -2246,73 +2246,6 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
2246 return &node.base;2246 return &node.base;
2247 }2247 }
22482248
2249 if (try parseArrayTypeStart(arena, it, tree)) |node| {
2250 switch (node.cast(Node.PrefixOp).?.op) {
2251 .ArrayType => {},
2252 .SliceType => |*slice_type| {
2253 // Collect pointer qualifiers in any order, but disallow duplicates
2254 while (true) {
2255 if (eatToken(it, .Keyword_null)) |null_token| {
2256 if (slice_type.null_token != null) {
2257 try tree.errors.push(AstError{
2258 .ExtraNullQualifier = AstError.ExtraNullQualifier{ .token = it.index },
2259 });
2260 return error.ParseError;
2261 }
2262 slice_type.null_token = null_token;
2263 continue;
2264 }
2265 if (try parseByteAlign(arena, it, tree)) |align_expr| {
2266 if (slice_type.align_info != null) {
2267 try tree.errors.push(AstError{
2268 .ExtraAlignQualifier = AstError.ExtraAlignQualifier{ .token = it.index },
2269 });
2270 return error.ParseError;
2271 }
2272 slice_type.align_info = Node.PrefixOp.PtrInfo.Align{
2273 .node = align_expr,
2274 .bit_range = null,
2275 };
2276 continue;
2277 }
2278 if (eatToken(it, .Keyword_const)) |const_token| {
2279 if (slice_type.const_token != null) {
2280 try tree.errors.push(AstError{
2281 .ExtraConstQualifier = AstError.ExtraConstQualifier{ .token = it.index },
2282 });
2283 return error.ParseError;
2284 }
2285 slice_type.const_token = const_token;
2286 continue;
2287 }
2288 if (eatToken(it, .Keyword_volatile)) |volatile_token| {
2289 if (slice_type.volatile_token != null) {
2290 try tree.errors.push(AstError{
2291 .ExtraVolatileQualifier = AstError.ExtraVolatileQualifier{ .token = it.index },
2292 });
2293 return error.ParseError;
2294 }
2295 slice_type.volatile_token = volatile_token;
2296 continue;
2297 }
2298 if (eatToken(it, .Keyword_allowzero)) |allowzero_token| {
2299 if (slice_type.allowzero_token != null) {
2300 try tree.errors.push(AstError{
2301 .ExtraAllowZeroQualifier = AstError.ExtraAllowZeroQualifier{ .token = it.index },
2302 });
2303 return error.ParseError;
2304 }
2305 slice_type.allowzero_token = allowzero_token;
2306 continue;
2307 }
2308 break;
2309 }
2310 },
2311 else => unreachable,
2312 }
2313 return node;
2314 }
2315
2316 if (try parsePtrTypeStart(arena, it, tree)) |node| {2249 if (try parsePtrTypeStart(arena, it, tree)) |node| {
2317 // If the token encountered was **, there will be two nodes instead of one.2250 // If the token encountered was **, there will be two nodes instead of one.
2318 // The attributes should be applied to the rightmost operator.2251 // The attributes should be applied to the rightmost operator.
...@@ -2323,10 +2256,6 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -2323,10 +2256,6 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
2323 &prefix_op.op.PtrType;2256 &prefix_op.op.PtrType;
23242257
2325 while (true) {2258 while (true) {
2326 if (eatToken(it, .Keyword_null)) |null_token| {
2327 ptr_info.null_token = null_token;
2328 continue;
2329 }
2330 if (eatToken(it, .Keyword_align)) |align_token| {2259 if (eatToken(it, .Keyword_align)) |align_token| {
2331 const lparen = try expectToken(it, tree, .LParen);2260 const lparen = try expectToken(it, tree, .LParen);
2332 const expr_node = try expectNode(arena, it, tree, parseExpr, AstError{2261 const expr_node = try expectNode(arena, it, tree, parseExpr, AstError{
...@@ -2375,6 +2304,63 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -2375,6 +2304,63 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
2375 return node;2304 return node;
2376 }2305 }
23772306
2307 if (try parseArrayTypeStart(arena, it, tree)) |node| {
2308 switch (node.cast(Node.PrefixOp).?.op) {
2309 .ArrayType => {},
2310 .SliceType => |*slice_type| {
2311 // Collect pointer qualifiers in any order, but disallow duplicates
2312 while (true) {
2313 if (try parseByteAlign(arena, it, tree)) |align_expr| {
2314 if (slice_type.align_info != null) {
2315 try tree.errors.push(AstError{
2316 .ExtraAlignQualifier = AstError.ExtraAlignQualifier{ .token = it.index },
2317 });
2318 return error.ParseError;
2319 }
2320 slice_type.align_info = Node.PrefixOp.PtrInfo.Align{
2321 .node = align_expr,
2322 .bit_range = null,
2323 };
2324 continue;
2325 }
2326 if (eatToken(it, .Keyword_const)) |const_token| {
2327 if (slice_type.const_token != null) {
2328 try tree.errors.push(AstError{
2329 .ExtraConstQualifier = AstError.ExtraConstQualifier{ .token = it.index },
2330 });
2331 return error.ParseError;
2332 }
2333 slice_type.const_token = const_token;
2334 continue;
2335 }
2336 if (eatToken(it, .Keyword_volatile)) |volatile_token| {
2337 if (slice_type.volatile_token != null) {
2338 try tree.errors.push(AstError{
2339 .ExtraVolatileQualifier = AstError.ExtraVolatileQualifier{ .token = it.index },
2340 });
2341 return error.ParseError;
2342 }
2343 slice_type.volatile_token = volatile_token;
2344 continue;
2345 }
2346 if (eatToken(it, .Keyword_allowzero)) |allowzero_token| {
2347 if (slice_type.allowzero_token != null) {
2348 try tree.errors.push(AstError{
2349 .ExtraAllowZeroQualifier = AstError.ExtraAllowZeroQualifier{ .token = it.index },
2350 });
2351 return error.ParseError;
2352 }
2353 slice_type.allowzero_token = allowzero_token;
2354 continue;
2355 }
2356 break;
2357 }
2358 },
2359 else => unreachable,
2360 }
2361 return node;
2362 }
2363
2378 return null;2364 return null;
2379}2365}
23802366
...@@ -2473,14 +2459,19 @@ const AnnotatedParamList = struct {...@@ -2473,14 +2459,19 @@ const AnnotatedParamList = struct {
2473fn parseArrayTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {2459fn parseArrayTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
2474 const lbracket = eatToken(it, .LBracket) orelse return null;2460 const lbracket = eatToken(it, .LBracket) orelse return null;
2475 const expr = try parseExpr(arena, it, tree);2461 const expr = try parseExpr(arena, it, tree);
2462 const sentinel = if (eatToken(it, .Colon)) |_|
2463 try expectNode(arena, it, tree, parseExpr, AstError{
2464 .ExpectedExpr = .{ .token = it.index },
2465 })
2466 else
2467 null;
2476 const rbracket = try expectToken(it, tree, .RBracket);2468 const rbracket = try expectToken(it, tree, .RBracket);
2477 const null_token = eatToken(it, .Keyword_null);
24782469
2479 const op = if (expr) |len_expr|2470 const op = if (expr) |len_expr|
2480 Node.PrefixOp.Op{2471 Node.PrefixOp.Op{
2481 .ArrayType = .{2472 .ArrayType = .{
2482 .len_expr = len_expr,2473 .len_expr = len_expr,
2483 .null_token = null_token,2474 .sentinel = sentinel,
2484 },2475 },
2485 }2476 }
2486 else2477 else
...@@ -2490,7 +2481,7 @@ fn parseArrayTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No...@@ -2490,7 +2481,7 @@ fn parseArrayTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
2490 .align_info = null,2481 .align_info = null,
2491 .const_token = null,2482 .const_token = null,
2492 .volatile_token = null,2483 .volatile_token = null,
2493 .null_token = null,2484 .sentinel = sentinel,
2494 },2485 },
2495 };2486 };
24962487
...@@ -2510,49 +2501,76 @@ fn parseArrayTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No...@@ -2510,49 +2501,76 @@ fn parseArrayTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
2510/// / PTRUNKNOWN2501/// / PTRUNKNOWN
2511/// / PTRC2502/// / PTRC
2512fn parsePtrTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {2503fn parsePtrTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
2513 const token = eatAnnotatedToken(it, .Asterisk) orelse2504 if (eatToken(it, .Asterisk)) |asterisk| {
2514 eatAnnotatedToken(it, .AsteriskAsterisk) orelse2505 const sentinel = if (eatToken(it, .Colon)) |_|
2515 eatAnnotatedToken(it, .BracketStarBracket) orelse2506 try expectNode(arena, it, tree, parseExpr, AstError{
2516 eatAnnotatedToken(it, .BracketStarCBracket) orelse2507 .ExpectedExpr = .{ .token = it.index },
2517 return null;2508 })
2509 else
2510 null;
2511 const node = try arena.create(Node.PrefixOp);
2512 node.* = .{
2513 .op_token = asterisk,
2514 .op = .{ .PtrType = .{ .sentinel = sentinel } },
2515 .rhs = undefined, // set by caller
2516 };
2517 return &node.base;
2518 }
25182519
2519 const node = try arena.create(Node.PrefixOp);2520 if (eatToken(it, .AsteriskAsterisk)) |double_asterisk| {
2520 node.* = Node.PrefixOp{2521 const node = try arena.create(Node.PrefixOp);
2521 .base = Node{ .id = .PrefixOp },2522 node.* = Node.PrefixOp{
2522 .op_token = token.index,2523 .op_token = double_asterisk,
2523 .op = Node.PrefixOp.Op{2524 .op = Node.PrefixOp.Op{ .PtrType = .{} },
2524 .PtrType = Node.PrefixOp.PtrInfo{2525 .rhs = undefined, // set by caller
2525 .allowzero_token = null,2526 };
2526 .align_info = null,
2527 .const_token = null,
2528 .volatile_token = null,
2529 .null_token = null,
2530 },
2531 },
2532 .rhs = undefined, // set by caller
2533 };
25342527
2535 // Special case for **, which is its own token2528 // Special case for **, which is its own token
2536 if (token.ptr.id == .AsteriskAsterisk) {
2537 const child = try arena.create(Node.PrefixOp);2529 const child = try arena.create(Node.PrefixOp);
2538 child.* = Node.PrefixOp{2530 child.* = Node.PrefixOp{
2539 .base = Node{ .id = .PrefixOp },2531 .op_token = double_asterisk,
2540 .op_token = token.index,2532 .op = Node.PrefixOp.Op{ .PtrType = .{} },
2541 .op = Node.PrefixOp.Op{
2542 .PtrType = Node.PrefixOp.PtrInfo{
2543 .allowzero_token = null,
2544 .align_info = null,
2545 .const_token = null,
2546 .volatile_token = null,
2547 .null_token = null,
2548 },
2549 },
2550 .rhs = undefined, // set by caller2533 .rhs = undefined, // set by caller
2551 };2534 };
2552 node.rhs = &child.base;2535 node.rhs = &child.base;
2553 }
25542536
2555 return &node.base;2537 return &node.base;
2538 }
2539 if (eatToken(it, .LBracket)) |lbracket| {
2540 const asterisk = eatToken(it, .Asterisk) orelse {
2541 putBackToken(it, lbracket);
2542 return null;
2543 };
2544 if (eatToken(it, .Identifier)) |ident| {
2545 if (!std.mem.eql(u8, tree.tokenSlice(ident), "c")) {
2546 putBackToken(it, ident);
2547 } else {
2548 _ = try expectToken(it, tree, .RBracket);
2549 const node = try arena.create(Node.PrefixOp);
2550 node.* = .{
2551 .op_token = ident,
2552 .op = .{ .PtrType = .{} },
2553 .rhs = undefined, // set by caller
2554 };
2555 return &node.base;
2556 }
2557 }
2558 const sentinel = if (eatToken(it, .Colon)) |_|
2559 try expectNode(arena, it, tree, parseExpr, AstError{
2560 .ExpectedExpr = .{ .token = it.index },
2561 })
2562 else
2563 null;
2564 _ = try expectToken(it, tree, .RBracket);
2565 const node = try arena.create(Node.PrefixOp);
2566 node.* = .{
2567 .op_token = lbracket,
2568 .op = .{ .PtrType = .{ .sentinel = sentinel } },
2569 .rhs = undefined, // set by caller
2570 };
2571 return &node.base;
2572 }
2573 return null;
2556}2574}
25572575
2558/// ContainerDeclAuto <- ContainerDeclType LBRACE ContainerMembers RBRACE2576/// ContainerDeclAuto <- ContainerDeclType LBRACE ContainerMembers RBRACE
lib/std/zig/render.zig+29-11
...@@ -418,13 +418,26 @@ fn renderExpression(...@@ -418,13 +418,26 @@ fn renderExpression(
418418
419 switch (prefix_op_node.op) {419 switch (prefix_op_node.op) {
420 ast.Node.PrefixOp.Op.PtrType => |ptr_info| {420 ast.Node.PrefixOp.Op.PtrType => |ptr_info| {
421 const star_offset = switch (tree.tokens.at(prefix_op_node.op_token).id) {421 const op_tok_id = tree.tokens.at(prefix_op_node.op_token).id;
422 Token.Id.AsteriskAsterisk => @as(usize, 1),422 switch (op_tok_id) {
423 else => @as(usize, 0),423 .Asterisk, .AsteriskAsterisk => try stream.writeByte('*'),
424 };424 .Identifier => try stream.write("[*c]"),
425 try renderTokenOffset(tree, stream, prefix_op_node.op_token, indent, start_col, Space.None, star_offset); // *425 .LBracket => try stream.write("[*"),
426 if (ptr_info.null_token) |null_token| {426 else => unreachable,
427 try renderToken(tree, stream, null_token, indent, start_col, Space.Space); // null427 }
428 if (ptr_info.sentinel) |sentinel| {
429 const colon_token = tree.prevToken(sentinel.firstToken());
430 try renderToken(tree, stream, colon_token, indent, start_col, Space.None); // :
431 const sentinel_space = switch (op_tok_id) {
432 .LBracket => Space.None,
433 else => Space.Space,
434 };
435 try renderExpression(allocator, stream, tree, indent, start_col, sentinel, sentinel_space);
436 }
437 switch (op_tok_id) {
438 .Asterisk, .AsteriskAsterisk, .Identifier => {},
439 .LBracket => try stream.writeByte(']'),
440 else => unreachable,
428 }441 }
429 if (ptr_info.allowzero_token) |allowzero_token| {442 if (ptr_info.allowzero_token) |allowzero_token| {
430 try renderToken(tree, stream, allowzero_token, indent, start_col, Space.Space); // allowzero443 try renderToken(tree, stream, allowzero_token, indent, start_col, Space.Space); // allowzero
...@@ -504,7 +517,10 @@ fn renderExpression(...@@ -504,7 +517,10 @@ fn renderExpression(
504517
505 ast.Node.PrefixOp.Op.ArrayType => |array_info| {518 ast.Node.PrefixOp.Op.ArrayType => |array_info| {
506 const lbracket = prefix_op_node.op_token;519 const lbracket = prefix_op_node.op_token;
507 const rbracket = tree.nextToken(array_info.len_expr.lastToken());520 const rbracket = tree.nextToken(if (array_info.sentinel) |sentinel|
521 sentinel.lastToken()
522 else
523 array_info.len_expr.lastToken());
508524
509 try renderToken(tree, stream, lbracket, indent, start_col, Space.None); // [525 try renderToken(tree, stream, lbracket, indent, start_col, Space.None); // [
510526
...@@ -519,10 +535,12 @@ fn renderExpression(...@@ -519,10 +535,12 @@ fn renderExpression(
519 if (ends_with_comment or starts_with_comment) {535 if (ends_with_comment or starts_with_comment) {
520 try stream.writeByteNTimes(' ', indent);536 try stream.writeByteNTimes(' ', indent);
521 }537 }
522 try renderToken(tree, stream, rbracket, indent, start_col, Space.None); // ]538 if (array_info.sentinel) |sentinel| {
523 if (array_info.null_token) |null_token| {539 const colon_token = tree.prevToken(sentinel.firstToken());
524 try renderToken(tree, stream, null_token, indent, start_col, Space.Space); // null540 try renderToken(tree, stream, colon_token, indent, start_col, Space.None); // :
541 try renderExpression(allocator, stream, tree, indent, start_col, sentinel, Space.None);
525 }542 }
543 try renderToken(tree, stream, rbracket, indent, start_col, Space.None); // ]
526 },544 },
527 ast.Node.PrefixOp.Op.BitNot,545 ast.Node.PrefixOp.Op.BitNot,
528 ast.Node.PrefixOp.Op.BoolNot,546 ast.Node.PrefixOp.Op.BoolNot,
lib/std/zig/tokenizer.zig+10-52
...@@ -143,8 +143,6 @@ pub const Token = struct {...@@ -143,8 +143,6 @@ pub const Token = struct {
143 LineComment,143 LineComment,
144 DocComment,144 DocComment,
145 ContainerDocComment,145 ContainerDocComment,
146 BracketStarBracket,
147 BracketStarCBracket,
148 ShebangLine,146 ShebangLine,
149 Keyword_align,147 Keyword_align,
150 Keyword_allowzero,148 Keyword_allowzero,
...@@ -269,8 +267,6 @@ pub const Token = struct {...@@ -269,8 +267,6 @@ pub const Token = struct {
269 .AngleBracketAngleBracketRight => ">>",267 .AngleBracketAngleBracketRight => ">>",
270 .AngleBracketAngleBracketRightEqual => ">>=",268 .AngleBracketAngleBracketRightEqual => ">>=",
271 .Tilde => "~",269 .Tilde => "~",
272 .BracketStarBracket => "[*]",
273 .BracketStarCBracket => "[*c]",
274 .Keyword_align => "align",270 .Keyword_align => "align",
275 .Keyword_allowzero => "allowzero",271 .Keyword_allowzero => "allowzero",
276 .Keyword_and => "and",272 .Keyword_and => "and",
...@@ -400,9 +396,6 @@ pub const Tokenizer = struct {...@@ -400,9 +396,6 @@ pub const Tokenizer = struct {
400 Period,396 Period,
401 Period2,397 Period2,
402 SawAtSign,398 SawAtSign,
403 LBracket,
404 LBracketStar,
405 LBracketStarC,
406 };399 };
407400
408 pub fn next(self: *Tokenizer) Token {401 pub fn next(self: *Tokenizer) Token {
...@@ -460,7 +453,9 @@ pub const Tokenizer = struct {...@@ -460,7 +453,9 @@ pub const Tokenizer = struct {
460 break;453 break;
461 },454 },
462 '[' => {455 '[' => {
463 state = State.LBracket;456 result.id = .LBracket;
457 self.index += 1;
458 break;
464 },459 },
465 ']' => {460 ']' => {
466 result.id = Token.Id.RBracket;461 result.id = Token.Id.RBracket;
...@@ -564,43 +559,6 @@ pub const Tokenizer = struct {...@@ -564,43 +559,6 @@ pub const Tokenizer = struct {
564 },559 },
565 },560 },
566561
567 State.LBracket => switch (c) {
568 '*' => {
569 state = State.LBracketStar;
570 },
571 else => {
572 result.id = Token.Id.LBracket;
573 break;
574 },
575 },
576
577 State.LBracketStar => switch (c) {
578 'c' => {
579 state = State.LBracketStarC;
580 },
581 ']' => {
582 result.id = Token.Id.BracketStarBracket;
583 self.index += 1;
584 break;
585 },
586 else => {
587 result.id = Token.Id.Invalid;
588 break;
589 },
590 },
591
592 State.LBracketStarC => switch (c) {
593 ']' => {
594 result.id = Token.Id.BracketStarCBracket;
595 self.index += 1;
596 break;
597 },
598 else => {
599 result.id = Token.Id.Invalid;
600 break;
601 },
602 },
603
604 State.Ampersand => switch (c) {562 State.Ampersand => switch (c) {
605 '&' => {563 '&' => {
606 result.id = Token.Id.Invalid_ampersands;564 result.id = Token.Id.Invalid_ampersands;
...@@ -1227,8 +1185,6 @@ pub const Tokenizer = struct {...@@ -1227,8 +1185,6 @@ pub const Tokenizer = struct {
1227 State.CharLiteralEnd,1185 State.CharLiteralEnd,
1228 State.CharLiteralUnicode,1186 State.CharLiteralUnicode,
1229 State.StringLiteralBackslash,1187 State.StringLiteralBackslash,
1230 State.LBracketStar,
1231 State.LBracketStarC,
1232 => {1188 => {
1233 result.id = Token.Id.Invalid;1189 result.id = Token.Id.Invalid;
1234 },1190 },
...@@ -1245,9 +1201,6 @@ pub const Tokenizer = struct {...@@ -1245,9 +1201,6 @@ pub const Tokenizer = struct {
1245 State.Slash => {1201 State.Slash => {
1246 result.id = Token.Id.Slash;1202 result.id = Token.Id.Slash;
1247 },1203 },
1248 State.LBracket => {
1249 result.id = Token.Id.LBracket;
1250 },
1251 State.Zero => {1204 State.Zero => {
1252 result.id = Token.Id.IntegerLiteral;1205 result.id = Token.Id.IntegerLiteral;
1253 },1206 },
...@@ -1368,9 +1321,14 @@ test "tokenizer - unknown length pointer and then c pointer" {...@@ -1368,9 +1321,14 @@ test "tokenizer - unknown length pointer and then c pointer" {
1368 \\[*]u81321 \\[*]u8
1369 \\[*c]u81322 \\[*c]u8
1370 , [_]Token.Id{1323 , [_]Token.Id{
1371 Token.Id.BracketStarBracket,1324 Token.Id.LBracket,
1325 Token.Id.Asterisk,
1326 Token.Id.RBracket,
1327 Token.Id.Identifier,
1328 Token.Id.LBracket,
1329 Token.Id.Asterisk,
1372 Token.Id.Identifier,1330 Token.Id.Identifier,
1373 Token.Id.BracketStarCBracket,1331 Token.Id.RBracket,
1374 Token.Id.Identifier,1332 Token.Id.Identifier,
1375 });1333 });
1376}1334}
src-self-hosted/translate_c.zig+20-9
...@@ -1105,19 +1105,32 @@ fn transCreateNodePtrType(...@@ -1105,19 +1105,32 @@ fn transCreateNodePtrType(
1105 is_const: bool,1105 is_const: bool,
1106 is_volatile: bool,1106 is_volatile: bool,
1107 op_tok_id: std.zig.Token.Id,1107 op_tok_id: std.zig.Token.Id,
1108 bytes: []const u8,
1109) !*ast.Node.PrefixOp {1108) !*ast.Node.PrefixOp {
1110 const node = try c.a().create(ast.Node.PrefixOp);1109 const node = try c.a().create(ast.Node.PrefixOp);
1110 const op_token = switch (op_tok_id) {
1111 .LBracket => blk: {
1112 const lbracket = try appendToken(c, .LBracket, "[");
1113 _ = try appendToken(c, .Asterisk, "*");
1114 _ = try appendToken(c, .RBracket, "]");
1115 break :blk lbracket;
1116 },
1117 .Identifier => blk: {
1118 _ = try appendToken(c, .LBracket, "[");
1119 _ = try appendToken(c, .Asterisk, "*");
1120 const c_ident = try appendToken(c, .Identifier, "c");
1121 _ = try appendToken(c, .RBracket, "]");
1122 break :blk c_ident;
1123 },
1124 .Asterisk => try appendToken(c, .Asterisk, "*"),
1125 else => unreachable,
1126 };
1111 node.* = ast.Node.PrefixOp{1127 node.* = ast.Node.PrefixOp{
1112 .base = ast.Node{ .id = .PrefixOp },1128 .base = ast.Node{ .id = .PrefixOp },
1113 .op_token = try appendToken(c, op_tok_id, bytes),1129 .op_token = op_token,
1114 .op = ast.Node.PrefixOp.Op{1130 .op = ast.Node.PrefixOp.Op{
1115 .PtrType = ast.Node.PrefixOp.PtrInfo{1131 .PtrType = .{
1116 .allowzero_token = null,
1117 .align_info = null,
1118 .const_token = if (is_const) try appendToken(c, .Keyword_const, "const") else null,1132 .const_token = if (is_const) try appendToken(c, .Keyword_const, "const") else null,
1119 .volatile_token = if (is_volatile) try appendToken(c, .Keyword_volatile, "volatile") else null,1133 .volatile_token = if (is_volatile) try appendToken(c, .Keyword_volatile, "volatile") else null,
1120 .null_token = null,
1121 },1134 },
1122 },1135 },
1123 .rhs = undefined, // translate and set afterward1136 .rhs = undefined, // translate and set afterward
...@@ -1226,7 +1239,6 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour...@@ -1226,7 +1239,6 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
1226 ZigClangQualType_isConstQualified(child_qt),1239 ZigClangQualType_isConstQualified(child_qt),
1227 ZigClangQualType_isVolatileQualified(child_qt),1240 ZigClangQualType_isVolatileQualified(child_qt),
1228 .Asterisk,1241 .Asterisk,
1229 "*",
1230 );1242 );
1231 optional_node.rhs = &pointer_node.base;1243 optional_node.rhs = &pointer_node.base;
1232 pointer_node.rhs = try transQualType(rp, child_qt, source_loc);1244 pointer_node.rhs = try transQualType(rp, child_qt, source_loc);
...@@ -1236,8 +1248,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour...@@ -1236,8 +1248,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
1236 rp.c,1248 rp.c,
1237 ZigClangQualType_isConstQualified(child_qt),1249 ZigClangQualType_isConstQualified(child_qt),
1238 ZigClangQualType_isVolatileQualified(child_qt),1250 ZigClangQualType_isVolatileQualified(child_qt),
1239 .BracketStarCBracket,1251 .Identifier,
1240 "[*c]",
1241 );1252 );
1242 pointer_node.rhs = try transQualType(rp, child_qt, source_loc);1253 pointer_node.rhs = try transQualType(rp, child_qt, source_loc);
1243 return &pointer_node.base;1254 return &pointer_node.base;