| ... | @@ -2136,12 +2136,24 @@ pub const Value = extern union { | ... | @@ -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 { | 2139 | pub fn intTrunc(val: Value, allocator: *Allocator, signedness: std.builtin.Signedness, bits: u16) !Value { |
| 2140 | const x = val.toUnsignedInt(); // TODO: implement comptime truncate on big ints | 2140 | var val_space: Value.BigIntSpace = undefined; |
| 2141 | if (bits == 64) return val; | 2141 | const val_bigint = val.toBigInt(&val_space); |
| 2142 | const mask = (@as(u64, 1) << @intCast(u6, bits)) - 1; | 2142 | |
| 2143 | const truncated = x & mask; | 2143 | const limbs = try allocator.alloc( |
| 2144 | return Tag.int_u64.create(arena, truncated); | 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 | pub fn shl(lhs: Value, rhs: Value, allocator: *Allocator) !Value { | 2159 | pub fn shl(lhs: Value, rhs: Value, allocator: *Allocator) !Value { |