2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-04 06:07:52 +01:00
|
|
|
;---------------------------------------------------------------------------------------------
|
2023-03-22 19:20:17 +01:00
|
|
|
; SCHEME LIBRARY
|
2023-03-04 06:07:52 +01:00
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
2023-03-22 18:21:48 +01:00
|
|
|
|
2023-03-12 00:43:51 +01:00
|
|
|
;---------------------------------------------------------------------------------------------
|
2023-03-22 18:21:48 +01:00
|
|
|
; Derived expression types
|
2023-03-12 00:43:51 +01:00
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
2023-03-22 23:13:12 +01:00
|
|
|
; builtins:
|
|
|
|
;
|
|
|
|
; (quote const)
|
|
|
|
; (set! id expr)
|
|
|
|
; (set& id)
|
|
|
|
; (if expr1 expr2)
|
|
|
|
; (if expr1 expr2 expr3)
|
|
|
|
; (begin expr ...)
|
|
|
|
; (lambda args expr ...)
|
|
|
|
; (lambda* [arity expr] ...)
|
2023-03-24 19:16:10 +01:00
|
|
|
; (body expr ...) -- lexical scope for definitions
|
|
|
|
; (letcc id expr)
|
|
|
|
; (withcc expr expr ...)
|
2023-03-22 23:13:12 +01:00
|
|
|
; (define id expr)
|
|
|
|
; (define (id . args) expr ...)
|
|
|
|
; (define-syntax kw form)
|
|
|
|
; (syntax-lambda (id ...) form ...)
|
|
|
|
; (syntax-rules (lit ...) [pat templ] ...)
|
|
|
|
; (syntax-rules ellipsis (lit ...) [pat templ] ...)
|
|
|
|
|
2023-03-22 18:21:48 +01:00
|
|
|
(define-syntax let-syntax
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ ([kw init] ...))
|
|
|
|
(begin)]
|
|
|
|
[(_ ([kw init] ...) . forms)
|
|
|
|
((syntax-lambda (kw ...) . forms)
|
|
|
|
init ...)]))
|
|
|
|
|
|
|
|
(define-syntax letrec-syntax
|
2023-02-28 06:31:08 +01:00
|
|
|
(syntax-rules ()
|
2023-03-22 19:20:17 +01:00
|
|
|
[(_ ([key trans] ...) . forms)
|
2023-03-22 18:21:48 +01:00
|
|
|
(body (define-syntax key trans) ... . forms)]))
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-22 18:21:48 +01:00
|
|
|
(define-syntax letrec
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ ([var init] ...) . forms)
|
|
|
|
(body (define var init) ... . forms)]))
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-24 19:16:10 +01:00
|
|
|
(define-syntax letrec*
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ ([var expr] ...) . forms)
|
|
|
|
(let ([var #f] ...)
|
|
|
|
(set! var expr)
|
|
|
|
...
|
|
|
|
(body . forms))]))
|
|
|
|
|
2023-03-22 18:21:48 +01:00
|
|
|
(define-syntax let
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ ([var init] ...) . forms)
|
|
|
|
((lambda (var ...) . forms) init ...)]
|
|
|
|
[(_ name ([var init] ...) . forms)
|
|
|
|
((letrec ((name (lambda (var ...) . forms))) name) init ...)]))
|
|
|
|
|
|
|
|
(define-syntax let*
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ () . forms)
|
|
|
|
(body . forms)]
|
|
|
|
[(_ (first . more) . forms)
|
|
|
|
(let (first) (let* more . forms))]))
|
|
|
|
|
2023-03-24 19:16:10 +01:00
|
|
|
(define-syntax let*-values
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ () . forms) (body . forms)]
|
|
|
|
[(_ ([(a) x] . b*) . forms) (let ([a x]) (let*-values b* . forms))]
|
|
|
|
[(_ ([aa x] . b*) . forms) (call-with-values (lambda () x) (lambda aa (let*-values b* . forms)))]))
|
|
|
|
|
|
|
|
(define-syntax %let-values-loop
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ (new-b ...) new-aa x map-b* () () . forms)
|
|
|
|
(let*-values (new-b ... [new-aa x]) (let map-b* . forms))]
|
|
|
|
[(_ (new-b ...) new-aa old-x map-b* () ([aa x] . b*) . forms)
|
|
|
|
(%let-values-loop (new-b ... [new-aa old-x]) () x map-b* aa b* . forms)]
|
|
|
|
[(_ new-b* (new-a ...) x (map-b ...) (a . aa) b* . forms)
|
|
|
|
(%let-values-loop new-b* (new-a ... tmp-a) x (map-b ... [a tmp-a]) aa b* . forms)]
|
|
|
|
[(_ new-b* (new-a ...) x (map-b ...) a b* . forms)
|
|
|
|
(%let-values-loop new-b* (new-a ... . tmp-a) x (map-b ... [a tmp-a]) () b* . forms)]))
|
|
|
|
|
|
|
|
(define-syntax let-values
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ () . forms) (let () . forms)]
|
|
|
|
[(_ ([aa x] . b*) . forms)
|
|
|
|
(%let-values-loop () () x () aa b* . forms)]))
|
|
|
|
|
|
|
|
(define-syntax %define-values-loop
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ new-aa ([a tmp-a] ...) () x)
|
|
|
|
(begin
|
|
|
|
(define a (begin)) ...
|
|
|
|
(define () (call-with-values (lambda () x) (lambda new-aa (set! a tmp-a) ...))))]
|
|
|
|
[(_ (new-a ...) (map-a ...) (a . aa) x)
|
|
|
|
(%define-values-loop (new-a ... tmp-a) (map-a ... [a tmp-a]) aa x)]
|
|
|
|
[(_ (new-a ...) (map-a ...) a x)
|
|
|
|
(%define-values-loop (new-a ... . tmp-a) (map-a ... [a tmp-a]) () x)]))
|
|
|
|
|
|
|
|
(define-syntax define-values
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ () x) (define () (call-with-values (lambda () x) (lambda ())))] ; use idless define
|
|
|
|
[(_ aa x) (%define-values-loop () () aa x)]))
|
|
|
|
|
2023-03-22 18:21:48 +01:00
|
|
|
(define-syntax and
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_) #t]
|
|
|
|
[(_ test) test]
|
|
|
|
[(_ test . tests) (if test (and . tests) #f)]))
|
|
|
|
|
|
|
|
(define-syntax or
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_) #f]
|
|
|
|
[(_ test) test]
|
|
|
|
[(_ test . tests) (let ([x test]) (if x x (or . tests)))]))
|
|
|
|
|
|
|
|
(define-syntax cond
|
|
|
|
(syntax-rules (else =>)
|
|
|
|
[(_) #f]
|
|
|
|
[(_ (else . exps)) (begin . exps)]
|
|
|
|
[(_ (x) . rest) (or x (cond . rest))]
|
|
|
|
[(_ (x => proc) . rest) (let ([tmp x]) (cond [tmp (proc tmp)] . rest))]
|
|
|
|
[(_ (x . exps) . rest) (if x (begin . exps) (cond . rest))]))
|
|
|
|
|
2023-03-24 19:16:10 +01:00
|
|
|
(define-syntax %case-test
|
2023-03-25 05:35:23 +01:00
|
|
|
(syntax-rules ()
|
|
|
|
[(_ k ()) #f]
|
|
|
|
[(_ k (datum)) (eqv? k 'datum)]
|
|
|
|
[(_ k data) (memv k 'data)]))
|
|
|
|
|
|
|
|
(define-syntax %case
|
|
|
|
(syntax-rules (else =>)
|
|
|
|
[(_ key) (begin)]
|
|
|
|
[(_ key (else => resproc))
|
|
|
|
(resproc key)]
|
|
|
|
[(_ key (else expr ...))
|
|
|
|
(begin expr ...)]
|
|
|
|
[(_ key ((datum ...) => resproc) . clauses)
|
|
|
|
(if (%case-test key (datum ...))
|
|
|
|
(resproc key)
|
|
|
|
(%case key . clauses))]
|
|
|
|
[(_ key ((datum ...) expr ...) . clauses)
|
|
|
|
(if (%case-test key (datum ...))
|
|
|
|
(begin expr ...)
|
|
|
|
(%case key . clauses))]))
|
2023-03-22 18:21:48 +01:00
|
|
|
|
|
|
|
(define-syntax case
|
|
|
|
(syntax-rules ()
|
2023-03-25 05:35:23 +01:00
|
|
|
[(_ x . clauses) (let ([key x]) (%case key . clauses))]))
|
|
|
|
|
|
|
|
(define-syntax %do-step
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ x) x] [(_ x y) y]))
|
2023-03-22 18:21:48 +01:00
|
|
|
|
|
|
|
(define-syntax do
|
|
|
|
(syntax-rules ()
|
2023-03-25 05:35:23 +01:00
|
|
|
[(_ ([var init step ...] ...)
|
|
|
|
[test expr ...]
|
|
|
|
command ...)
|
2023-03-22 18:21:48 +01:00
|
|
|
(let loop ([var init] ...)
|
2023-03-25 05:35:23 +01:00
|
|
|
(if test
|
|
|
|
(begin expr ...)
|
|
|
|
(let () command ...
|
|
|
|
(loop (%do-step var step ...) ...))))]))
|
|
|
|
|
2023-03-22 18:21:48 +01:00
|
|
|
|
|
|
|
(define-syntax quasiquote
|
|
|
|
(syntax-rules (unquote unquote-splicing quasiquote)
|
|
|
|
[(_ ,x) x]
|
|
|
|
[(_ (,@x . y)) (append x `y)]
|
|
|
|
[(_ `x . d) (cons 'quasiquote (quasiquote (x) d))]
|
|
|
|
[(_ ,x d) (cons 'unquote (quasiquote (x) . d))]
|
|
|
|
[(_ ,@x d) (cons 'unquote-splicing (quasiquote (x) . d))]
|
|
|
|
[(_ (x . y) . d) (cons (quasiquote x . d) (quasiquote y . d))]
|
|
|
|
[(_ #(x ...) . d) (list->vector (quasiquote (x ...) . d))]
|
|
|
|
[(_ x . d) 'x]))
|
|
|
|
|
|
|
|
(define-syntax when
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ test . rest) (if test (begin . rest))]))
|
|
|
|
|
|
|
|
(define-syntax unless
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ test . rest) (if (not test) (begin . rest))]))
|
|
|
|
|
|
|
|
(define-syntax case-lambda
|
|
|
|
(syntax-rules ()
|
2023-03-24 19:16:10 +01:00
|
|
|
[(_ [args . forms] ...) (lambda* [args (lambda args . forms)] ...)]))
|
2023-03-12 00:43:51 +01:00
|
|
|
|
|
|
|
;cond-expand
|
|
|
|
|
|
|
|
;delay
|
|
|
|
;delay-force
|
|
|
|
|
|
|
|
|
2023-02-28 06:31:08 +01:00
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; Equivalence predicates
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
2023-03-20 04:31:28 +01:00
|
|
|
; integrables:
|
|
|
|
;
|
|
|
|
; (eq? x y)
|
|
|
|
; (eqv? x y)
|
|
|
|
; (equal? x y)
|
2023-02-28 06:31:08 +01:00
|
|
|
|
|
|
|
|
2023-03-12 00:43:51 +01:00
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; Boxes, aka cells
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
2023-03-20 04:31:28 +01:00
|
|
|
; integrables:
|
|
|
|
;
|
|
|
|
; (box? x)
|
|
|
|
; (box x)
|
|
|
|
; (unbox x)
|
|
|
|
; (set-box! x y)
|
2023-03-12 00:43:51 +01:00
|
|
|
|
|
|
|
|
2023-02-28 06:31:08 +01:00
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; Exact integer numbers (fixnums)
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
2023-03-20 04:31:28 +01:00
|
|
|
; integrables:
|
|
|
|
;
|
2023-03-25 05:35:23 +01:00
|
|
|
; (fixnum? o)
|
2023-03-20 04:31:28 +01:00
|
|
|
; (fxzero? x)
|
|
|
|
; (fxpositive? x)
|
|
|
|
; (fxnegative? x)
|
2023-03-25 05:35:23 +01:00
|
|
|
; (fxeven? x)
|
|
|
|
; (fxodd? x)
|
2023-03-20 18:49:00 +01:00
|
|
|
; (fx+ x ...)
|
|
|
|
; (fx* x ...)
|
|
|
|
; (fx- x y ...)
|
|
|
|
; (fx/ x y ...)
|
2023-03-20 04:31:28 +01:00
|
|
|
; (fxquotient x y)
|
|
|
|
; (fxremainder x y)
|
|
|
|
; (fxmodquo x y)
|
|
|
|
; (fxmodulo x y)
|
2023-03-20 23:47:10 +01:00
|
|
|
; (fxeucquo x y) a.k.a. euclidean-quotient, R6RS div
|
|
|
|
; (fxeucrem x y) a.k.a. euclidean-remainder, R6RS mod
|
2023-03-20 04:31:28 +01:00
|
|
|
; (fxneg x)
|
|
|
|
; (fxabs x)
|
2023-03-20 18:49:00 +01:00
|
|
|
; (fx<? x y z ...)
|
|
|
|
; (fx<=? x y z ...)
|
|
|
|
; (fx>? x y z ...)
|
|
|
|
; (fx>=? x y z ...)
|
|
|
|
; (fx=? x y z ...)
|
|
|
|
; (fx!=? x y)
|
2023-03-20 04:31:28 +01:00
|
|
|
; (fxmin x y)
|
|
|
|
; (fxmax x y)
|
2023-03-25 05:35:23 +01:00
|
|
|
; (fxneg x)
|
|
|
|
; (fxabs x)
|
|
|
|
; (fxgcd x y)
|
|
|
|
; (fxexpt x y)
|
|
|
|
; (fxsqrt x)
|
|
|
|
; (fxnot x)
|
|
|
|
; (fxand x ...)
|
|
|
|
; (fxior x ...)
|
|
|
|
; (fxxor x ...)
|
|
|
|
; (fxsll x y)
|
|
|
|
; (fxsrl x y)
|
2023-03-20 04:31:28 +01:00
|
|
|
; (fixnum->flonum x)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (fixnum->string x (radix 10))
|
|
|
|
; (string->fixnum s (radix 10))
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-25 05:35:23 +01:00
|
|
|
;fx-width
|
|
|
|
;fx-greatest
|
|
|
|
;fx-least
|
|
|
|
;fxarithmetic-shift-right
|
|
|
|
;fxarithmetic-shift-left
|
|
|
|
;fxlength cf. integer-length (+ 1 (integer-length i))
|
|
|
|
; is the number of bits needed to represent i in a signed twos-complement representation
|
|
|
|
; 0 => 0, 1 => 1, -1 => 0, 7 => 3, -7 => 3, 8 => 4, -8 => 3
|
|
|
|
;fxbit-count cf. bit-count
|
|
|
|
; Returns the population count of 1's (i >= 0) or 0's (i < 0)
|
|
|
|
; 0 => 0, -1 => 0, 7 => 3, 13 => 3, -13 => 2
|
2023-02-28 06:31:08 +01:00
|
|
|
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; Inexact floating-point numbers (flonums)
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
2023-03-20 04:31:28 +01:00
|
|
|
; integrables:
|
|
|
|
;
|
2023-03-25 05:35:23 +01:00
|
|
|
; (flonum? o)
|
2023-03-20 04:31:28 +01:00
|
|
|
; (flzero? x)
|
|
|
|
; (flpositive? x)
|
|
|
|
; (flnegative? x)
|
|
|
|
; (flinteger? x)
|
|
|
|
; (flnan? x)
|
|
|
|
; (flinfinite? x)
|
|
|
|
; (flfinite? x)
|
|
|
|
; (fleven? x)
|
|
|
|
; (flodd? x)
|
2023-03-20 18:49:00 +01:00
|
|
|
; (fl+ x ...)
|
|
|
|
; (fl* x ...)
|
|
|
|
; (fl- x y ...)
|
|
|
|
; (fl/ x y ...)
|
2023-03-20 04:31:28 +01:00
|
|
|
; (flneg x)
|
|
|
|
; (flabs x)
|
2023-03-25 17:03:28 +01:00
|
|
|
; (flgcd x y)
|
|
|
|
; (flexpt x y)
|
|
|
|
; (flsqrt x)
|
|
|
|
; (flfloor x)
|
|
|
|
; (flceiling x)
|
|
|
|
; (fltruncate x)
|
|
|
|
; (flround x)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (flexp x)
|
|
|
|
; (fllog x (base fl-e))
|
|
|
|
; (flsin x)
|
|
|
|
; (flcos x)
|
|
|
|
; (fltan x)
|
|
|
|
; (flasin x)
|
|
|
|
; (flacos x)
|
|
|
|
; (flatan (y) x)
|
2023-03-20 18:49:00 +01:00
|
|
|
; (fl<? x y z ...)
|
|
|
|
; (fl<=? x y z ...)
|
|
|
|
; (fl>? x y z ...)
|
|
|
|
; (fl>=? x y z ...)
|
|
|
|
; (fl=? x y z ...)
|
2023-03-20 19:42:40 +01:00
|
|
|
; (fl!=? x y)
|
2023-03-20 04:31:28 +01:00
|
|
|
; (flmin x y)
|
|
|
|
; (flmax x y)
|
|
|
|
; (flonum->fixnum x)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (flonum->string x)
|
|
|
|
; (string->flonum s)
|
2023-03-19 01:09:46 +01:00
|
|
|
|
2023-02-28 06:31:08 +01:00
|
|
|
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; Numbers (fixnums or flonums)
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
2023-03-20 19:42:40 +01:00
|
|
|
; integrables:
|
|
|
|
;
|
|
|
|
; (number? x)
|
2023-03-20 23:47:10 +01:00
|
|
|
; (complex? x) == number? what about inf and nan?
|
|
|
|
; (real? x) == number? what about inf and nan?
|
|
|
|
; (rational? x) == number? what about inf and nan?
|
2023-03-25 05:35:23 +01:00
|
|
|
; (integer? x)
|
2023-03-20 23:47:10 +01:00
|
|
|
; (exact? x)
|
|
|
|
; (inexact? x)
|
2023-03-25 05:35:23 +01:00
|
|
|
; (exact-integer? x) == fixnum?
|
2023-03-20 19:42:40 +01:00
|
|
|
; (finite? x)
|
|
|
|
; (infinite? x)
|
|
|
|
; (nan? x)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (= x y z ...)
|
|
|
|
; (< x y z ...)
|
|
|
|
; (> x y z ...)
|
|
|
|
; (<= x y z ...)
|
|
|
|
; (>= x y z ...)
|
2023-03-20 19:42:40 +01:00
|
|
|
; (zero? x)
|
|
|
|
; (positive? x)
|
|
|
|
; (negative? x)
|
|
|
|
; (odd? x)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (even? x)
|
2023-03-25 05:35:23 +01:00
|
|
|
; (max x y ...)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (min x y ...)
|
2023-03-20 19:42:40 +01:00
|
|
|
; (+ x ...)
|
|
|
|
; (* x ...)
|
|
|
|
; (- x y ...)
|
|
|
|
; (/ x y ...)
|
|
|
|
; (abs x)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (floor-quotient x y)
|
|
|
|
; (floor-remainder x y)
|
2023-03-20 23:47:10 +01:00
|
|
|
; (truncate-quotient x y)
|
|
|
|
; (truncate-remainder x y)
|
|
|
|
; (quotient x y) == truncate-quotient
|
|
|
|
; (remainder x y) == truncate-remainder
|
2023-03-26 04:22:28 +02:00
|
|
|
; (modulo x y) == floor-remainder
|
2023-03-25 17:03:28 +01:00
|
|
|
; (gcd x y)
|
|
|
|
; (floor x)
|
|
|
|
; (ceiling x)
|
|
|
|
; (truncate x)
|
|
|
|
; (round x)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (exp x)
|
|
|
|
; (log x (base fl-e))
|
|
|
|
; (sin x)
|
|
|
|
; (cos x)
|
|
|
|
; (tan x)
|
|
|
|
; (asin x)
|
|
|
|
; (acos x)
|
|
|
|
; (atan (y) x)
|
2023-03-25 17:03:28 +01:00
|
|
|
; (sqrt x)
|
|
|
|
; (expt x y)
|
2023-03-25 05:35:23 +01:00
|
|
|
; (inexact x)
|
|
|
|
; (exact x)
|
|
|
|
; (number->string x (radix 10))
|
|
|
|
; (string->number x (radix 10))
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-07 23:48:27 +01:00
|
|
|
(define (floor/ x y)
|
2023-03-21 18:43:26 +01:00
|
|
|
(values (floor-quotient x y) (floor-remainder x y)))
|
2023-03-07 23:48:27 +01:00
|
|
|
|
|
|
|
(define (truncate/ x y)
|
2023-03-21 18:43:26 +01:00
|
|
|
(values (truncate-quotient x y) (truncate-remainder x y)))
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-25 17:03:28 +01:00
|
|
|
(define (lcm . args)
|
|
|
|
(if (null? args) 1
|
|
|
|
(let loop ([x (car args)] [args (cdr args)])
|
|
|
|
(if (null? args) x
|
|
|
|
(let* ([y (car args)] [g (gcd x y)])
|
|
|
|
(loop (if (zero? g) g (* (quotient (abs x) g) (abs y))) (cdr args)))))))
|
|
|
|
|
|
|
|
(define (numerator n) n)
|
|
|
|
|
|
|
|
(define (denominator n) 1)
|
|
|
|
|
|
|
|
(define (rationalize n d) n)
|
|
|
|
|
|
|
|
(define (square x) (* x x))
|
|
|
|
|
2023-03-26 04:22:28 +02:00
|
|
|
(define (exact-integer-sqrt x)
|
|
|
|
(let ([r (fxsqrt x)])
|
|
|
|
(values r (- x (* r r)))))
|
|
|
|
|
|
|
|
(define (make-rectangular r i)
|
|
|
|
(if (= i 0) r (error "make-rectangular: nonzero imag part not supported" i)))
|
|
|
|
|
2023-03-26 18:02:36 +02:00
|
|
|
(define (make-polar m a)
|
2023-03-26 04:22:28 +02:00
|
|
|
(cond [(= a 0) m]
|
|
|
|
[(= a 3.141592653589793238462643) (- m)]
|
|
|
|
[else (error "make-polar: angle not supported" a)]))
|
|
|
|
|
2023-03-26 18:02:36 +02:00
|
|
|
(define (real-part x) x)
|
2023-03-26 04:22:28 +02:00
|
|
|
|
2023-03-26 18:02:36 +02:00
|
|
|
(define (imag-part x) 0)
|
2023-03-26 04:22:28 +02:00
|
|
|
|
2023-03-26 18:02:36 +02:00
|
|
|
(define (magnitude x) (abs x))
|
2023-03-26 04:22:28 +02:00
|
|
|
|
2023-03-26 18:02:36 +02:00
|
|
|
(define (angle x) (if (negative? x) 3.141592653589793238462643 0))
|
2023-03-25 05:35:23 +01:00
|
|
|
|
2023-02-28 06:31:08 +01:00
|
|
|
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; Booleans
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
2023-03-20 04:31:28 +01:00
|
|
|
; integrables:
|
|
|
|
;
|
|
|
|
; (boolean? x)
|
|
|
|
; (not x)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (boolean=? x y z ...)
|
2023-02-28 06:31:08 +01:00
|
|
|
|
|
|
|
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; Null and Pairs
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
2023-03-20 04:31:28 +01:00
|
|
|
; integrables:
|
|
|
|
;
|
|
|
|
; (null? x)
|
|
|
|
; (pair? x)
|
|
|
|
; (cons x y)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (car p)
|
|
|
|
; (cdr p)
|
|
|
|
; (set-car! p v)
|
|
|
|
; (set-cdr! p v)
|
|
|
|
; (caar p)
|
|
|
|
; ...
|
|
|
|
; (cddddr p)
|
2023-02-28 06:31:08 +01:00
|
|
|
|
|
|
|
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; Lists
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
2023-03-22 23:13:12 +01:00
|
|
|
; integrables:
|
|
|
|
;
|
2023-03-20 23:47:10 +01:00
|
|
|
; (list? x)
|
2023-03-21 03:32:33 +01:00
|
|
|
; (list x ...)
|
2023-03-21 18:43:26 +01:00
|
|
|
; (make-list n (i #f))
|
2023-03-20 23:47:10 +01:00
|
|
|
; (length l)
|
|
|
|
; (list-ref l i)
|
2023-03-21 01:00:18 +01:00
|
|
|
; (list-set! l i x)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (list-cat l1 l2) + 2-arg append
|
2023-03-22 23:13:12 +01:00
|
|
|
; (memq v l)
|
|
|
|
; (memv v l) ; TODO: make sure memv checks list
|
2023-03-26 04:22:28 +02:00
|
|
|
; (meme v l) + 2-arg member; TODO: make sure meme checks list
|
|
|
|
; (assq v y)
|
2023-03-22 23:13:12 +01:00
|
|
|
; (assv v y) ; TODO: make sure assv checks list
|
2023-03-26 04:22:28 +02:00
|
|
|
; (asse v y) + 2-arg assoc; TODO: make sure asse checks list
|
2023-03-22 23:13:12 +01:00
|
|
|
; (list-tail l i)
|
|
|
|
; (last-pair l)
|
|
|
|
; (reverse l)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (reverse! l) +
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-21 18:43:26 +01:00
|
|
|
(define (%append . args)
|
|
|
|
(let loop ([args args])
|
|
|
|
(cond [(null? args) '()]
|
|
|
|
[(null? (cdr args)) (car args)]
|
|
|
|
[else (list-cat (car args) (loop (cdr args)))])))
|
|
|
|
|
2023-02-28 06:31:08 +01:00
|
|
|
(define-syntax append
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_) '()] [(_ x) x]
|
2023-03-21 01:00:18 +01:00
|
|
|
[(_ x y) (list-cat x y)]
|
|
|
|
[(_ x y z ...) (list-cat x (append y z ...))]
|
2023-03-21 18:43:26 +01:00
|
|
|
[_ %append]))
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-20 23:47:10 +01:00
|
|
|
(define (%member v l . ?eq)
|
|
|
|
(if (null? ?eq)
|
|
|
|
(meme v l)
|
|
|
|
(let loop ([v v] [l l] [eq (car ?eq)])
|
|
|
|
(and (pair? l)
|
|
|
|
(if (eq v (car l))
|
|
|
|
l
|
|
|
|
(loop v (cdr l) eq))))))
|
2023-02-28 06:31:08 +01:00
|
|
|
|
|
|
|
(define-syntax member
|
|
|
|
(syntax-rules ()
|
2023-03-20 23:47:10 +01:00
|
|
|
[(_ v l) (meme v l)]
|
|
|
|
[(_ . args) (%member . args)]
|
|
|
|
[_ %member]))
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-20 23:47:10 +01:00
|
|
|
(define (%assoc v al . ?eq)
|
|
|
|
(if (null? ?eq)
|
|
|
|
(asse v al)
|
|
|
|
(let loop ([v v] [al al] [eq (car ?eq)])
|
|
|
|
(and (pair? al)
|
|
|
|
(if (eq v (caar al))
|
|
|
|
(car al)
|
|
|
|
(loop v (cdr al) eq))))))
|
2023-02-28 06:31:08 +01:00
|
|
|
|
|
|
|
(define-syntax assoc
|
|
|
|
(syntax-rules ()
|
2023-03-20 23:47:10 +01:00
|
|
|
[(_ v al) (asse v al)]
|
|
|
|
[(_ . args) (%assoc . args)]
|
|
|
|
[_ %assoc]))
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-22 18:21:48 +01:00
|
|
|
(define (list-copy obj)
|
|
|
|
(let loop ([obj obj])
|
|
|
|
(if (pair? obj)
|
|
|
|
(cons (car obj) (loop (cdr obj)))
|
|
|
|
obj)))
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-21 18:43:26 +01:00
|
|
|
(define (%list* x . l)
|
|
|
|
(let loop ([x x] [l l])
|
|
|
|
(if (null? l) x (cons x (loop (car l) (cdr l))))))
|
|
|
|
|
2023-02-28 06:31:08 +01:00
|
|
|
(define-syntax list*
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ x) x]
|
2023-03-19 19:52:49 +01:00
|
|
|
[(_ x y) (cons x y)]
|
|
|
|
[(_ x y z ...) (cons x (list* y z ...))]
|
2023-03-21 18:43:26 +01:00
|
|
|
[(_ . args) (%list* . args)]
|
|
|
|
[_ %list*]))
|
2023-02-28 06:31:08 +01:00
|
|
|
|
|
|
|
(define-syntax cons* list*)
|
|
|
|
|
2023-03-26 04:22:28 +02:00
|
|
|
;list-copy
|
|
|
|
|
2023-02-28 06:31:08 +01:00
|
|
|
|
|
|
|
;---------------------------------------------------------------------------------------------
|
2023-03-25 05:35:23 +01:00
|
|
|
; Symbols
|
2023-02-28 06:31:08 +01:00
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
2023-03-22 23:13:12 +01:00
|
|
|
; integrables:
|
|
|
|
;
|
2023-03-25 05:35:23 +01:00
|
|
|
; (symbol? x)
|
|
|
|
; (symbol->string y)
|
|
|
|
; (string->symbol s)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (symbol=? x y z ...)
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-08 19:03:39 +01:00
|
|
|
|
2023-03-25 05:35:23 +01:00
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; Characters
|
|
|
|
;---------------------------------------------------------------------------------------------
|
2023-03-08 19:03:39 +01:00
|
|
|
|
2023-03-25 05:35:23 +01:00
|
|
|
; integrables:
|
|
|
|
;
|
|
|
|
; (char? x)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (char-cmp c1 c2) +
|
2023-03-25 05:35:23 +01:00
|
|
|
; (char=? c1 c2 c ...)
|
|
|
|
; (char<? c1 c2 c ...)
|
|
|
|
; (char>? c1 c2 c ...)
|
|
|
|
; (char<=? c1 c2 c ...)
|
|
|
|
; (char>=? c1 c2 c ...)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (char-ci-cmp c1 c2) +
|
2023-03-25 05:35:23 +01:00
|
|
|
; (char-ci=? c1 c2 c ...)
|
|
|
|
; (char-ci<? c1 c2 c ...)
|
|
|
|
; (char-ci>? c1 c2 c ...)
|
|
|
|
; (char-ci<=? c1 c2 c ...)
|
|
|
|
; (char-ci>=? c1 c2 c ...)
|
|
|
|
; (char-alphabetic? c)
|
|
|
|
; (char-numeric? x)
|
|
|
|
; (char-whitespace? c)
|
|
|
|
; (char-upper-case? c)
|
|
|
|
; (char-lower-case? c)
|
|
|
|
; (char-upcase c)
|
|
|
|
; (char-downcase c)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (char-foldcase c)
|
|
|
|
; (digit-value c)
|
2023-03-25 05:35:23 +01:00
|
|
|
; (char->integer c)
|
|
|
|
; (integer->char n)
|
2023-03-08 19:03:39 +01:00
|
|
|
|
2023-02-28 06:31:08 +01:00
|
|
|
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; Strings
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
2023-03-22 23:13:12 +01:00
|
|
|
; integrables:
|
|
|
|
;
|
2023-03-21 01:00:18 +01:00
|
|
|
; (string? x)
|
2023-03-21 03:32:33 +01:00
|
|
|
; (string c ...)
|
2023-03-21 01:00:18 +01:00
|
|
|
; (make-string n (i #\space))
|
|
|
|
; (string-length s)
|
|
|
|
; (string-ref x i)
|
2023-03-21 03:32:33 +01:00
|
|
|
; (string-set! x i v)
|
2023-03-21 01:00:18 +01:00
|
|
|
; (list->string l)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (%string->list1 s) +
|
|
|
|
; (string-cat s1 s2) +
|
2023-03-21 01:00:18 +01:00
|
|
|
; (substring s from to)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (string-cmp s1 s2) +
|
2023-03-22 23:13:12 +01:00
|
|
|
; (string=? s1 s2 s ...)
|
|
|
|
; (string<? s1 s2 s ...)
|
|
|
|
; (string>? s1 s2 s ...)
|
|
|
|
; (string<=? s1 s2 s ...)
|
|
|
|
; (string>=? s1 s2 s ...)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (string-ci-cmp s1 s2) +
|
2023-03-22 23:13:12 +01:00
|
|
|
; (string-ci=? s1 s2 s ...)
|
|
|
|
; (string-ci<? s1 s2 s ...)
|
|
|
|
; (string-ci>? s1 s2 s ...)
|
|
|
|
; (string-ci<=? s1 s2 s ...)
|
|
|
|
; (string-ci>=? s1 s2 s ...)
|
2023-03-07 23:48:27 +01:00
|
|
|
|
|
|
|
(define (substring->list str start end)
|
|
|
|
(let loop ([i (fx- end 1)] [l '()])
|
|
|
|
(if (fx<? i start) l (loop (fx- i 1) (cons (string-ref str i) l)))))
|
|
|
|
|
2023-03-21 01:00:18 +01:00
|
|
|
(define %string->list
|
2023-03-07 23:48:27 +01:00
|
|
|
(case-lambda
|
2023-03-21 18:43:26 +01:00
|
|
|
[(str) (%string->list1 str)]
|
2023-03-07 23:48:27 +01:00
|
|
|
[(str start) (substring->list str start (string-length str))]
|
|
|
|
[(str start end) (substring->list str start end)]))
|
|
|
|
|
2023-03-21 01:00:18 +01:00
|
|
|
(define-syntax string->list
|
|
|
|
(syntax-rules ()
|
2023-03-21 18:43:26 +01:00
|
|
|
[(_ x) (%string->list1 x)]
|
2023-03-21 01:00:18 +01:00
|
|
|
[(_ . r) (%string->list . r)]
|
|
|
|
[_ %string->list]))
|
|
|
|
|
2023-03-07 23:48:27 +01:00
|
|
|
(define (substring-copy! to at from start end)
|
|
|
|
(let ([limit (fxmin end (fx+ start (fx- (string-length to) at)))])
|
|
|
|
(if (fx<=? at start)
|
|
|
|
(do ([i at (fx+ i 1)] [j start (fx+ j 1)])
|
|
|
|
[(fx>=? j limit)]
|
|
|
|
(string-set! to i (string-ref from j)))
|
|
|
|
(do ([i (fx+ at (fx- (fx- end start) 1)) (fx- i 1)] [j (fx- limit 1) (fx- j 1)])
|
|
|
|
[(fx<? j start)]
|
|
|
|
(string-set! to i (string-ref from j))))))
|
|
|
|
|
|
|
|
(define string-copy!
|
|
|
|
(case-lambda
|
|
|
|
[(to at from) (substring-copy! to at from 0 (string-length from))]
|
|
|
|
[(to at from start) (substring-copy! to at from start (string-length from))]
|
|
|
|
[(to at from start end) (substring-copy! to at from start end)]))
|
|
|
|
|
|
|
|
(define string-copy
|
|
|
|
(case-lambda
|
|
|
|
[(str) (substring str 0 (string-length str))] ; TODO: %scpy ?
|
|
|
|
[(str start) (substring str start (string-length str))]
|
|
|
|
[(str start end) (substring str start end)]))
|
|
|
|
|
|
|
|
(define (substring-fill! str c start end)
|
|
|
|
(do ([i start (fx+ i 1)]) [(fx>=? i end)] (string-set! str i c)))
|
|
|
|
|
|
|
|
(define string-fill!
|
|
|
|
(case-lambda
|
|
|
|
[(str c) (substring-fill! str c 0 (string-length str))]
|
|
|
|
[(str c start) (substring-fill! str c start (string-length str))]
|
|
|
|
[(str c start end) (substring-fill! str c start end)]))
|
|
|
|
|
|
|
|
(define (substring-vector-copy! to at from start end)
|
|
|
|
(let ([limit (fxmin end (fx+ start (fx- (vector-length to) at)))])
|
|
|
|
(do ([i at (fx+ i 1)] [j start (fx+ j 1)])
|
|
|
|
[(fx>=? j limit) to]
|
|
|
|
(vector-set! to i (string-ref from j)))))
|
|
|
|
|
|
|
|
(define (substring->vector str start end)
|
|
|
|
(substring-vector-copy! (make-vector (fx- end start)) 0 str start end))
|
|
|
|
|
|
|
|
(define string->vector
|
|
|
|
(case-lambda
|
|
|
|
[(str) (substring->vector str 0 (string-length str))]
|
|
|
|
[(str start) (substring->vector str start (string-length str))]
|
|
|
|
[(str start end) (substring->vector str start end)]))
|
|
|
|
|
2023-03-08 19:03:39 +01:00
|
|
|
(define (strings-sum-length strs)
|
|
|
|
(let loop ([strs strs] [l 0])
|
|
|
|
(if (null? strs) l (loop (cdr strs) (fx+ l (string-length (car strs)))))))
|
|
|
|
|
|
|
|
(define (strings-copy-into! to strs)
|
|
|
|
(let loop ([strs strs] [i 0])
|
|
|
|
(if (null? strs)
|
|
|
|
to
|
|
|
|
(let ([str (car strs)] [strs (cdr strs)])
|
|
|
|
(let ([len (string-length str)])
|
|
|
|
(substring-copy! to i str 0 len)
|
|
|
|
(loop strs (fx+ i len)))))))
|
|
|
|
|
2023-03-21 01:00:18 +01:00
|
|
|
(define (%string-append . strs)
|
2023-03-08 19:03:39 +01:00
|
|
|
(strings-copy-into! (make-string (strings-sum-length strs)) strs))
|
|
|
|
|
|
|
|
(define-syntax string-append
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_) ""] [(_ x) (%cks x)]
|
2023-03-21 01:00:18 +01:00
|
|
|
[(_ x y) (string-cat x y)]
|
|
|
|
[(_ . r) (%string-append . r)]
|
|
|
|
[_ %string-append]))
|
|
|
|
|
2023-02-28 06:31:08 +01:00
|
|
|
;string-upcase
|
|
|
|
;string-downcase
|
|
|
|
;string-foldcase
|
|
|
|
|
|
|
|
|
2023-03-25 05:35:23 +01:00
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; Vectors
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
; integrables:
|
|
|
|
;
|
|
|
|
; (vector? x)
|
|
|
|
; (vector x ...)
|
|
|
|
; (make-vector n (i #f))
|
|
|
|
; (vector-length v)
|
|
|
|
; (vector-ref v i)
|
|
|
|
; (vector-set! v i x)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (%vector->list1 v) +
|
2023-03-25 05:35:23 +01:00
|
|
|
; (list->vector l)
|
2023-03-26 04:22:28 +02:00
|
|
|
; (vector-cat v1 v2) +
|
2023-03-25 05:35:23 +01:00
|
|
|
|
|
|
|
(define (subvector->list vec start end)
|
|
|
|
(let loop ([i (fx- end 1)] [l '()])
|
|
|
|
(if (fx<? i start) l (loop (fx- i 1) (cons (vector-ref vec i) l)))))
|
|
|
|
|
|
|
|
(define %vector->list
|
|
|
|
(case-lambda
|
|
|
|
[(vec) (%vector->list1 vec)]
|
|
|
|
[(vec start) (subvector->list vec start (vector-length vec))]
|
|
|
|
[(vec start end) (subvector->list vec start end)]))
|
|
|
|
|
|
|
|
(define-syntax vector->list
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ x) (%vector->list1 x)]
|
|
|
|
[(_ . r) (%vector->list . r)]
|
|
|
|
[_ %vector->list]))
|
|
|
|
|
|
|
|
(define (subvector-copy! to at from start end)
|
|
|
|
(let ([limit (fxmin end (fx+ start (fx- (vector-length to) at)))])
|
|
|
|
(if (fx<=? at start)
|
|
|
|
(do ([i at (fx+ i 1)] [j start (fx+ j 1)])
|
|
|
|
[(fx>=? j limit)]
|
|
|
|
(vector-set! to i (vector-ref from j)))
|
|
|
|
(do ([i (fx+ at (fx- (fx- end start) 1)) (fx- i 1)] [j (fx- limit 1) (fx- j 1)])
|
|
|
|
[(fx<? j start)]
|
|
|
|
(vector-set! to i (vector-ref from j))))))
|
|
|
|
|
|
|
|
(define vector-copy!
|
|
|
|
(case-lambda
|
|
|
|
[(to at from) (subvector-copy! to at from 0 (vector-length from))]
|
|
|
|
[(to at from start) (subvector-copy! to at from start (vector-length from))]
|
|
|
|
[(to at from start end) (subvector-copy! to at from start end)]))
|
|
|
|
|
|
|
|
(define (subvector vec start end) ; TODO: %vsub?
|
|
|
|
(let ([v (make-vector (fx- end start))])
|
|
|
|
(subvector-copy! v 0 vec start end)
|
|
|
|
v))
|
|
|
|
|
|
|
|
(define vector-copy
|
|
|
|
(case-lambda
|
|
|
|
[(vec) (subvector vec 0 (vector-length vec))] ; TODO: %vcpy ?
|
|
|
|
[(vec start) (subvector vec start (vector-length vec))]
|
|
|
|
[(vec start end) (subvector vec start end)]))
|
|
|
|
|
|
|
|
(define (subvector-fill! vec x start end)
|
|
|
|
(do ([i start (fx+ i 1)]) [(fx>=? i end)] (vector-set! vec i x)))
|
|
|
|
|
|
|
|
(define vector-fill!
|
|
|
|
(case-lambda
|
|
|
|
[(vec x) (subvector-fill! vec x 0 (vector-length vec))]
|
|
|
|
[(vec x start) (subvector-fill! vec x start (vector-length vec))]
|
|
|
|
[(vec x start end) (subvector-fill! vec x start end)]))
|
|
|
|
|
|
|
|
(define (subvector-string-copy! to at from start end)
|
|
|
|
(let ([limit (fxmin end (fx+ start (fx- (string-length to) at)))])
|
|
|
|
(do ([i at (fx+ i 1)] [j start (fx+ j 1)])
|
|
|
|
[(fx>=? j limit) to]
|
|
|
|
(string-set! to i (vector-ref from j)))))
|
|
|
|
|
|
|
|
(define (subvector->string vec start end)
|
|
|
|
(subvector-string-copy! (make-string (fx- end start)) 0 vec start end))
|
|
|
|
|
|
|
|
(define vector->string
|
|
|
|
(case-lambda
|
|
|
|
[(vec) (subvector->string vec 0 (vector-length vec))]
|
|
|
|
[(vec start) (subvector->string vec start (vector-length vec))]
|
|
|
|
[(vec start end) (subvector->string vec start end)]))
|
|
|
|
|
|
|
|
(define (vectors-sum-length vecs)
|
|
|
|
(let loop ([vecs vecs] [l 0])
|
|
|
|
(if (null? vecs) l (loop (cdr vecs) (fx+ l (vector-length (car vecs)))))))
|
|
|
|
|
|
|
|
(define (vectors-copy-into! to vecs)
|
|
|
|
(let loop ([vecs vecs] [i 0])
|
|
|
|
(if (null? vecs)
|
|
|
|
to
|
|
|
|
(let ([vec (car vecs)] [vecs (cdr vecs)])
|
|
|
|
(let ([len (vector-length vec)])
|
|
|
|
(subvector-copy! to i vec 0 len)
|
|
|
|
(loop vecs (fx+ i len)))))))
|
|
|
|
|
|
|
|
(define (%vector-append . vecs)
|
|
|
|
(vectors-copy-into! (make-vector (vectors-sum-length vecs)) vecs))
|
|
|
|
|
|
|
|
(define-syntax vector-append
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_) '#()] [(_ x) (%ckv x)]
|
|
|
|
[(_ x y) (vector-cat x y)]
|
|
|
|
[(_ . r) (%vector-append . r)]
|
|
|
|
[_ %vector-append]))
|
|
|
|
|
|
|
|
|
2023-02-28 06:31:08 +01:00
|
|
|
;---------------------------------------------------------------------------------------------
|
2023-03-26 04:22:28 +02:00
|
|
|
; Bytevectors
|
2023-02-28 06:31:08 +01:00
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
2023-03-26 19:20:33 +02:00
|
|
|
; (bytevector? x)
|
|
|
|
; (make-bytevector n (u8 0))
|
|
|
|
; (bytevector u8 ...)
|
|
|
|
; (bytevector-length b)
|
|
|
|
; (bytevector-u8-ref b i)
|
|
|
|
; (bytevector-u8-set! b i u8)
|
2023-03-26 20:21:19 +02:00
|
|
|
; (list->bytevector l)
|
|
|
|
; (subbytevector b from to)
|
|
|
|
; (bytevector=? b1 b2 b ...)
|
|
|
|
|
|
|
|
(define (subbytevector->list bvec start end)
|
|
|
|
(let loop ([i (fx- end 1)] [l '()])
|
|
|
|
(if (fx<? i start) l (loop (fx- i 1) (cons (bytevector-u8-ref bvec i) l)))))
|
|
|
|
|
|
|
|
(define bytevector->list
|
|
|
|
(case-lambda
|
|
|
|
[(bvec) (subbytevector->list bvec 0 (bytevector-length bvec))]
|
|
|
|
[(bvec start) (subbytevector->list bvec start (bytevector-length bvec))]
|
|
|
|
[(bvec start end) (subbytevector->list bvec start end)]))
|
|
|
|
|
|
|
|
(define (subbytevector-copy! to at from start end)
|
|
|
|
(let ([limit (fxmin end (fx+ start (fx- (bytevector-length to) at)))])
|
|
|
|
(if (fx<=? at start)
|
|
|
|
(do ([i at (fx+ i 1)] [j start (fx+ j 1)])
|
|
|
|
[(fx>=? j limit)]
|
|
|
|
(bytevector-u8-set! to i (bytevector-u8-ref from j)))
|
|
|
|
(do ([i (fx+ at (fx- end start 1)) (fx- i 1)] [j (fx- limit 1) (fx- j 1)])
|
|
|
|
[(fx<? j start)]
|
|
|
|
(bytevector-u8-set! to i (bytevector-u8-ref from j))))))
|
|
|
|
|
|
|
|
(define bytevector-copy!
|
|
|
|
(case-lambda
|
|
|
|
[(to at from) (subbytevector-copy! to at from 0 (bytevector-length from))]
|
|
|
|
[(to at from start) (subbytevector-copy! to at from start (bytevector-length from))]
|
|
|
|
[(to at from start end) (subbytevector-copy! to at from start end)]))
|
|
|
|
|
|
|
|
(define bytevector-copy
|
|
|
|
(case-lambda
|
|
|
|
[(bvec) (subbytevector bvec 0 (bytevector-length bvec))]
|
|
|
|
[(bvec start) (subbytevector bvec start (bytevector-length bvec))]
|
|
|
|
[(bvec start end) (subbytevector bvec start end)]))
|
|
|
|
|
|
|
|
(define (subbytevector-fill! bvec b start end)
|
|
|
|
(do ([i start (fx+ i 1)]) [(fx>=? i end)] (bytevector-u8-set! bvec i b)))
|
|
|
|
|
|
|
|
(define bytevector-fill!
|
|
|
|
(case-lambda
|
|
|
|
[(bvec b) (subbytevector-fill! bvec b 0 (bytevector-length bvec))]
|
|
|
|
[(bvec b start) (subbytevector-fill! bvec b start (bytevector-length bvec))]
|
|
|
|
[(bvec b start end) (subbytevector-fill! bvec b start end)]))
|
|
|
|
|
|
|
|
(define (%bytevectors-sum-length bvecs)
|
|
|
|
(let loop ([bvecs bvecs] [l 0])
|
|
|
|
(if (null? bvecs) l (loop (cdr bvecs) (fx+ l (bytevector-length (car bvecs)))))))
|
|
|
|
|
|
|
|
(define (%bytevectors-copy-into! to bvecs)
|
|
|
|
(let loop ([bvecs bvecs] [i 0])
|
|
|
|
(if (null? bvecs) to
|
|
|
|
(let ([bvec (car bvecs)] [bvecs (cdr bvecs)])
|
|
|
|
(let ([len (bytevector-length bvec)])
|
|
|
|
(subbytevector-copy! to i bvec 0 len)
|
|
|
|
(loop bvecs (fx+ i len)))))))
|
|
|
|
|
|
|
|
(define (bytevector-append . bvecs)
|
|
|
|
(%bytevectors-copy-into! (make-bytevector (%bytevectors-sum-length bvecs)) bvecs))
|
2023-03-26 19:20:33 +02:00
|
|
|
|
|
|
|
;utf8->string
|
|
|
|
;string->utf8
|
2023-02-28 06:31:08 +01:00
|
|
|
|
|
|
|
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; Control features
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
2023-03-22 23:13:12 +01:00
|
|
|
; integrables:
|
|
|
|
;
|
2023-03-21 01:00:18 +01:00
|
|
|
; (procedure? x)
|
2023-03-22 23:13:12 +01:00
|
|
|
; (values x ...)
|
|
|
|
; (call-with-values thunk receiver)
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-21 18:43:26 +01:00
|
|
|
(define (%apply p x . l)
|
|
|
|
(apply-to-list p
|
|
|
|
(let loop ([x x] [l l])
|
|
|
|
(if (null? l) x (cons x (loop (car l) (cdr l)))))))
|
|
|
|
|
2023-02-28 06:31:08 +01:00
|
|
|
(define-syntax apply
|
|
|
|
(syntax-rules ()
|
2023-03-21 18:43:26 +01:00
|
|
|
[(_ p l) (apply-to-list p l)]
|
|
|
|
[(_ p a b ... l) (apply-to-list p (list* a b ... l))]
|
|
|
|
[(_ . args) (%apply . args)]
|
|
|
|
[_ %apply]))
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-22 23:13:12 +01:00
|
|
|
(define (%call/cc p) (letcc k (p k)))
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-21 18:43:26 +01:00
|
|
|
(define-syntax call/cc
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ p) (letcc k (p k))]
|
|
|
|
[(_ . args) (%call/cc . args)]
|
|
|
|
[_ %call/cc]))
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-21 18:43:26 +01:00
|
|
|
(define-syntax call-with-current-continuation call/cc)
|
2023-03-06 21:53:37 +01:00
|
|
|
|
2023-03-26 06:16:52 +02:00
|
|
|
;dynamic-wind
|
|
|
|
|
2023-03-21 18:43:26 +01:00
|
|
|
(define (%map1 p l)
|
|
|
|
(let loop ([l l] [r '()])
|
|
|
|
(if (pair? l)
|
|
|
|
(loop (cdr l) (cons (p (car l)) r))
|
|
|
|
(reverse! r))))
|
|
|
|
|
|
|
|
(define (%map2 p l1 l2)
|
|
|
|
(let loop ([l1 l1] [l2 l2] [r '()])
|
|
|
|
(if (and (pair? l1) (pair? l2))
|
|
|
|
(loop (cdr l1) (cdr l2) (cons (p (car l1) (car l2)) r))
|
|
|
|
(reverse! r))))
|
|
|
|
|
|
|
|
(define (%map p l . l*)
|
|
|
|
(cond [(null? l*) (%map1 p l)]
|
|
|
|
[(null? (cdr l*)) (%map2 p l (car l*))]
|
|
|
|
[else
|
|
|
|
(let loop ([l* (cons l l*)] [r '()])
|
|
|
|
(if (let lp ([l* l*])
|
|
|
|
(or (null? l*) (and (pair? (car l*)) (lp (cdr l*)))))
|
|
|
|
(loop (%map1 cdr l*) (cons (apply p (%map1 car l*)) r))
|
|
|
|
(reverse! r)))]))
|
2023-03-06 21:53:37 +01:00
|
|
|
|
|
|
|
(define-syntax map
|
|
|
|
(syntax-rules ()
|
2023-03-21 18:43:26 +01:00
|
|
|
[(_ p l) (%map1 p l)]
|
|
|
|
[(_ p l1 l2) (%map2 p l1 l2)]
|
|
|
|
[(_ . args) (%map . args)]
|
|
|
|
[_ %map]))
|
|
|
|
|
|
|
|
(define (%for-each1 p l)
|
|
|
|
(let loop ([l l])
|
|
|
|
(if (pair? l)
|
|
|
|
(begin (p (car l))
|
|
|
|
(loop (cdr l))))))
|
|
|
|
|
|
|
|
(define (%for-each2 p l1 l2)
|
|
|
|
(let loop ([l1 l1] [l2 l2])
|
|
|
|
(if (and (pair? l1) (pair? l2))
|
|
|
|
(begin (p (car l1) (car l2))
|
|
|
|
(loop (cdr l1) (cdr l2))))))
|
|
|
|
|
|
|
|
(define (%for-each p l . l*)
|
|
|
|
(cond [(null? l*) (%for-each1 p l)]
|
|
|
|
[(null? (cdr l*)) (%for-each2 p l (car l*))]
|
|
|
|
[else
|
|
|
|
(let loop ([l* (cons l l*)])
|
|
|
|
(if (let lp ([l* l*])
|
|
|
|
(or (null? l*) (and (pair? (car l*)) (lp (cdr l*)))))
|
|
|
|
(begin (apply p (map car l*)) (loop (map cdr l*)))))]))
|
2023-03-06 21:53:37 +01:00
|
|
|
|
|
|
|
(define-syntax for-each
|
|
|
|
(syntax-rules ()
|
2023-03-21 18:43:26 +01:00
|
|
|
[(_ p l) (%for-each1 p l)]
|
|
|
|
[(_ p l1 l2) (%for-each2 p l1 l2)]
|
|
|
|
[(_ . args) (%for-each . args)]
|
|
|
|
[_ %for-each]))
|
2023-03-06 21:53:37 +01:00
|
|
|
|
|
|
|
(define (string-map p s . s*)
|
|
|
|
(if (null? s*)
|
|
|
|
(let* ([len (string-length s)] [res (make-string len)])
|
|
|
|
(do ([i 0 (fx+ i 1)]) [(fx>=? i len) res]
|
|
|
|
(string-set! res i (p (string-ref s i)))))
|
|
|
|
(list->string (apply map p (map string->list (cons s s*))))))
|
|
|
|
|
|
|
|
(define (vector-map p v . v*)
|
|
|
|
(if (null? v*)
|
|
|
|
(let* ([len (vector-length v)] [res (make-vector len)])
|
|
|
|
(do ([i 0 (fx+ i 1)]) [(fx>=? i len) res]
|
|
|
|
(vector-set! res i (p (vector-ref v i)))))
|
|
|
|
(list->vector (apply map p (map vector->list (cons v v*))))))
|
|
|
|
|
|
|
|
(define (string-for-each p s . s*)
|
|
|
|
(if (null? s*)
|
|
|
|
(let ([len (string-length s)])
|
|
|
|
(do ([i 0 (fx+ i 1)]) [(fx>=? i len)] (p (string-ref s i))))
|
|
|
|
(apply for-each p (map string->list (cons s s*)))))
|
|
|
|
|
|
|
|
(define (vector-for-each p v . v*)
|
|
|
|
(if (null? v*)
|
|
|
|
(let ([len (vector-length v)])
|
|
|
|
(do ([i 0 (fx+ i 1)]) [(fx>=? i len)] (p (vector-ref v i))))
|
|
|
|
(apply for-each p (map vector->list (cons v v*)))))
|
2023-02-28 06:31:08 +01:00
|
|
|
|
|
|
|
|
2023-03-26 06:16:52 +02:00
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; Exceptions
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
;TBD:
|
|
|
|
;
|
|
|
|
;with-exception-handler
|
|
|
|
;raise
|
|
|
|
;raise-continuable
|
|
|
|
;error-object?
|
|
|
|
;error-object-message
|
|
|
|
;error-object-irritants
|
|
|
|
;read-error?
|
|
|
|
;file-error?
|
|
|
|
|
2023-03-26 19:20:33 +02:00
|
|
|
(define (error msg . args)
|
|
|
|
(%panic msg args)) ; should work for now
|
|
|
|
|
|
|
|
(define (read-error msg . args)
|
|
|
|
(%panic msg args)) ; should work for now
|
2023-03-26 18:02:36 +02:00
|
|
|
|
|
|
|
|
2023-03-26 06:16:52 +02:00
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; Environments and evaluation
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
;TBD:
|
|
|
|
;
|
|
|
|
;environment
|
|
|
|
;scheme-report-environment
|
|
|
|
;null-environment
|
|
|
|
;interaction-environment
|
|
|
|
;eval
|
|
|
|
|
|
|
|
|
2023-02-28 06:31:08 +01:00
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; I/O Ports
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
2023-03-22 23:13:12 +01:00
|
|
|
; integrables:
|
|
|
|
;
|
2023-03-20 23:47:10 +01:00
|
|
|
; (input-port? x)
|
|
|
|
; (output-port? x)
|
|
|
|
; (input-port-open? p)
|
|
|
|
; (output-port-open? p)
|
|
|
|
; (current-input-port)
|
|
|
|
; (current-output-port)
|
|
|
|
; (current-error-port)
|
|
|
|
; (open-output-string)
|
|
|
|
; (open-input-file s)
|
|
|
|
; (open-output-file x)
|
|
|
|
; (open-input-string x)
|
|
|
|
; (close-input-port x)
|
|
|
|
; (close-output-port x)
|
|
|
|
; (get-output-string x)
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-07 05:52:38 +01:00
|
|
|
(define (port? x) (or (input-port? x) (output-port? x)))
|
|
|
|
|
|
|
|
(define (close-port p)
|
|
|
|
(if (input-port? p) (close-input-port p))
|
|
|
|
(if (output-port? p) (close-output-port p)))
|
|
|
|
|
|
|
|
(define (call-with-port port proc)
|
|
|
|
(call-with-values (lambda () (proc port))
|
|
|
|
(lambda vals (close-port port) (apply values vals))))
|
|
|
|
|
|
|
|
(define (call-with-input-file fname proc)
|
|
|
|
(call-with-port (open-input-file fname) proc))
|
|
|
|
|
|
|
|
(define (call-with-output-file fname proc)
|
|
|
|
(call-with-port (open-output-file fname) proc))
|
|
|
|
|
|
|
|
;with-input-from-file -- requires parameterize
|
|
|
|
;with-output-to-file -- requires parameterize
|
2023-03-06 21:53:37 +01:00
|
|
|
;open-binary-input-file
|
|
|
|
;open-binary-output-file
|
|
|
|
;open-input-bytevector
|
|
|
|
;open-output-bytevector
|
|
|
|
;get-output-bytevector
|
|
|
|
|
|
|
|
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; Input
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
2023-03-22 23:13:12 +01:00
|
|
|
; integrables:
|
|
|
|
;
|
2023-03-20 23:47:10 +01:00
|
|
|
; (read-char (p (current-input-port)))
|
|
|
|
; (peek-char (p (current-input-port)))
|
|
|
|
; (char-ready? (p (current-input-port)))
|
2023-03-22 23:13:12 +01:00
|
|
|
; (eof-object? x)
|
|
|
|
; (eof-object)
|
2023-03-07 05:52:38 +01:00
|
|
|
|
2023-03-20 23:47:10 +01:00
|
|
|
(define (read-line . ?p)
|
|
|
|
(let ([p (if (null? ?p) (current-input-port) (car ?p))]
|
|
|
|
[op (open-output-string)])
|
2023-03-07 05:52:38 +01:00
|
|
|
(let loop ([read-nothing? #t])
|
2023-03-20 23:47:10 +01:00
|
|
|
(let ([c (read-char p)])
|
|
|
|
(cond [(or (eof-object? c) (char=? c #\newline))
|
|
|
|
(if (and (eof-object? c) read-nothing?)
|
|
|
|
c
|
|
|
|
(let ([s (get-output-string op)])
|
|
|
|
(close-output-port op)
|
|
|
|
s))]
|
2023-03-07 05:52:38 +01:00
|
|
|
[(char=? c #\return) (loop #f)]
|
2023-03-20 23:47:10 +01:00
|
|
|
[else (write-char c op) (loop #f)])))))
|
2023-03-07 05:52:38 +01:00
|
|
|
|
2023-03-06 21:53:37 +01:00
|
|
|
;read
|
2023-03-26 18:02:36 +02:00
|
|
|
|
|
|
|
(define (read-substring! str start end p)
|
|
|
|
(let loop ([i start])
|
|
|
|
(if (fx>=? i end) (fx- i start)
|
|
|
|
(let ([c (read-char p)])
|
|
|
|
(cond [(eof-object? c) (if (fx=? i start) c (fx- i start))]
|
|
|
|
[else (string-set! str i c) (loop (fx+ i 1))])))))
|
|
|
|
|
|
|
|
(define (read-substring k p)
|
|
|
|
(let ([str (make-string k)])
|
|
|
|
(let ([r (read-substring! str 0 k p)])
|
|
|
|
(if (eof-object? r) r
|
|
|
|
(if (fx=? r k) str (substring str 0 r))))))
|
|
|
|
|
|
|
|
(define read-string!
|
|
|
|
(case-lambda
|
|
|
|
[(str) (read-substring! str 0 (string-length str) (current-input-port))]
|
|
|
|
[(str p) (read-substring! str 0 (string-length str) p)]
|
|
|
|
[(str p start) (read-substring! str start (string-length str) p)]
|
|
|
|
[(str p start end) (read-substring! str start end p)]))
|
|
|
|
|
|
|
|
(define read-string
|
|
|
|
(case-lambda
|
|
|
|
[(k) (read-substring k (current-input-port))]
|
|
|
|
[(k p) (read-substring k p)]))
|
|
|
|
|
2023-03-06 21:53:37 +01:00
|
|
|
;read-u8
|
|
|
|
;peek-u8
|
|
|
|
;u8-ready?
|
|
|
|
;read-bytevector
|
|
|
|
;read-bytevector!
|
|
|
|
|
|
|
|
|
2023-02-28 06:31:08 +01:00
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; Output
|
|
|
|
;---------------------------------------------------------------------------------------------
|
2023-03-20 23:47:10 +01:00
|
|
|
|
2023-03-22 23:13:12 +01:00
|
|
|
; integrables:
|
|
|
|
;
|
2023-03-20 23:47:10 +01:00
|
|
|
; (write-char c (p (current-output-port)))
|
|
|
|
; (write-string s (p (current-output-port)))
|
|
|
|
; (display x (p (current-output-port)))
|
|
|
|
; (write x (p (current-output-port)))
|
|
|
|
; (newline (p (current-output-port)))
|
|
|
|
; (write-shared x (p (current-output-port)))
|
|
|
|
; (write-simple x (p (current-output-port)))
|
2023-03-26 18:02:36 +02:00
|
|
|
; (flush-output-port p)
|
2023-03-07 05:52:38 +01:00
|
|
|
|
2023-02-28 06:31:08 +01:00
|
|
|
|
2023-03-06 21:53:37 +01:00
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
; System interface
|
|
|
|
;---------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
;load
|
|
|
|
;file-exists?
|
|
|
|
;delete-file
|
|
|
|
;command-line
|
|
|
|
;exit
|
|
|
|
;emergency-exit
|
|
|
|
;get-environment-variable
|
|
|
|
;get-environment-variables
|
|
|
|
;current-second
|
|
|
|
;current-jiffy
|
|
|
|
;jiffies-per-second
|
|
|
|
;features
|
|
|
|
|