picrin/piclib/scheme/base.scm

589 lines
13 KiB
Scheme

(define-library (scheme base)
(import (picrin base)
(picrin macro)
(picrin record)
(picrin syntax-rules))
;; 4.1.2. Literal expressions
(export quote)
;; 4.1.4. Procedures
(export lambda)
;; 4.1.5. Conditionals
(export if)
;; 4.1.6. Assignments
(export set!)
;; 4.1.7. Inclusion
(export include)
;; 4.2.1. Conditionals
(export cond
case
else
=>
and
or
when
unless)
;; 4.2.2. Binding constructs
(export let
let*
letrec
letrec*
let-values
let*-values)
;; 4.2.3. Sequencing
(export begin)
;; 4.2.4. Iteration
(export do)
;; 4.2.6. Dynamic bindings
(define-syntax parameterize
(ir-macro-transformer
(lambda (form inject compare)
(let ((formal (car (cdr form)))
(body (cdr (cdr form))))
(let ((vars (map car formal))
(vals (map cadr formal)))
`(begin
,@(map (lambda (var val) `(parameter-push! ,var ,val)) vars vals)
(let ((result (begin ,@body)))
,@(map (lambda (var) `(parameter-pop! ,var)) vars)
result)))))))
(export make-parameter
parameterize)
;; 4.2.7. Exception handling
(define-syntax guard-aux
(syntax-rules (else =>)
((guard-aux reraise (else result1 result2 ...))
(begin result1 result2 ...))
((guard-aux reraise (test => result))
(let ((temp test))
(if temp
(result temp)
reraise)))
((guard-aux reraise (test => result)
clause1 clause2 ...)
(let ((temp test))
(if temp
(result temp)
(guard-aux reraise clause1 clause2 ...))))
((guard-aux reraise (test))
(or test reraise))
((guard-aux reraise (test) clause1 clause2 ...)
(let ((temp test))
(if temp
temp
(guard-aux reraise clause1 clause2 ...))))
((guard-aux reraise (test result1 result2 ...))
(if test
(begin result1 result2 ...)
reraise))
((guard-aux reraise
(test result1 result2 ...)
clause1 clause2 ...)
(if test
(begin result1 result2 ...)
(guard-aux reraise clause1 clause2 ...)))))
(define-syntax guard
(syntax-rules ()
((guard (var clause ...) e1 e2 ...)
((call/cc
(lambda (guard-k)
(with-exception-handler
(lambda (condition)
((call/cc
(lambda (handler-k)
(guard-k
(lambda ()
(let ((var condition))
(guard-aux
(handler-k
(lambda ()
(raise-continuable condition)))
clause ...))))))))
(lambda ()
(call-with-values
(lambda () e1 e2 ...)
(lambda args
(guard-k
(lambda ()
(apply values args)))))))))))))
(export guard)
;; 4.2.8. Quasiquotation
(export quasiquote
unquote
unquote-splicing)
;; 4.3.1. Binding constructs for syntactic keywords
(export let-syntax
letrec-syntax)
;; 4.3.2 Pattern language
(export syntax-rules
_
...)
;; 4.3.3. Signaling errors in macro transformers
(export syntax-error)
;; 5.3. Variable definitions
(export define)
;; 5.3.3. Multiple-value definitions
(export define-values)
;; 5.4. Syntax definitions
(export define-syntax)
;; 5.5 Recored-type definitions
(export define-record-type)
;; 6.1. Equivalence predicates
(export eq?
eqv?
equal?)
;; 6.2. Numbers
(define (exact-integer? x)
(and (exact? x)
(integer? x)))
(define (zero? x)
(= x 0))
(define (positive? x)
(> x 0))
(define (negative? x)
(< x 0))
(define (even? x)
(= x (* (exact (floor (/ x 2))) 2)))
(define (odd? x)
(not (even? x)))
(define (min . args)
(define (min a b)
(if (< a b) a b))
(let loop ((args args) (acc +inf.0))
(if (null? args)
acc
(loop (cdr args) (min (car args) acc)))))
(define (max . args)
(define (max a b)
(if (> a b) a b))
(let loop ((args args) (acc -inf.0))
(if (null? args)
acc
(loop (cdr args) (max (car args) acc)))))
(define (floor-quotient i j)
(call-with-values (lambda () (floor/ i j))
(lambda (q r)
q)))
(define (floor-remainder i j)
(call-with-values (lambda () (floor/ i j))
(lambda (q r)
r)))
(define (truncate-quotient i j)
(call-with-values (lambda () (truncate/ i j))
(lambda (q r)
q)))
(define (truncate-remainder i j)
(call-with-values (lambda () (truncate/ i j))
(lambda (q r)
r)))
(define (gcd . args)
(define (gcd i j)
(cond
((> i j) (gcd j i))
((< i 0) (gcd (- i) j))
((> i 0) (gcd (truncate-remainder j i) i))
(else j)))
(let loop ((args args) (acc 0))
(if (null? args)
acc
(loop (cdr args)
(gcd acc (car args))))))
(define (lcm . args)
(define (lcm i j)
(/ (abs (* i j)) (gcd i j)))
(let loop ((args args) (acc 1))
(if (null? args)
acc
(loop (cdr args)
(lcm acc (car args))))))
(define (square x)
(* x x))
(define (exact-integer-sqrt k)
(let ((s (exact (sqrt k))))
(values s (- k (square s)))))
(export number?
complex?
real?
rational?
integer?
exact?
inexact?
exact-integer?
exact
inexact
=
<
>
<=
>=
zero?
positive?
negative?
odd?
even?
min
max
+
-
*
/
abs
floor-quotient
floor-remainder
floor/
truncate-quotient
truncate-remainder
truncate/
(rename truncate-quotient quotient)
(rename truncate-remainder remainder)
(rename floor-remainder modulo)
gcd
lcm
floor
ceiling
truncate
round
exact-integer-sqrt
square
expt
number->string
string->number)
;; 6.3. Booleans
(export boolean?
boolean=?
not)
;; 6.4 Pairs and lists
(export pair?
cons
car
cdr
set-car!
set-cdr!
null?
caar
cadr
cdar
cddr
list?
make-list
list
length
append
reverse
list-tail
list-ref
list-set!
list-copy
memq
memv
member
assq
assv
assoc)
;; 6.5. Symbols
(export symbol?
symbol=?
symbol->string
string->symbol)
;; 6.6. Characters
(define-macro (define-char-transitive-predicate name op)
`(define (,name . cs)
(apply ,op (map char->integer cs))))
(define-char-transitive-predicate char=? =)
(define-char-transitive-predicate char<? <)
(define-char-transitive-predicate char>? >)
(define-char-transitive-predicate char<=? <=)
(define-char-transitive-predicate char>=? >=)
(export char?
char->integer
integer->char
char=?
char<?
char>?
char<=?
char>=?)
;; 6.7. Strings
(define (string->list string . opts)
(let ((start (if (pair? opts) (car opts) 0))
(end (if (>= (length opts) 2)
(cadr opts)
(string-length string))))
(do ((i start (+ i 1))
(res '()))
((= i end)
(reverse res))
(set! res (cons (string-ref string i) res)))))
(define (list->string list)
(let ((len (length list)))
(let ((v (make-string len)))
(do ((i 0 (+ i 1))
(l list (cdr l)))
((= i len)
v)
(string-set! v i (car l))))))
(define (string . objs)
(list->string objs))
(export string?
string
make-string
string-length
string-ref
string-set!
string-copy
string-copy!
string-append
string-fill!
string=?
string<?
string>?
string<=?
string>=?
string->list
list->string
(rename string-copy substring))
;; 6.8. Vectors
(define (vector . objs)
(list->vector objs))
(define (vector->string . args)
(list->string (apply vector->list args)))
(define (string->vector . args)
(list->vector (apply string->list args)))
(export vector
vector->string
string->vector)
(export vector?
make-vector
vector-length
vector-ref
vector-set!
vector-copy!
vector-copy
vector-append
vector-fill!
list->vector
vector->list)
;; 6.9. bytevector
(define (bytevector->list v start end)
(do ((i start (+ i 1))
(res '()))
((= i end)
(reverse res))
(set! res (cons (bytevector-u8-ref v i) res))))
(define (list->bytevector list)
(let ((len (length list)))
(let ((v (make-bytevector len)))
(do ((i 0 (+ i 1))
(l list (cdr l)))
((= i len)
v)
(bytevector-u8-set! v i (car l))))))
(define (bytevector . objs)
(list->bytevector objs))
(define (utf8->string v . opts)
(let ((start (if (pair? opts) (car opts) 0))
(end (if (>= (length opts) 2)
(cadr opts)
(bytevector-length v))))
(list->string (map integer->char (bytevector->list v start end)))))
(define (string->utf8 s . opts)
(let ((start (if (pair? opts) (car opts) 0))
(end (if (>= (length opts) 2)
(cadr opts)
(string-length s))))
(list->bytevector (map char->integer (string->list s start end)))))
(export bytevector?
bytevector
make-bytevector
bytevector-length
bytevector-u8-ref
bytevector-u8-set!
bytevector-copy
bytevector-copy!
bytevector-append
bytevector->list
list->bytevector
utf8->string
string->utf8)
;; 6.10. Control features
(define (string-map f . strings)
(list->string (apply map f (map string->list strings))))
(define (string-for-each f . strings)
(apply for-each f (map string->list strings)))
(define (vector-map f . vectors)
(list->vector (apply map f (map vector->list vectors))))
(define (vector-for-each f . vectors)
(apply for-each f (map vector->list vectors)))
(export procedure?
apply
map
for-each
string-map
string-for-each
vector-map
vector-for-each
call-with-current-continuation
call/cc
dynamic-wind
values
call-with-values)
;; 6.11. Exceptions
(export with-exception-handler
raise
raise-continuable
error
error-object?
error-object-message
error-object-irritants
read-error?
file-error?)
;; 6.13. Input and output
(define (call-with-port port proc)
(let ((value (proc port)))
(close-port port)
value))
(export current-input-port
current-output-port
current-error-port
call-with-port
port?
input-port?
output-port?
textual-port?
binary-port?
(rename port-open? input-port-open?)
(rename port-open? output-port-open?)
close-port
(rename close-port close-input-port)
(rename close-port close-output-port)
open-input-string
open-output-string
get-output-string
open-input-bytevector
open-output-bytevector
get-output-bytevector
eof-object?
eof-object
read-char
peek-char
char-ready?
read-line
read-string
read-u8
peek-u8
u8-ready?
read-bytevector
read-bytevector!
newline
write-char
write-string
write-u8
write-bytevector
flush-output-port))