Bignum AND, OR, XOR

This commit is contained in:
Justin Ethier 2017-03-29 07:34:30 +00:00
parent 6e9fcc6434
commit f8bbff4ebb

View file

@ -29,15 +29,22 @@
;;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;;;; ;;;;
(define-c raw-logand (define-syntax binop
"(void* data, int argc, closure _, object k, object x, object y)" (er-macro-transformer
(lambda (expr rename compare)
(let* ((fnc (cadr expr))
(args
"(void* data, int argc, closure _, object k, object x, object y)")
(int-code (caddr expr))
(bn-op-code (cadddr expr))
(body
(string-append
"Cyc_check_int(data, x); "Cyc_check_int(data, x);
Cyc_check_int(data, y); Cyc_check_int(data, y);
if (obj_is_int(x) && obj_is_int(y)) { if (obj_is_int(x) && obj_is_int(y)) {"
int result = ((int)unbox_number(x)) & ((int)unbox_number(y)); int-code
return_closcall1(data, k, obj_int2obj(result)); "} else {
} else {
int result; int result;
alloc_bignum(data, bn); alloc_bignum(data, bn);
mp_int *xx, *yy; mp_int *xx, *yy;
@ -59,7 +66,9 @@
yy = &bignum_value(y); yy = &bignum_value(y);
} }
result = mp_and(xx, yy, &(bignum_value(bn))); "
bn-op-code
"
if (MP_OKAY != result) { if (MP_OKAY != result) {
char buffer[128]; char buffer[128];
snprintf(buffer, 127, \"Bignum error: %s\", mp_error_to_string(result)); snprintf(buffer, 127, \"Bignum error: %s\", mp_error_to_string(result));
@ -67,7 +76,26 @@
} }
return_closcall1(data, k, Cyc_bignum_normalize(data, bn)); return_closcall1(data, k, Cyc_bignum_normalize(data, bn));
} }
") ")))
`(define-c ,fnc ,args ,body)))))
(begin
(binop
raw-logand
" int result = ((int)unbox_number(x)) & ((int)unbox_number(y));
return_closcall1(data, k, obj_int2obj(result)); "
" result = mp_and(xx, yy, &(bignum_value(bn))); ")
(binop
raw-logior
" int result = ((int)unbox_number(x)) | ((int)unbox_number(y));
return_closcall1(data, k, obj_int2obj(result)); "
" result = mp_or(xx, yy, &(bignum_value(bn))); ")
(binop
raw-logxor
" int result = ((int)unbox_number(x)) ^ ((int)unbox_number(y));
return_closcall1(data, k, obj_int2obj(result)); "
" result = mp_xor(xx, yy, &(bignum_value(bn))); ")
)
(define (logand x . rest) (define (logand x . rest)
(if (null? rest) (if (null? rest)
@ -76,13 +104,6 @@
(define bitwise-and logand) (define bitwise-and logand)
(define-c raw-logior
"(void* data, int argc, closure _, object k, object x, object y)"
"Cyc_check_fixnum(data, x); // TODO: bignum support
Cyc_check_fixnum(data, y);
int result = ((int)unbox_number(x)) | ((int)unbox_number(y));
return_closcall1(data, k, obj_int2obj(result));")
(define (logior x . rest) (define (logior x . rest)
(if (null? rest) (if (null? rest)
x x
@ -90,13 +111,6 @@
(define bitwise-ior logior) (define bitwise-ior logior)
(define-c raw-logxor
"(void* data, int argc, closure _, object k, object x, object y)"
"Cyc_check_int(data, x);
Cyc_check_int(data, y);
int result = ((int)unbox_number(x)) ^ ((int)unbox_number(y));
return_closcall1(data, k, obj_int2obj(result));")
(define (logxor x . rest) (define (logxor x . rest)
(if (null? rest) (if (null? rest)
x x
@ -107,8 +121,13 @@
(define-c lognot (define-c lognot
"(void* data, int argc, closure _, object k, object x)" "(void* data, int argc, closure _, object k, object x)"
"Cyc_check_int(data, x); "Cyc_check_int(data, x);
if (Cyc_is_bignum(x) == boolean_t) {
// uh oh, libtommath doesn't provide this!
Cyc_rt_raise_msg(data, \"bignum negation not supported yet\");
} else {
int result = ~((int)unbox_number(x)); int result = ~((int)unbox_number(x));
return_closcall1(data, k, obj_int2obj(result));") return_closcall1(data, k, obj_int2obj(result));
}")
(define bitwise-not lognot) (define bitwise-not lognot)