feature. See also
. The project being documented here (as the example) is the Zig library itself.
Walk.Scope
pub const Scope = struct
File
Code
pub const Scope = struct {
tag: Tag,
const Tag = enum { top, local, namespace };
const Local = struct {
base: Scope = .{ .tag = .local },
parent: *Scope,
var_node: Ast.Node.Index,
};
const Namespace = struct {
base: Scope = .{ .tag = .namespace },
parent: *Scope,
names: std.array_hash_map.String(Ast.Node.Index) = .empty,
doctests: std.array_hash_map.String(Ast.Node.Index) = .empty,
decl_index: Decl.Index,
};
fn getNamespaceDecl(start_scope: *Scope) Decl.Index {
var it: *Scope = start_scope;
while (true) switch (it.tag) {
.top => unreachable,
.local => {
const local: *Local = @alignCast(@fieldParentPtr("base", it));
it = local.parent;
},
.namespace => {
const namespace: *Namespace = @alignCast(@fieldParentPtr("base", it));
return namespace.decl_index;
},
};
}
pub fn get_child(scope: *Scope, name: []const u8) ?Ast.Node.Index {
switch (scope.tag) {
.top, .local => return null,
.namespace => {
const namespace: *Namespace = @alignCast(@fieldParentPtr("base", scope));
return namespace.names.get(name);
},
}
}
pub fn lookup(start_scope: *Scope, ast: *const Ast, name: []const u8) ?Ast.Node.Index {
var it: *Scope = start_scope;
while (true) switch (it.tag) {
.top => break,
.local => {
const local: *Local = @alignCast(@fieldParentPtr("base", it));
const name_token = ast.nodeMainToken(local.var_node) + 1;
const ident_name = ast.tokenSlice(name_token);
if (std.mem.eql(u8, ident_name, name)) {
return local.var_node;
}
it = local.parent;
},
.namespace => {
const namespace: *Namespace = @alignCast(@fieldParentPtr("base", it));
if (namespace.names.get(name)) |node| {
return node;
}
it = namespace.parent;
},
};
return null;
}
}