small refactor

This commit is contained in:
Techatrix 2023-01-23 22:21:47 +01:00
parent f2b133c428
commit 4b7a434feb
2 changed files with 59 additions and 53 deletions

View File

@ -13,8 +13,8 @@ const offsets = @import("offsets.zig");
const DocumentStore = @import("DocumentStore.zig"); const DocumentStore = @import("DocumentStore.zig");
pub const InternPool = @import("InternPool.zig"); pub const InternPool = @import("InternPool.zig");
pub const IPIndex = InternPool.Index; pub const Index = InternPool.Index;
pub const IPKey = InternPool.Key; pub const Key = InternPool.Key;
pub const ComptimeInterpreter = @This(); pub const ComptimeInterpreter = @This();
const log = std.log.scoped(.comptime_interpreter); const log = std.log.scoped(.comptime_interpreter);
@ -31,7 +31,7 @@ errors: std.AutoArrayHashMapUnmanaged(Ast.Node.Index, InterpreterError) = .{},
pub fn getHandle(interpreter: *ComptimeInterpreter) *const DocumentStore.Handle { pub fn getHandle(interpreter: *ComptimeInterpreter) *const DocumentStore.Handle {
// This interpreter is loaded from a known-valid handle so a valid handle must exist // This interpreter is loaded from a known-valid handle so a valid handle must exist
return interpreter.document_store.getOrLoadHandle(interpreter.uri).?; return interpreter.document_store.getHandle(interpreter.uri).?;
} }
pub const InterpreterError = struct { pub const InterpreterError = struct {
@ -39,7 +39,6 @@ pub const InterpreterError = struct {
message: []const u8, message: []const u8,
}; };
/// `message` must be allocated with interpreter allocator
pub fn recordError( pub fn recordError(
interpreter: *ComptimeInterpreter, interpreter: *ComptimeInterpreter,
node_idx: Ast.Node.Index, node_idx: Ast.Node.Index,
@ -73,21 +72,21 @@ pub const Type = struct {
interpreter: *ComptimeInterpreter, interpreter: *ComptimeInterpreter,
node_idx: Ast.Node.Index, node_idx: Ast.Node.Index,
ty: IPIndex, ty: Index,
}; };
pub const Value = struct { pub const Value = struct {
interpreter: *ComptimeInterpreter, interpreter: *ComptimeInterpreter,
node_idx: Ast.Node.Index, node_idx: Ast.Node.Index,
ty: IPIndex, ty: Index,
val: IPIndex, val: Index,
}; };
pub const Decl = struct { pub const Decl = struct {
name: []const u8, name: []const u8,
ty: IPIndex, ty: Index,
val: IPIndex, val: Index,
alignment: u16, alignment: u16,
address_space: std.builtin.AddressSpace, address_space: std.builtin.AddressSpace,
is_pub: bool, is_pub: bool,
@ -103,7 +102,7 @@ pub const Namespace = struct {
parent: NamespaceIndex, parent: NamespaceIndex,
node_idx: Ast.Node.Index, node_idx: Ast.Node.Index,
/// Will be a struct, enum, union, opaque or .none /// Will be a struct, enum, union, opaque or .none
ty: IPIndex, ty: Index,
decls: std.StringArrayHashMapUnmanaged(Decl) = .{}, decls: std.StringArrayHashMapUnmanaged(Decl) = .{},
usingnamespaces: std.ArrayListUnmanaged(NamespaceIndex) = .{}, usingnamespaces: std.ArrayListUnmanaged(NamespaceIndex) = .{},
@ -219,7 +218,7 @@ pub fn interpret(
// .tagged_union_enum_tag_trailing, // .tagged_union_enum_tag_trailing,
.root, .root,
=> { => {
const type_type = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type }); const type_type = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .type });
try interpreter.namespaces.append(interpreter.allocator, .{ try interpreter.namespaces.append(interpreter.allocator, .{
.parent = namespace, .parent = namespace,
@ -242,7 +241,7 @@ pub fn interpret(
var init_type_value = try (try interpreter.interpret(container_field.ast.type_expr, container_namespace, .{})).getValue(); var init_type_value = try (try interpreter.interpret(container_field.ast.type_expr, container_namespace, .{})).getValue();
var default_value = if (container_field.ast.value_expr == 0) var default_value = if (container_field.ast.value_expr == 0)
IPIndex.none Index.none
else else
(try (try interpreter.interpret(container_field.ast.value_expr, container_namespace, .{})).getValue()).val; // TODO check ty (try (try interpreter.interpret(container_field.ast.value_expr, container_namespace, .{})).getValue()).val; // TODO check ty
@ -269,7 +268,7 @@ pub fn interpret(
try fields.append(interpreter.allocator, field); try fields.append(interpreter.allocator, field);
} }
const struct_type = try interpreter.ip.get(interpreter.allocator, IPKey{ const struct_type = try interpreter.ip.get(interpreter.allocator, Key{
.struct_type = .{ .struct_type = .{
.fields = fields.items, .fields = fields.items,
.namespace = namespace, .namespace = namespace,
@ -309,7 +308,7 @@ pub fn interpret(
if (type_value == null and init_value == null) return InterpretResult{ .nothing = {} }; if (type_value == null and init_value == null) return InterpretResult{ .nothing = {} };
if (type_value) |v| { if (type_value) |v| {
const type_type = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type }); const type_type = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .type });
if (v.ty != type_type) return InterpretResult{ .nothing = {} }; if (v.ty != type_type) return InterpretResult{ .nothing = {} };
} }
@ -420,8 +419,8 @@ pub fn interpret(
return InterpretResult{ .value = Value{ return InterpretResult{ .value = Value{
.interpreter = interpreter, .interpreter = interpreter,
.node_idx = node_idx, .node_idx = node_idx,
.ty = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = simple.toType() }), .ty = try interpreter.ip.get(interpreter.allocator, Key{ .simple = simple.toType() }),
.val = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = simple }), .val = try interpreter.ip.get(interpreter.allocator, Key{ .simple = simple }),
} }; } };
} }
@ -429,8 +428,8 @@ pub fn interpret(
return InterpretResult{ .value = Value{ return InterpretResult{ .value = Value{
.interpreter = interpreter, .interpreter = interpreter,
.node_idx = node_idx, .node_idx = node_idx,
.ty = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type }), .ty = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .type }),
.val = try interpreter.ip.get(interpreter.allocator, IPKey{ .int_type = .{ .val = try interpreter.ip.get(interpreter.allocator, Key{ .int_type = .{
.signedness = if (identifier[0] == 'u') .unsigned else .signed, .signedness = if (identifier[0] == 'u') .unsigned else .signed,
.bits = std.fmt.parseInt(u16, identifier[1..], 10) catch break :blk, .bits = std.fmt.parseInt(u16, identifier[1..], 10) catch break :blk,
} }), } }),
@ -473,7 +472,6 @@ pub fn interpret(
.type => blk: { .type => blk: {
const ty_key = interpreter.ip.indexToKey(irv.val); const ty_key = interpreter.ip.indexToKey(irv.val);
if (interpreter.huntItDown(ty_key.getNamespace(), field_name, options)) |decl| { if (interpreter.huntItDown(ty_key.getNamespace(), field_name, options)) |decl| {
std.debug.print("here {s}: {}\n", .{field_name, decl.ty.fmtType(interpreter.ip)});
return InterpretResult{ .value = Value{ return InterpretResult{ .value = Value{
.interpreter = interpreter, .interpreter = interpreter,
.node_idx = node_idx, .node_idx = node_idx,
@ -488,7 +486,7 @@ pub fn interpret(
}, },
.union_type => {}, // TODO .union_type => {}, // TODO
.enum_type => |enum_info| { // TODO .enum_type => |enum_info| { // TODO
if (interpreter.ip.contains(IPKey{ .bytes = field_name })) |field_name_index| { if (interpreter.ip.contains(Key{ .bytes = field_name })) |field_name_index| {
for (enum_info.fields) |field| { for (enum_info.fields) |field| {
if (field.name != field_name_index) continue; if (field.name != field_name_index) continue;
return InterpretResult{ return InterpretResult{
@ -580,10 +578,9 @@ pub fn interpret(
}, },
.struct_type => |struct_info| blk: { .struct_type => |struct_info| blk: {
// if the intern pool does not contain the field name, it is impossible that there is a field with the given name // if the intern pool does not contain the field name, it is impossible that there is a field with the given name
const field_name_index = interpreter.ip.contains(IPKey{ .bytes = field_name }) orelse break :blk true; const field_name_index = interpreter.ip.contains(Key{ .bytes = field_name }) orelse break :blk true;
for (struct_info.fields) |field, i| { for (struct_info.fields) |field, i| {
std.debug.print("field {} {}\n", .{field.ty, field.ty.fmtType(interpreter.ip)});
if (field.name != field_name_index) continue; if (field.name != field_name_index) continue;
const val = found_val: { const val = found_val: {
if (irv.val == .none) break :found_val .none; if (irv.val == .none) break :found_val .none;
@ -653,8 +650,8 @@ pub fn interpret(
// if (options.observe_values) { // if (options.observe_values) {
const ir = try interpreter.interpret(if_info.ast.cond_expr, namespace, options); const ir = try interpreter.interpret(if_info.ast.cond_expr, namespace, options);
const false_value = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool_false }); const false_value = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .bool_false });
const true_value = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool_true }); const true_value = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .bool_true });
const condition = (try ir.getValue()).val; const condition = (try ir.getValue()).val;
std.debug.assert(condition == false_value or condition == true_value); std.debug.assert(condition == false_value or condition == true_value);
@ -673,8 +670,8 @@ pub fn interpret(
.value = Value{ .value = Value{
.interpreter = interpreter, .interpreter = interpreter,
.node_idx = node_idx, .node_idx = node_idx,
.ty = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool }), .ty = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .bool }),
.val = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = if (a.value.val == b.value.val) .bool_true else .bool_false }), // TODO eql function required? .val = try interpreter.ip.get(interpreter.allocator, Key{ .simple = if (a.value.val == b.value.val) .bool_true else .bool_false }), // TODO eql function required?
}, },
}; };
}, },
@ -684,19 +681,19 @@ pub fn interpret(
if (nl == .failure) return error.CriticalAstFailure; if (nl == .failure) return error.CriticalAstFailure;
const number_type = try interpreter.ip.get(interpreter.allocator, IPKey{ const number_type = try interpreter.ip.get(interpreter.allocator, Key{
.simple = if (nl == .float) .comptime_float else .comptime_int, .simple = if (nl == .float) .comptime_float else .comptime_int,
}); });
const value = try interpreter.ip.get( const value = try interpreter.ip.get(
interpreter.allocator, interpreter.allocator,
switch (nl) { switch (nl) {
.float => IPKey{ .float => Key{
.float_128_value = try std.fmt.parseFloat(f128, s), .float_128_value = try std.fmt.parseFloat(f128, s),
}, },
.int => if (s[0] == '-') IPKey{ .int => if (s[0] == '-') Key{
.int_i64_value = try std.fmt.parseInt(i64, s, 0), .int_i64_value = try std.fmt.parseInt(i64, s, 0),
} else IPKey{ } else Key{
.int_u64_value = try std.fmt.parseInt(u64, s, 0), .int_u64_value = try std.fmt.parseInt(u64, s, 0),
}, },
.big_int => |base| blk: { .big_int => |base| blk: {
@ -704,7 +701,7 @@ pub fn interpret(
defer big_int.deinit(); defer big_int.deinit();
const prefix_length: usize = if (base != .decimal) 2 else 0; const prefix_length: usize = if (base != .decimal) 2 else 0;
try big_int.setString(@enumToInt(base), s[prefix_length..]); try big_int.setString(@enumToInt(base), s[prefix_length..]);
break :blk IPKey{ .int_big_value = big_int.toConst() }; break :blk Key{ .int_big_value = big_int.toConst() };
}, },
.failure => return error.CriticalAstFailure, .failure => return error.CriticalAstFailure,
}, },
@ -812,13 +809,13 @@ pub fn interpret(
return InterpretResult{ .value = Value{ return InterpretResult{ .value = Value{
.interpreter = interpreter, .interpreter = interpreter,
.node_idx = node_idx, .node_idx = node_idx,
.ty = try interpreter.ip.get(interpreter.allocator, IPKey{ .struct_type = .{ .ty = try interpreter.ip.get(interpreter.allocator, Key{ .struct_type = .{
.fields = &.{}, .fields = &.{},
.namespace = .none, .namespace = .none,
.layout = .Auto, .layout = .Auto,
.backing_int_ty = .none, .backing_int_ty = .none,
} }), } }),
.val = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .undefined_value }), .val = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .undefined_value }),
} }; } };
} }
@ -832,7 +829,7 @@ pub fn interpret(
.value = Value{ .value = Value{
.interpreter = interpreter, .interpreter = interpreter,
.node_idx = node_idx, .node_idx = node_idx,
.ty = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type }), .ty = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .type }),
.val = .none, // TODO .val = .none, // TODO
}, },
}; };
@ -845,7 +842,7 @@ pub fn interpret(
return InterpretResult{ .value = Value{ return InterpretResult{ .value = Value{
.interpreter = interpreter, .interpreter = interpreter,
.node_idx = node_idx, .node_idx = node_idx,
.ty = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type }), .ty = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .type }),
.val = value.ty, .val = value.ty,
} }; } };
} }
@ -856,7 +853,7 @@ pub fn interpret(
const value = try (try interpreter.interpret(params[0], namespace, options)).getValue(); const value = try (try interpreter.interpret(params[0], namespace, options)).getValue();
const field_name = try (try interpreter.interpret(params[1], namespace, options)).getValue(); const field_name = try (try interpreter.interpret(params[1], namespace, options)).getValue();
const type_type = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type }); const type_type = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .type });
if (value.ty != type_type) return error.InvalidBuiltin; if (value.ty != type_type) return error.InvalidBuiltin;
if (interpreter.ip.indexToKey(field_name.ty) != .pointer_type) return error.InvalidBuiltin; // Check if it's a []const u8 if (interpreter.ip.indexToKey(field_name.ty) != .pointer_type) return error.InvalidBuiltin; // Check if it's a []const u8
@ -872,8 +869,8 @@ pub fn interpret(
return InterpretResult{ .value = Value{ return InterpretResult{ .value = Value{
.interpreter = interpreter, .interpreter = interpreter,
.node_idx = node_idx, .node_idx = node_idx,
.ty = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool }), .ty = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .bool }),
.val = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = if (has_decl) .bool_true else .bool_false }), .val = try interpreter.ip.get(interpreter.allocator, Key{ .simple = if (has_decl) .bool_true else .bool_false }),
} }; } };
} }
@ -883,7 +880,7 @@ pub fn interpret(
const as_type = try (try interpreter.interpret(params[0], namespace, options)).getValue(); const as_type = try (try interpreter.interpret(params[0], namespace, options)).getValue();
const value = try (try interpreter.interpret(params[1], namespace, options)).getValue(); const value = try (try interpreter.interpret(params[1], namespace, options)).getValue();
const type_type = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type }); const type_type = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .type });
if (as_type.ty != type_type) return error.InvalidBuiltin; if (as_type.ty != type_type) return error.InvalidBuiltin;
@ -903,14 +900,14 @@ pub fn interpret(
.string_literal => { .string_literal => {
const str = tree.getNodeSource(node_idx)[1 .. tree.getNodeSource(node_idx).len - 1]; const str = tree.getNodeSource(node_idx)[1 .. tree.getNodeSource(node_idx).len - 1];
const string_literal_type = try interpreter.ip.get(interpreter.allocator, IPKey{ .pointer_type = .{ const string_literal_type = try interpreter.ip.get(interpreter.allocator, Key{ .pointer_type = .{
.elem_type = try interpreter.ip.get(interpreter.allocator, IPKey{ .array_type = .{ .elem_type = try interpreter.ip.get(interpreter.allocator, Key{ .array_type = .{
.child = try interpreter.ip.get(interpreter.allocator, IPKey{ .int_type = .{ .child = try interpreter.ip.get(interpreter.allocator, Key{ .int_type = .{
.signedness = .unsigned, .signedness = .unsigned,
.bits = 8, .bits = 8,
} }), } }),
.len = @intCast(u32, str.len), .len = @intCast(u64, str.len),
.sentinel = try interpreter.ip.get(interpreter.allocator, IPKey{ .int_u64_value = 0 }), .sentinel = try interpreter.ip.get(interpreter.allocator, Key{ .int_u64_value = 0 }),
} }), } }),
.sentinel = .none, .sentinel = .none,
.alignment = 0, .alignment = 0,
@ -925,7 +922,7 @@ pub fn interpret(
.interpreter = interpreter, .interpreter = interpreter,
.node_idx = node_idx, .node_idx = node_idx,
.ty = string_literal_type, .ty = string_literal_type,
.val = try interpreter.ip.get(interpreter.allocator, IPKey{ .bytes = str }), .val = try interpreter.ip.get(interpreter.allocator, Key{ .bytes = str }),
} }; } };
}, },
// TODO: Add comptime autodetection; e.g. const MyArrayList = std.ArrayList(u8) // TODO: Add comptime autodetection; e.g. const MyArrayList = std.ArrayList(u8)
@ -943,14 +940,14 @@ pub fn interpret(
// TODO: Resolve function type // TODO: Resolve function type
const type_type = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type }); const type_type = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .type });
const function_type = try interpreter.ip.get(interpreter.allocator, IPKey{ .function_type = .{ const function_type = try interpreter.ip.get(interpreter.allocator, Key{ .function_type = .{
.calling_convention = .Unspecified, .calling_convention = .Unspecified,
.alignment = 0, .alignment = 0,
.is_generic = false, .is_generic = false,
.is_var_args = false, .is_var_args = false,
.return_type = IPIndex.none, .return_type = Index.none,
.args = &.{}, .args = &.{},
} }); } });
@ -1028,7 +1025,7 @@ pub fn interpret(
}, },
.bool_not => { .bool_not => {
const result = try interpreter.interpret(data[node_idx].lhs, namespace, .{}); const result = try interpreter.interpret(data[node_idx].lhs, namespace, .{});
const bool_type = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool }); const bool_type = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .bool });
const value = try result.getValue(); const value = try result.getValue();
if (value.ty != bool_type) { if (value.ty != bool_type) {
@ -1041,8 +1038,8 @@ pub fn interpret(
return error.InvalidOperation; return error.InvalidOperation;
} }
const false_value = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool_false }); const false_value = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .bool_false });
const true_value = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .bool_true }); const true_value = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .bool_true });
std.debug.assert(value.val == false_value or value.val == true_value); std.debug.assert(value.val == false_value or value.val == true_value);
return InterpretResult{ .value = .{ return InterpretResult{ .value = .{
@ -1059,7 +1056,7 @@ pub fn interpret(
const result = try interpreter.interpret(data[node_idx].lhs, namespace, .{}); const result = try interpreter.interpret(data[node_idx].lhs, namespace, .{});
const value = (try result.getValue()); const value = (try result.getValue());
const pointer_type = try interpreter.ip.get(interpreter.allocator, IPKey{ .pointer_type = .{ const pointer_type = try interpreter.ip.get(interpreter.allocator, Key{ .pointer_type = .{
.elem_type = value.ty, .elem_type = value.ty,
.sentinel = .none, .sentinel = .none,
.alignment = 0, .alignment = 0,
@ -1134,7 +1131,7 @@ pub fn call(
}); });
const fn_namespace = @intToEnum(NamespaceIndex, interpreter.namespaces.len - 1); const fn_namespace = @intToEnum(NamespaceIndex, interpreter.namespaces.len - 1);
const type_type = try interpreter.ip.get(interpreter.allocator, IPKey{ .simple = .type }); const type_type = try interpreter.ip.get(interpreter.allocator, Key{ .simple = .type });
var arg_it = proto.iterate(&tree); var arg_it = proto.iterate(&tree);
var arg_index: usize = 0; var arg_index: usize = 0;

View File

@ -44,6 +44,7 @@ pub const Struct = struct {
backing_int_ty: Index, backing_int_ty: Index,
pub const Field = packed struct { pub const Field = packed struct {
/// guaranteed to be .bytes
name: Index, name: Index,
ty: Index, ty: Index,
default_value: Index = .none, default_value: Index = .none,
@ -62,6 +63,7 @@ pub const ErrorUnion = packed struct {
}; };
pub const ErrorSet = struct { pub const ErrorSet = struct {
/// every element is guaranteed to be .bytes
names: []const Index, names: []const Index,
}; };
@ -72,6 +74,7 @@ pub const Enum = struct {
tag_type_infered: bool, tag_type_infered: bool,
pub const Field = packed struct { pub const Field = packed struct {
/// guaranteed to be .bytes
name: Index, name: Index,
val: Index, val: Index,
}; };
@ -79,8 +82,11 @@ pub const Enum = struct {
pub const Function = struct { pub const Function = struct {
args: []const Index, args: []const Index,
/// zig only lets the first 32 arguments be `comptime`
args_is_comptime: std.StaticBitSet(32) = std.StaticBitSet(32).initEmpty(), args_is_comptime: std.StaticBitSet(32) = std.StaticBitSet(32).initEmpty(),
/// zig only lets the first 32 arguments be generic
args_is_generic: std.StaticBitSet(32) = std.StaticBitSet(32).initEmpty(), args_is_generic: std.StaticBitSet(32) = std.StaticBitSet(32).initEmpty(),
/// zig only lets the first 32 arguments be `noalias`
args_is_noalias: std.StaticBitSet(32) = std.StaticBitSet(32).initEmpty(), args_is_noalias: std.StaticBitSet(32) = std.StaticBitSet(32).initEmpty(),
return_type: Index, return_type: Index,
alignment: u16 = 0, alignment: u16 = 0,
@ -96,6 +102,7 @@ pub const Union = struct {
layout: std.builtin.Type.ContainerLayout = .Auto, layout: std.builtin.Type.ContainerLayout = .Auto,
pub const Field = packed struct { pub const Field = packed struct {
/// guaranteed to be .bytes
name: Index, name: Index,
ty: Index, ty: Index,
alignment: u16, alignment: u16,
@ -1226,6 +1233,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
}; };
} }
/// TODO rename to getOrPut
pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
const adapter: KeyAdapter = .{ .ip = ip }; const adapter: KeyAdapter = .{ .ip = ip };
const gop = try ip.map.getOrPutAdapted(gpa, key, adapter); const gop = try ip.map.getOrPutAdapted(gpa, key, adapter);
@ -1254,6 +1262,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
return @intToEnum(Index, ip.items.len - 1); return @intToEnum(Index, ip.items.len - 1);
} }
/// TODO rename to get
pub fn contains(ip: InternPool, key: Key) ?Index { pub fn contains(ip: InternPool, key: Key) ?Index {
const adapter: KeyAdapter = .{ .ip = &ip }; const adapter: KeyAdapter = .{ .ip = &ip };
const index = ip.map.getIndexAdapted(key, adapter) orelse return null; const index = ip.map.getIndexAdapted(key, adapter) orelse return null;