Merge remote-tracking branch 'upstream/master' into native-record

Conflicts:
	piclib/scheme/base.scm
This commit is contained in:
Yuito Murase 2014-08-03 16:19:54 +09:00
commit 0c4d2b9cef
2 changed files with 327 additions and 367 deletions

View File

@ -1,6 +1,6 @@
list(APPEND PICLIB_SCHEME_LIBS list(APPEND PICLIB_SCHEME_LIBS
${PROJECT_SOURCE_DIR}/piclib/picrin/macro.scm # the only dependency prelude requires ${PROJECT_SOURCE_DIR}/piclib/picrin/macro.scm
${PROJECT_SOURCE_DIR}/piclib/prelude.scm ${PROJECT_SOURCE_DIR}/piclib/scheme/base.scm
${PROJECT_SOURCE_DIR}/piclib/picrin/array.scm ${PROJECT_SOURCE_DIR}/piclib/picrin/array.scm
${PROJECT_SOURCE_DIR}/piclib/picrin/dictionary.scm ${PROJECT_SOURCE_DIR}/piclib/picrin/dictionary.scm
${PROJECT_SOURCE_DIR}/piclib/picrin/test.scm ${PROJECT_SOURCE_DIR}/piclib/picrin/test.scm

View File

@ -1,7 +1,7 @@
;;; core syntaces (define-library (scheme base)
(define-library (picrin core-syntax) (import (picrin macro))
(import (scheme base)
(picrin macro)) ;; core syntax
(define-syntax syntax-error (define-syntax syntax-error
(er-macro-transformer (er-macro-transformer
@ -275,23 +275,46 @@
do when unless do when unless
let-syntax letrec-syntax let-syntax letrec-syntax
include include
_ ... syntax-error)) _ ... syntax-error)
(import (picrin core-syntax))
(export let let* letrec letrec* ;; utility functions
quasiquote unquote unquote-splicing
and or
cond case else =>
do when unless
let-syntax letrec-syntax
include
_ ... syntax-error)
;;; multiple value (define (walk proc expr)
(define-library (picrin values) (cond
(import (scheme base) ((null? expr)
(picrin macro)) '())
((pair? expr)
(cons (walk proc (car expr))
(walk proc (cdr expr))))
((vector? expr)
(list->vector (map proc (vector->list expr))))
(else
(proc expr))))
(define (flatten expr)
(let ((list '()))
(walk
(lambda (x)
(set! list (cons x list)))
expr)
(reverse list)))
(define (reverse* l)
;; (reverse* '(a b c d . e)) => (e d c b a)
(let loop ((a '())
(d l))
(if (pair? d)
(loop (cons (car d) a) (cdr d))
(cons d a))))
(define (every? pred l)
(if (null? l)
#t
(and (pred (car l)) (every? pred (cdr l)))))
;; extra syntax
(define-syntax let*-values (define-syntax let*-values
(er-macro-transformer (er-macro-transformer
@ -309,26 +332,6 @@
(lambda (form r c) (lambda (form r c)
`(,(r 'let*-values) ,@(cdr form))))) `(,(r 'let*-values) ,@(cdr form)))))
(define (walk proc expr)
(cond
((null? expr)
'())
((pair? expr)
(cons (proc (car expr))
(walk proc (cdr expr))))
((vector? expr)
(list->vector (map proc (vector->list expr))))
(else
(proc expr))))
(define (flatten expr)
(let ((list '()))
(walk
(lambda (x)
(set! list (cons x list)))
expr)
(reverse list)))
(define uniq (define uniq
(let ((counter 0)) (let ((counter 0))
(lambda (x) (lambda (x)
@ -355,274 +358,8 @@
(export let-values (export let-values
let*-values let*-values
define-values)) define-values)
;;; parameter
(define-library (picrin parameter)
(import (scheme base)
(picrin macro))
(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 parameterize))
;;; Record Type
(define-library (picrin record)
(import (scheme base)
(picrin macro)
(picrin record-primitive))
(define (caddr x) (car (cddr x)))
(define (cdddr x) (cdr (cddr x)))
(define (cadddr x) (car (cdddr x)))
(define (cddddr x) (cdr (cdddr x)))
(define (make-record-type name)
(let ((rectype (make-record #t)))
(record-set! rectype #t 'name name)
rectype))
(define-syntax define-record-constructor
(ir-macro-transformer
(lambda (form inject compare?)
(let ((rectype (cadr form))
(name (caddr form))
(fields (cdddr form)))
`(define (,name ,@fields)
(let ((record (make-record ,rectype)))
,@(map (lambda (field)
`(record-set! record ,rectype ',field ,field))
fields)
record))))))
(define-syntax define-record-predicate
(ir-macro-transformer
(lambda (form inject compare?)
(let ((rectype (cadr form))
(name (caddr form)))
`(define (,name obj)
(record-of? obj ,rectype))))))
(define-syntax define-record-field
(ir-macro-transformer
(lambda (form inject compare?)
(let ((rectype (cadr form))
(field-name (caddr form))
(accessor (cadddr form))
(modifier? (cddddr form)))
(if (null? modifier?)
`(define (,accessor record)
(record-roef record ,rectype ',field-name))
`(begin
(define (,accessor record)
(record-ref record ,rectype ',field-name))
(define (,(car modifier?) record val)
(record-set! record ,rectype ',field-name val))))))))
(define-syntax define-record-type
(ir-macro-transformer
(lambda (form inject compare?)
(let ((name (cadr form))
(constructor (caddr form))
(pred (cadddr form))
(fields (cddddr form)))
`(begin
(define ,name (make-record-type ',name))
(define-record-constructor ,name ,@constructor)
(define-record-predicate ,name ,pred)
,@(map (lambda (field) `(define-record-field ,name ,@field))
fields))))))
(export define-record-type))
(import (picrin macro)
(picrin values)
(picrin parameter)
(picrin record))
(export let-values
let*-values
define-values)
(export make-parameter
parameterize)
(export define-record-type)
;;; 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<?
char>?
char<=?
char>=?)
;;; 6.7 String
(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->list list->string)
;;; 6.8. Vector
(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)
;;; 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->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 string-map string-for-each
vector-map vector-for-each)
;;; 6.13. Input and output
(define (call-with-port port proc)
(dynamic-wind
(lambda () #f)
(lambda () (proc port))
(lambda () (close-port port))))
(export call-with-port)
;;; syntax-rules
(define-library (picrin syntax-rules)
(import (scheme base)
(picrin macro))
;;; utility functions
(define (reverse* l)
;; (reverse* '(a b c d . e)) => (e d c b a)
(let loop ((a '())
(d l))
(if (pair? d)
(loop (cons (car d) a) (cdr d))
(cons d a))))
(define (var->sym v)
(let loop ((cnt 0)
(v v))
(if (symbol? v)
(string->symbol (string-append (symbol->string v) "/" (number->string cnt)))
(loop (+ 1 cnt) (car v)))))
(define push-var list)
(define (every? pred l)
(if (null? l)
#t
(and (pred (car l)) (every? pred (cdr l)))))
(define (flatten l)
(cond
((null? l) '())
((pair? (car l))
(append (flatten (car l)) (flatten (cdr l))))
(else
(cons (car l) (flatten (cdr l))))))
;;; main function
(define-syntax syntax-rules (define-syntax syntax-rules
(er-macro-transformer (er-macro-transformer
(lambda (form r compare) (lambda (form r compare)
@ -653,6 +390,16 @@
(define _call/cc (r 'call/cc)) (define _call/cc (r 'call/cc))
(define _er-macro-transformer (r 'er-macro-transformer)) (define _er-macro-transformer (r 'er-macro-transformer))
(define (var->sym v)
(let loop ((cnt 0)
(v v))
(if (symbol? v)
(string->symbol
(string-append (symbol->string v) "/" (number->string cnt)))
(loop (+ 1 cnt) (car v)))))
(define push-var list)
(define (compile-match ellipsis literals pattern) (define (compile-match ellipsis literals pattern)
(letrec ((compile-match-base (letrec ((compile-match-base
(lambda (pattern) (lambda (pattern)
@ -906,68 +653,281 @@
`(,_syntax-error "malformed syntax-rules")))))) `(,_syntax-error "malformed syntax-rules"))))))
(export syntax-rules)) (export syntax-rules)
(import (picrin syntax-rules)) (define-syntax guard-aux
(export syntax-rules) (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-aux (define-syntax guard
(syntax-rules (else =>) (syntax-rules ()
((guard-aux reraise (else result1 result2 ...)) ((guard (var clause ...) e1 e2 ...)
(begin result1 result2 ...)) ((call/cc
((guard-aux reraise (test => result)) (lambda (guard-k)
(let ((temp test)) (with-exception-handler
(if temp (lambda (condition)
(result temp) ((call/cc
reraise))) (lambda (handler-k)
((guard-aux reraise (test => result) (guard-k
clause1 clause2 ...) (lambda ()
(let ((temp test)) (let ((var condition))
(if temp (guard-aux
(result temp) (handler-k
(guard-aux reraise clause1 clause2 ...)))) (lambda ()
((guard-aux reraise (test)) (raise-continuable condition)))
(or test reraise)) clause ...))))))))
((guard-aux reraise (test) clause1 clause2 ...) (lambda ()
(let ((temp test)) (call-with-values
(if temp (lambda () e1 e2 ...)
temp (lambda args
(guard-aux reraise clause1 clause2 ...)))) (guard-k
((guard-aux reraise (test result1 result2 ...)) (lambda ()
(if test (apply values args)))))))))))))
(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 (export 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) (import (picrin parameter))
(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 parameterize make-parameter)
;;; Record Type
(define-library (picrin record)
(import (scheme base)
(picrin macro)
(picrin record-primitive))
(define (caddr x) (car (cddr x)))
(define (cdddr x) (cdr (cddr x)))
(define (cadddr x) (car (cdddr x)))
(define (cddddr x) (cdr (cdddr x)))
(define (make-record-type name)
(let ((rectype (make-record #t)))
(record-set! rectype #t 'name name)
rectype))
(define-syntax define-record-constructor
(ir-macro-transformer
(lambda (form inject compare?)
(let ((rectype (cadr form))
(name (caddr form))
(fields (cdddr form)))
`(define (,name ,@fields)
(let ((record (make-record ,rectype)))
,@(map (lambda (field)
`(record-set! record ,rectype ',field ,field))
fields)
record))))))
(define-syntax define-record-predicate
(ir-macro-transformer
(lambda (form inject compare?)
(let ((rectype (cadr form))
(name (caddr form)))
`(define (,name obj)
(record-of? obj ,rectype))))))
(define-syntax define-record-field
(ir-macro-transformer
(lambda (form inject compare?)
(let ((rectype (cadr form))
(field-name (caddr form))
(accessor (cadddr form))
(modifier? (cddddr form)))
(if (null? modifier?)
`(define (,accessor record)
(record-ref record ,rectype ',field-name))
`(begin
(define (,accessor record)
(record-ref record ,rectype ',field-name))
(define (,(car modifier?) record val)
(record-set! record ,rectype ',field-name val))))))))
(define-syntax define-record-type
(ir-macro-transformer
(lambda (form inject compare?)
(let ((name (cadr form))
(constructor (caddr form))
(pred (cadddr form))
(fields (cddddr form)))
`(begin
(define ,name (make-record-type ',name))
(define-record-constructor ,name ,@constructor)
(define-record-predicate ,name ,pred)
,@(map (lambda (field) `(define-record-field ,name ,@field))
fields))))))
(export define-record-type))
(import (picrin record))
(export define-record-type)
;; 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<?
char>?
char<=?
char>=?)
;; 6.7 String
(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->list list->string)
;; 6.8. Vector
(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)
;; 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->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 string-map string-for-each
vector-map vector-for-each)
;; 6.13. Input and output
(define (call-with-port port proc)
(dynamic-wind
(lambda () #f)
(lambda () (proc port))
(lambda () (close-port port))))
(export call-with-port))