feature. See also
. The project being documented here (as the example) is the Zig library itself.
ast.Context
const Context = struct
File
Code
const Context = struct {
gpa: Allocator,
buf: std.ArrayList(u8) = .empty,
nodes: std.zig.Ast.NodeList = .empty,
extra_data: std.ArrayList(u32) = .empty,
tokens: std.zig.Ast.TokenList = .empty,
fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex {
const start_index = c.buf.items.len;
try c.buf.print(c.gpa, format ++ " ", args);
try c.tokens.append(c.gpa, .{
.tag = tag,
.start = @intCast(start_index),
});
return @intCast(c.tokens.len - 1);
}
fn addToken(c: *Context, tag: TokenTag, bytes: []const u8) Allocator.Error!TokenIndex {
return c.addTokenFmt(tag, "{s}", .{bytes});
}
fn addIdentifier(c: *Context, bytes: []const u8) Allocator.Error!TokenIndex {
if (std.zig.primitives.isPrimitive(bytes))
return c.addTokenFmt(.identifier, "@\"{s}\"", .{bytes});
return c.addTokenFmt(.identifier, "{f}", .{std.zig.fmtId(bytes)});
}
fn listToSpan(c: *Context, list: []const NodeIndex) Allocator.Error!NodeSubRange {
try c.extra_data.appendSlice(c.gpa, @ptrCast(list));
return .{
.start = @fromBackingInt(@intCast(c.extra_data.items.len - list.len)),
.end = @fromBackingInt(@intCast(c.extra_data.items.len)),
};
}
fn addNode(c: *Context, elem: std.zig.Ast.Node) Allocator.Error!NodeIndex {
const result: NodeIndex = @fromBackingInt(@intCast(c.nodes.len));
try c.nodes.append(c.gpa, elem);
return result;
}
fn addExtra(c: *Context, extra: anytype) Allocator.Error!std.zig.Ast.ExtraIndex {
const info = @typeInfo(@TypeOf(extra)).@"struct";
try c.extra_data.ensureUnusedCapacity(c.gpa, info.field_names.len);
const result: std.zig.Ast.ExtraIndex = @fromBackingInt(@intCast(c.extra_data.items.len));
inline for (info.field_names, info.field_types) |field_name, field_type| {
const data: u32 = switch (field_type) {
NodeIndex,
std.zig.Ast.Node.OptionalIndex,
std.zig.Ast.OptionalTokenIndex,
std.zig.Ast.ExtraIndex,
=> @backingInt(@field(extra, field_name)),
TokenIndex,
=> @field(extra, field_name),
else => @compileError("unexpected field type"),
};
c.extra_data.appendAssumeCapacity(data);
}
return result;
}
}