feature. See also
. The project being documented here (as the example) is the Zig library itself.
Interner.put
pub fn put(i: *Interner, gpa: Allocator, key: Key) !Ref
File
Code
pub fn put(i: *Interner, gpa: Allocator, key: Key) !Ref {
if (key.toRef()) |some| return some;
const adapter: KeyAdapter = .{ .interner = i };
const gop = try i.map.getOrPutAdapted(gpa, key, adapter);
if (gop.found_existing) return @fromBackingInt(@intCast(gop.index));
try i.items.ensureUnusedCapacity(gpa, 1);
switch (key) {
.int_ty => |bits| {
i.items.appendAssumeCapacity(.{
.tag = .int_ty,
.data = bits,
});
},
.float_ty => |bits| {
i.items.appendAssumeCapacity(.{
.tag = .float_ty,
.data = bits,
});
},
.complex_ty => |bits| {
i.items.appendAssumeCapacity(.{
.tag = .complex_ty,
.data = bits,
});
},
.array_ty => |info| {
const split_len = PackedU64.init(info.len);
i.items.appendAssumeCapacity(.{
.tag = .array_ty,
.data = try i.addExtra(gpa, Tag.Array{
.len0 = split_len.a,
.len1 = split_len.b,
.child = info.child,
}),
});
},
.vector_ty => |info| {
i.items.appendAssumeCapacity(.{
.tag = .vector_ty,
.data = try i.addExtra(gpa, Tag.Vector{
.len = info.len,
.child = info.child,
}),
});
},
.pointer => |info| {
i.items.appendAssumeCapacity(.{
.tag = .pointer,
.data = try i.addExtra(gpa, Tag.Pointer{
.node = info.node,
.offset = info.offset,
}),
});
},
.int => |repr| int: {
var space: Tag.Int.BigIntSpace = undefined;
const big = repr.toBigInt(&space);
switch (repr) {
.u64 => |data| if (std.math.cast(u32, data)) |small| {
i.items.appendAssumeCapacity(.{
.tag = .u32,
.data = small,
});
break :int;
},
.i64 => |data| if (std.math.cast(i32, data)) |small| {
i.items.appendAssumeCapacity(.{
.tag = .i32,
.data = @bitCast(small),
});
break :int;
},
.big_int => |data| {
if (data.fitsInTwosComp(.unsigned, 32)) {
i.items.appendAssumeCapacity(.{
.tag = .u32,
.data = data.toInt(u32) catch unreachable,
});
break :int;
} else if (data.fitsInTwosComp(.signed, 32)) {
i.items.appendAssumeCapacity(.{
.tag = .i32,
.data = @bitCast(data.toInt(i32) catch unreachable),
});
break :int;
}
},
}
const limbs_index: u32 = @intCast(i.limbs.items.len);
try i.limbs.appendSlice(gpa, big.limbs);
i.items.appendAssumeCapacity(.{
.tag = if (big.positive) .int_positive else .int_negative,
.data = try i.addExtra(gpa, Tag.Int{
.limbs_index = limbs_index,
.limbs_len = @intCast(big.limbs.len),
}),
});
},
.float => |repr| switch (repr) {
.f16 => |data| i.items.appendAssumeCapacity(.{
.tag = .f16,
.data = @as(u16, @bitCast(data)),
}),
.f32 => |data| i.items.appendAssumeCapacity(.{
.tag = .f32,
.data = @as(u32, @bitCast(data)),
}),
.f64 => |data| i.items.appendAssumeCapacity(.{
.tag = .f64,
.data = try i.addExtra(gpa, Tag.F64.pack(data)),
}),
.f80 => |data| i.items.appendAssumeCapacity(.{
.tag = .f80,
.data = try i.addExtra(gpa, Tag.F80.pack(data)),
}),
.f128 => |data| i.items.appendAssumeCapacity(.{
.tag = .f128,
.data = try i.addExtra(gpa, Tag.F128.pack(data)),
}),
},
.complex => |repr| switch (repr) {
.cf16 => |data| i.items.appendAssumeCapacity(.{
.tag = .cf16,
.data = try i.addExtra(gpa, Tag.CF16.pack(data)),
}),
.cf32 => |data| i.items.appendAssumeCapacity(.{
.tag = .cf32,
.data = try i.addExtra(gpa, Tag.CF32.pack(data)),
}),
.cf64 => |data| i.items.appendAssumeCapacity(.{
.tag = .cf64,
.data = try i.addExtra(gpa, Tag.CF64.pack(data)),
}),
.cf80 => |data| i.items.appendAssumeCapacity(.{
.tag = .cf80,
.data = try i.addExtra(gpa, Tag.CF80.pack(data)),
}),
.cf128 => |data| i.items.appendAssumeCapacity(.{
.tag = .cf128,
.data = try i.addExtra(gpa, Tag.CF128.pack(data)),
}),
},
.bytes => |bytes| {
const strings_index: u32 = @intCast(i.strings.items.len);
try i.strings.appendSlice(gpa, bytes);
i.items.appendAssumeCapacity(.{
.tag = .bytes,
.data = try i.addExtra(gpa, Tag.Bytes{
.strings_index = strings_index,
.len = @intCast(bytes.len),
}),
});
},
.record_ty => |elems| {
try i.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.Record).@"struct".field_names.len +
elems.len);
i.items.appendAssumeCapacity(.{
.tag = .record_ty,
.data = i.addExtraAssumeCapacity(Tag.Record{
.elements_len = @intCast(elems.len),
}),
});
i.extra.appendSliceAssumeCapacity(@ptrCast(elems));
},
.ptr_ty,
.noreturn_ty,
.void_ty,
.func_ty,
.null,
=> unreachable,
}
return @fromBackingInt(@intCast(gop.index));
}