Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

parseTypeExpr

Parse.parseTypeExpr
fn parseTypeExpr(p: *Parse) Error!?Node.Index

File

lib/std/zig/Parse.zig:1657

Code

fn parseTypeExpr(p: *Parse) Error!?Node.Index {
    switch (p.tokenTag(p.tok_i)) {
        .question_mark => return try p.addNode(.{
            .tag = .optional_type,
            .main_token = p.nextToken(),
            .data = .{ .node = try p.expectTypeExpr() },
        }),
        .keyword_anyframe => switch (p.tokenTag(p.tok_i + 1)) {
            .arrow => return try p.addNode(.{
                .tag = .anyframe_type,
                .main_token = p.nextToken(),
                .data = .{ .token_and_node = .{
                    p.nextToken(),
                    try p.expectTypeExpr(),
                } },
            }),
            else => return try p.parseErrorUnionExpr(),
        },
        .asterisk => {
            const asterisk = p.nextToken();
            const mods = try p.parsePtrModifiers(.bit_align);
            const elem_type = try p.expectTypeExpr();
            if (mods.bit_range_start != .none) {
                return try p.addNode(.{
                    .tag = .ptr_type_bit_range,
                    .main_token = asterisk,
                    .data = .{ .extra_and_node = .{
                        try p.addExtra(Node.PtrTypeBitRange{
                            .sentinel = .none,
                            .align_node = mods.align_node.unwrap().?,
                            .addrspace_node = mods.addrspace_node,
                            .bit_range_start = mods.bit_range_start.unwrap().?,
                            .bit_range_end = mods.bit_range_end.unwrap().?,
                        }),
                        elem_type,
                    } },
                });
            } else if (mods.addrspace_node != .none) {
                return try p.addNode(.{
                    .tag = .ptr_type,
                    .main_token = asterisk,
                    .data = .{ .extra_and_node = .{
                        try p.addExtra(Node.PtrType{
                            .sentinel = .none,
                            .align_node = mods.align_node,
                            .addrspace_node = mods.addrspace_node,
                        }),
                        elem_type,
                    } },
                });
            } else {
                return try p.addNode(.{
                    .tag = .ptr_type_aligned,
                    .main_token = asterisk,
                    .data = .{ .opt_node_and_node = .{
                        mods.align_node,
                        elem_type,
                    } },
                });
            }
        },
        .l_bracket => switch (p.tokenTag(p.tok_i + 1)) {
            .asterisk => {
                const l_bracket = p.nextToken();
                _ = p.nextToken();
                var sentinel: ?Node.Index = null;
                if (p.eatToken(.identifier)) |ident| {
                    const ident_slice = p.source[p.tokenStart(ident)..p.tokenStart(ident + 1)];
                    if (!std.mem.eql(u8, std.mem.trimEnd(u8, ident_slice, &std.ascii.whitespace), "c")) {
                        p.tok_i -= 1;
                    }
                } else if (p.eatToken(.colon)) |_| {
                    sentinel = try p.expectExpr();
                }
                _ = try p.expectToken(.r_bracket);
                const mods = try p.parsePtrModifiers(.byte_align);
                const elem_type = try p.expectTypeExpr();
                if (sentinel == null and mods.addrspace_node == .none) {
                    return try p.addNode(.{
                        .tag = .ptr_type_aligned,
                        .main_token = l_bracket,
                        .data = .{ .opt_node_and_node = .{
                            mods.align_node,
                            elem_type,
                        } },
                    });
                } else if (mods.align_node == .none and mods.addrspace_node == .none) {
                    return try p.addNode(.{
                        .tag = .ptr_type_sentinel,
                        .main_token = l_bracket,
                        .data = .{ .opt_node_and_node = .{
                            .fromOptional(sentinel),
                            elem_type,
                        } },
                    });
                } else {
                    return try p.addNode(.{
                        .tag = .ptr_type,
                        .main_token = l_bracket,
                        .data = .{ .extra_and_node = .{
                            try p.addExtra(Node.PtrType{
                                .sentinel = .fromOptional(sentinel),
                                .align_node = mods.align_node,
                                .addrspace_node = mods.addrspace_node,
                            }),
                            elem_type,
                        } },
                    });
                }
            },
            else => {
                const lbracket = p.nextToken();
                const len_expr = try p.parseExpr();
                const sentinel: ?Node.Index = if (p.eatToken(.colon)) |_|
                    try p.expectExpr()
                else
                    null;
                _ = try p.expectToken(.r_bracket);
                if (len_expr == null) {
                    const mods = try p.parsePtrModifiers(.byte_align);
                    const elem_type = try p.expectTypeExpr();
                    if (sentinel == null and mods.addrspace_node == .none) {
                        return try p.addNode(.{
                            .tag = .ptr_type_aligned,
                            .main_token = lbracket,
                            .data = .{ .opt_node_and_node = .{
                                mods.align_node,
                                elem_type,
                            } },
                        });
                    } else if (mods.align_node == .none and mods.addrspace_node == .none) {
                        return try p.addNode(.{
                            .tag = .ptr_type_sentinel,
                            .main_token = lbracket,
                            .data = .{ .opt_node_and_node = .{
                                .fromOptional(sentinel),
                                elem_type,
                            } },
                        });
                    } else {
                        return try p.addNode(.{
                            .tag = .ptr_type,
                            .main_token = lbracket,
                            .data = .{ .extra_and_node = .{
                                try p.addExtra(Node.PtrType{
                                    .sentinel = .fromOptional(sentinel),
                                    .align_node = mods.align_node,
                                    .addrspace_node = mods.addrspace_node,
                                }),
                                elem_type,
                            } },
                        });
                    }
                } else {
                    switch (p.tokenTag(p.tok_i)) {
                        .keyword_align,
                        .keyword_const,
                        .keyword_volatile,
                        .keyword_allowzero,
                        .keyword_addrspace,
                        => return p.fail(.ptr_mod_on_array_child_type),
                        else => {},
                    }
                    const elem_type = try p.expectTypeExpr();
                    if (sentinel == null) {
                        return try p.addNode(.{
                            .tag = .array_type,
                            .main_token = lbracket,
                            .data = .{ .node_and_node = .{
                                len_expr.?,
                                elem_type,
                            } },
                        });
                    } else {
                        return try p.addNode(.{
                            .tag = .array_type_sentinel,
                            .main_token = lbracket,
                            .data = .{ .node_and_extra = .{
                                len_expr.?,
                                try p.addExtra(Node.ArrayTypeSentinel{
                                    .sentinel = sentinel.?,
                                    .elem_type = elem_type,
                                }),
                            } },
                        });
                    }
                }
            },
        },
        else => return p.parseErrorUnionExpr(),
    }
}