Skip to content

Commit 6ebd329

Browse files
Port biginteger (#581)
* Port `biginteger` * Use the same implementation in `bigint` & `biginteger`
1 parent e671f1b commit 6ebd329

4 files changed

Lines changed: 34 additions & 19 deletions

File tree

compiler+runtime/include/cpp/jank/runtime/core/math.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace jank::runtime
99
using integer_ref = oref<struct integer>;
1010
using real_ref = oref<struct real>;
1111
using ratio_ref = oref<struct ratio>;
12+
using big_integer_ref = oref<struct big_integer>;
1213
using big_decimal_ref = oref<struct big_decimal>;
1314
}
1415

@@ -278,6 +279,8 @@ namespace jank::runtime
278279
i64 parse_long(object_ref o);
279280
f64 parse_double(object_ref o);
280281

282+
obj::big_integer_ref to_big_integer(object_ref const o);
283+
281284
bool is_big_decimal(object_ref const o);
282285
obj::big_decimal_ref to_big_decimal(object_ref const o);
283286
}

compiler+runtime/src/cpp/jank/runtime/core/math.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,6 +1775,34 @@ namespace jank::runtime
17751775
}
17761776
}
17771777

1778+
obj::big_integer_ref to_big_integer(object_ref const o)
1779+
{
1780+
return visit_number_like(
1781+
[&](auto const typed_o) -> obj::big_integer_ref {
1782+
using T = typename decltype(typed_o)::value_type;
1783+
1784+
if constexpr(std::same_as<T, obj::big_integer>)
1785+
{
1786+
return typed_o;
1787+
}
1788+
else if constexpr(std::same_as<T, obj::integer>)
1789+
{
1790+
return make_box<obj::big_integer>(typed_o->data);
1791+
}
1792+
else if constexpr(std::same_as<T, obj::real> || std::same_as<T, obj::ratio>
1793+
|| std::same_as<T, obj::big_decimal>)
1794+
{
1795+
return make_box<obj::big_integer>(typed_o->to_integer());
1796+
}
1797+
else
1798+
{
1799+
throw make_box(util::format("Expected a numeric value, got {}", object_type_str(o->type)))
1800+
.erase();
1801+
}
1802+
},
1803+
o);
1804+
}
1805+
17781806
bool is_big_decimal(object_ref const o)
17791807
{
17801808
return o->type == object_type::big_decimal;

compiler+runtime/src/jank/clojure/core.jank

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5444,28 +5444,12 @@
54445444
(defn bigint
54455445
"Coerce to BigInt"
54465446
[x]
5447-
;; (cond
5448-
;; (instance? clojure.lang.BigInt x) x
5449-
;; (instance? BigInteger x) (clojure.lang.BigInt/fromBigInteger x)
5450-
;; (decimal? x) (bigint (.toBigInteger ^BigDecimal x))
5451-
;; (float? x) (bigint (. BigDecimal valueOf (double x)))
5452-
;; (ratio? x) (bigint (.bigIntegerValue ^clojure.lang.Ratio x))
5453-
;; (number? x) (clojure.lang.BigInt/valueOf (long x))
5454-
;; :else (bigint (BigInteger. x)))
5455-
(throw "TODO: port bigint"))
5447+
(cpp/jank.runtime.to_big_integer x))
54565448

54575449
(defn biginteger
54585450
"Coerce to BigInteger"
54595451
[x]
5460-
;; (cond
5461-
;; (instance? BigInteger x) x
5462-
;; (instance? clojure.lang.BigInt x) (.toBigInteger ^clojure.lang.BigInt x)
5463-
;; (decimal? x) (.toBigInteger ^BigDecimal x)
5464-
;; (float? x) (.toBigInteger (. BigDecimal valueOf (double x)))
5465-
;; (ratio? x) (.bigIntegerValue ^clojure.lang.Ratio x)
5466-
;; (number? x) (BigInteger/valueOf (long x))
5467-
;; :else (BigInteger. x))
5468-
(throw "TODO: port biginteger"))
5452+
(cpp/jank.runtime.to_big_integer x))
54695453

54705454
(defn bigdec
54715455
"Coerce to BigDecimal"

compiler+runtime/test/bash/clojure-test-suite/src/jank_test/run_clojure_test_suite.cljc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
clojure.core-test.any-qmark
1111
;clojure.core-test.associative-qmark ; TODO: port to-array
1212
clojure.core-test.bigdec ; Unable to resolve symbol 'java.math.BigDecimal'., Read error (312 - 314): invalid number: chars 'M' are invalid for radix 10
13-
;clojure.core-test.bigint ; Unable to resolve symbol 'clojure.lang.BigInt'.
13+
;clojure.core-test.bigint ; TODO: port inc' & dec'.
1414
;clojure.core-test.binding ; TODO: port future
1515
;clojure.core-test.bit-and ; Uncaught exception: invalid object type: 0
1616
;clojure.core-test.bit-and-not ; Uncaught exception: invalid object type: 0

0 commit comments

Comments
 (0)