@@ -0,0 +1,242 @@
7+ return MKINT((i_int)val);
10+VAL MKBIGC(VM* vm, char* val) {
12+ VAL cl = allocate(vm, sizeof(ClosureType) + sizeof(void*));
13+ bigint = allocate(vm, sizeof(mpz_t));
16+ mpz_set_str(*bigint, val, 10);
19+ cl -> info.ptr = (void*)bigint;
24+VAL MKBIGM(VM* vm, void* big) {
26+ VAL cl = allocate(vm, sizeof(ClosureType) + sizeof(void*));
27+ bigint = allocate(vm, sizeof(mpz_t));
30+ mpz_set(*bigint, *((mpz_t*)big));
33+ cl -> info.ptr = (void*)bigint;
38+VAL GETBIG(VM * vm, VAL x) {
41+ VAL cl = allocate(vm, sizeof(ClosureType) + sizeof(void*));
42+ bigint = allocate(vm, sizeof(mpz_t));
45+ mpz_set_si(*bigint, GETINT(x));
48+ cl -> info.ptr = (void*)bigint;
56+VAL bigAdd(VM* vm, VAL x, VAL y) {
58+ VAL cl = allocate(vm, sizeof(ClosureType) + sizeof(void*));
59+ bigint = allocate(vm, sizeof(mpz_t));
60+ mpz_add(*bigint, GETMPZ(x), GETMPZ(y));
62+ cl -> info.ptr = (void*)bigint;
66+VAL bigSub(VM* vm, VAL x, VAL y) {
68+ VAL cl = allocate(vm, sizeof(ClosureType) + sizeof(void*));
69+ bigint = allocate(vm, sizeof(mpz_t));
70+ mpz_sub(*bigint, GETMPZ(x), GETMPZ(y));
72+ cl -> info.ptr = (void*)bigint;
76+VAL bigMul(VM* vm, VAL x, VAL y) {
78+ VAL cl = allocate(vm, sizeof(ClosureType) + sizeof(void*));
79+ bigint = allocate(vm, sizeof(mpz_t));
80+ mpz_mul(*bigint, GETMPZ(x), GETMPZ(y));
82+ cl -> info.ptr = (void*)bigint;
86+VAL bigDiv(VM* vm, VAL x, VAL y) {
88+ VAL cl = allocate(vm, sizeof(ClosureType) + sizeof(void*));
89+ bigint = allocate(vm, sizeof(mpz_t));
90+ mpz_div(*bigint, GETMPZ(x), GETMPZ(y));
92+ cl -> info.ptr = (void*)bigint;
96+VAL idris_bigPlus(VM* vm, VAL x, VAL y) {
97+ if (ISINT(x) && ISINT(y)) {
98+ i_int vx = GETINT(x);
99+ i_int vy = GETINT(y);
100+ if ((vx <= 0 && vy >=0) || (vx >=0 && vy <=0)) {
103+ i_int res = vx + vy;
104+ if (res >= 1<<30 || res <= -(1 << 30)) {
105+ return bigAdd(vm, GETBIG(vm, x), GETBIG(vm, y));
110+ return bigAdd(vm, GETBIG(vm, x), GETBIG(vm, y));
114+VAL idris_bigMinus(VM* vm, VAL x, VAL y) {
115+ if (ISINT(x) && ISINT(y)) {
116+ i_int vx = GETINT(x);
117+ i_int vy = GETINT(y);
118+ if ((vx <= 0 && vy <=0) || (vx >=0 && vy <=0)) {
119+ return INTOP(-, x, y);
121+ i_int res = vx - vy;
122+ if (res >= 1<<30 || res <= -(1 << 30)) {
123+ return bigSub(vm, GETBIG(vm, x), GETBIG(vm, y));
128+ return bigSub(vm, GETBIG(vm, x), GETBIG(vm, y));
132+VAL idris_bigTimes(VM* vm, VAL x, VAL y) {
133+ if (ISINT(x) && ISINT(y)) {
134+ i_int vx = GETINT(x);
135+ i_int vy = GETINT(y);
136+ // we could work out likelihood of overflow by checking the number
137+ // of necessary bits. Here's a quick conservative hack instead.
138+ if ((vx < (1<<15) && vy < (1<16)) ||
139+ (vx < (1<<16) && vy < (1<15)) ||
140+ (vx < (1<<20) && vy < (1<11)) ||
141+ (vx < (1<<11) && vy < (1<20)) ||
142+ (vx < (1<<23) && vy < (1<<8)) ||
143+ (vx < (1<<8) && vy < (1<<23))) { // ultra-conservative!
144+ return INTOP(*,x,y);
146+ return bigMul(vm, GETBIG(vm, x), GETBIG(vm, y));
149+ return bigMul(vm, GETBIG(vm, x), GETBIG(vm, y));
153+VAL idris_bigDivide(VM* vm, VAL x, VAL y) {
154+ if (ISINT(x) && ISINT(y)) {
155+ return INTOP(/, x, y);
157+ return bigDiv(vm, GETBIG(vm, x), GETBIG(vm, y));
161+VAL bigEq(VM* vm, VAL x, VAL y) {
162+ return MKINT((i_int)(mpz_cmp(GETMPZ(x), GETMPZ(y)) == 0));
165+VAL bigLt(VM* vm, VAL x, VAL y) {
166+ return MKINT((i_int)(mpz_cmp(GETMPZ(x), GETMPZ(y)) < 0));
169+VAL bigGt(VM* vm, VAL x, VAL y) {
170+ return MKINT((i_int)(mpz_cmp(GETMPZ(x), GETMPZ(y)) > 0));
173+VAL bigLe(VM* vm, VAL x, VAL y) {
174+ return MKINT((i_int)(mpz_cmp(GETMPZ(x), GETMPZ(y)) <= 0));
177+VAL bigGe(VM* vm, VAL x, VAL y) {
178+ return MKINT((i_int)(mpz_cmp(GETMPZ(x), GETMPZ(y)) >= 0));
181+VAL idris_bigEq(VM* vm, VAL x, VAL y) {
182+ if (ISINT(x) && ISINT(y)) {
183+ return MKINT((i_int)(GETINT(x) == GETINT(y)));
185+ return bigEq(vm, x, y);
189+VAL idris_bigLt(VM* vm, VAL x, VAL y) {
190+ if (ISINT(x) && ISINT(y)) {
191+ return MKINT((i_int)(GETINT(x) < GETINT(y)));
193+ return bigLt(vm, x, y);
197+VAL idris_bigLe(VM* vm, VAL x, VAL y) {
198+ if (ISINT(x) && ISINT(y)) {
199+ return MKINT((i_int)GETINT(x) <= GETINT(y));
201+ return bigLe(vm, x, y);
205+VAL idris_bigGt(VM* vm, VAL x, VAL y) {
206+ if (ISINT(x) && ISINT(y)) {
207+ return MKINT((i_int)(GETINT(x) > GETINT(y)));
209+ return bigGt(vm, x, y);
213+VAL idris_bigGe(VM* vm, VAL x, VAL y) {
214+ if (ISINT(x) && ISINT(y)) {
215+ return MKINT((i_int)(GETINT(x) >= GETINT(y)));
217+ return bigGe(vm, x, y);
222+VAL idris_castIntBig(VM* vm, VAL i) {
226+VAL idris_castBigInt(VM* vm, VAL i) {
230+ return MKINT((i_int)(mpz_get_ui(GETMPZ(i))));
234+VAL idris_castStrBig(VM* vm, VAL i) {
235+ return MKBIGC(vm, GETSTR(i));
238+VAL idris_castBigStr(VM* vm, VAL i) {
239+ char* str = mpz_get_str(NULL, 10, GETMPZ(GETBIG(vm, i)));
240+ return MKSTR(vm, str);