Note that this function is additionally used to render if expressions, with respective values set to null.
fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void
fn renderWhile(r: *Render, while_node: Ast.full.While, space: Space) Error!void {
const tree = r.tree;
if (while_node.label_token) |label| {
try renderIdentifier(r, label, .none, .eagerly_unquote); // label
try renderToken(r, label + 1, .space); // :
}
if (while_node.inline_token) |inline_token| {
try renderToken(r, inline_token, .space); // inline
}
try renderToken(r, while_node.ast.while_token, .space); // if/for/while
try renderToken(r, while_node.ast.while_token + 1, .none); // lparen
try renderExpression(r, while_node.ast.cond_expr, .none); // condition
var last_prefix_token = tree.lastToken(while_node.ast.cond_expr) + 1; // rparen
if (while_node.payload_token) |payload_token| {
try renderToken(r, last_prefix_token, .space);
try renderToken(r, payload_token - 1, .none); // |
const ident = blk: {
if (tree.tokenTag(payload_token) == .asterisk) {
try renderToken(r, payload_token, .none); // *
break :blk payload_token + 1;
} else {
break :blk payload_token;
}
};
try renderIdentifier(r, ident, .none, .preserve_when_shadowing); // identifier
const pipe = blk: {
if (tree.tokenTag(ident + 1) == .comma) {
try renderToken(r, ident + 1, .space); // ,
try renderIdentifier(r, ident + 2, .none, .preserve_when_shadowing); // index
break :blk ident + 3;
} else {
break :blk ident + 1;
}
};
last_prefix_token = pipe;
}
if (while_node.ast.cont_expr.unwrap()) |cont_expr| {
try renderToken(r, last_prefix_token, .space);
const lparen = tree.firstToken(cont_expr) - 1;
try renderToken(r, lparen - 1, .space); // :
try renderToken(r, lparen, .none); // lparen
try renderExpression(r, cont_expr, .none);
last_prefix_token = tree.lastToken(cont_expr) + 1; // rparen
}
try renderThenElse(
r,
last_prefix_token,
while_node.ast.then_expr,
while_node.else_token,
while_node.error_token,
while_node.ast.else_expr,
space,
);
}