authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-02-06 22:55:29+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-06 21:29:45-08:00
log33915cb1ed88417d3495c160ffd15c93f9197e5b
tree98de1c8df774c75ddc405ed2405e533a3310dc70
parentd898945786b527b09ef056099e923e946425e146

zig fmt: implement pointer types

rename PtrType => PtrTypeBitRange, SliceType => PtrType This rename was done as the current SliceType is used for non-bitrange pointers as well as slices and because PtrTypeSentinel/PtrTypeAligned are also used for slices. Therefore using the same Ptr prefix for all these pointer/slice nodes is an improvement.

4 files changed, 307 insertions(+), 139 deletions(-)

lib/std/zig/ast.zig+168-14
...@@ -387,10 +387,22 @@ pub const Tree = struct {...@@ -387,10 +387,22 @@ pub const Tree = struct {
387 }387 }
388 },388 },
389389
390 .PtrTypeAligned => unreachable, // TODO390 .PtrTypeAligned,
391 .PtrTypeSentinel => unreachable, // TODO391 .PtrTypeSentinel,
392 .PtrType => unreachable, // TODO392 .PtrType,
393 .SliceType => unreachable, // TODO393 .PtrTypeBitRange,
394 => {
395 const main_token = main_tokens[n];
396 return switch (token_tags[main_token]) {
397 .Asterisk => switch (token_tags[main_token - 1]) {
398 .LBrace => main_token - 1,
399 else => main_token,
400 },
401 .LBrace => main_token,
402 else => unreachable,
403 };
404 },
405
394 .SwitchCaseMulti => unreachable, // TODO406 .SwitchCaseMulti => unreachable, // TODO
395 .WhileSimple => unreachable, // TODO407 .WhileSimple => unreachable, // TODO
396 .WhileCont => unreachable, // TODO408 .WhileCont => unreachable, // TODO
...@@ -477,6 +489,10 @@ pub const Tree = struct {...@@ -477,6 +489,10 @@ pub const Tree = struct {
477 .IfSimple,489 .IfSimple,
478 .WhileSimple,490 .WhileSimple,
479 .FnDecl,491 .FnDecl,
492 .PtrTypeAligned,
493 .PtrTypeSentinel,
494 .PtrType,
495 .PtrTypeBitRange,
480 => n = datas[n].rhs,496 => n = datas[n].rhs,
481497
482 .FieldAccess,498 .FieldAccess,
...@@ -698,10 +714,6 @@ pub const Tree = struct {...@@ -698,10 +714,6 @@ pub const Tree = struct {
698 .SwitchRange => unreachable, // TODO714 .SwitchRange => unreachable, // TODO
699 .ArrayType => unreachable, // TODO715 .ArrayType => unreachable, // TODO
700 .ArrayTypeSentinel => unreachable, // TODO716 .ArrayTypeSentinel => unreachable, // TODO
701 .PtrTypeAligned => unreachable, // TODO
702 .PtrTypeSentinel => unreachable, // TODO
703 .PtrType => unreachable, // TODO
704 .SliceType => unreachable, // TODO
705 .SwitchCaseMulti => unreachable, // TODO717 .SwitchCaseMulti => unreachable, // TODO
706 .WhileCont => unreachable, // TODO718 .WhileCont => unreachable, // TODO
707 .While => unreachable, // TODO719 .While => unreachable, // TODO
...@@ -1028,6 +1040,60 @@ pub const Tree = struct {...@@ -1028,6 +1040,60 @@ pub const Tree = struct {
1028 };1040 };
1029 }1041 }
10301042
1043 pub fn ptrTypeAligned(tree: Tree, node: Node.Index) Full.PtrType {
1044 assert(tree.nodes.items(.tag)[node] == .PtrTypeAligned);
1045 const data = tree.nodes.items(.data)[node];
1046 return tree.fullPtrType(.{
1047 .main_token = tree.nodes.items(.main_token)[node],
1048 .align_node = data.lhs,
1049 .sentinel = 0,
1050 .bit_range_start = 0,
1051 .bit_range_end = 0,
1052 .child_type = data.rhs,
1053 });
1054 }
1055
1056 pub fn ptrTypeSentinel(tree: Tree, node: Node.Index) Full.PtrType {
1057 assert(tree.nodes.items(.tag)[node] == .PtrTypeSentinel);
1058 const data = tree.nodes.items(.data)[node];
1059 return tree.fullPtrType(.{
1060 .main_token = tree.nodes.items(.main_token)[node],
1061 .align_node = 0,
1062 .sentinel = data.lhs,
1063 .bit_range_start = 0,
1064 .bit_range_end = 0,
1065 .child_type = data.rhs,
1066 });
1067 }
1068
1069 pub fn ptrType(tree: Tree, node: Node.Index) Full.PtrType {
1070 assert(tree.nodes.items(.tag)[node] == .PtrType);
1071 const data = tree.nodes.items(.data)[node];
1072 const extra = tree.extraData(data.lhs, Node.PtrType);
1073 return tree.fullPtrType(.{
1074 .main_token = tree.nodes.items(.main_token)[node],
1075 .align_node = extra.align_node,
1076 .sentinel = extra.sentinel,
1077 .bit_range_start = 0,
1078 .bit_range_end = 0,
1079 .child_type = data.rhs,
1080 });
1081 }
1082
1083 pub fn ptrTypeBitRange(tree: Tree, node: Node.Index) Full.PtrType {
1084 assert(tree.nodes.items(.tag)[node] == .PtrTypeBitRange);
1085 const data = tree.nodes.items(.data)[node];
1086 const extra = tree.extraData(data.lhs, Node.PtrTypeBitRange);
1087 return tree.fullPtrType(.{
1088 .main_token = tree.nodes.items(.main_token)[node],
1089 .align_node = extra.align_node,
1090 .sentinel = extra.sentinel,
1091 .bit_range_start = extra.bit_range_start,
1092 .bit_range_end = extra.bit_range_end,
1093 .child_type = data.rhs,
1094 });
1095 }
1096
1031 pub fn containerDeclTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) Full.ContainerDecl {1097 pub fn containerDeclTwo(tree: Tree, buffer: *[2]Node.Index, node: Node.Index) Full.ContainerDecl {
1032 assert(tree.nodes.items(.tag)[node] == .ContainerDeclTwo or1098 assert(tree.nodes.items(.tag)[node] == .ContainerDeclTwo or
1033 tree.nodes.items(.tag)[node] == .ContainerDeclTwoComma);1099 tree.nodes.items(.tag)[node] == .ContainerDeclTwoComma);
...@@ -1195,6 +1261,64 @@ pub const Tree = struct {...@@ -1195,6 +1261,64 @@ pub const Tree = struct {
1195 return result;1261 return result;
1196 }1262 }
11971263
1264 fn fullPtrType(tree: Tree, info: Full.PtrType.Ast) Full.PtrType {
1265 const token_tags = tree.tokens.items(.tag);
1266 // TODO: looks like stage1 isn't quite smart enough to handle enum
1267 // literals in some places here
1268 const Kind = Full.PtrType.Kind;
1269 const kind: Kind = switch (token_tags[info.main_token]) {
1270 .Asterisk => switch (token_tags[info.main_token + 1]) {
1271 .RBracket => .many,
1272 .Colon => .sentinel,
1273 .Identifier => if (token_tags[info.main_token - 1] == .LBracket) Kind.c else .one,
1274 else => .one,
1275 },
1276 .LBracket => switch (token_tags[info.main_token + 1]) {
1277 .RBracket => Kind.slice,
1278 .Colon => .slice_sentinel,
1279 else => unreachable,
1280 },
1281 else => unreachable,
1282 };
1283 var result: Full.PtrType = .{
1284 .kind = kind,
1285 .allowzero_token = null,
1286 .const_token = null,
1287 .volatile_token = null,
1288 .ast = info,
1289 };
1290 // We need to be careful that we don't iterate over any sub-expressions
1291 // here while looking for modifiers as that could result in false
1292 // positives. Therefore, start after a sentinel if there is one and
1293 // skip over any align node and bit range nodes.
1294 var i = if (kind == .sentinel or kind == .slice_sentinel) blk: {
1295 assert(info.sentinel != 0);
1296 break :blk tree.lastToken(info.sentinel) + 1;
1297 } else blk: {
1298 assert(info.sentinel == 0);
1299 break :blk info.main_token;
1300 };
1301 const end = tree.firstToken(info.child_type);
1302 while (i < end) : (i += 1) {
1303 switch (token_tags[i]) {
1304 .Keyword_allowzero => result.allowzero_token = i,
1305 .Keyword_const => result.const_token = i,
1306 .Keyword_volatile => result.volatile_token = i,
1307 .Keyword_align => {
1308 assert(info.align_node != 0);
1309 if (info.bit_range_end != 0) {
1310 assert(info.bit_range_start != 0);
1311 i = tree.lastToken(info.bit_range_end) + 1;
1312 } else {
1313 i = tree.lastToken(info.align_node) + 1;
1314 }
1315 },
1316 else => {},
1317 }
1318 }
1319 return result;
1320 }
1321
1198 fn fullContainerDecl(tree: Tree, info: Full.ContainerDecl.Ast) Full.ContainerDecl {1322 fn fullContainerDecl(tree: Tree, info: Full.ContainerDecl.Ast) Full.ContainerDecl {
1199 const token_tags = tree.tokens.items(.tag);1323 const token_tags = tree.tokens.items(.tag);
1200 var result: Full.ContainerDecl = .{1324 var result: Full.ContainerDecl = .{
...@@ -1302,6 +1426,32 @@ pub const Full = struct {...@@ -1302,6 +1426,32 @@ pub const Full = struct {
1302 };1426 };
1303 };1427 };
13041428
1429 pub const PtrType = struct {
1430 kind: Kind,
1431 allowzero_token: ?TokenIndex,
1432 const_token: ?TokenIndex,
1433 volatile_token: ?TokenIndex,
1434 ast: Ast,
1435
1436 pub const Kind = enum {
1437 one,
1438 many,
1439 sentinel,
1440 c,
1441 slice,
1442 slice_sentinel,
1443 };
1444
1445 pub const Ast = struct {
1446 main_token: TokenIndex,
1447 align_node: Node.Index,
1448 sentinel: Node.Index,
1449 bit_range_start: Node.Index,
1450 bit_range_end: Node.Index,
1451 child_type: Node.Index,
1452 };
1453 };
1454
1305 pub const ContainerDecl = struct {1455 pub const ContainerDecl = struct {
1306 layout_token: ?TokenIndex,1456 layout_token: ?TokenIndex,
1307 ast: Ast,1457 ast: Ast,
...@@ -1696,16 +1846,19 @@ pub const Node = struct {...@@ -1696,16 +1846,19 @@ pub const Node = struct {
1696 /// `[*]align(lhs) rhs`. lhs can be omitted.1846 /// `[*]align(lhs) rhs`. lhs can be omitted.
1697 /// `*align(lhs) rhs`. lhs can be omitted.1847 /// `*align(lhs) rhs`. lhs can be omitted.
1698 /// `[]rhs`.1848 /// `[]rhs`.
1849 /// main_token is the asterisk if a pointer or the lbrace if a slice
1699 PtrTypeAligned,1850 PtrTypeAligned,
1700 /// `[*:lhs]rhs`. lhs can be omitted.1851 /// `[*:lhs]rhs`. lhs can be omitted.
1701 /// `*rhs`.1852 /// `*rhs`.
1702 /// `[:lhs]rhs`.1853 /// `[:lhs]rhs`.
1854 /// main_token is the asterisk if a pointer or the lbrace if a slice
1703 PtrTypeSentinel,1855 PtrTypeSentinel,
1704 /// lhs is index into PtrType. rhs is the element type expression.1856 /// lhs is index into PtrType. rhs is the element type expression.
1857 /// main_token is the asterisk if a pointer or the lbrace if a slice
1705 PtrType,1858 PtrType,
1706 /// lhs is index into SliceType. rhs is the element type expression.1859 /// lhs is index into PtrTypeBitRange. rhs is the element type expression.
1707 /// Can be pointer or slice, depending on main_token.1860 /// main_token is the asterisk if a pointer or the lbrace if a slice
1708 SliceType,1861 PtrTypeBitRange,
1709 /// `lhs[rhs..]`1862 /// `lhs[rhs..]`
1710 /// main_token is the `[`.1863 /// main_token is the `[`.
1711 SliceOpen,1864 SliceOpen,
...@@ -1954,14 +2107,15 @@ pub const Node = struct {...@@ -1954,14 +2107,15 @@ pub const Node = struct {
1954 pub const PtrType = struct {2107 pub const PtrType = struct {
1955 sentinel: Index,2108 sentinel: Index,
1956 align_node: Index,2109 align_node: Index,
1957 bit_range_start: Index,
1958 bit_range_end: Index,
1959 };2110 };
19602111
1961 pub const SliceType = struct {2112 pub const PtrTypeBitRange = struct {
1962 sentinel: Index,2113 sentinel: Index,
1963 align_node: Index,2114 align_node: Index,
2115 bit_range_start: Index,
2116 bit_range_end: Index,
1964 };2117 };
2118
1965 pub const SubRange = struct {2119 pub const SubRange = struct {
1966 /// Index into sub_list.2120 /// Index into sub_list.
1967 start: Index,2121 start: Index,
lib/std/zig/parse.zig+10-10
...@@ -1618,10 +1618,10 @@ const Parser = struct {...@@ -1618,10 +1618,10 @@ const Parser = struct {
1618 });1618 });
1619 } else {1619 } else {
1620 return p.addNode(.{1620 return p.addNode(.{
1621 .tag = .PtrType,1621 .tag = .PtrTypeBitRange,
1622 .main_token = asterisk,1622 .main_token = asterisk,
1623 .data = .{1623 .data = .{
1624 .lhs = try p.addExtra(Node.PtrType{1624 .lhs = try p.addExtra(Node.PtrTypeBitRange{
1625 .sentinel = 0,1625 .sentinel = 0,
1626 .align_node = mods.align_node,1626 .align_node = mods.align_node,
1627 .bit_range_start = mods.bit_range_start,1627 .bit_range_start = mods.bit_range_start,
...@@ -1648,10 +1648,10 @@ const Parser = struct {...@@ -1648,10 +1648,10 @@ const Parser = struct {
1648 });1648 });
1649 } else {1649 } else {
1650 break :inner try p.addNode(.{1650 break :inner try p.addNode(.{
1651 .tag = .PtrType,1651 .tag = .PtrTypeBitRange,
1652 .main_token = asterisk,1652 .main_token = asterisk,
1653 .data = .{1653 .data = .{
1654 .lhs = try p.addExtra(Node.PtrType{1654 .lhs = try p.addExtra(Node.PtrTypeBitRange{
1655 .sentinel = 0,1655 .sentinel = 0,
1656 .align_node = mods.align_node,1656 .align_node = mods.align_node,
1657 .bit_range_start = mods.bit_range_start,1657 .bit_range_start = mods.bit_range_start,
...@@ -1713,10 +1713,10 @@ const Parser = struct {...@@ -1713,10 +1713,10 @@ const Parser = struct {
1713 });1713 });
1714 } else {1714 } else {
1715 return p.addNode(.{1715 return p.addNode(.{
1716 .tag = .SliceType,1716 .tag = .PtrType,
1717 .main_token = asterisk,1717 .main_token = asterisk,
1718 .data = .{1718 .data = .{
1719 .lhs = try p.addExtra(.{1719 .lhs = try p.addExtra(Node.PtrType{
1720 .sentinel = sentinel,1720 .sentinel = sentinel,
1721 .align_node = mods.align_node,1721 .align_node = mods.align_node,
1722 }),1722 }),
...@@ -1726,10 +1726,10 @@ const Parser = struct {...@@ -1726,10 +1726,10 @@ const Parser = struct {
1726 }1726 }
1727 } else {1727 } else {
1728 return p.addNode(.{1728 return p.addNode(.{
1729 .tag = .PtrType,1729 .tag = .PtrTypeBitRange,
1730 .main_token = asterisk,1730 .main_token = asterisk,
1731 .data = .{1731 .data = .{
1732 .lhs = try p.addExtra(.{1732 .lhs = try p.addExtra(Node.PtrTypeBitRange{
1733 .sentinel = sentinel,1733 .sentinel = sentinel,
1734 .align_node = mods.align_node,1734 .align_node = mods.align_node,
1735 .bit_range_start = mods.bit_range_start,1735 .bit_range_start = mods.bit_range_start,
...@@ -1777,10 +1777,10 @@ const Parser = struct {...@@ -1777,10 +1777,10 @@ const Parser = struct {
1777 });1777 });
1778 } else {1778 } else {
1779 return p.addNode(.{1779 return p.addNode(.{
1780 .tag = .SliceType,1780 .tag = .PtrType,
1781 .main_token = lbracket,1781 .main_token = lbracket,
1782 .data = .{1782 .data = .{
1783 .lhs = try p.addExtra(.{1783 .lhs = try p.addExtra(Node.PtrType{
1784 .sentinel = sentinel,1784 .sentinel = sentinel,
1785 .align_node = mods.align_node,1785 .align_node = mods.align_node,
1786 }),1786 }),
lib/std/zig/parser_test.zig+53-1
...@@ -345,7 +345,59 @@ test "zig fmt: builtin call with trailing comma" {...@@ -345,7 +345,59 @@ test "zig fmt: builtin call with trailing comma" {
345// \\345// \\
346// );346// );
347//}347//}
348//348
349test "zig fmt: pointer-to-one with modifiers" {
350 try testCanonical(
351 \\const x: *u32 = undefined;
352 \\const y: *allowzero align(8) const volatile u32 = undefined;
353 \\const z: *allowzero align(8:4:2) const volatile u32 = undefined;
354 \\
355 );
356}
357
358test "zig fmt: pointer-to-many with modifiers" {
359 try testCanonical(
360 \\const x: [*]u32 = undefined;
361 \\const y: [*]allowzero align(8) const volatile u32 = undefined;
362 \\const z: [*]allowzero align(8:4:2) const volatile u32 = undefined;
363 \\
364 );
365}
366
367test "zig fmt: sentinel pointer with modifiers" {
368 try testCanonical(
369 \\const x: [*:42]u32 = undefined;
370 \\const y: [*:42]allowzero align(8) const volatile u32 = undefined;
371 \\const y: [*:42]allowzero align(8:4:2) const volatile u32 = undefined;
372 \\
373 );
374}
375
376test "zig fmt: c pointer with modifiers" {
377 try testCanonical(
378 \\const x: [*c]u32 = undefined;
379 \\const y: [*c]allowzero align(8) const volatile u32 = undefined;
380 \\const z: [*c]allowzero align(8:4:2) const volatile u32 = undefined;
381 \\
382 );
383}
384
385test "zig fmt: slice with modifiers" {
386 try testCanonical(
387 \\const x: []u32 = undefined;
388 \\const y: []allowzero align(8) const volatile u32 = undefined;
389 \\
390 );
391}
392
393test "zig fmt: sentinel slice with modifiers" {
394 try testCanonical(
395 \\const x: [:42]u32 = undefined;
396 \\const y: [:42]allowzero align(8) const volatile u32 = undefined;
397 \\
398 );
399}
400
349//test "zig fmt: anon literal in array" {401//test "zig fmt: anon literal in array" {
350// try testCanonical(402// try testCanonical(
351// \\var arr: [2]Foo = .{403// \\var arr: [2]Foo = .{
lib/std/zig/render.zig+76-114
...@@ -370,120 +370,10 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -370,120 +370,10 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
370 .ArrayType => return renderArrayType(ais, tree, tree.arrayType(node), space),370 .ArrayType => return renderArrayType(ais, tree, tree.arrayType(node), space),
371 .ArrayTypeSentinel => return renderArrayType(ais, tree, tree.arrayTypeSentinel(node), space),371 .ArrayTypeSentinel => return renderArrayType(ais, tree, tree.arrayTypeSentinel(node), space),
372372
373 .PtrType => unreachable, // TODO373 .PtrTypeAligned => return renderPtrType(ais, tree, tree.ptrTypeAligned(node), space),
374 .PtrTypeAligned => unreachable, // TODO374 .PtrTypeSentinel => return renderPtrType(ais, tree, tree.ptrTypeSentinel(node), space),
375 .PtrTypeSentinel => unreachable, // TODO375 .PtrType => return renderPtrType(ais, tree, tree.ptrType(node), space),
376 //.PtrType => {376 .PtrTypeBitRange => return renderPtrType(ais, tree, tree.ptrTypeBitRange(node), space),
377 // const ptr_type = @fieldParentPtr(ast.Node.PtrType, "base", base);
378 // const op_tok_id = tree.token_tags[ptr_type.op_token];
379 // switch (op_tok_id) {
380 // .Asterisk, .AsteriskAsterisk => try ais.writer().writeByte('*'),
381 // .LBracket => if (tree.token_tags[ptr_type.op_token + 2] == .Identifier)
382 // try ais.writer().writeAll("[*c")
383 // else
384 // try ais.writer().writeAll("[*"),
385 // else => unreachable,
386 // }
387 // if (ptr_type.ptr_info.sentinel) |sentinel| {
388 // const colon_token = tree.prevToken(sentinel.firstToken());
389 // try renderToken(ais, tree, colon_token, Space.None); // :
390 // const sentinel_space = switch (op_tok_id) {
391 // .LBracket => Space.None,
392 // else => Space.Space,
393 // };
394 // try renderExpression(ais, tree, sentinel, sentinel_space);
395 // }
396 // switch (op_tok_id) {
397 // .Asterisk, .AsteriskAsterisk => {},
398 // .LBracket => try ais.writer().writeByte(']'),
399 // else => unreachable,
400 // }
401 // if (ptr_type.ptr_info.allowzero_token) |allowzero_token| {
402 // try renderToken(ais, tree, allowzero_token, Space.Space); // allowzero
403 // }
404 // if (ptr_type.ptr_info.align_info) |align_info| {
405 // const lparen_token = tree.prevToken(align_info.node.firstToken());
406 // const align_token = tree.prevToken(lparen_token);
407
408 // try renderToken(ais, tree, align_token, Space.None); // align
409 // try renderToken(ais, tree, lparen_token, Space.None); // (
410
411 // try renderExpression(ais, tree, align_info.node, Space.None);
412
413 // if (align_info.bit_range) |bit_range| {
414 // const colon1 = tree.prevToken(bit_range.start.firstToken());
415 // const colon2 = tree.prevToken(bit_range.end.firstToken());
416
417 // try renderToken(ais, tree, colon1, Space.None); // :
418 // try renderExpression(ais, tree, bit_range.start, Space.None);
419 // try renderToken(ais, tree, colon2, Space.None); // :
420 // try renderExpression(ais, tree, bit_range.end, Space.None);
421
422 // const rparen_token = tree.nextToken(bit_range.end.lastToken());
423 // try renderToken(ais, tree, rparen_token, Space.Space); // )
424 // } else {
425 // const rparen_token = tree.nextToken(align_info.node.lastToken());
426 // try renderToken(ais, tree, rparen_token, Space.Space); // )
427 // }
428 // }
429 // if (ptr_type.ptr_info.const_token) |const_token| {
430 // try renderToken(ais, tree, const_token, Space.Space); // const
431 // }
432 // if (ptr_type.ptr_info.volatile_token) |volatile_token| {
433 // try renderToken(ais, tree, volatile_token, Space.Space); // volatile
434 // }
435 // return renderExpression(ais, tree, ptr_type.rhs, space);
436 //},
437
438 .SliceType => unreachable, // TODO
439 //.SliceType => {
440 // const slice_type = @fieldParentPtr(ast.Node.SliceType, "base", base);
441 // try renderToken(ais, tree, slice_type.op_token, Space.None); // [
442 // if (slice_type.ptr_info.sentinel) |sentinel| {
443 // const colon_token = tree.prevToken(sentinel.firstToken());
444 // try renderToken(ais, tree, colon_token, Space.None); // :
445 // try renderExpression(ais, tree, sentinel, Space.None);
446 // try renderToken(ais, tree, tree.nextToken(sentinel.lastToken()), Space.None); // ]
447 // } else {
448 // try renderToken(ais, tree, tree.nextToken(slice_type.op_token), Space.None); // ]
449 // }
450
451 // if (slice_type.ptr_info.allowzero_token) |allowzero_token| {
452 // try renderToken(ais, tree, allowzero_token, Space.Space); // allowzero
453 // }
454 // if (slice_type.ptr_info.align_info) |align_info| {
455 // const lparen_token = tree.prevToken(align_info.node.firstToken());
456 // const align_token = tree.prevToken(lparen_token);
457
458 // try renderToken(ais, tree, align_token, Space.None); // align
459 // try renderToken(ais, tree, lparen_token, Space.None); // (
460
461 // try renderExpression(ais, tree, align_info.node, Space.None);
462
463 // if (align_info.bit_range) |bit_range| {
464 // const colon1 = tree.prevToken(bit_range.start.firstToken());
465 // const colon2 = tree.prevToken(bit_range.end.firstToken());
466
467 // try renderToken(ais, tree, colon1, Space.None); // :
468 // try renderExpression(ais, tree, bit_range.start, Space.None);
469 // try renderToken(ais, tree, colon2, Space.None); // :
470 // try renderExpression(ais, tree, bit_range.end, Space.None);
471
472 // const rparen_token = tree.nextToken(bit_range.end.lastToken());
473 // try renderToken(ais, tree, rparen_token, Space.Space); // )
474 // } else {
475 // const rparen_token = tree.nextToken(align_info.node.lastToken());
476 // try renderToken(ais, tree, rparen_token, Space.Space); // )
477 // }
478 // }
479 // if (slice_type.ptr_info.const_token) |const_token| {
480 // try renderToken(ais, tree, const_token, Space.Space);
481 // }
482 // if (slice_type.ptr_info.volatile_token) |volatile_token| {
483 // try renderToken(ais, tree, volatile_token, Space.Space);
484 // }
485 // return renderExpression(ais, tree, slice_type.rhs, space);
486 //},
487377
488 .ArrayInitOne => {378 .ArrayInitOne => {
489 var elements: [1]ast.Node.Index = undefined;379 var elements: [1]ast.Node.Index = undefined;
...@@ -1180,6 +1070,78 @@ fn renderArrayType(...@@ -1180,6 +1070,78 @@ fn renderArrayType(
1180 return renderExpression(ais, tree, array_type.ast.elem_type, space);1070 return renderExpression(ais, tree, array_type.ast.elem_type, space);
1181}1071}
11821072
1073fn renderPtrType(
1074 ais: *Ais,
1075 tree: ast.Tree,
1076 ptr_type: ast.Full.PtrType,
1077 space: Space,
1078) Error!void {
1079 switch (ptr_type.kind) {
1080 .one => {
1081 try renderToken(ais, tree, ptr_type.ast.main_token, .None); // asterisk
1082 },
1083 .many => {
1084 try renderToken(ais, tree, ptr_type.ast.main_token - 1, .None); // lbracket
1085 try renderToken(ais, tree, ptr_type.ast.main_token, .None); // asterisk
1086 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .None); // rbracket
1087 },
1088 .sentinel => {
1089 try renderToken(ais, tree, ptr_type.ast.main_token - 1, .None); // lbracket
1090 try renderToken(ais, tree, ptr_type.ast.main_token, .None); // asterisk
1091 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .None); // colon
1092 try renderExpression(ais, tree, ptr_type.ast.sentinel, .None);
1093 try renderToken(ais, tree, tree.lastToken(ptr_type.ast.sentinel) + 1, .None); // rbracket
1094 },
1095 .c => {
1096 try renderToken(ais, tree, ptr_type.ast.main_token - 1, .None); // lbracket
1097 try renderToken(ais, tree, ptr_type.ast.main_token, .None); // asterisk
1098 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .None); // c
1099 try renderToken(ais, tree, ptr_type.ast.main_token + 2, .None); // rbracket
1100 },
1101 .slice => {
1102 try renderToken(ais, tree, ptr_type.ast.main_token, .None); // lbracket
1103 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .None); // rbracket
1104 },
1105 .slice_sentinel => {
1106 try renderToken(ais, tree, ptr_type.ast.main_token, .None); // lbracket
1107 try renderToken(ais, tree, ptr_type.ast.main_token + 1, .None); // colon
1108 try renderExpression(ais, tree, ptr_type.ast.sentinel, .None);
1109 try renderToken(ais, tree, tree.lastToken(ptr_type.ast.sentinel) + 1, .None); // rbracket
1110 },
1111 }
1112
1113 if (ptr_type.allowzero_token) |allowzero_token| {
1114 try renderToken(ais, tree, allowzero_token, .Space);
1115 }
1116
1117 if (ptr_type.ast.align_node != 0) {
1118 const align_first = tree.firstToken(ptr_type.ast.align_node);
1119 try renderToken(ais, tree, align_first - 2, .None); // align
1120 try renderToken(ais, tree, align_first - 1, .None); // lparen
1121 try renderExpression(ais, tree, ptr_type.ast.align_node, .None);
1122 if (ptr_type.ast.bit_range_start != 0) {
1123 assert(ptr_type.ast.bit_range_end != 0);
1124 try renderToken(ais, tree, tree.firstToken(ptr_type.ast.bit_range_start) - 1, .None); // colon
1125 try renderExpression(ais, tree, ptr_type.ast.bit_range_start, .None);
1126 try renderToken(ais, tree, tree.firstToken(ptr_type.ast.bit_range_end) - 1, .None); // colon
1127 try renderExpression(ais, tree, ptr_type.ast.bit_range_end, .None);
1128 try renderToken(ais, tree, tree.lastToken(ptr_type.ast.bit_range_end) + 1, .Space); // rparen
1129 } else {
1130 try renderToken(ais, tree, tree.lastToken(ptr_type.ast.align_node) + 1, .Space); // rparen
1131 }
1132 }
1133
1134 if (ptr_type.const_token) |const_token| {
1135 try renderToken(ais, tree, const_token, .Space);
1136 }
1137
1138 if (ptr_type.volatile_token) |volatile_token| {
1139 try renderToken(ais, tree, volatile_token, .Space);
1140 }
1141
1142 try renderExpression(ais, tree, ptr_type.ast.child_type, space);
1143}
1144
1183fn renderAsmOutput(1145fn renderAsmOutput(
1184 allocator: *mem.Allocator,1146 allocator: *mem.Allocator,
1185 ais: *Ais,1147 ais: *Ais,