;;;; Cyclone Scheme ;;;; https://github.com/justinethier/cyclone ;;;; ;;;; Copyright (c) 2014-2016, Justin Ethier ;;;; All rights reserved. ;;;; ;;;; SRFI 143: Fixnums ;;;; (define-library (srfi 143) (import (scheme base) (scheme inexact)) (export fx-width fx-greatest fx-least fixnum? fx=? fx? fx<=? fx>=? fxzero? fxpositive? fxnegative? fxodd? fxeven? fxmax fxmin fx+ fx- fx* fxneg fxquotient fxremainder fxabs fxsquare fxsqrt ; TODO: requires SRFI 141 ; fx+/carry fx-/carry fx*/carry fxnot fxand fxior fxxor fxarithmetic-shift fxarithmetic-shift-left fxarithmetic-shift-right fxbit-count fxlength fxif fxbit-set? fxcopy-bit fxfirst-set-bit fxbit-field fxbit-field-rotate fxbit-field-reverse ) (inline fx-width fx-greatest fx-least fixnum? fx=? fx? fx<=? fx>=? fxzero? fxpositive? fxnegative? fxodd? fxeven? fx+ fx- fx* fxneg fxquotient fxremainder fxsquare fxabs fxnot fxand fxior fxxor fxarithmetic-shift fxarithmetic-shift-left fxarithmetic-shift-right fxbit-count fxif fxbit-set? fxcopy-bit fxfirst-set-bit fxbit-field mask ) (begin (define (fx-width) 31) (define (fx-greatest) 1073741823) (define (fx-least) -1073741824) (define-syntax bin-num-op (er-macro-transformer (lambda (expr rename compare) (let* ((fnc (cadr expr)) (op-str (caddr expr)) (zero-check? (and (> (length expr) 3) (cadddr expr))) (args "(void* data, int argc, closure _, object k, object i, object j)") (body (string-append " Cyc_check_fixnum(data, i); Cyc_check_fixnum(data, j); " (if zero-check? " if (obj_obj2int(j) == 0) { Cyc_rt_raise_msg(data, \"Divide by zero\");}" "") " object result = obj_int2obj(obj_obj2int(i) " op-str " obj_obj2int(j)); return_closcall1(data, k, result); "))) `(define-c ,fnc ,args ,body))))) ;; TODO: should be able to support any number of arguments (define-syntax cmp-op (er-macro-transformer (lambda (expr rename compare) (let* ((fnc (cadr expr)) (args "(void* data, int argc, closure _, object k, object i, object j)") (op-str (caddr expr)) (body (string-append " Cyc_check_fixnum(data, i); Cyc_check_fixnum(data, j); object result = (obj_obj2int(i) " op-str " obj_obj2int(j)) ? boolean_t : boolean_f; return_closcall1(data, k, result); "))) `(define-c ,fnc ,args ,body))))) (bin-num-op fx+ "+") (bin-num-op fx- "-") (bin-num-op fx* "*") (bin-num-op fxquotient "/" #t) (bin-num-op fxremainder "%" #t) (bin-num-op fxand "&") (bin-num-op fxior "|") (bin-num-op fxxor "^") (bin-num-op fxarithmetic-shift-left "<<") (bin-num-op fxarithmetic-shift-right ">>") (cmp-op fx=? "==") (cmp-op fx? ">") (cmp-op fx<=? "<=") (cmp-op fx>=? ">=") (define-c fixnum? "(void *data, int argc, closure _, object k, object obj)" " return_closcall1(data, k, obj_is_int(obj) ? boolean_t : boolean_f); ") (define-c fxzero? "(void* data, int argc, closure _, object k, object i)" " Cyc_check_fixnum(data, i); return_closcall1(data, k, obj_obj2int(i) == 0 ? boolean_t : boolean_f); ") (define (fxpositive? i) (fx>? i 0)) (define (fxnegative? i) (fx? old new) old new)) first rest)) (define (fxmin first . rest) (foldl (lambda (old new) (if (fx