| ... | ... | @@ -2136,12 +2136,24 @@ pub const Value = extern union { |
| 2136 | 2136 | } |
| 2137 | 2137 | } |
| 2138 | 2138 | |
| 2139 | | pub fn intTrunc(val: Value, arena: *Allocator, bits: u16) !Value { |
| 2140 | | const x = val.toUnsignedInt(); // TODO: implement comptime truncate on big ints |
| 2141 | | if (bits == 64) return val; |
| 2142 | | const mask = (@as(u64, 1) << @intCast(u6, bits)) - 1; |
| 2143 | | const truncated = x & mask; |
| 2144 | | return Tag.int_u64.create(arena, truncated); |
| 2139 | pub fn intTrunc(val: Value, allocator: *Allocator, signedness: std.builtin.Signedness, bits: u16) !Value { |
| 2140 | var val_space: Value.BigIntSpace = undefined; |
| 2141 | const val_bigint = val.toBigInt(&val_space); |
| 2142 | |
| 2143 | const limbs = try allocator.alloc( |
| 2144 | std.math.big.Limb, |
| 2145 | std.math.big.int.calcTwosCompLimbCount(bits), |
| 2146 | ); |
| 2147 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| 2148 | |
| 2149 | result_bigint.truncate(val_bigint, signedness, bits); |
| 2150 | const result_limbs = result_bigint.limbs[0..result_bigint.len]; |
| 2151 | |
| 2152 | if (result_bigint.positive) { |
| 2153 | return Value.Tag.int_big_positive.create(allocator, result_limbs); |
| 2154 | } else { |
| 2155 | return Value.Tag.int_big_negative.create(allocator, result_limbs); |
| 2156 | } |
| 2145 | 2157 | } |
| 2146 | 2158 | |
| 2147 | 2159 | pub fn shl(lhs: Value, rhs: Value, allocator: *Allocator) !Value { |