This repository has been archived on 2022-08-10. You can view files and clone it, but cannot push or open issues or pull requests.
chez-openbsd/unicode/extract-common.ss
2022-07-29 15:12:07 +02:00

137 lines
5.3 KiB
Scheme

;;; Copyright (C) 2008 Abdulaziz Ghuloum, R. Kent Dybvig
;;; Copyright (C) 2006,2007 Abdulaziz Ghuloum
;;;
;;; Permission is hereby granted, free of charge, to any person obtaining a
;;; copy of this software and associated documentation files (the "Software"),
;;; to deal in the Software without restriction, including without limitation
;;; the rights to use, copy, modify, merge, publish, distribute, sublicense,
;;; and/or sell copies of the Software, and to permit persons to whom the
;;; Software is furnished to do so, subject to the following conditions:
;;;
;;; The above copyright notice and this permission notice shall be included in
;;; all copies or substantial portions of the Software.
;;;
;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
;;; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
;;; DEALINGS IN THE SOFTWARE.
(define-syntax assert
(syntax-rules ()
[(_ e) (unless e (syntax-error #'e "assertion failed"))]))
(module ((define-table maker accessor mutator))
(define-syntax maker
(syntax-rules ()
[(_ make-inner x t) (make-inner t x)]
[(_ make-inner x t1 t2 ...)
(let ([v (make-vector t1)])
(do ([i 0 (fx+ i 1)])
((fx= i t1))
(vector-set! v i (maker make-inner x t2 ...)))
v)]))
(define-syntax accessor
(syntax-rules ()
[(_ inner-ref tbl i t) (inner-ref tbl i)]
[(_ inner-ref tbl i t1 t2 ...)
(let ([d (* t2 ...)])
(accessor inner-ref (vector-ref tbl (fxdiv i d))
(fxmod i d) t2 ...))]))
(define-syntax mutator
(syntax-rules ()
[(_ inner-set! tbl i x t) (inner-set! tbl i x)]
[(_ inner-set! tbl i x t1 t2 ...)
(let ([d (* t2 ...)])
(mutator inner-set! (vector-ref tbl (fxdiv i d))
(fxmod i d) x t2 ...))]))
(define-syntax define-table
(lambda (x)
(define accessor-code
(lambda (x)
(syntax-case x ()
[(inner-ref tbl i t) #'(inner-ref tbl i)]
[(inner-ref tbl i t1 t2 ...)
(with-syntax ([(d) (generate-temporaries '(d))])
(with-syntax ([body (accessor-code
#'(inner-ref
(vector-ref tbl (fxdiv i d))
(fxmod i d) t2 ...))])
#'(let ([d (* t2 ...)]) body)))])))
(syntax-case x ()
[(_ (make-table table-ref table-set! table-ref-code)
(make-inner inner-ref inner-set!) size dim ...)
(with-syntax ([(t1 t2 ...) (generate-temporaries #'(size dim ...))]
[code (accessor-code
#'(inner-ref tbl i
(/ size (* dim ...))
dim ...))])
#'(module (make-table table-ref table-set! table-ref-code)
(define t2 dim) ...
(define t1 (/ size (* t2 ...)))
(define make-table (lambda (x) (maker make-inner x t1 t2 ...)))
(define table-ref-code '(lambda (tbl i) code))
(define table-ref (lambda (tbl i) (accessor inner-ref tbl i t1 t2 ...)))
(define table-set! (lambda (tbl i x) (mutator inner-set! tbl i x t1 t2 ...)))))]))))
(define (with-output-to-file* file thunk)
(when (file-exists? file) (delete-file file))
(with-output-to-file file thunk))
(define common-equal?
(lambda (x y)
(cond
[(eq? x y) #t]
[(vector? x)
(and (vector? y)
(let ([n (vector-length x)])
(and (fx= (vector-length y) n)
(let f ([i 0])
(or (fx= i n)
(and (eq? (vector-ref x i) (vector-ref y i))
(f (fx+ i 1))))))))]
[(pair? x) (and (pair? y) (eq? (car x) (car y)) (eq? (cdr x) (cdr y)))]
[else (equal? x y)])))
(define cache '())
#;(define commonize ; 5.8s
(lambda (x)
(or (find (lambda (y) (common-equal? y x)) cache)
(begin (set! cache (cons x cache)) x))))
#;(define commonize ; 2.6s
(let ([cache-table (make-hashtable equal-hash common-equal?)])
(lambda (x)
(or (hashtable-ref cache-table x #f)
(begin
(set! cache (cons x cache)) ; for sizeof
(hashtable-set! cache-table x x)
x)))))
(define commonize ; 1.9s
(lambda (x)
(let ([v (find (lambda (y) (common-equal? y x)) cache)])
(if v
(begin (set! cache (cons v (remq v cache))) v)
(begin (set! cache (cons x cache)) x)))))
(define commonize*
(lambda (x)
(cond
[(vector? x)
(let ([n (vector-length x)])
(do ([i 0 (fx+ i 1)])
((fx= i n))
(vector-set! x i (commonize* (vector-ref x i)))))
(commonize x)]
[(bytevector? x) (commonize x)]
[(pair? x)
(set-car! x (commonize* (car x)))
(set-cdr! x (commonize* (cdr x)))
(commonize x)]
[else x])))
(define (sizeof ls) (compute-size ls))
(define (hex->num x) (string->number x 16))