authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-03 22:12:11-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-03 22:12:11-07:00
log725adf833289e0a1b0826c6a774cea5283cec744
tree175d0b05f09f90129ebc3923e5d945dc81fd7b45
parentf5279cbada9199023049abe02dbf65a894ba317c

zig fmt: builtin calls and array access


4 files changed, 308 insertions(+), 196 deletions(-)

lib/std/zig/ast.zig+116-83
...@@ -319,35 +319,54 @@ pub const Tree = struct {...@@ -319,35 +319,54 @@ pub const Tree = struct {
319 }319 }
320 },320 },
321321
322 .GlobalVarDecl => unreachable,322 .GlobalVarDecl,
323 .LocalVarDecl => unreachable,323 .LocalVarDecl,
324 .SimpleVarDecl => unreachable,324 .SimpleVarDecl,
325 .AlignedVarDecl => unreachable,325 .AlignedVarDecl,
326 .ArrayType => unreachable,326 => {
327 .ArrayTypeSentinel => unreachable,327 var i = main_tokens[n]; // mut token
328 .PtrTypeAligned => unreachable,328 while (i > 0) {
329 .PtrTypeSentinel => unreachable,329 i -= 1;
330 .PtrType => unreachable,330 switch (token_tags[i]) {
331 .SliceType => unreachable,331 .Keyword_extern,
332 .StructInit => unreachable,332 .Keyword_export,
333 .SwitchCaseMulti => unreachable,333 .Keyword_comptime,
334 .WhileSimple => unreachable,334 .Keyword_pub,
335 .WhileCont => unreachable,335 .Keyword_threadlocal,
336 .While => unreachable,336 .StringLiteral,
337 .ForSimple => unreachable,337 => continue,
338 .For => unreachable,338
339 .FnProtoSimple => unreachable,339 else => return i + 1,
340 .FnProtoSimpleMulti => unreachable,340 }
341 .FnProtoOne => unreachable,341 }
342 .FnProto => unreachable,342 return i;
343 .ContainerDecl => unreachable,343 },
344 .ContainerDeclArg => unreachable,344
345 .TaggedUnion => unreachable,345 .ArrayType => unreachable, // TODO
346 .TaggedUnionEnumTag => unreachable,346 .ArrayTypeSentinel => unreachable, // TODO
347 .AsmOutput => unreachable,347 .PtrTypeAligned => unreachable, // TODO
348 .AsmInput => unreachable,348 .PtrTypeSentinel => unreachable, // TODO
349 .ErrorValue => unreachable,349 .PtrType => unreachable, // TODO
350 .ErrorUnion => unreachable,350 .SliceType => unreachable, // TODO
351 .StructInit => unreachable, // TODO
352 .SwitchCaseMulti => unreachable, // TODO
353 .WhileSimple => unreachable, // TODO
354 .WhileCont => unreachable, // TODO
355 .While => unreachable, // TODO
356 .ForSimple => unreachable, // TODO
357 .For => unreachable, // TODO
358 .FnProtoSimple => unreachable, // TODO
359 .FnProtoSimpleMulti => unreachable, // TODO
360 .FnProtoOne => unreachable, // TODO
361 .FnProto => unreachable, // TODO
362 .ContainerDecl => unreachable, // TODO
363 .ContainerDeclArg => unreachable, // TODO
364 .TaggedUnion => unreachable, // TODO
365 .TaggedUnionEnumTag => unreachable, // TODO
366 .AsmOutput => unreachable, // TODO
367 .AsmInput => unreachable, // TODO
368 .ErrorValue => unreachable, // TODO
369 .ErrorUnion => unreachable, // TODO
351 };370 };
352 }371 }
353372
...@@ -445,7 +464,9 @@ pub const Tree = struct {...@@ -445,7 +464,9 @@ pub const Tree = struct {
445 .Identifier,464 .Identifier,
446 => return main_tokens[n] + end_offset,465 => return main_tokens[n] + end_offset,
447466
448 .Call => {467 .Call,
468 .BuiltinCall,
469 => {
449 end_offset += 1; // for the `)`470 end_offset += 1; // for the `)`
450 const params = tree.extraData(datas[n].rhs, Node.SubRange);471 const params = tree.extraData(datas[n].rhs, Node.SubRange);
451 if (params.end - params.start == 0) {472 if (params.end - params.start == 0) {
...@@ -453,69 +474,81 @@ pub const Tree = struct {...@@ -453,69 +474,81 @@ pub const Tree = struct {
453 }474 }
454 n = tree.extra_data[params.end - 1]; // last parameter475 n = tree.extra_data[params.end - 1]; // last parameter
455 },476 },
456 .CallOne => {477 .CallOne,
457 end_offset += 1; // for the `)`478 .ArrayAccess,
479 => {
480 end_offset += 1; // for the rparen/rbracket
458 if (datas[n].rhs == 0) {481 if (datas[n].rhs == 0) {
459 return main_tokens[n] + end_offset;482 return main_tokens[n] + end_offset;
460 }483 }
461 n = datas[n].rhs;484 n = datas[n].rhs;
462 },485 },
463486
487 .BuiltinCallTwo => {
488 end_offset += 1; // for the rparen
489 if (datas[n].rhs == 0) {
490 if (datas[n].lhs == 0) {
491 return main_tokens[n] + end_offset;
492 } else {
493 n = datas[n].lhs;
494 }
495 } else {
496 n = datas[n].rhs;
497 }
498 },
499
464 .ContainerFieldInit => unreachable,500 .ContainerFieldInit => unreachable,
465 .ContainerFieldAlign => unreachable,501 .ContainerFieldAlign => unreachable,
466 .ContainerField => unreachable,502 .ContainerField => unreachable,
467503
468 .ArrayInitDotTwo => unreachable,504 .ArrayInitDotTwo => unreachable, // TODO
469 .ArrayInitDot => unreachable,505 .ArrayInitDot => unreachable, // TODO
470 .StructInitDotTwo => unreachable,506 .StructInitDotTwo => unreachable, // TODO
471 .StructInitDot => unreachable,507 .StructInitDot => unreachable, // TODO
472 .Switch => unreachable,508 .Switch => unreachable, // TODO
473 .If => unreachable,509 .If => unreachable, // TODO
474 .Continue => unreachable,510 .Continue => unreachable, // TODO
475 .EnumLiteral => unreachable,511 .EnumLiteral => unreachable, // TODO
476 .BuiltinCallTwo => unreachable,512 .ErrorSetDecl => unreachable, // TODO
477 .BuiltinCall => unreachable,513 .Block => unreachable, // TODO
478 .ErrorSetDecl => unreachable,514 .AsmSimple => unreachable, // TODO
479 .Block => unreachable,515 .Asm => unreachable, // TODO
480 .AsmSimple => unreachable,516 .SliceOpen => unreachable, // TODO
481 .Asm => unreachable,517 .Slice => unreachable, // TODO
482 .SliceOpen => unreachable,518 .Deref => unreachable, // TODO
483 .Slice => unreachable,519 .ArrayInitOne => unreachable, // TODO
484 .Deref => unreachable,520 .ArrayInit => unreachable, // TODO
485 .ArrayAccess => unreachable,521 .StructInitOne => unreachable, // TODO
486 .ArrayInitOne => unreachable,522 .SwitchCaseOne => unreachable, // TODO
487 .ArrayInit => unreachable,523 .SwitchRange => unreachable, // TODO
488 .StructInitOne => unreachable,524 .FnDecl => unreachable, // TODO
489 .SwitchCaseOne => unreachable,525 .GlobalVarDecl => unreachable, // TODO
490 .SwitchRange => unreachable,526 .LocalVarDecl => unreachable, // TODO
491 .FnDecl => unreachable,527 .SimpleVarDecl => unreachable, // TODO
492 .GlobalVarDecl => unreachable,528 .AlignedVarDecl => unreachable, // TODO
493 .LocalVarDecl => unreachable,529 .ArrayType => unreachable, // TODO
494 .SimpleVarDecl => unreachable,530 .ArrayTypeSentinel => unreachable, // TODO
495 .AlignedVarDecl => unreachable,531 .PtrTypeAligned => unreachable, // TODO
496 .ArrayType => unreachable,532 .PtrTypeSentinel => unreachable, // TODO
497 .ArrayTypeSentinel => unreachable,533 .PtrType => unreachable, // TODO
498 .PtrTypeAligned => unreachable,534 .SliceType => unreachable, // TODO
499 .PtrTypeSentinel => unreachable,535 .StructInit => unreachable, // TODO
500 .PtrType => unreachable,536 .SwitchCaseMulti => unreachable, // TODO
501 .SliceType => unreachable,537 .WhileCont => unreachable, // TODO
502 .StructInit => unreachable,538 .While => unreachable, // TODO
503 .SwitchCaseMulti => unreachable,539 .ForSimple => unreachable, // TODO
504 .WhileCont => unreachable,540 .For => unreachable, // TODO
505 .While => unreachable,541 .FnProtoSimple => unreachable, // TODO
506 .ForSimple => unreachable,542 .FnProtoSimpleMulti => unreachable, // TODO
507 .For => unreachable,543 .FnProtoOne => unreachable, // TODO
508 .FnProtoSimple => unreachable,544 .FnProto => unreachable, // TODO
509 .FnProtoSimpleMulti => unreachable,545 .ContainerDecl => unreachable, // TODO
510 .FnProtoOne => unreachable,546 .ContainerDeclArg => unreachable, // TODO
511 .FnProto => unreachable,547 .TaggedUnion => unreachable, // TODO
512 .ContainerDecl => unreachable,548 .TaggedUnionEnumTag => unreachable, // TODO
513 .ContainerDeclArg => unreachable,549 .AsmOutput => unreachable, // TODO
514 .TaggedUnion => unreachable,550 .AsmInput => unreachable, // TODO
515 .TaggedUnionEnumTag => unreachable,551 .ErrorValue => unreachable, // TODO
516 .AsmOutput => unreachable,
517 .AsmInput => unreachable,
518 .ErrorValue => unreachable,
519 };552 };
520 }553 }
521554
lib/std/zig/parse.zig+100-5
...@@ -3483,9 +3483,8 @@ const Parser = struct {...@@ -3483,9 +3483,8 @@ const Parser = struct {
3483 /// ExprList <- (Expr COMMA)* Expr?3483 /// ExprList <- (Expr COMMA)* Expr?
3484 /// TODO detect when we can emit BuiltinCallTwo instead of BuiltinCall.3484 /// TODO detect when we can emit BuiltinCallTwo instead of BuiltinCall.
3485 fn parseBuiltinCall(p: *Parser) !Node.Index {3485 fn parseBuiltinCall(p: *Parser) !Node.Index {
3486 const builtin_token = p.eatToken(.Builtin) orelse return null_node;3486 const builtin_token = p.assertToken(.Builtin);
34873487 _ = (try p.expectTokenRecoverable(.LParen)) orelse {
3488 const lparen = (try p.expectTokenRecoverable(.LParen)) orelse {
3489 try p.warn(.{3488 try p.warn(.{
3490 .ExpectedParamList = .{ .token = p.tok_i },3489 .ExpectedParamList = .{ .token = p.tok_i },
3491 });3490 });
...@@ -3499,8 +3498,104 @@ const Parser = struct {...@@ -3499,8 +3498,104 @@ const Parser = struct {
3499 },3498 },
3500 });3499 });
3501 };3500 };
3502 const params = try ListParseFn(parseExpr)(p);3501 if (p.eatToken(.RParen)) |_| {
3503 _ = try p.expectToken(.RParen);3502 return p.addNode(.{
3503 .tag = .BuiltinCallTwo,
3504 .main_token = builtin_token,
3505 .data = .{
3506 .lhs = 0,
3507 .rhs = 0,
3508 },
3509 });
3510 }
3511 const param_one = try p.expectExpr();
3512 switch (p.token_tags[p.nextToken()]) {
3513 .Comma => {
3514 if (p.eatToken(.RParen)) |_| {
3515 return p.addNode(.{
3516 .tag = .BuiltinCallTwo,
3517 .main_token = builtin_token,
3518 .data = .{
3519 .lhs = param_one,
3520 .rhs = 0,
3521 },
3522 });
3523 }
3524 },
3525 .RParen => return p.addNode(.{
3526 .tag = .BuiltinCallTwo,
3527 .main_token = builtin_token,
3528 .data = .{
3529 .lhs = param_one,
3530 .rhs = 0,
3531 },
3532 }),
3533 else => {
3534 // This is likely just a missing comma;
3535 // give an error but continue parsing this list.
3536 p.tok_i -= 1;
3537 try p.warn(.{
3538 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .Comma },
3539 });
3540 },
3541 }
3542 const param_two = try p.expectExpr();
3543 switch (p.token_tags[p.nextToken()]) {
3544 .Comma => {
3545 if (p.eatToken(.RParen)) |_| {
3546 return p.addNode(.{
3547 .tag = .BuiltinCallTwo,
3548 .main_token = builtin_token,
3549 .data = .{
3550 .lhs = param_one,
3551 .rhs = param_two,
3552 },
3553 });
3554 }
3555 },
3556 .RParen => return p.addNode(.{
3557 .tag = .BuiltinCallTwo,
3558 .main_token = builtin_token,
3559 .data = .{
3560 .lhs = param_one,
3561 .rhs = param_two,
3562 },
3563 }),
3564 else => {
3565 // This is likely just a missing comma;
3566 // give an error but continue parsing this list.
3567 p.tok_i -= 1;
3568 try p.warn(.{
3569 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .Comma },
3570 });
3571 },
3572 }
3573
3574 var list = std.ArrayList(Node.Index).init(p.gpa);
3575 defer list.deinit();
3576
3577 try list.appendSlice(&[_]Node.Index{ param_one, param_two });
3578
3579 while (true) {
3580 const param = try p.expectExpr();
3581 try list.append(param);
3582 switch (p.token_tags[p.nextToken()]) {
3583 .Comma => {
3584 if (p.eatToken(.RParen)) |_| break;
3585 continue;
3586 },
3587 .RParen => break,
3588 else => {
3589 // This is likely just a missing comma;
3590 // give an error but continue parsing this list.
3591 p.tok_i -= 1;
3592 try p.warn(.{
3593 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .Comma },
3594 });
3595 },
3596 }
3597 }
3598 const params = try p.listToSpan(list.items);
3504 return p.addNode(.{3599 return p.addNode(.{
3505 .tag = .BuiltinCall,3600 .tag = .BuiltinCall,
3506 .main_token = builtin_token,3601 .main_token = builtin_token,
lib/std/zig/parser_test.zig+15-15
...@@ -21,21 +21,21 @@ test "zig fmt: two spaced line comments before decl" {...@@ -21,21 +21,21 @@ test "zig fmt: two spaced line comments before decl" {
21 );21 );
22}22}
2323
24//test "zig fmt: respect line breaks after var declarations" {24test "zig fmt: respect line breaks after var declarations" {
25// try testCanonical(25 try testCanonical(
26// \\const crc =26 \\const crc =
27// \\ lookup_tables[0][p[7]] ^27 \\ lookup_tables[0][p[7]] ^
28// \\ lookup_tables[1][p[6]] ^28 \\ lookup_tables[1][p[6]] ^
29// \\ lookup_tables[2][p[5]] ^29 \\ lookup_tables[2][p[5]] ^
30// \\ lookup_tables[3][p[4]] ^30 \\ lookup_tables[3][p[4]] ^
31// \\ lookup_tables[4][@truncate(u8, self.crc >> 24)] ^31 \\ lookup_tables[4][@truncate(u8, self.crc >> 24)] ^
32// \\ lookup_tables[5][@truncate(u8, self.crc >> 16)] ^32 \\ lookup_tables[5][@truncate(u8, self.crc >> 16)] ^
33// \\ lookup_tables[6][@truncate(u8, self.crc >> 8)] ^33 \\ lookup_tables[6][@truncate(u8, self.crc >> 8)] ^
34// \\ lookup_tables[7][@truncate(u8, self.crc >> 0)];34 \\ lookup_tables[7][@truncate(u8, self.crc >> 0)];
35// \\35 \\
36// );36 );
37//}37}
38//38
39//test "zig fmt: multiline string mixed with comments" {39//test "zig fmt: multiline string mixed with comments" {
40// try testCanonical(40// try testCanonical(
41// \\const s1 =41// \\const s1 =
lib/std/zig/render.zig+77-93
...@@ -308,7 +308,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -308,7 +308,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
308 const field_access = datas[node];308 const field_access = datas[node];
309 try renderExpression(ais, tree, field_access.lhs, .None);309 try renderExpression(ais, tree, field_access.lhs, .None);
310 try renderToken(ais, tree, main_tokens[node], .None);310 try renderToken(ais, tree, main_tokens[node], .None);
311 return renderToken(ais, tree, field_access.rhs, .None);311 return renderToken(ais, tree, field_access.rhs, space);
312 },312 },
313313
314 .ErrorUnion,314 .ErrorUnion,
...@@ -362,18 +362,15 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -362,18 +362,15 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
362 => {362 => {
363 const infix = datas[node];363 const infix = datas[node];
364 try renderExpression(ais, tree, infix.lhs, .Space);364 try renderExpression(ais, tree, infix.lhs, .Space);
365
366 const op_token = main_tokens[node];365 const op_token = main_tokens[node];
367 const after_op_space: Space = if (tree.tokensOnSameLine(op_token, op_token + 1))366 if (tree.tokensOnSameLine(op_token, op_token + 1)) {
368 .Space367 try renderToken(ais, tree, op_token, .Space);
369 else368 } else {
370 .Newline;
371 {
372 ais.pushIndent();369 ais.pushIndent();
373 try renderToken(ais, tree, op_token, after_op_space);370 try renderToken(ais, tree, op_token, .Newline);
374 ais.popIndent();371 ais.popIndent();
372 ais.pushIndentOneShot();
375 }373 }
376 ais.pushIndentOneShot();
377 return renderExpression(ais, tree, infix.rhs, space);374 return renderExpression(ais, tree, infix.rhs, space);
378 },375 },
379376
...@@ -955,28 +952,15 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -955,28 +952,15 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
955 return renderToken(ais, tree, after_last_param_tok, space); // )952 return renderToken(ais, tree, after_last_param_tok, space); // )
956 },953 },
957954
958 .ArrayAccess => unreachable, // TODO955 .ArrayAccess => {
959 //.ArrayAccess => {956 const suffix = datas[node];
960 // const suffix_op = base.castTag(.ArrayAccess).?;957 const lbracket = tree.firstToken(suffix.rhs) - 1;
961958 const rbracket = tree.lastToken(suffix.rhs) + 1;
962 // const lbracket = tree.nextToken(suffix_op.lhs.lastToken());959 try renderExpression(ais, tree, suffix.lhs, .None);
963 // const rbracket = tree.nextToken(suffix_op.index_expr.lastToken());960 try renderToken(ais, tree, lbracket, .None); // [
964961 try renderExpression(ais, tree, suffix.rhs, .None);
965 // try renderExpression(ais, tree, suffix_op.lhs, Space.None);962 return renderToken(ais, tree, rbracket, space); // ]
966 // try renderToken(ais, tree, lbracket, Space.None); // [963 },
967
968 // const starts_with_comment = tree.token_tags[lbracket + 1] == .LineComment;
969 // const ends_with_comment = tree.token_tags[rbracket - 1] == .LineComment;
970 // {
971 // const new_space = if (ends_with_comment) Space.Newline else Space.None;
972
973 // ais.pushIndent();
974 // defer ais.popIndent();
975 // try renderExpression(ais, tree, suffix_op.index_expr, new_space);
976 // }
977 // if (starts_with_comment) try ais.maybeInsertNewline();
978 // return renderToken(ais, tree, rbracket, space); // ]
979 //},
980964
981 .Slice => unreachable, // TODO965 .Slice => unreachable, // TODO
982 .SliceOpen => unreachable, // TODO966 .SliceOpen => unreachable, // TODO
...@@ -1278,68 +1262,22 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac...@@ -1278,68 +1262,22 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
1278 // }1262 // }
1279 //},1263 //},
12801264
1281 .BuiltinCall => unreachable, // TODO1265 .BuiltinCallTwo => {
1282 .BuiltinCallTwo => unreachable, // TODO1266 if (datas[node].lhs == 0) {
1283 //.BuiltinCall => {1267 const params = [_]ast.Node.Index{};
1284 // const builtin_call = @fieldParentPtr(ast.Node.BuiltinCall, "base", base);1268 return renderBuiltinCall(ais, tree, main_tokens[node], &params, space);
12851269 } else if (datas[node].rhs == 0) {
1286 // // TODO remove after 0.7.0 release1270 const params = [_]ast.Node.Index{datas[node].lhs};
1287 // if (mem.eql(u8, tree.tokenSlice(builtin_call.builtin_token), "@OpaqueType"))1271 return renderBuiltinCall(ais, tree, main_tokens[node], &params, space);
1288 // return ais.writer().writeAll("opaque {}");1272 } else {
12891273 const params = [_]ast.Node.Index{ datas[node].lhs, datas[node].rhs };
1290 // // TODO remove after 0.7.0 release1274 return renderBuiltinCall(ais, tree, main_tokens[node], &params, space);
1291 // {1275 }
1292 // const params = builtin_call.paramsConst();1276 },
1293 // if (mem.eql(u8, tree.tokenSlice(builtin_call.builtin_token), "@Type") and1277 .BuiltinCall => {
1294 // params.len == 1)1278 const params = tree.extra_data[datas[node].lhs..datas[node].rhs];
1295 // {1279 return renderBuiltinCall(ais, tree, main_tokens[node], params, space);
1296 // if (params[0].castTag(.EnumLiteral)) |enum_literal|1280 },
1297 // if (mem.eql(u8, tree.tokenSlice(enum_literal.name), "Opaque"))
1298 // return ais.writer().writeAll("opaque {}");
1299 // }
1300 // }
1301
1302 // try renderToken(ais, tree, builtin_call.builtin_token, Space.None); // @name
1303
1304 // const src_params_trailing_comma = blk: {
1305 // if (builtin_call.params_len == 0) break :blk false;
1306 // const last_node = builtin_call.params()[builtin_call.params_len - 1];
1307 // const maybe_comma = tree.nextToken(last_node.lastToken());
1308 // break :blk tree.token_tags[maybe_comma] == .Comma;
1309 // };
1310
1311 // const lparen = tree.nextToken(builtin_call.builtin_token);
1312
1313 // if (!src_params_trailing_comma) {
1314 // try renderToken(ais, tree, lparen, Space.None); // (
1315
1316 // // render all on one line, no trailing comma
1317 // const params = builtin_call.params();
1318 // for (params) |param_node, i| {
1319 // const maybe_comment = param_node.firstToken() - 1;
1320 // if (param_node.*.tag == .MultilineStringLiteral or tree.token_tags[maybe_comment] == .LineComment) {
1321 // ais.pushIndentOneShot();
1322 // }
1323 // try renderExpression(ais, tree, param_node, Space.None);
1324
1325 // if (i + 1 < params.len) {
1326 // const comma_token = tree.nextToken(param_node.lastToken());
1327 // try renderToken(ais, tree, comma_token, Space.Space); // ,
1328 // }
1329 // }
1330 // } else {
1331 // // one param per line
1332 // ais.pushIndent();
1333 // defer ais.popIndent();
1334 // try renderToken(ais, tree, lparen, Space.Newline); // (
1335
1336 // for (builtin_call.params()) |param_node| {
1337 // try renderExpression(ais, tree, param_node, Space.Comma);
1338 // }
1339 // }
1340
1341 // return renderToken(ais, tree, builtin_call.rparen_token, space); // )
1342 //},
13431281
1344 .FnProtoSimple => unreachable, // TODO1282 .FnProtoSimple => unreachable, // TODO
1345 .FnProtoSimpleMulti => unreachable, // TODO1283 .FnProtoSimpleMulti => unreachable, // TODO
...@@ -2221,6 +2159,52 @@ fn renderParamDecl(...@@ -2221,6 +2159,52 @@ fn renderParamDecl(
2221 }2159 }
2222}2160}
22232161
2162fn renderBuiltinCall(
2163 ais: *Ais,
2164 tree: ast.Tree,
2165 builtin_token: ast.TokenIndex,
2166 params: []const ast.Node.Index,
2167 space: Space,
2168) Error!void {
2169 const token_tags = tree.tokens.items(.tag);
2170
2171 try renderToken(ais, tree, builtin_token, .None); // @name
2172
2173 if (params.len == 0) {
2174 try renderToken(ais, tree, builtin_token + 1, .None); // (
2175 return renderToken(ais, tree, builtin_token + 2, space); // )
2176 }
2177
2178 const last_param = params[params.len - 1];
2179 const after_last_param_token = tree.lastToken(last_param) + 1;
2180
2181 if (token_tags[after_last_param_token] != .Comma) {
2182 // Render all on one line, no trailing comma.
2183 try renderToken(ais, tree, builtin_token + 1, .None); // (
2184
2185 for (params) |param_node, i| {
2186 try renderExpression(ais, tree, param_node, .None);
2187
2188 if (i + 1 < params.len) {
2189 const comma_token = tree.lastToken(param_node) + 1;
2190 try renderToken(ais, tree, comma_token, .Space); // ,
2191 }
2192 }
2193 return renderToken(ais, tree, after_last_param_token, space); // )
2194 } else {
2195 // Render one param per line.
2196 ais.pushIndent();
2197 try renderToken(ais, tree, builtin_token + 1, Space.Newline); // (
2198
2199 for (params) |param_node| {
2200 try renderExpression(ais, tree, param_node, .Comma);
2201 }
2202 ais.popIndent();
2203
2204 return renderToken(ais, tree, after_last_param_token + 1, space); // )
2205 }
2206}
2207
2224/// Render an expression, and the comma that follows it, if it is present in the source.2208/// Render an expression, and the comma that follows it, if it is present in the source.
2225fn renderExpressionComma(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {2209fn renderExpressionComma(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void {
2226 const token_tags = tree.tokens.items(.tag);2210 const token_tags = tree.tokens.items(.tag);