diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig index 7040028cf2..64b3fa7887 100644 --- a/lib/std/zig/ast.zig +++ b/lib/std/zig/ast.zig @@ -195,6 +195,7 @@ pub const Tree = struct { const tags = tree.nodes.items(.tag); const datas = tree.nodes.items(.data); const main_tokens = tree.nodes.items(.main_token); + const token_tags = tree.tokens.items(.tag); var n = node; while (true) switch (tags[n]) { .Root => return 0, @@ -304,39 +305,49 @@ pub const Tree = struct { .FnDecl, => n = datas[n].lhs, - .GlobalVarDecl, - .LocalVarDecl, - .SimpleVarDecl, - .AlignedVarDecl, - .ArrayType, - .ArrayTypeSentinel, - .PtrTypeAligned, - .PtrTypeSentinel, - .PtrType, - .SliceType, - .StructInit, - .SwitchCaseMulti, - .WhileSimple, - .WhileCont, - .While, - .ForSimple, - .For, - .FnProtoSimple, - .FnProtoSimpleMulti, - .FnProtoOne, - .FnProto, - .ContainerDecl, - .ContainerDeclArg, - .TaggedUnion, - .TaggedUnionEnumTag, .ContainerFieldInit, .ContainerFieldAlign, .ContainerField, - .AsmOutput, - .AsmInput, - .ErrorValue, - .ErrorUnion, - => @panic("TODO finish implementing firstToken"), + => { + const name_token = main_tokens[n]; + if (name_token > 0 and + token_tags[name_token - 1] == .Keyword_comptime) + { + return name_token - 1; + } else { + return name_token; + } + }, + + .GlobalVarDecl => unreachable, + .LocalVarDecl => unreachable, + .SimpleVarDecl => unreachable, + .AlignedVarDecl => unreachable, + .ArrayType => unreachable, + .ArrayTypeSentinel => unreachable, + .PtrTypeAligned => unreachable, + .PtrTypeSentinel => unreachable, + .PtrType => unreachable, + .SliceType => unreachable, + .StructInit => unreachable, + .SwitchCaseMulti => unreachable, + .WhileSimple => unreachable, + .WhileCont => unreachable, + .While => unreachable, + .ForSimple => unreachable, + .For => unreachable, + .FnProtoSimple => unreachable, + .FnProtoSimpleMulti => unreachable, + .FnProtoOne => unreachable, + .FnProto => unreachable, + .ContainerDecl => unreachable, + .ContainerDeclArg => unreachable, + .TaggedUnion => unreachable, + .TaggedUnionEnumTag => unreachable, + .AsmOutput => unreachable, + .AsmInput => unreachable, + .ErrorValue => unreachable, + .ErrorUnion => unreachable, }; } @@ -431,6 +442,7 @@ pub const Tree = struct { .NullLiteral, .UndefinedLiteral, .UnreachableLiteral, + .Identifier, => return main_tokens[n] + end_offset, .Call => { @@ -449,62 +461,61 @@ pub const Tree = struct { n = datas[n].rhs; }, - .ArrayInitDotTwo, - .ArrayInitDot, - .StructInitDotTwo, - .StructInitDot, - .Switch, - .If, - .Continue, - .Identifier, - .EnumLiteral, - .BuiltinCallTwo, - .BuiltinCall, - .ErrorSetDecl, - .Block, - .AsmSimple, - .Asm, - .SliceOpen, - .Slice, - .Deref, - .ArrayAccess, - .ArrayInitOne, - .ArrayInit, - .StructInitOne, - .SwitchCaseOne, - .SwitchRange, - .FnDecl, - .GlobalVarDecl, - .LocalVarDecl, - .SimpleVarDecl, - .AlignedVarDecl, - .ArrayType, - .ArrayTypeSentinel, - .PtrTypeAligned, - .PtrTypeSentinel, - .PtrType, - .SliceType, - .StructInit, - .SwitchCaseMulti, - .WhileCont, - .While, - .ForSimple, - .For, - .FnProtoSimple, - .FnProtoSimpleMulti, - .FnProtoOne, - .FnProto, - .ContainerDecl, - .ContainerDeclArg, - .TaggedUnion, - .TaggedUnionEnumTag, - .ContainerFieldInit, - .ContainerFieldAlign, - .ContainerField, - .AsmOutput, - .AsmInput, - .ErrorValue, - => @panic("TODO finish implementing lastToken"), + .ContainerFieldInit => unreachable, + .ContainerFieldAlign => unreachable, + .ContainerField => unreachable, + + .ArrayInitDotTwo => unreachable, + .ArrayInitDot => unreachable, + .StructInitDotTwo => unreachable, + .StructInitDot => unreachable, + .Switch => unreachable, + .If => unreachable, + .Continue => unreachable, + .EnumLiteral => unreachable, + .BuiltinCallTwo => unreachable, + .BuiltinCall => unreachable, + .ErrorSetDecl => unreachable, + .Block => unreachable, + .AsmSimple => unreachable, + .Asm => unreachable, + .SliceOpen => unreachable, + .Slice => unreachable, + .Deref => unreachable, + .ArrayAccess => unreachable, + .ArrayInitOne => unreachable, + .ArrayInit => unreachable, + .StructInitOne => unreachable, + .SwitchCaseOne => unreachable, + .SwitchRange => unreachable, + .FnDecl => unreachable, + .GlobalVarDecl => unreachable, + .LocalVarDecl => unreachable, + .SimpleVarDecl => unreachable, + .AlignedVarDecl => unreachable, + .ArrayType => unreachable, + .ArrayTypeSentinel => unreachable, + .PtrTypeAligned => unreachable, + .PtrTypeSentinel => unreachable, + .PtrType => unreachable, + .SliceType => unreachable, + .StructInit => unreachable, + .SwitchCaseMulti => unreachable, + .WhileCont => unreachable, + .While => unreachable, + .ForSimple => unreachable, + .For => unreachable, + .FnProtoSimple => unreachable, + .FnProtoSimpleMulti => unreachable, + .FnProtoOne => unreachable, + .FnProto => unreachable, + .ContainerDecl => unreachable, + .ContainerDeclArg => unreachable, + .TaggedUnion => unreachable, + .TaggedUnionEnumTag => unreachable, + .AsmOutput => unreachable, + .AsmInput => unreachable, + .ErrorValue => unreachable, }; } @@ -587,6 +598,40 @@ pub const Tree = struct { }); } + pub fn containerField(tree: Tree, node: Node.Index) Full.ContainerField { + assert(tree.nodes.items(.tag)[node] == .ContainerField); + const data = tree.nodes.items(.data)[node]; + const extra = tree.extraData(data.rhs, Node.ContainerField); + return tree.fullContainerField(.{ + .name_token = tree.nodes.items(.main_token)[node], + .type_expr = data.lhs, + .value_expr = extra.value_expr, + .align_expr = extra.align_expr, + }); + } + + pub fn containerFieldInit(tree: Tree, node: Node.Index) Full.ContainerField { + assert(tree.nodes.items(.tag)[node] == .ContainerFieldInit); + const data = tree.nodes.items(.data)[node]; + return tree.fullContainerField(.{ + .name_token = tree.nodes.items(.main_token)[node], + .type_expr = data.lhs, + .value_expr = data.rhs, + .align_expr = 0, + }); + } + + pub fn containerFieldAlign(tree: Tree, node: Node.Index) Full.ContainerField { + assert(tree.nodes.items(.tag)[node] == .ContainerFieldAlign); + const data = tree.nodes.items(.data)[node]; + return tree.fullContainerField(.{ + .name_token = tree.nodes.items(.main_token)[node], + .type_expr = data.lhs, + .value_expr = 0, + .align_expr = data.rhs, + }); + } + fn fullVarDecl(tree: Tree, info: Full.VarDecl.Ast) Full.VarDecl { const token_tags = tree.tokens.items(.tag); var result: Full.VarDecl = .{ @@ -636,6 +681,20 @@ pub const Tree = struct { } return result; } + + fn fullContainerField(tree: Tree, info: Full.ContainerField.Ast) Full.ContainerField { + const token_tags = tree.tokens.items(.tag); + var result: Full.ContainerField = .{ + .ast = info, + .comptime_token = null, + }; + // comptime name: type = init, + // ^ + if (info.name_token > 0 and token_tags[info.name_token - 1] == .Keyword_comptime) { + result.comptime_token = info.name_token - 1; + } + return result; + } }; /// Fully assembled AST node information. @@ -674,6 +733,18 @@ pub const Full = struct { else_expr: Node.Index, }; }; + + pub const ContainerField = struct { + comptime_token: ?TokenIndex, + ast: Ast, + + pub const Ast = struct { + name_token: TokenIndex, + type_expr: Node.Index, + value_expr: Node.Index, + align_expr: Node.Index, + }; + }; }; pub const Error = union(enum) { diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 7a22b9a6a1..988eb9c233 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -91,15 +91,15 @@ test "zig fmt: if statment" { ); } -//test "zig fmt: top-level fields" { -// try testCanonical( -// \\a: did_you_know, -// \\b: all_files_are, -// \\structs: ?x, -// \\ -// ); -//} -// +test "zig fmt: top-level fields" { + try testCanonical( + \\a: did_you_know, + \\b: all_files_are, + \\structs: ?x, + \\ + ); +} + //test "zig fmt: decl between fields" { // try testError( // \\const S = struct { diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index e481fd7f10..7c901da458 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -28,7 +28,7 @@ const Ais = std.io.AutoIndentingStream(Writer); pub fn render(gpa: *mem.Allocator, writer: Writer, tree: ast.Tree) Error!void { assert(tree.errors.len == 0); // cannot render an invalid tree var auto_indenting_stream = std.io.autoIndentingStream(indent_delta, writer); - try renderRoot(&auto_indenting_stream, tree); + return renderRoot(&auto_indenting_stream, tree); } /// Assumes there are no tokens in between start and end. @@ -66,10 +66,9 @@ fn renderRoot(ais: *Ais, tree: ast.Tree) Error!void { // Root is always index 0. const nodes_data = tree.nodes.items(.data); const root_decls = tree.extra_data[nodes_data[0].lhs..nodes_data[0].rhs]; - if (root_decls.len == 0) return; for (root_decls) |decl| { - return renderContainerDecl(ais, tree, decl, .Newline); + try renderContainerDecl(ais, tree, decl, .Newline); } } @@ -102,17 +101,11 @@ fn renderContainerDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: S const datas = tree.nodes.items(.data); try renderDocComments(ais, tree, tree.firstToken(decl)); switch (tree.nodes.items(.tag)[decl]) { - .UsingNamespace, - .FnProtoSimple, - .FnProtoSimpleMulti, - .FnProtoOne, - .FnProto, - .FnDecl, - .ContainerFieldInit, - .ContainerFieldAlign, - .ContainerField, - => @panic("TODO implement renderContainerDecl"), - + .FnProtoSimple => unreachable, // TODO + .FnProtoSimpleMulti => unreachable, // TODO + .FnProtoOne => unreachable, // TODO + .FnDecl => unreachable, // TODO + .FnProto => unreachable, // TODO // .FnProto => { // const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", decl); @@ -127,6 +120,7 @@ fn renderContainerDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: S // } // }, + .UsingNamespace => unreachable, // TODO // .Use => { // const use_decl = @fieldParentPtr(ast.Node.Use, "base", decl); @@ -152,88 +146,10 @@ fn renderContainerDecl(ais: *Ais, tree: ast.Tree, decl: ast.Node.Index, space: S try renderExpression(ais, tree, datas[decl].rhs, space); }, - // .ContainerField => { - // const field = @fieldParentPtr(ast.Node.ContainerField, "base", decl); - - // try renderDocComments(ais, tree, field, field.doc_comments); - // if (field.comptime_token) |t| { - // try renderToken(ais, tree, t, .Space); // comptime - // } - - // const src_has_trailing_comma = blk: { - // const maybe_comma = tree.nextToken(field.lastToken()); - // break :blk tree.token_tags[maybe_comma] == .Comma; - // }; - - // // The trailing comma is emitted at the end, but if it's not present - // // we still have to respect the specified `space` parameter - // const last_token_space: Space = if (src_has_trailing_comma) .None else space; - - // if (field.type_expr == null and field.value_expr == null) { - // try renderToken(ais, tree, field.name_token, last_token_space); // name - // } else if (field.type_expr != null and field.value_expr == null) { - // try renderToken(ais, tree, field.name_token, .None); // name - // try renderToken(ais, tree, tree.nextToken(field.name_token), .Space); // : - - // if (field.align_expr) |align_value_expr| { - // try renderExpression(ais, tree, field.type_expr.?, .Space); // type - // const lparen_token = tree.prevToken(align_value_expr.firstToken()); - // const align_kw = tree.prevToken(lparen_token); - // const rparen_token = tree.nextToken(align_value_expr.lastToken()); - // try renderToken(ais, tree, align_kw, .None); // align - // try renderToken(ais, tree, lparen_token, .None); // ( - // try renderExpression(ais, tree, align_value_expr, .None); // alignment - // try renderToken(ais, tree, rparen_token, last_token_space); // ) - // } else { - // try renderExpression(ais, tree, field.type_expr.?, last_token_space); // type - // } - // } else if (field.type_expr == null and field.value_expr != null) { - // try renderToken(ais, tree, field.name_token, .Space); // name - // try renderToken(ais, tree, tree.nextToken(field.name_token), .Space); // = - // try renderExpression(ais, tree, field.value_expr.?, last_token_space); // value - // } else { - // try renderToken(ais, tree, field.name_token, .None); // name - // try renderToken(ais, tree, tree.nextToken(field.name_token), .Space); // : - - // if (field.align_expr) |align_value_expr| { - // try renderExpression(ais, tree, field.type_expr.?, .Space); // type - // const lparen_token = tree.prevToken(align_value_expr.firstToken()); - // const align_kw = tree.prevToken(lparen_token); - // const rparen_token = tree.nextToken(align_value_expr.lastToken()); - // try renderToken(ais, tree, align_kw, .None); // align - // try renderToken(ais, tree, lparen_token, .None); // ( - // try renderExpression(ais, tree, align_value_expr, .None); // alignment - // try renderToken(ais, tree, rparen_token, .Space); // ) - // } else { - // try renderExpression(ais, tree, field.type_expr.?, .Space); // type - // } - // try renderToken(ais, tree, tree.prevToken(field.value_expr.?.firstToken()), .Space); // = - // try renderExpression(ais, tree, field.value_expr.?, last_token_space); // value - // } - - // if (src_has_trailing_comma) { - // const comma = tree.nextToken(field.lastToken()); - // try renderToken(ais, tree, comma, space); - // } - // }, + .ContainerFieldInit => return renderContainerField(ais, tree, tree.containerFieldInit(decl), space), + .ContainerFieldAlign => return renderContainerField(ais, tree, tree.containerFieldAlign(decl), space), + .ContainerField => return renderContainerField(ais, tree, tree.containerField(decl), space), .Comptime => return renderExpression(ais, tree, decl, space), - - // .DocComment => { - // const comment = @fieldParentPtr(ast.Node.DocComment, "base", decl); - // const kind = tree.token_tags[comment.first_line]; - // try renderToken(ais, tree, comment.first_line, .Newline); - // var tok_i = comment.first_line + 1; - // while (true) : (tok_i += 1) { - // const tok_id = tree.token_tags[tok_i]; - // if (tok_id == kind) { - // try renderToken(ais, tree, tok_i, .Newline); - // } else if (tok_id == .LineComment) { - // continue; - // } else { - // break; - // } - // } - // }, else => unreachable, } } @@ -254,8 +170,12 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac .NullLiteral, .UnreachableLiteral, .UndefinedLiteral, + .AnyFrameLiteral, => return renderToken(ais, tree, main_tokens[node], space), + .ErrorValue => unreachable, // TODO + + .AnyType => unreachable, // TODO //.AnyType => { // const any_type = base.castTag(.AnyType).?; // if (mem.eql(u8, tree.tokenSlice(any_type.token), "var")) { @@ -322,6 +242,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac } }, + .Defer => unreachable, // TODO + .ErrDefer => unreachable, // TODO //.Defer => { // const defer_node = @fieldParentPtr(ast.Node.Defer, "base", base); @@ -337,6 +259,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac try renderToken(ais, tree, comptime_token, .Space); return renderExpression(ais, tree, block, space); }, + .Nosuspend => unreachable, // TODO //.Nosuspend => { // const nosuspend_node = @fieldParentPtr(ast.Node.Nosuspend, "base", base); // if (mem.eql(u8, tree.tokenSlice(nosuspend_node.nosuspend_token), "noasync")) { @@ -348,6 +271,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // return renderExpression(ais, tree, nosuspend_node.expr, space); //}, + .Suspend => unreachable, // TODO //.Suspend => { // const suspend_node = @fieldParentPtr(ast.Node.Suspend, "base", base); @@ -359,6 +283,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // } //}, + .Catch => unreachable, // TODO //.Catch => { // const infix_op_node = @fieldParentPtr(ast.Node.Catch, "base", base); @@ -452,27 +377,26 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac return renderExpression(ais, tree, infix.rhs, space); }, - //.BitNot, - //.BoolNot, - //.Negation, - //.NegationWrap, - //.OptionalType, - //.AddressOf, - //=> { - // const casted_node = @fieldParentPtr(ast.Node.SimplePrefixOp, "base", base); - // try renderToken(ais, tree, casted_node.op_token, Space.None); - // return renderExpression(ais, tree, casted_node.rhs, space); - //}, + .BitNot, + .BoolNot, + .Negation, + .NegationWrap, + .OptionalType, + .AddressOf, + => { + try renderToken(ais, tree, main_tokens[node], .None); + return renderExpression(ais, tree, datas[node].lhs, space); + }, - //.Try, - //.Resume, - //.Await, - //=> { - // const casted_node = @fieldParentPtr(ast.Node.SimplePrefixOp, "base", base); - // try renderToken(ais, tree, casted_node.op_token, Space.Space); - // return renderExpression(ais, tree, casted_node.rhs, space); - //}, + .Try, + .Resume, + .Await, + => { + try renderToken(ais, tree, main_tokens[node], .Space); + return renderExpression(ais, tree, datas[node].lhs, space); + }, + .ArrayType => unreachable, // TODO //.ArrayType => { // const array_type = @fieldParentPtr(ast.Node.ArrayType, "base", base); // return renderArrayType( @@ -486,6 +410,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // space, // ); //}, + .ArrayTypeSentinel => unreachable, // TODO //.ArrayTypeSentinel => { // const array_type = @fieldParentPtr(ast.Node.ArrayTypeSentinel, "base", base); // return renderArrayType( @@ -500,6 +425,9 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // ); //}, + .PtrType => unreachable, // TODO + .PtrTypeAligned => unreachable, // TODO + .PtrTypeSentinel => unreachable, // TODO //.PtrType => { // const ptr_type = @fieldParentPtr(ast.Node.PtrType, "base", base); // const op_tok_id = tree.token_tags[ptr_type.op_token]; @@ -562,6 +490,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // return renderExpression(ais, tree, ptr_type.rhs, space); //}, + .SliceType => unreachable, // TODO //.SliceType => { // const slice_type = @fieldParentPtr(ast.Node.SliceType, "base", base); // try renderToken(ais, tree, slice_type.op_token, Space.None); // [ @@ -611,6 +540,10 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // return renderExpression(ais, tree, slice_type.rhs, space); //}, + .ArrayInitOne => unreachable, // TODO + .ArrayInitDotTwo => unreachable, // TODO + .ArrayInitDot => unreachable, // TODO + .ArrayInit => unreachable, // TODO //.ArrayInitializer, .ArrayInitializerDot => { // var rtoken: ast.TokenIndex = undefined; // var exprs: []ast.Node.Index = undefined; @@ -823,6 +756,10 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // return renderToken(ais, tree, rtoken, space); //}, + .StructInitOne => unreachable, // TODO + .StructInitDotTwo => unreachable, // TODO + .StructInitDot => unreachable, // TODO + .StructInit => unreachable, // TODO //.StructInitializer, .StructInitializerDot => { // var rtoken: ast.TokenIndex = undefined; // var field_inits: []ast.Node.Index = undefined; @@ -959,6 +896,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // return renderToken(ais, tree, rtoken, space); //}, + .CallOne => unreachable, // TODO .Call => { const call = datas[node]; const params_range = tree.extraData(call.rhs, ast.Node.SubRange); @@ -1017,6 +955,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac return renderToken(ais, tree, after_last_param_tok, space); // ) }, + .ArrayAccess => unreachable, // TODO //.ArrayAccess => { // const suffix_op = base.castTag(.ArrayAccess).?; @@ -1039,6 +978,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // return renderToken(ais, tree, rbracket, space); // ] //}, + .Slice => unreachable, // TODO + .SliceOpen => unreachable, // TODO //.Slice => { // const suffix_op = base.castTag(.Slice).?; // try renderExpression(ais, tree, suffix_op.lhs, Space.None); @@ -1066,12 +1007,14 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // return renderToken(ais, tree, suffix_op.rtoken, space); // ] //}, + .Deref => unreachable, // TODO //.Deref => { // const suffix_op = base.castTag(.Deref).?; // try renderExpression(ais, tree, suffix_op.lhs, Space.None); // return renderToken(ais, tree, suffix_op.rtoken, space); // .* //}, + .UnwrapOptional => unreachable, // TODO //.UnwrapOptional => { // const suffix_op = base.castTag(.UnwrapOptional).?; @@ -1080,6 +1023,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // return renderToken(ais, tree, suffix_op.rtoken, space); // ? //}, + .Break => unreachable, // TODO //.Break => { // const flow_expr = base.castTag(.Break).?; // const maybe_rhs = flow_expr.getRHS(); @@ -1102,6 +1046,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // return renderExpression(ais, tree, maybe_rhs.?, space); //}, + .Continue => unreachable, // TODO //.Continue => { // const flow_expr = base.castTag(.Continue).?; // if (flow_expr.getLabel()) |label| { @@ -1114,6 +1059,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // } //}, + .Return => unreachable, // TODO //.Return => { // const flow_expr = base.castTag(.Return).?; // if (flow_expr.getRHS()) |rhs| { @@ -1124,36 +1070,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // } //}, - //.PointerPayload => { - // const payload = @fieldParentPtr(ast.Node.PointerPayload, "base", base); - - // try renderToken(ais, tree, payload.lpipe, Space.None); - // if (payload.ptr_token) |ptr_token| { - // try renderToken(ais, tree, ptr_token, Space.None); - // } - // try renderExpression(ais, tree, payload.value_symbol, Space.None); - // return renderToken(ais, tree, payload.rpipe, space); - //}, - - //.PointerIndexPayload => { - // const payload = @fieldParentPtr(ast.Node.PointerIndexPayload, "base", base); - - // try renderToken(ais, tree, payload.lpipe, Space.None); - // if (payload.ptr_token) |ptr_token| { - // try renderToken(ais, tree, ptr_token, Space.None); - // } - // try renderExpression(ais, tree, payload.value_symbol, Space.None); - - // if (payload.index_symbol) |index_symbol| { - // const comma = tree.nextToken(payload.value_symbol.lastToken()); - - // try renderToken(ais, tree, comma, Space.Space); - // try renderExpression(ais, tree, index_symbol, Space.None); - // } - - // return renderToken(ais, tree, payload.rpipe, space); - //}, - + .GroupedExpression => unreachable, // TODO //.GroupedExpression => { // const grouped_expr = @fieldParentPtr(ast.Node.GroupedExpression, "base", base); @@ -1165,15 +1082,10 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // return renderToken(ais, tree, grouped_expr.rparen, space); //}, - //.FieldInitializer => { - // const field_init = @fieldParentPtr(ast.Node.FieldInitializer, "base", base); - - // try renderToken(ais, tree, field_init.period_token, Space.None); // . - // try renderToken(ais, tree, field_init.name_token, Space.Space); // name - // try renderToken(ais, tree, tree.nextToken(field_init.name_token), Space.Space); // = - // return renderExpression(ais, tree, field_init.expr, space); - //}, - + .ContainerDecl => unreachable, // TODO + .ContainerDeclArg => unreachable, // TODO + .TaggedUnion => unreachable, // TODO + .TaggedUnionEnumTag => unreachable, // TODO //.ContainerDecl => { // const container_decl = @fieldParentPtr(ast.Node.ContainerDecl, "base", base); @@ -1289,6 +1201,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // return renderToken(ais, tree, container_decl.rbrace_token, space); // } //}, + .ErrorSetDecl => unreachable, // TODO //.ErrorSetDecl => { // const err_set_decl = @fieldParentPtr(ast.Node.ErrorSetDecl, "base", base); @@ -1365,28 +1278,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // } //}, - //.ErrorTag => { - // const tag = @fieldParentPtr(ast.Node.ErrorTag, "base", base); - - // try renderDocComments(ais, tree, tag, tag.doc_comments); - // return renderToken(ais, tree, tag.name_token, space); // name - //}, - - //.MultilineStringLiteral => { - // const multiline_str_literal = @fieldParentPtr(ast.Node.MultilineStringLiteral, "base", base); - - // { - // const locked_indents = ais.lockOneShotIndent(); - // defer { - // var i: u8 = 0; - // while (i < locked_indents) : (i += 1) ais.popIndent(); - // } - // try ais.maybeInsertNewline(); - - // for (multiline_str_literal.lines()) |t| try renderToken(ais, tree, t, Space.None); - // } - //}, - + .BuiltinCall => unreachable, // TODO + .BuiltinCallTwo => unreachable, // TODO //.BuiltinCall => { // const builtin_call = @fieldParentPtr(ast.Node.BuiltinCall, "base", base); @@ -1448,6 +1341,10 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // return renderToken(ais, tree, builtin_call.rparen_token, space); // ) //}, + .FnProtoSimple => unreachable, // TODO + .FnProtoSimpleMulti => unreachable, // TODO + .FnProtoOne => unreachable, // TODO + .FnProto => unreachable, // TODO //.FnProto => { // const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", base); @@ -1579,6 +1476,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // } //}, + .AnyFrameType => unreachable, // TODO //.AnyFrameType => { // const anyframe_type = @fieldParentPtr(ast.Node.AnyFrameType, "base", base); @@ -1591,8 +1489,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // } //}, - //.DocComment => unreachable, // doc comments are attached to nodes - + .Switch => unreachable, // TODO //.Switch => { // const switch_node = @fieldParentPtr(ast.Node.Switch, "base", base); @@ -1630,6 +1527,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // return renderToken(ais, tree, switch_node.rbrace, space); // } //}, + .SwitchCaseOne => unreachable, // TODO + .SwitchCaseMulti => unreachable, // TODO //.SwitchCase => { // const switch_case = @fieldParentPtr(ast.Node.SwitchCase, "base", base); @@ -1676,11 +1575,10 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // return renderExpression(ais, tree, switch_case.expr, space); //}, - //.SwitchElse => { - // const switch_else = @fieldParentPtr(ast.Node.SwitchElse, "base", base); - // return renderToken(ais, tree, switch_else.token, space); - //}, + .WhileSimple => unreachable, // TODO + .WhileCont => unreachable, // TODO + .While => unreachable, // TODO //.While => { // const while_node = @fieldParentPtr(ast.Node.While, "base", base); @@ -1749,6 +1647,8 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // } //}, + .ForSimple => unreachable, // TODO + .For => unreachable, // TODO //.For => { // const for_node = @fieldParentPtr(ast.Node.For, "base", base); @@ -1802,6 +1702,11 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac .IfSimple => return renderIf(ais, tree, tree.ifSimple(node), space), .If => return renderIf(ais, tree, tree.ifFull(node), space), + + .Asm => unreachable, // TODO + .AsmSimple => unreachable, // TODO + .AsmOutput => unreachable, // TODO + .AsmInput => unreachable, // TODO //.Asm => { // const asm_node = @fieldParentPtr(ast.Node.Asm, "base", base); @@ -1911,6 +1816,7 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // return renderToken(ais, tree, asm_node.rparen, space); //}, + .EnumLiteral => unreachable, // TODO //.EnumLiteral => { // const enum_literal = @fieldParentPtr(ast.Node.EnumLiteral, "base", base); @@ -1918,13 +1824,17 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac // return renderToken(ais, tree, enum_literal.name, space); // name //}, - //.ContainerField, - //.Root, - //.VarDecl, - //.Use, - //.TestDecl, - //=> unreachable, - else => @panic("TODO implement more renderExpression"), + .FnDecl => unreachable, + .ContainerField => unreachable, + .ContainerFieldInit => unreachable, + .ContainerFieldAlign => unreachable, + .Root => unreachable, + .GlobalVarDecl => unreachable, + .LocalVarDecl => unreachable, + .SimpleVarDecl => unreachable, + .AlignedVarDecl => unreachable, + .UsingNamespace => unreachable, + .TestDecl => unreachable, } } @@ -2234,6 +2144,59 @@ fn renderIf(ais: *Ais, tree: ast.Tree, if_node: ast.Full.If, space: Space) Error } } +fn renderContainerField( + ais: *Ais, + tree: ast.Tree, + field: ast.Full.ContainerField, + space: Space, +) Error!void { + const main_tokens = tree.nodes.items(.main_token); + if (field.comptime_token) |t| { + try renderToken(ais, tree, t, .Space); // comptime + } + if (field.ast.type_expr == 0 and field.ast.value_expr == 0) { + return renderTokenComma(ais, tree, field.ast.name_token, space); // name + } + if (field.ast.type_expr != 0 and field.ast.value_expr == 0) { + try renderToken(ais, tree, field.ast.name_token, .None); // name + try renderToken(ais, tree, field.ast.name_token + 1, .Space); // : + + if (field.ast.align_expr != 0) { + try renderExpression(ais, tree, field.ast.type_expr, .Space); // type + const align_token = tree.firstToken(field.ast.align_expr) - 2; + try renderToken(ais, tree, align_token, .None); // align + try renderToken(ais, tree, align_token + 1, .None); // ( + try renderExpression(ais, tree, field.ast.align_expr, .None); // alignment + const rparen = tree.lastToken(field.ast.align_expr) + 1; + return renderTokenComma(ais, tree, rparen, space); // ) + } else { + return renderExpressionComma(ais, tree, field.ast.type_expr, space); // type + } + } + if (field.ast.type_expr == 0 and field.ast.value_expr != 0) { + try renderToken(ais, tree, field.ast.name_token, .Space); // name + try renderToken(ais, tree, field.ast.name_token + 1, .Space); // = + return renderExpressionComma(ais, tree, field.ast.value_expr, space); // value + } + + try renderToken(ais, tree, field.ast.name_token, .None); // name + try renderToken(ais, tree, field.ast.name_token + 1, .Space); // : + try renderExpression(ais, tree, field.ast.type_expr, .Space); // type + + if (field.ast.align_expr != 0) { + const lparen_token = tree.firstToken(field.ast.align_expr) - 1; + const align_kw = lparen_token - 1; + const rparen_token = tree.lastToken(field.ast.align_expr) + 1; + try renderToken(ais, tree, align_kw, .None); // align + try renderToken(ais, tree, lparen_token, .None); // ( + try renderExpression(ais, tree, field.ast.align_expr, .None); // alignment + try renderToken(ais, tree, rparen_token, .Space); // ) + } + const eq_token = tree.firstToken(field.ast.value_expr) - 1; + try renderToken(ais, tree, eq_token, .Space); // = + return renderExpressionComma(ais, tree, field.ast.value_expr, space); // value +} + fn renderParamDecl( allocator: *mem.Allocator, ais: *Ais, @@ -2258,6 +2221,29 @@ fn renderParamDecl( } } +/// Render an expression, and the comma that follows it, if it is present in the source. +fn renderExpressionComma(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Space) Error!void { + const token_tags = tree.tokens.items(.tag); + const maybe_comma = tree.lastToken(node) + 1; + if (token_tags[maybe_comma] == .Comma) { + try renderExpression(ais, tree, node, .None); + return renderToken(ais, tree, maybe_comma, space); + } else { + return renderExpression(ais, tree, node, space); + } +} + +fn renderTokenComma(ais: *Ais, tree: ast.Tree, token: ast.TokenIndex, space: Space) Error!void { + const token_tags = tree.tokens.items(.tag); + const maybe_comma = token + 1; + if (token_tags[maybe_comma] == .Comma) { + try renderToken(ais, tree, token, .None); + return renderToken(ais, tree, maybe_comma, space); + } else { + return renderToken(ais, tree, token, space); + } +} + const Space = enum { None, Newline,