| ... | @@ -1660,19 +1660,26 @@ pub const Value = extern union { | ... | @@ -1660,19 +1660,26 @@ pub const Value = extern union { |
| 1660 | if (ty.isAnyFloat()) { | 1660 | if (ty.isAnyFloat()) { |
| 1661 | return floatAdd(lhs, rhs, ty, arena); | 1661 | return floatAdd(lhs, rhs, ty, arena); |
| 1662 | } | 1662 | } |
| 1663 | const result = try intAdd(lhs, rhs, arena); | | |
| 1664 | | 1663 | |
| 1665 | const max = try ty.maxInt(arena, target); | 1664 | const info = ty.intInfo(target); |
| 1666 | if (compare(result, .gt, max, ty)) { | | |
| 1667 | @panic("TODO comptime wrapping integer addition"); | | |
| 1668 | } | | |
| 1669 | | 1665 | |
| 1670 | const min = try ty.minInt(arena, target); | 1666 | var lhs_space: Value.BigIntSpace = undefined; |
| 1671 | if (compare(result, .lt, min, ty)) { | 1667 | var rhs_space: Value.BigIntSpace = undefined; |
| 1672 | @panic("TODO comptime wrapping integer addition"); | 1668 | const lhs_bigint = lhs.toBigInt(&lhs_space); |
| 1673 | } | 1669 | const rhs_bigint = rhs.toBigInt(&rhs_space); |
| | 1670 | const limbs = try arena.alloc( |
| | 1671 | std.math.big.Limb, |
| | 1672 | std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1, |
| | 1673 | ); |
| | 1674 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| | 1675 | result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| | 1676 | const result_limbs = result_bigint.limbs[0..result_bigint.len]; |
| 1674 | | 1677 | |
| 1675 | return result; | 1678 | if (result_bigint.positive) { |
| | 1679 | return Value.Tag.int_big_positive.create(arena, result_limbs); |
| | 1680 | } else { |
| | 1681 | return Value.Tag.int_big_negative.create(arena, result_limbs); |
| | 1682 | } |
| 1676 | } | 1683 | } |
| 1677 | | 1684 | |
| 1678 | /// Supports integers only; asserts neither operand is undefined. | 1685 | /// Supports integers only; asserts neither operand is undefined. |
| ... | @@ -1714,19 +1721,27 @@ pub const Value = extern union { | ... | @@ -1714,19 +1721,27 @@ pub const Value = extern union { |
| 1714 | if (ty.isAnyFloat()) { | 1721 | if (ty.isAnyFloat()) { |
| 1715 | return floatSub(lhs, rhs, ty, arena); | 1722 | return floatSub(lhs, rhs, ty, arena); |
| 1716 | } | 1723 | } |
| 1717 | const result = try intSub(lhs, rhs, arena); | | |
| 1718 | | 1724 | |
| 1719 | const max = try ty.maxInt(arena, target); | 1725 | const info = ty.intInfo(target); |
| 1720 | if (compare(result, .gt, max, ty)) { | | |
| 1721 | @panic("TODO comptime wrapping integer subtraction"); | | |
| 1722 | } | | |
| 1723 | | 1726 | |
| 1724 | const min = try ty.minInt(arena, target); | 1727 | var lhs_space: Value.BigIntSpace = undefined; |
| 1725 | if (compare(result, .lt, min, ty)) { | 1728 | var rhs_space: Value.BigIntSpace = undefined; |
| 1726 | @panic("TODO comptime wrapping integer subtraction"); | 1729 | const lhs_bigint = lhs.toBigInt(&lhs_space); |
| | 1730 | const rhs_bigint = rhs.toBigInt(&rhs_space); |
| | 1731 | const limbs = try arena.alloc( |
| | 1732 | std.math.big.Limb, |
| | 1733 | std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1, |
| | 1734 | ); |
| | 1735 | var result_bigint = BigIntMutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| | 1736 | result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| | 1737 | const result_limbs = result_bigint.limbs[0..result_bigint.len]; |
| | 1738 | |
| | 1739 | if (result_bigint.positive) { |
| | 1740 | return Value.Tag.int_big_positive.create(arena, result_limbs); |
| | 1741 | } else { |
| | 1742 | return Value.Tag.int_big_negative.create(arena, result_limbs); |
| 1727 | } | 1743 | } |
| 1728 | | 1744 | |
| 1729 | return result; | | |
| 1730 | } | 1745 | } |
| 1731 | | 1746 | |
| 1732 | /// Supports integers only; asserts neither operand is undefined. | 1747 | /// Supports integers only; asserts neither operand is undefined. |