VAL bigMod(VM* vm, VAL x, VAL y) { mpz_t* bigint; VAL cl = allocate(vm, sizeof(Closure) + sizeof(mpz_t), 0); bigint = (mpz_t*)(((char*)cl) + sizeof(Closure)); mpz_mod(*bigint, GETMPZ(GETBIG(vm,x)), GETMPZ(GETBIG(vm,y))); SETTY(cl, BIGINT); cl -> info.ptr = (void*)bigint; return cl; }
VAL bigDiv(VM* vm, VAL x, VAL y) { idris_requireAlloc(IDRIS_MAXGMP); mpz_t* bigint; VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0); bigint = (mpz_t*)(((char*)cl) + sizeof(Closure)); mpz_tdiv_q(*bigint, GETMPZ(GETBIG(vm,x)), GETMPZ(GETBIG(vm,y))); SETTY(cl, BIGINT); cl -> info.ptr = (void*)bigint; return cl; }
VAL idris_bigMinus(VM* vm, VAL x, VAL y) { if (ISINT(x) && ISINT(y)) { i_int vx = GETINT(x); i_int vy = GETINT(y); if ((vx <= 0 && vy <=0) || (vx >=0 && vy <=0)) { return INTOP(-, x, y); } i_int res = vx - vy; if (res >= 1<<30 || res <= -(1 << 30)) { return bigSub(vm, GETBIG(vm, x), GETBIG(vm, y)); } else { return MKINT(res); } } else {
VAL GETBIG(VM * vm, VAL x) { idris_requireAlloc(IDRIS_MAXGMP); if (ISINT(x)) { mpz_t* bigint; VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0); idris_doneAlloc(); bigint = (mpz_t*)(((char*)cl) + sizeof(Closure)); mpz_init(*bigint); mpz_set_si(*bigint, GETINT(x)); SETTY(cl, CT_BIGINT); cl -> info.ptr = (void*)bigint; return cl; } else { idris_doneAlloc(); switch(GETTY(x)) { case CT_FWD: return GETBIG(vm, x->info.ptr); default: return x; } } }
VAL idris_bigPlus(VM* vm, VAL x, VAL y) { if (ISINT(x) && ISINT(y)) { i_int vx = GETINT(x); i_int vy = GETINT(y); if ((vx <= 0 && vy >=0) || (vx >=0 && vy <=0)) { return ADD(x, y); } i_int res = vx + vy; if (res >= 1<<30 || res <= -(1 << 30)) { return bigAdd(vm, GETBIG(vm, x), GETBIG(vm, y)); } else { return MKINT(res); } } else { return bigAdd(vm, GETBIG(vm, x), GETBIG(vm, y)); } }
VAL bigAShiftRight(VM* vm, VAL x, VAL y) { idris_requireAlloc(IDRIS_MAXGMP); mpz_t* bigint; VAL cl = allocate(sizeof(Closure) + sizeof(mpz_t), 0); idris_doneAlloc(); bigint = (mpz_t*)(((char*)cl) + sizeof(Closure)); mpz_fdiv_q_2exp(*bigint, GETMPZ(GETBIG(vm,x)), GETINT(y)); SETTY(cl, CT_BIGINT); cl -> info.ptr = (void*)bigint; return cl; }
VAL GETBIG(VM * vm, VAL x) { if (ISINT(x)) { mpz_t* bigint; VAL cl = allocate(vm, sizeof(Closure) + sizeof(mpz_t), 0); bigint = (mpz_t*)(((char*)cl) + sizeof(Closure)); mpz_init(*bigint); mpz_set_si(*bigint, GETINT(x)); SETTY(cl, BIGINT); cl -> info.ptr = (void*)bigint; return cl; } else { switch(GETTY(x)) { case FWD: return GETBIG(vm, x->info.ptr); default: return x; } } }