* Fixed a bug in ratnum multiplication.
This commit is contained in:
parent
22d15fe6da
commit
054e076651
BIN
src/ikarus.boot
BIN
src/ikarus.boot
Binary file not shown.
|
@ -528,8 +528,8 @@
|
||||||
(binary/ (binary* x ($ratnum-n y)) ($ratnum-d y))]
|
(binary/ (binary* x ($ratnum-n y)) ($ratnum-d y))]
|
||||||
[else
|
[else
|
||||||
(error '* "~s is not a number" y)])]
|
(error '* "~s is not a number" y)])]
|
||||||
[(ratnum? y)
|
[(ratnum? x)
|
||||||
(if (ratnum? x)
|
(if (ratnum? y)
|
||||||
(binary/ (binary* ($ratnum-n x) ($ratnum-n y))
|
(binary/ (binary* ($ratnum-n x) ($ratnum-n y))
|
||||||
(binary* ($ratnum-d x) ($ratnum-d y)))
|
(binary* ($ratnum-d x) ($ratnum-d y)))
|
||||||
(binary* y x))]
|
(binary* y x))]
|
||||||
|
|
|
@ -120,30 +120,32 @@
|
||||||
(generate-rtd name parent uid sealed? opaque? fields)]
|
(generate-rtd name parent uid sealed? opaque? fields)]
|
||||||
[else (error who "~s is not a valid uid" uid)]))))
|
[else (error who "~s is not a valid uid" uid)]))))
|
||||||
|
|
||||||
(define-record rcd (rtd pproc proc))
|
(define-record rcd (rtd prcd proc))
|
||||||
|
(define (is-parent-of? prtd rtd)
|
||||||
|
(let ([p (rtd-parent rtd)])
|
||||||
|
(cond
|
||||||
|
[(eq? p prtd) #t]
|
||||||
|
[(not p) #f]
|
||||||
|
[else (is-parent-of? prtd p)])))
|
||||||
|
|
||||||
(define make-record-constructor-descriptor
|
(define make-record-constructor-descriptor
|
||||||
(lambda (rtd parent protocol)
|
(lambda (rtd prcd protocol)
|
||||||
(define who 'make-record-constructor-descriptor)
|
(define who 'make-record-constructor-descriptor)
|
||||||
(define (make-rcd/default-proto&prcd rtd)
|
|
||||||
(make-rcd rtd #f #f))
|
|
||||||
(define (make-rcd/default-proto rtd parent)
|
|
||||||
(cond
|
|
||||||
[(not parent)
|
|
||||||
(make-rcd/default-proto&prcd rtd)]
|
|
||||||
[(rcd? parent)
|
|
||||||
(error who "BUG1")]
|
|
||||||
[else (error who "~s is not a valid record constructor descriptor"
|
|
||||||
parent)]))
|
|
||||||
(define (make-rcd/procedure-proto rtd parent protocol)
|
|
||||||
(error who "BUG2"))
|
|
||||||
(unless (rtd? rtd)
|
(unless (rtd? rtd)
|
||||||
(error who "~s is not an rtd" rtd))
|
(error who "~s is not a record type descriptor" rtd))
|
||||||
|
(unless (or (not protocol) (procedure? protocol))
|
||||||
|
(error who "invalid protocol ~s" protocol))
|
||||||
|
(let ([prtd (rtd-parent rtd)])
|
||||||
(cond
|
(cond
|
||||||
[(not protocol)
|
[(not prcd)
|
||||||
(make-rcd/default-proto rtd parent)]
|
(make-rcd rtd #f protocol)]
|
||||||
[(procedure? protocol)
|
[(rcd? prcd)
|
||||||
(make-rcd/procedure-proto rtd parent protocol)]
|
(unless (is-parent-of? (rcd-rtd prcd) rtd)
|
||||||
[else (error who "~s is not a valid protocol" protocol)])))
|
(error who "descriptor ~s does not apply to ~s"
|
||||||
|
prcd rtd))
|
||||||
|
(make-rcd rtd prcd protocol)]
|
||||||
|
[else (error who "~s is not a valid record constructor
|
||||||
|
descriptor" prcd)]))))
|
||||||
|
|
||||||
(define (iota i n)
|
(define (iota i n)
|
||||||
(if (= i n)
|
(if (= i n)
|
||||||
|
@ -152,30 +154,97 @@
|
||||||
(define (sym n)
|
(define (sym n)
|
||||||
(string->symbol (format "v~s" n)))
|
(string->symbol (format "v~s" n)))
|
||||||
|
|
||||||
(define (default-constructor-maker n)
|
(define general-base-constructor
|
||||||
;;; FIXME: should cache compiled procedures
|
(lambda (n)
|
||||||
|
(lambda (rtd)
|
||||||
|
(lambda args
|
||||||
|
(unless (= (length args) n)
|
||||||
|
(error 'record-constructor
|
||||||
|
"incorrect number of arguments to constructor"))
|
||||||
|
(let f ([r ($make-record rtd n)] [i 0] [args args])
|
||||||
|
(cond
|
||||||
|
[(null? args) r]
|
||||||
|
[else
|
||||||
|
($record-set! r i (car args))
|
||||||
|
(f r (add1 i) (cdr args))]))))))
|
||||||
|
|
||||||
|
(define base-constructors
|
||||||
|
'#(#f #f #f #f #f #f #f #f #f #f #f #f))
|
||||||
|
|
||||||
|
(define (base-constructor-maker n)
|
||||||
|
(cond
|
||||||
|
[(< n (vector-length base-constructors))
|
||||||
|
(or (vector-ref base-constructors n)
|
||||||
(let ([vars (map sym (iota 0 n))])
|
(let ([vars (map sym (iota 0 n))])
|
||||||
|
(let ([proc
|
||||||
(eval `(lambda (rtd)
|
(eval `(lambda (rtd)
|
||||||
(lambda ,vars
|
(lambda ,vars
|
||||||
($record rtd . ,vars)))
|
($record rtd . ,vars)))
|
||||||
(environment '(ikarus) '(ikarus system $records)))))
|
(environment
|
||||||
|
'(ikarus)
|
||||||
|
'(ikarus system $records)))])
|
||||||
|
(vector-set! base-constructors n proc)
|
||||||
|
proc)))]
|
||||||
|
[else (general-base-constructor n)]))
|
||||||
|
|
||||||
|
(define extended-constructors
|
||||||
|
'#(#f #f #f #f #f #f #f #f #f #f #f #f))
|
||||||
|
|
||||||
|
(define general-extended-constructor
|
||||||
|
(lambda (n m)
|
||||||
|
(lambda (record-constructor)
|
||||||
|
(lambda args-n
|
||||||
|
(unless (= (length args-n) n)
|
||||||
|
(error 'record-constructor "incorrect arguments"))
|
||||||
|
(lambda args-m
|
||||||
|
(unless (= (length args-m) m)
|
||||||
|
(error 'record-constructor "incorrect arguments"))
|
||||||
|
(apply record-constructor (append args-n args-m)))))))
|
||||||
|
|
||||||
|
(define (extended-constructor-maker n m)
|
||||||
|
(cond
|
||||||
|
[(< n (vector-length extended-constructors))
|
||||||
|
(let ([v (let ([v (vector-ref extended-constructors n)])
|
||||||
|
(or v
|
||||||
|
(let ([v (make-vector (+ n 1) #f)])
|
||||||
|
(vector-set! extended-constructors n)
|
||||||
|
v)))])
|
||||||
|
(or (vector-ref v m)
|
||||||
|
(let* ([vars-0m (map sym (iota 0 m))]
|
||||||
|
[vars-mn (map sym (iota m n))]
|
||||||
|
[proc
|
||||||
|
(eval
|
||||||
|
`(lambda (record-constructor)
|
||||||
|
(lambda ,vars-0m
|
||||||
|
(lambda ,vars-mn
|
||||||
|
(record-constructor ,@vars-0m ,@vars-mn))))
|
||||||
|
(environment '(ikarus)))])
|
||||||
|
(vector-set! v m proc)
|
||||||
|
proc)))]
|
||||||
|
[else (general-extended-constructor n m)]))
|
||||||
|
|
||||||
(define (record-constructor rcd)
|
(define (record-constructor rcd)
|
||||||
(define who 'record-constructor)
|
(define who 'record-constructor)
|
||||||
(unless (rcd? rcd)
|
(unless (rcd? rcd)
|
||||||
(error who "~s is not a record constructor descriptor" rcd))
|
(error who "~s is not a record constructor descriptor" rcd))
|
||||||
(let ([rtd (rcd-rtd rcd)]
|
(let ([rtd (rcd-rtd rcd)]
|
||||||
[pproc (rcd-pproc rcd)]
|
[prcd (rcd-prcd rcd)]
|
||||||
[proc (rcd-proc rcd)])
|
[proc (rcd-proc rcd)])
|
||||||
(cond
|
(cond
|
||||||
[(not pproc)
|
[(not prcd)
|
||||||
(cond
|
(cond
|
||||||
[(not proc)
|
[(not proc)
|
||||||
((default-constructor-maker (rtd-size rtd)) rtd)]
|
((base-constructor-maker (rtd-size rtd)) rtd)]
|
||||||
[else (error who "BUG")])]
|
[(rtd-parent rtd) =>
|
||||||
[else (error who "BUG")])))
|
(lambda (parent)
|
||||||
|
(let ([n (rtd-size rtd)]
|
||||||
|
[m (rtd-size parent)])
|
||||||
|
(let ([c0 ((base-constructor-maker n) rtd)])
|
||||||
|
(let ([c1 ((extended-constructor-maker n m) c0)])
|
||||||
|
(proc c1)))))]
|
||||||
|
[else
|
||||||
|
(proc ((base-constructor-maker (rtd-size rtd)) rtd))])]
|
||||||
|
[else (error who "BUG22")])))
|
||||||
|
|
||||||
(define (record-accessor rtd k)
|
(define (record-accessor rtd k)
|
||||||
(define who 'record-accessor)
|
(define who 'record-accessor)
|
||||||
|
|
Loading…
Reference in New Issue