213 lines
4.9 KiB
Scheme
213 lines
4.9 KiB
Scheme
(module base-gm mzscheme
|
|
(require (lib "list.ss")
|
|
(lib "etc.ss"))
|
|
|
|
(provide cons-to-end
|
|
assoc-get
|
|
debug
|
|
make-debug
|
|
to-string
|
|
member-eq?
|
|
string->char
|
|
last
|
|
member-str?
|
|
quicksort-vector!
|
|
for
|
|
for-vector
|
|
but-last
|
|
halt
|
|
prog1
|
|
struct->list
|
|
for-list
|
|
|
|
make-hash
|
|
hash-get
|
|
hash-put!
|
|
hash-remove!
|
|
hash-map
|
|
hash-for-each
|
|
hash-mem?
|
|
|
|
(all-from (lib "list.ss"))
|
|
(all-from (lib "etc.ss")))
|
|
|
|
(define-syntax prog1
|
|
(syntax-rules
|
|
()
|
|
{(prog1 arg1 args ...)
|
|
(let ((v arg1))
|
|
args ...
|
|
v)}))
|
|
|
|
(define-syntax halt
|
|
(syntax-rules
|
|
()
|
|
[(halt arg ...)
|
|
(begin
|
|
(debug "There was a problem with " arg ...)
|
|
(error "Error."))]))
|
|
|
|
;;;(define (halt . args)
|
|
;;; (apply error
|
|
;;; (list (string-append
|
|
;;; "Error: "
|
|
;;; (foldl string-append "" (reverse (map to-string args)))))))
|
|
|
|
(define (but-last ls)
|
|
(cond
|
|
((empty? ls) (error "incorrect list to butlast"))
|
|
((empty? (rest ls)) empty)
|
|
(else (cons (first ls) (but-last (rest ls))))))
|
|
|
|
(define-syntax for
|
|
(syntax-rules
|
|
()
|
|
[(for x start stop body ...)
|
|
(let ((x start))
|
|
(letrec ((loop
|
|
(lambda ()
|
|
(if (> x stop)
|
|
'done
|
|
(begin
|
|
body ...
|
|
(set! x (+ x 1))
|
|
(loop))))))
|
|
(loop)))]))
|
|
|
|
(define-syntax for-vector
|
|
(syntax-rules
|
|
(with)
|
|
[(for-vector v with x body ...)
|
|
(for x 0 (- (vector-length v) 1)
|
|
body ...)]))
|
|
|
|
(define-syntax for-list
|
|
(syntax-rules
|
|
(with)
|
|
[(for-list ls with x body ...)
|
|
(let ((x 'dummy))
|
|
(letrec ((loop
|
|
(lambda (param)
|
|
(if (empty? param)
|
|
'done
|
|
(begin
|
|
(set! x (car param))
|
|
body ...
|
|
(loop (rest param)))))))
|
|
(loop ls)))]))
|
|
|
|
(define (quicksort-vector! v less-than)
|
|
(let ([count (vector-length v)])
|
|
(let loop ([min 0][max count])
|
|
(if (< min (sub1 max))
|
|
(let ([pval (vector-ref v min)])
|
|
(let pivot-loop ([pivot min]
|
|
[pos (add1 min)])
|
|
(if (< pos max)
|
|
(let ([cval (vector-ref v pos)])
|
|
(if (less-than cval pval)
|
|
(begin
|
|
(vector-set! v pos (vector-ref v pivot))
|
|
(vector-set! v pivot cval)
|
|
(pivot-loop (add1 pivot) (add1 pos)))
|
|
(pivot-loop pivot (add1 pos))))
|
|
(if (= min pivot)
|
|
(loop (add1 pivot) max)
|
|
(begin
|
|
(loop min pivot)
|
|
(loop pivot max)))))))))
|
|
v)
|
|
|
|
|
|
|
|
|
|
|
|
(define (member-str? s ls)
|
|
(cond
|
|
((empty? ls) false)
|
|
((string=? s (first ls)) true)
|
|
(else (member-str? s (rest ls)))))
|
|
|
|
(define (last ls)
|
|
(cond
|
|
((empty? ls) (error "took a last but it was emptry"))
|
|
((empty? (rest ls)) (first ls))
|
|
(else (last (rest ls)))))
|
|
|
|
(define (string->char s)
|
|
(first (string->list s)))
|
|
|
|
(define (member-eq? x ls)
|
|
(not (empty? (filter (lambda (y) (eq? x y)) ls))))
|
|
|
|
(define (to-string arg . fns)
|
|
(let loop ((arg arg))
|
|
(cond
|
|
((not arg) "#f")
|
|
((void? arg) "#<void>")
|
|
((eq? arg #t) "#t")
|
|
((char? arg) (list->string (list arg)))
|
|
((string? arg) arg)
|
|
((symbol? arg) (symbol->string arg))
|
|
((number? arg) (number->string arg))
|
|
((vector? arg) (loop (vector->list arg)))
|
|
((empty? arg) "empty")
|
|
((list? arg) (string-append
|
|
"("
|
|
(loop (first arg))
|
|
(foldr string-append ""
|
|
(map (lambda (x)
|
|
(string-append " "
|
|
(loop x))) (rest arg)))
|
|
")"))
|
|
((cons? arg) (string-append
|
|
"("
|
|
(loop (first arg))
|
|
" . "
|
|
(loop (rest arg))
|
|
")"))
|
|
|
|
(true (let loop ((cur fns))
|
|
(if (empty? cur) (halt "to-string: " arg)
|
|
(or ((first cur) arg)
|
|
(loop (rest cur)))))))))
|
|
|
|
|
|
(define (debug . args)
|
|
(for-each display args)
|
|
(newline))
|
|
|
|
(define (make-debug . fns)
|
|
(lambda args (for-each (lambda (x) (display (apply to-string (cons x fns)))
|
|
(display " ")) args)
|
|
(newline)))
|
|
|
|
(define (assoc-get label ls)
|
|
(cond
|
|
((empty? ls) (error (string-append "failed to find " (to-string label))))
|
|
((eq? label (first (first ls)))
|
|
(first ls))
|
|
(else (assoc-get label (rest ls)))))
|
|
|
|
(define (cons-to-end a ls)
|
|
(cond
|
|
((empty? ls) (cons a ls))
|
|
(else (cons (first ls)
|
|
(cons-to-end a (rest ls))))))
|
|
|
|
(define (struct->list itm)
|
|
(cond [(struct? itm) (map struct->list (vector->list (struct->vector itm)))]
|
|
[(list? itm) (map struct->list itm)]
|
|
[else itm]))
|
|
|
|
(define (struct-name s) (vector-ref (struct->vector s) 0))
|
|
|
|
|
|
(define make-hash make-hash-table)
|
|
(define hash-get hash-table-get)
|
|
(define hash-put! hash-table-put!)
|
|
(define hash-remove! hash-table-remove!)
|
|
(define hash-map hash-table-map)
|
|
(define hash-for-each hash-table-for-each)
|
|
(define (hash-mem? hash item) (hash-get hash item (lambda () false)))
|
|
) |