Merge branch 'piclib-to-contrib'
This commit is contained in:
		
						commit
						881bfa807d
					
				
							
								
								
									
										13
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										13
									
								
								Makefile
								
								
								
								
							|  | @ -7,15 +7,6 @@ PICRIN_SRCS = \ | ||||||
| 	src/init_contrib.c | 	src/init_contrib.c | ||||||
| PICRIN_OBJS = \
 | PICRIN_OBJS = \
 | ||||||
| 	$(PICRIN_SRCS:.c=.o) | 	$(PICRIN_SRCS:.c=.o) | ||||||
| PICRIN_LIBS = \
 |  | ||||||
| 	piclib/picrin/base.scm\
 |  | ||||||
| 	piclib/picrin/macro.scm\
 |  | ||||||
| 	piclib/picrin/record.scm\
 |  | ||||||
| 	piclib/picrin/array.scm\
 |  | ||||||
| 	piclib/picrin/control.scm\
 |  | ||||||
| 	piclib/picrin/experimental/lambda.scm\
 |  | ||||||
| 	piclib/picrin/syntax-rules.scm\
 |  | ||||||
| 	piclib/picrin/test.scm |  | ||||||
| 
 | 
 | ||||||
| CONTRIB_SRCS = | CONTRIB_SRCS = | ||||||
| CONTRIB_OBJS = $(CONTRIB_SRCS:.c=.o) | CONTRIB_OBJS = $(CONTRIB_SRCS:.c=.o) | ||||||
|  | @ -40,8 +31,8 @@ debug: bin/picrin | ||||||
| bin/picrin: $(PICRIN_OBJS) $(CONTRIB_OBJS) lib/libbenz.a | bin/picrin: $(PICRIN_OBJS) $(CONTRIB_OBJS) lib/libbenz.a | ||||||
| 	$(CC) $(CFLAGS) -o $@ $(PICRIN_OBJS) $(CONTRIB_OBJS) lib/libbenz.a $(LDFLAGS) | 	$(CC) $(CFLAGS) -o $@ $(PICRIN_OBJS) $(CONTRIB_OBJS) lib/libbenz.a $(LDFLAGS) | ||||||
| 
 | 
 | ||||||
| src/load_piclib.c: $(PICRIN_LIBS) $(CONTRIB_LIBS) | src/load_piclib.c: $(CONTRIB_LIBS) | ||||||
| 	perl etc/mkloader.pl $(PICRIN_LIBS) $(CONTRIB_LIBS) > $@ | 	perl etc/mkloader.pl $(CONTRIB_LIBS) > $@ | ||||||
| 
 | 
 | ||||||
| src/init_contrib.c: | src/init_contrib.c: | ||||||
| 	perl etc/mkinit.pl $(CONTRIB_INITS) > $@ | 	perl etc/mkinit.pl $(CONTRIB_INITS) > $@ | ||||||
|  |  | ||||||
|  | @ -0,0 +1,6 @@ | ||||||
|  | CONTRIB_LIBS += $(wildcard contrib/10.macro/*.scm) | ||||||
|  | 
 | ||||||
|  | CONTRIB_TESTS += test-macro | ||||||
|  | 
 | ||||||
|  | test-macro: bin/picrin | ||||||
|  | 	bin/picrin contrib/10.macro/t/ir-macro.scm | ||||||
|  | @ -1,8 +1,6 @@ | ||||||
| (define-library (scheme base) | (define-library (scheme base) | ||||||
|   (import (picrin base) |   (import (picrin base) | ||||||
|           (picrin macro) |           (picrin macro) | ||||||
|           (picrin record) |  | ||||||
|           (picrin syntax-rules) |  | ||||||
|           (picrin string) |           (picrin string) | ||||||
|           (scheme file)) |           (scheme file)) | ||||||
| 
 | 
 | ||||||
|  | @ -76,43 +74,37 @@ | ||||||
| 
 | 
 | ||||||
|   ;; 4.2.7. Exception handling |   ;; 4.2.7. Exception handling | ||||||
| 
 | 
 | ||||||
|   (define-syntax guard-aux |   (define-syntax (guard-aux reraise . clauses) | ||||||
|     (syntax-rules (else =>) |     (letrec | ||||||
|       ((guard-aux reraise (else result1 result2 ...)) |         ((else? | ||||||
|        (begin result1 result2 ...)) |           (lambda (clause) | ||||||
|       ((guard-aux reraise (test => result)) |             (and (list? clause) (equal? #'else (car clause))))) | ||||||
|        (let ((temp test)) |          (=>? | ||||||
|          (if temp |           (lambda (clause) | ||||||
|              (result temp) |             (and (list? clause) (= (length clause) 3) (equal? #'=> (list-ref clause 1)))))) | ||||||
|              reraise))) |       (if (null? clauses) | ||||||
|       ((guard-aux reraise (test => result) |           reraise | ||||||
|                   clause1 clause2 ...) |           (let ((clause (car clauses)) | ||||||
|        (let ((temp test)) |                 (rest (cdr clauses))) | ||||||
|          (if temp |             (cond | ||||||
|              (result temp) |              ((else? clause) | ||||||
|              (guard-aux reraise clause1 clause2 ...)))) |               #`(begin #,@(cdr clause))) | ||||||
|       ((guard-aux reraise (test)) |              ((=>? clause) | ||||||
|        (or test reraise)) |               #`(let ((tmp #,(list-ref clause 0))) | ||||||
|       ((guard-aux reraise (test) clause1 clause2 ...) |                   (if tmp | ||||||
|        (let ((temp test)) |                       (#,(list-ref clause 2) tmp) | ||||||
|          (if temp |                       (guard-aux #,reraise #,@rest)))) | ||||||
|              temp |              ((= (length clause) 1) | ||||||
|              (guard-aux reraise clause1 clause2 ...)))) |               #`(or #,(car clause) (guard-aux #,reraise #,@rest))) | ||||||
|       ((guard-aux reraise (test result1 result2 ...)) |              (else | ||||||
|        (if test |               #`(if #,(car clause) | ||||||
|            (begin result1 result2 ...) |                     (begin #,@(cdr clause)) | ||||||
|            reraise)) |                     (guard-aux #,reraise #,@rest)))))))) | ||||||
|       ((guard-aux reraise |  | ||||||
|                   (test result1 result2 ...) |  | ||||||
|                   clause1 clause2 ...) |  | ||||||
|        (if test |  | ||||||
|            (begin result1 result2 ...) |  | ||||||
|            (guard-aux reraise clause1 clause2 ...))))) |  | ||||||
| 
 | 
 | ||||||
|   (define-syntax guard |   (define-syntax (guard formal . body) | ||||||
|     (syntax-rules () |     (let ((var (car formal)) | ||||||
|       ((guard (var clause ...) e1 e2 ...) |           (clauses (cdr formal))) | ||||||
|        ((call/cc |       #`((call/cc | ||||||
|           (lambda (guard-k) |           (lambda (guard-k) | ||||||
|             (with-exception-handler |             (with-exception-handler | ||||||
|              (lambda (condition) |              (lambda (condition) | ||||||
|  | @ -120,19 +112,19 @@ | ||||||
|                  (lambda (handler-k) |                  (lambda (handler-k) | ||||||
|                    (guard-k |                    (guard-k | ||||||
|                     (lambda () |                     (lambda () | ||||||
|                      (let ((var condition)) |                       (let ((#,var condition)) | ||||||
|                         (guard-aux |                         (guard-aux | ||||||
|                          (handler-k |                          (handler-k | ||||||
|                           (lambda () |                           (lambda () | ||||||
|                             (raise-continuable condition))) |                             (raise-continuable condition))) | ||||||
|                         clause ...)))))))) |                          #,@clauses)))))))) | ||||||
|              (lambda () |              (lambda () | ||||||
|                (call-with-values |                (call-with-values | ||||||
|                   (lambda () e1 e2 ...) |                    (lambda () #,@body) | ||||||
|                  (lambda args |                  (lambda args | ||||||
|                    (guard-k |                    (guard-k | ||||||
|                     (lambda () |                     (lambda () | ||||||
|                      (apply values args))))))))))))) |                       (apply values args)))))))))))) | ||||||
| 
 | 
 | ||||||
|   (export guard) |   (export guard) | ||||||
| 
 | 
 | ||||||
|  | @ -149,6 +141,242 @@ | ||||||
| 
 | 
 | ||||||
|   ;; 4.3.2 Pattern language |   ;; 4.3.2 Pattern language | ||||||
| 
 | 
 | ||||||
|  |   (define (succ n) | ||||||
|  |     (+ n 1)) | ||||||
|  | 
 | ||||||
|  |   (define (pred n) | ||||||
|  |     (if (= n 0) | ||||||
|  |         0 | ||||||
|  |         (- n 1))) | ||||||
|  | 
 | ||||||
|  |   (define (every? args) | ||||||
|  |     (if (null? args) | ||||||
|  |         #t | ||||||
|  |         (if (car args) | ||||||
|  |             (every? (cdr args)) | ||||||
|  |             #f))) | ||||||
|  | 
 | ||||||
|  |   (define (filter f list) | ||||||
|  |     (if (null? list) | ||||||
|  |         '() | ||||||
|  |         (if (f (car list)) | ||||||
|  |             (cons (car list) | ||||||
|  |                   (filter f (cdr list))) | ||||||
|  |             (filter f (cdr list))))) | ||||||
|  | 
 | ||||||
|  |   (define (take-tail n list) | ||||||
|  |     (let drop ((n (- (length list) n)) (list list)) | ||||||
|  |       (if (= n 0) | ||||||
|  |           list | ||||||
|  |           (drop (- n 1) (cdr list))))) | ||||||
|  | 
 | ||||||
|  |   (define (drop-tail n list) | ||||||
|  |     (let take ((n (- (length list) n)) (list list)) | ||||||
|  |       (if (= n 0) | ||||||
|  |           '() | ||||||
|  |           (cons (car list) (take (- n 1) (cdr list)))))) | ||||||
|  | 
 | ||||||
|  |   (define (map-keys f assoc) | ||||||
|  |     (map (lambda (s) `(,(f (car s)) . ,(cdr s))) assoc)) | ||||||
|  | 
 | ||||||
|  |   (define (map-values f assoc) | ||||||
|  |     (map (lambda (s) `(,(car s) . ,(f (cdr s)))) assoc)) | ||||||
|  | 
 | ||||||
|  |   ;; TODO | ||||||
|  |   ;; - placeholder | ||||||
|  |   ;; - vector | ||||||
|  |   ;; - (... template) pattern | ||||||
|  | 
 | ||||||
|  |   ;; p ::= constant | ||||||
|  |   ;;     | var | ||||||
|  |   ;;     | (p ... . p)      (in input pattern, tail p should be a proper list) | ||||||
|  |   ;;     | (p . p) | ||||||
|  | 
 | ||||||
|  |   (define (compile ellipsis literals rules) | ||||||
|  | 
 | ||||||
|  |     (define (constant? obj) | ||||||
|  |       (and (not (pair? obj)) | ||||||
|  |            (not (variable? obj)))) | ||||||
|  | 
 | ||||||
|  |     (define (literal? obj) | ||||||
|  |       (and (variable? obj) | ||||||
|  |            (memq obj literals))) | ||||||
|  | 
 | ||||||
|  |     (define (many? pat) | ||||||
|  |       (and (pair? pat) | ||||||
|  |            (pair? (cdr pat)) | ||||||
|  |            (variable? (cadr pat)) | ||||||
|  |            (variable=? (cadr pat) ellipsis))) | ||||||
|  | 
 | ||||||
|  |     (define (pattern-validator pat)      ; pattern -> validator | ||||||
|  |       (letrec | ||||||
|  |           ((pattern-validator | ||||||
|  |             (lambda (pat form) | ||||||
|  |               (cond | ||||||
|  |                ((constant? pat) | ||||||
|  |                 #`(equal? '#,pat #,form)) | ||||||
|  |                ((literal? pat) | ||||||
|  |                 #`(and (variable? #,form) (variable=? #'#,pat #,form))) | ||||||
|  |                ((variable? pat) | ||||||
|  |                 #t) | ||||||
|  |                ((many? pat) | ||||||
|  |                 (let ((head #`(drop-tail #,(length (cddr pat)) #,form)) | ||||||
|  |                       (tail #`(take-tail #,(length (cddr pat)) #,form))) | ||||||
|  |                   #`(and (list? #,form) | ||||||
|  |                          (>= (length #,form) #,(length (cddr pat))) | ||||||
|  |                          (every? (map (lambda (#,'it) #,(pattern-validator (car pat) 'it)) #,head)) | ||||||
|  |                          #,(pattern-validator (cddr pat) tail)))) | ||||||
|  |                ((pair? pat) | ||||||
|  |                 #`(and (pair? #,form) | ||||||
|  |                        #,(pattern-validator (car pat) #`(car #,form)) | ||||||
|  |                        #,(pattern-validator (cdr pat) #`(cdr #,form)))) | ||||||
|  |                (else | ||||||
|  |                 #f))))) | ||||||
|  |         (pattern-validator pat 'it))) | ||||||
|  | 
 | ||||||
|  |     (define (pattern-variables pat)       ; pattern -> (freevar) | ||||||
|  |       (cond | ||||||
|  |        ((constant? pat) | ||||||
|  |         '()) | ||||||
|  |        ((literal? pat) | ||||||
|  |         '()) | ||||||
|  |        ((variable? pat) | ||||||
|  |         `(,pat)) | ||||||
|  |        ((many? pat) | ||||||
|  |         (append (pattern-variables (car pat)) | ||||||
|  |                 (pattern-variables (cddr pat)))) | ||||||
|  |        ((pair? pat) | ||||||
|  |         (append (pattern-variables (car pat)) | ||||||
|  |                 (pattern-variables (cdr pat)))))) | ||||||
|  | 
 | ||||||
|  |     (define (pattern-levels pat)          ; pattern -> ((var * int)) | ||||||
|  |       (cond | ||||||
|  |        ((constant? pat) | ||||||
|  |         '()) | ||||||
|  |        ((literal? pat) | ||||||
|  |         '()) | ||||||
|  |        ((variable? pat) | ||||||
|  |         `((,pat . 0))) | ||||||
|  |        ((many? pat) | ||||||
|  |         (append (map-values succ (pattern-levels (car pat))) | ||||||
|  |                 (pattern-levels (cddr pat)))) | ||||||
|  |        ((pair? pat) | ||||||
|  |         (append (pattern-levels (car pat)) | ||||||
|  |                 (pattern-levels (cdr pat)))))) | ||||||
|  | 
 | ||||||
|  |     (define (pattern-selectors pat)       ; pattern -> ((var * selector)) | ||||||
|  |       (letrec | ||||||
|  |           ((pattern-selectors | ||||||
|  |             (lambda (pat form) | ||||||
|  |               (cond | ||||||
|  |                ((constant? pat) | ||||||
|  |                 '()) | ||||||
|  |                ((literal? pat) | ||||||
|  |                 '()) | ||||||
|  |                ((variable? pat) | ||||||
|  |                 `((,pat . ,form))) | ||||||
|  |                ((many? pat) | ||||||
|  |                 (let ((head #`(drop-tail #,(length (cddr pat)) #,form)) | ||||||
|  |                       (tail #`(take-tail #,(length (cddr pat)) #,form))) | ||||||
|  |                   (let ((envs (pattern-selectors (car pat) 'it))) | ||||||
|  |                     (append | ||||||
|  |                      (map-values (lambda (s) #`(map (lambda (#,'it) #,s) #,head)) envs) | ||||||
|  |                      (pattern-selectors (cddr pat) tail))))) | ||||||
|  |                ((pair? pat) | ||||||
|  |                 (append (pattern-selectors (car pat) #`(car #,form)) | ||||||
|  |                         (pattern-selectors (cdr pat) #`(cdr #,form)))))))) | ||||||
|  |         (pattern-selectors pat 'it))) | ||||||
|  | 
 | ||||||
|  |     (define (template-representation pat levels selectors) | ||||||
|  |       (cond | ||||||
|  |        ((constant? pat) | ||||||
|  |         pat) | ||||||
|  |        ((variable? pat) | ||||||
|  |         (let ((it (assq pat levels))) | ||||||
|  |           (if it | ||||||
|  |               (if (= 0 (cdr it)) | ||||||
|  |                   (cdr (assq pat selectors)) | ||||||
|  |                   (error "unmatched pattern variable level" pat)) | ||||||
|  |               #`(#,'rename '#,pat)))) | ||||||
|  |        ((many? pat) | ||||||
|  |         (letrec* | ||||||
|  |             ((inner-pat | ||||||
|  |               (car pat)) | ||||||
|  |              (inner-levels | ||||||
|  |               (map (lambda (s) `(,(car s) . ,(pred (cdr s)))) levels)) | ||||||
|  |              (inner-freevars | ||||||
|  |               (filter (lambda (v) (assq v levels)) (pattern-variables inner-pat))) | ||||||
|  |              (inner-vars | ||||||
|  |               ;; select only vars declared with ellipsis | ||||||
|  |               (filter (lambda (v) (> (cdr (assq v levels)) 0)) inner-freevars)) | ||||||
|  |              (inner-tmps | ||||||
|  |               (map (lambda (v) #'it) inner-vars)) | ||||||
|  |              (inner-selectors | ||||||
|  |               ;; first env '(map cons ...)' shadows second env 'selectors' | ||||||
|  |               (append (map cons inner-vars inner-tmps) selectors)) | ||||||
|  |              (inner-rep | ||||||
|  |               (template-representation inner-pat inner-levels inner-selectors)) | ||||||
|  |              (sorted-selectors | ||||||
|  |               (map (lambda (v) (assq v selectors)) inner-vars)) | ||||||
|  |              (list-of-selectors | ||||||
|  |               ;; ((a . xs) (b . ys) (c . zs)) -> (xs ys zs) | ||||||
|  |               (map cdr sorted-selectors))) | ||||||
|  |           (let ((rep1 #`(map (lambda #,inner-tmps #,inner-rep) #,@list-of-selectors)) | ||||||
|  |                 (rep2 (template-representation (cddr pat) levels selectors))) | ||||||
|  |             #`(append #,rep1 #,rep2)))) | ||||||
|  |        ((pair? pat) | ||||||
|  |         #`(cons #,(template-representation (car pat) levels selectors) | ||||||
|  |                 #,(template-representation (cdr pat) levels selectors))))) | ||||||
|  | 
 | ||||||
|  |     (define (compile-rule pattern template) | ||||||
|  |       (let ((levels | ||||||
|  |              (pattern-levels pattern)) | ||||||
|  |             (selectors | ||||||
|  |              (pattern-selectors pattern))) | ||||||
|  |         (template-representation template levels selectors))) | ||||||
|  | 
 | ||||||
|  |     (define (compile-rules rules) | ||||||
|  |       (if (null? rules) | ||||||
|  |           #`(error "unmatch") | ||||||
|  |           (let ((pattern (car (car rules))) | ||||||
|  |                 (template (cadr (car rules)))) | ||||||
|  |             #`(if #,(pattern-validator pattern) | ||||||
|  |                   #,(compile-rule pattern template) | ||||||
|  |                   #,(compile-rules (cdr rules)))))) | ||||||
|  | 
 | ||||||
|  |     (define (compile rules) | ||||||
|  |       #`(call-with-current-environment | ||||||
|  |          (lambda (env) | ||||||
|  |            (letrec | ||||||
|  |                ((#,'rename (let ((reg (make-register))) | ||||||
|  |                              (lambda (x) | ||||||
|  |                                (if (undefined? (reg x)) | ||||||
|  |                                    (let ((id (make-identifier x env))) | ||||||
|  |                                      (reg x id) | ||||||
|  |                                      id) | ||||||
|  |                                    (reg x)))))) | ||||||
|  |              (lambda #,'it | ||||||
|  |                #,(compile-rules rules)))))) | ||||||
|  | 
 | ||||||
|  |     (let ((rules (map-keys cdr rules))) ; TODO: check pattern head is a variable | ||||||
|  |       (compile rules))) | ||||||
|  | 
 | ||||||
|  |   (define-syntax (syntax-rules . args) | ||||||
|  |     (if (list? (car args)) | ||||||
|  |         #`(syntax-rules ... #,@args) | ||||||
|  |         (let ((ellipsis (car args)) | ||||||
|  |               (literals (car (cdr args))) | ||||||
|  |               (rules    (cdr (cdr args)))) | ||||||
|  |           (compile ellipsis literals rules)))) | ||||||
|  | 
 | ||||||
|  |   (define-syntax (define-auxiliary-syntax var) | ||||||
|  |     #`(define-macro #,var | ||||||
|  |         (lambda _ | ||||||
|  |           (error "invalid use of auxiliary syntax" '#,var)))) | ||||||
|  | 
 | ||||||
|  |   (define-auxiliary-syntax _) | ||||||
|  |   (define-auxiliary-syntax ...) | ||||||
|  | 
 | ||||||
|   (export syntax-rules |   (export syntax-rules | ||||||
|           _ |           _ | ||||||
|           ...) |           ...) | ||||||
|  | @ -171,6 +399,56 @@ | ||||||
| 
 | 
 | ||||||
|   ;; 5.5 Recored-type definitions |   ;; 5.5 Recored-type definitions | ||||||
| 
 | 
 | ||||||
|  |   (define ((boot-make-record-type <meta-type>) name) | ||||||
|  |     (let ((rectype (make-record <meta-type>))) | ||||||
|  |       (record-set! rectype 'name name) | ||||||
|  |       rectype)) | ||||||
|  | 
 | ||||||
|  |   (define <record-type> | ||||||
|  |     (let ((<record-type> ((boot-make-record-type #t) 'record-type))) | ||||||
|  |       (record-set! <record-type> '@@type <record-type>) | ||||||
|  |       <record-type>)) | ||||||
|  | 
 | ||||||
|  |   (define make-record-type (boot-make-record-type <record-type>)) | ||||||
|  | 
 | ||||||
|  |   (define-syntax (define-record-constructor type name . fields) | ||||||
|  |     (let ((record #'record)) | ||||||
|  |       #`(define (#,name . #,fields) | ||||||
|  |           (let ((#,record (make-record #,type))) | ||||||
|  |             #,@(map (lambda (field) #`(record-set! #,record '#,field #,field)) fields) | ||||||
|  |             #,record)))) | ||||||
|  | 
 | ||||||
|  |   (define-syntax (define-record-predicate type name) | ||||||
|  |     #`(define (#,name obj) | ||||||
|  |         (and (record? obj) | ||||||
|  |              (eq? (record-type obj) #,type)))) | ||||||
|  | 
 | ||||||
|  |   (define-syntax (define-record-accessor pred field accessor) | ||||||
|  |     #`(define (#,accessor record) | ||||||
|  |         (if (#,pred record) | ||||||
|  |             (record-ref record '#,field) | ||||||
|  |             (error (string-append (symbol->string  '#,accessor) ": wrong record type") record)))) | ||||||
|  | 
 | ||||||
|  |   (define-syntax (define-record-modifier pred field modifier) | ||||||
|  |     #`(define (#,modifier record val) | ||||||
|  |         (if (#,pred record) | ||||||
|  |             (record-set! record '#,field val) | ||||||
|  |             (error (string-append (symbol->string '#,modifier) ": wrong record type")  record)))) | ||||||
|  | 
 | ||||||
|  |   (define-syntax (define-record-field pred field accessor . modifier-opt) | ||||||
|  |     (if (null? modifier-opt) | ||||||
|  |         #`(define-record-accessor #,pred #,field #,accessor) | ||||||
|  |         #`(begin | ||||||
|  |             (define-record-accessor #,pred #,field #,accessor) | ||||||
|  |             (define-record-modifier #,pred #,field #,(car modifier-opt))))) | ||||||
|  | 
 | ||||||
|  |   (define-syntax (define-record-type name ctor pred . fields) | ||||||
|  |     #`(begin | ||||||
|  |         (define #,name (make-record-type '#,name)) | ||||||
|  |         (define-record-constructor #,name #,@ctor) | ||||||
|  |         (define-record-predicate #,name #,pred) | ||||||
|  |         #,@(map (lambda (field) #`(define-record-field #,pred #,@field)) fields))) | ||||||
|  | 
 | ||||||
|   (export define-record-type) |   (export define-record-type) | ||||||
| 
 | 
 | ||||||
|   ;; 6.1. Equivalence predicates |   ;; 6.1. Equivalence predicates | ||||||
|  |  | ||||||
|  | @ -1,8 +1,7 @@ | ||||||
| (import (picrin base) | (import (scheme base) | ||||||
|         (picrin syntax-rules) |  | ||||||
|         (picrin test)) |         (picrin test)) | ||||||
| 
 | 
 | ||||||
| (test-begin) | (test-begin "syntax-rules") | ||||||
| 
 | 
 | ||||||
| (define-syntax extract? | (define-syntax extract? | ||||||
|   (syntax-rules () |   (syntax-rules () | ||||||
|  | @ -2,7 +2,7 @@ | ||||||
|         (picrin readline history) |         (picrin readline history) | ||||||
|         (picrin test)) |         (picrin test)) | ||||||
|    |    | ||||||
| (define testfile "picrin_readline_test_file") | (define testfile "/tmp/picrin_readline_test_file") | ||||||
| (test-begin) | (test-begin) | ||||||
| 
 | 
 | ||||||
| (test 0 (history-length)) | (test 0 (history-length)) | ||||||
|  |  | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | CONTRIB_LIBS += $(wildcard contrib/30.test/*.scm) | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| (define-library (picrin test) | (define-library (picrin test) | ||||||
|   (import (picrin base) |   (import (scheme base) | ||||||
|           (picrin syntax-rules)) |           (scheme write)) | ||||||
| 
 | 
 | ||||||
|   (define test-counter 0) |   (define test-counter 0) | ||||||
|   (define counter 0) |   (define counter 0) | ||||||
|  | @ -0,0 +1,24 @@ | ||||||
|  | (define-library (picrin destructuring-bind) | ||||||
|  |   (import (picrin base) | ||||||
|  |           (picrin macro)) | ||||||
|  | 
 | ||||||
|  |   (define-syntax (destructuring-bind formal value . body) | ||||||
|  |     (cond | ||||||
|  |      ((variable? formal) | ||||||
|  |       #`(let ((#,formal #,value)) | ||||||
|  |           #,@body)) | ||||||
|  |      ((pair? formal) | ||||||
|  |       #`(let ((value #,value)) | ||||||
|  |           (destructuring-bind #,(car formal) (car value) | ||||||
|  |             (destructuring-bind #,(cdr formal) (cdr value) | ||||||
|  |               #,@body)))) | ||||||
|  |      ((vector? formal) | ||||||
|  |       ;; TODO | ||||||
|  |       (error "fixme")) | ||||||
|  |      (else | ||||||
|  |       #`(if (equal? #,value '#,formal) | ||||||
|  |             (begin | ||||||
|  |               #,@body) | ||||||
|  |             (error "match failure" #,value '#,formal))))) | ||||||
|  | 
 | ||||||
|  |   (export destructuring-bind)) | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | CONTRIB_LIBS += $(wildcard contrib/50.destructuring-bind/*.scm) | ||||||
|  | @ -1,6 +1,5 @@ | ||||||
| (define-library (picrin array) | (define-library (picrin array) | ||||||
|   (import (picrin base) |   (import (scheme base)) | ||||||
|           (picrin record)) |  | ||||||
| 
 | 
 | ||||||
|   (define-record-type <array> |   (define-record-type <array> | ||||||
|     (create-array data size head tail) |     (create-array data size head tail) | ||||||
|  | @ -10,11 +9,6 @@ | ||||||
|     (head array-head set-array-head!) |     (head array-head set-array-head!) | ||||||
|     (tail array-tail set-array-tail!)) |     (tail array-tail set-array-tail!)) | ||||||
| 
 | 
 | ||||||
|   (define (floor-remainder i j) |  | ||||||
|     (call-with-values (lambda () (floor/ i j)) |  | ||||||
|       (lambda (q r) |  | ||||||
|         r))) |  | ||||||
| 
 |  | ||||||
|   (define (translate ary i) |   (define (translate ary i) | ||||||
|     (floor-remainder i (array-size ary))) |     (floor-remainder i (array-size ary))) | ||||||
| 
 | 
 | ||||||
|  | @ -0,0 +1,6 @@ | ||||||
|  | CONTRIB_LIBS += $(wildcard contrib/90.array/*.scm) | ||||||
|  | 
 | ||||||
|  | CONTRIB_TESTS += test-array | ||||||
|  | 
 | ||||||
|  | test-array: bin/picrin | ||||||
|  | 	bin/picrin contrib/90.array/t/array.scm | ||||||
|  | @ -0,0 +1,26 @@ | ||||||
|  | (import (scheme base) | ||||||
|  |         (scheme write) | ||||||
|  |         (picrin array) | ||||||
|  |         (picrin test)) | ||||||
|  | 
 | ||||||
|  | (test-begin) | ||||||
|  | 
 | ||||||
|  | (define ary (make-array)) | ||||||
|  | 
 | ||||||
|  | (array-push! ary 1) | ||||||
|  | (array-push! ary 2) | ||||||
|  | (array-push! ary 3) | ||||||
|  | 
 | ||||||
|  | (test 3 (array-pop! ary)) | ||||||
|  | (test 2 (array-pop! ary)) | ||||||
|  | (test 1 (array-pop! ary)) | ||||||
|  | 
 | ||||||
|  | (array-unshift! ary 1) | ||||||
|  | (array-unshift! ary 2) | ||||||
|  | (array-unshift! ary 3) | ||||||
|  | 
 | ||||||
|  | (test 3 (array-shift! ary)) | ||||||
|  | (test 2 (array-shift! ary)) | ||||||
|  | (test 1 (array-shift! ary)) | ||||||
|  | 
 | ||||||
|  | (test-end) | ||||||
|  | @ -646,11 +646,6 @@ my $src = <<'EOL'; | ||||||
|                (library-export (car slot) (cdr slot)))))) |                (library-export (car slot) (cdr slot)))))) | ||||||
|       (for-each export (cdr form))))) |       (for-each export (cdr form))))) | ||||||
| 
 | 
 | ||||||
| (export define-library |  | ||||||
|         cond-expand |  | ||||||
|         import |  | ||||||
|         export) |  | ||||||
| 
 |  | ||||||
| (export define lambda quote set! if begin define-macro | (export define lambda quote set! if begin define-macro | ||||||
|         let let* letrec letrec* |         let let* letrec letrec* | ||||||
|         let-values let*-values define-values |         let-values let*-values define-values | ||||||
|  | @ -1001,12 +996,11 @@ const char pic_boot[][80] = { | ||||||
| ") . ,(list-ref spec 2)))\n             (else\n              (error \"malformed expo", | ") . ,(list-ref spec 2)))\n             (else\n              (error \"malformed expo", | ||||||
| "rt\")))))\n         (export\n           (lambda (spec)\n             (let ((slot (co", | "rt\")))))\n         (export\n           (lambda (spec)\n             (let ((slot (co", | ||||||
| "llect spec)))\n               (library-export (car slot) (cdr slot))))))\n      (f", | "llect spec)))\n               (library-export (car slot) (cdr slot))))))\n      (f", | ||||||
| "or-each export (cdr form)))))\n\n(export define-library\n        cond-expand\n      ", | "or-each export (cdr form)))))\n\n(export define lambda quote set! if begin define-", | ||||||
| "  import\n        export)\n\n(export define lambda quote set! if begin define-macro", | "macro\n        let let* letrec letrec*\n        let-values let*-values define-valu", | ||||||
| "\n        let let* letrec letrec*\n        let-values let*-values define-values\n  ", | "es\n        quasiquote unquote unquote-splicing\n        and or\n        cond case ", | ||||||
| "      quasiquote unquote unquote-splicing\n        and or\n        cond case else ", | "else =>\n        do when unless\n        parameterize\n        define-syntax\n      ", | ||||||
| "=>\n        do when unless\n        parameterize\n        define-syntax\n        syn", | "  syntax-quote syntax-unquote\n        syntax-quasiquote syntax-unquote-splicing\n", | ||||||
| "tax-quote syntax-unquote\n        syntax-quasiquote syntax-unquote-splicing\n     ", |  | ||||||
| "        let-syntax letrec-syntax\n        syntax-error)\n\n\n", | "        let-syntax letrec-syntax\n        syntax-error)\n\n\n", | ||||||
| "", | "", | ||||||
| "" | "" | ||||||
|  |  | ||||||
|  | @ -1,291 +0,0 @@ | ||||||
| (define-library (picrin base) |  | ||||||
| 
 |  | ||||||
|   (export define |  | ||||||
|           lambda |  | ||||||
|           if |  | ||||||
|           quote |  | ||||||
|           set! |  | ||||||
|           begin |  | ||||||
|           define-macro) |  | ||||||
| 
 |  | ||||||
|   (export syntax-error |  | ||||||
|           define-syntax |  | ||||||
|           let-syntax |  | ||||||
|           letrec-syntax |  | ||||||
|           syntax-quote |  | ||||||
|           syntax-quasiquote |  | ||||||
|           syntax-unquote |  | ||||||
|           syntax-unquote-splicing) |  | ||||||
| 
 |  | ||||||
|   (export let |  | ||||||
|           let* |  | ||||||
|           letrec |  | ||||||
|           letrec* |  | ||||||
|           quasiquote |  | ||||||
|           unquote |  | ||||||
|           unquote-splicing |  | ||||||
|           and |  | ||||||
|           or |  | ||||||
|           cond |  | ||||||
|           case |  | ||||||
|           => |  | ||||||
|           else |  | ||||||
|           do |  | ||||||
|           when |  | ||||||
|           unless) |  | ||||||
| 
 |  | ||||||
|   (export let-values |  | ||||||
|           let*-values |  | ||||||
|           define-values) |  | ||||||
| 
 |  | ||||||
|   (export eq? |  | ||||||
|           eqv? |  | ||||||
|           equal?) |  | ||||||
| 
 |  | ||||||
|   (export undefined?) |  | ||||||
| 
 |  | ||||||
|   (export boolean? |  | ||||||
|           boolean=? |  | ||||||
|           not) |  | ||||||
| 
 |  | ||||||
|   (export symbol? |  | ||||||
|           symbol->string |  | ||||||
|           string->symbol |  | ||||||
|           symbol=?) |  | ||||||
| 
 |  | ||||||
|   (export char? |  | ||||||
|           char->integer |  | ||||||
|           integer->char |  | ||||||
|           char=? |  | ||||||
|           char<? |  | ||||||
|           char>? |  | ||||||
|           char<=? |  | ||||||
|           char>=?) |  | ||||||
| 
 |  | ||||||
|   (export number? |  | ||||||
|           complex? |  | ||||||
|           real? |  | ||||||
|           rational? |  | ||||||
|           integer? |  | ||||||
|           exact? |  | ||||||
|           inexact? |  | ||||||
|           = |  | ||||||
|           < |  | ||||||
|           > |  | ||||||
|           <= |  | ||||||
|           >= |  | ||||||
|           + |  | ||||||
|           - |  | ||||||
|           * |  | ||||||
|           / |  | ||||||
|           abs |  | ||||||
|           floor/ |  | ||||||
|           truncate/ |  | ||||||
|           floor |  | ||||||
|           ceiling |  | ||||||
|           truncate |  | ||||||
|           round |  | ||||||
|           expt |  | ||||||
|           number->string |  | ||||||
|           string->number |  | ||||||
|           finite? |  | ||||||
|           infinite? |  | ||||||
|           nan? |  | ||||||
|           exp |  | ||||||
|           log |  | ||||||
|           sin |  | ||||||
|           cos |  | ||||||
|           tan |  | ||||||
|           acos |  | ||||||
|           asin |  | ||||||
|           atan |  | ||||||
|           sqrt) |  | ||||||
| 
 |  | ||||||
|   (export pair? |  | ||||||
|           cons |  | ||||||
|           car |  | ||||||
|           cdr |  | ||||||
|           set-car! |  | ||||||
|           set-cdr! |  | ||||||
|           null? |  | ||||||
|           caar |  | ||||||
|           cadr |  | ||||||
|           cdar |  | ||||||
|           cddr) |  | ||||||
| 
 |  | ||||||
|   (export list? |  | ||||||
|           make-list |  | ||||||
|           list |  | ||||||
|           length |  | ||||||
|           append |  | ||||||
|           reverse |  | ||||||
|           list-tail |  | ||||||
|           list-ref |  | ||||||
|           list-set! |  | ||||||
|           list-copy |  | ||||||
|           map |  | ||||||
|           for-each |  | ||||||
|           memq |  | ||||||
|           memv |  | ||||||
|           member |  | ||||||
|           assq |  | ||||||
|           assv |  | ||||||
|           assoc) |  | ||||||
| 
 |  | ||||||
|   (export bytevector? |  | ||||||
|           bytevector |  | ||||||
|           make-bytevector |  | ||||||
|           bytevector-length |  | ||||||
|           bytevector-u8-ref |  | ||||||
|           bytevector-u8-set! |  | ||||||
|           bytevector-copy |  | ||||||
|           bytevector-copy! |  | ||||||
|           bytevector-append |  | ||||||
|           bytevector->list |  | ||||||
|           list->bytevector) |  | ||||||
| 
 |  | ||||||
|   (export vector? |  | ||||||
|           vector |  | ||||||
|           make-vector |  | ||||||
|           vector-length |  | ||||||
|           vector-ref |  | ||||||
|           vector-set! |  | ||||||
|           vector-copy! |  | ||||||
|           vector-copy |  | ||||||
|           vector-append |  | ||||||
|           vector-fill! |  | ||||||
|           vector-map |  | ||||||
|           vector-for-each |  | ||||||
|           list->vector |  | ||||||
|           vector->list |  | ||||||
|           string->vector |  | ||||||
|           vector->string) |  | ||||||
| 
 |  | ||||||
|   (export string? |  | ||||||
|           string |  | ||||||
|           make-string |  | ||||||
|           string-length |  | ||||||
|           string-ref |  | ||||||
|           string-copy |  | ||||||
|           string-append |  | ||||||
|           string-map |  | ||||||
|           string-for-each |  | ||||||
|           string->list |  | ||||||
|           list->string |  | ||||||
|           string=? |  | ||||||
|           string<? |  | ||||||
|           string>? |  | ||||||
|           string<=? |  | ||||||
|           string>=?) |  | ||||||
| 
 |  | ||||||
|   (export make-dictionary |  | ||||||
|           dictionary? |  | ||||||
|           dictionary |  | ||||||
|           dictionary-ref |  | ||||||
|           dictionary-set! |  | ||||||
|           dictionary-size |  | ||||||
|           dictionary-map |  | ||||||
|           dictionary-for-each |  | ||||||
|           dictionary->plist |  | ||||||
|           plist->dictionary |  | ||||||
|           dictionary->alist |  | ||||||
|           alist->dictionary) |  | ||||||
| 
 |  | ||||||
|   (export make-record |  | ||||||
|           record? |  | ||||||
|           record-type |  | ||||||
|           record-ref |  | ||||||
|           record-set!) |  | ||||||
| 
 |  | ||||||
|   (export current-input-port |  | ||||||
|           current-output-port |  | ||||||
|           current-error-port |  | ||||||
| 
 |  | ||||||
|           call-with-port |  | ||||||
| 
 |  | ||||||
|           port? |  | ||||||
|           input-port? |  | ||||||
|           output-port? |  | ||||||
|           textual-port? |  | ||||||
|           binary-port? |  | ||||||
| 
 |  | ||||||
|           port-open? |  | ||||||
|           close-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) |  | ||||||
| 
 |  | ||||||
|   (export make-parameter |  | ||||||
|           parameterize) |  | ||||||
| 
 |  | ||||||
|   (export make-identifier |  | ||||||
|           identifier? |  | ||||||
|           identifier-variable |  | ||||||
|           identifier-environment |  | ||||||
| 
 |  | ||||||
|           variable? |  | ||||||
|           variable=?) |  | ||||||
| 
 |  | ||||||
|   (export make-library |  | ||||||
|           find-library |  | ||||||
|           current-library |  | ||||||
|           library-exports |  | ||||||
|           library-environment) |  | ||||||
| 
 |  | ||||||
|   (export call-with-current-continuation |  | ||||||
|           call/cc |  | ||||||
|           escape |  | ||||||
|           dynamic-wind |  | ||||||
|           values |  | ||||||
|           call-with-values) |  | ||||||
| 
 |  | ||||||
|   (export with-exception-handler |  | ||||||
|           raise |  | ||||||
|           raise-continuable |  | ||||||
|           error |  | ||||||
|           make-error-object |  | ||||||
|           error-object? |  | ||||||
|           error-object-message |  | ||||||
|           error-object-irritants |  | ||||||
|           error-object-type) |  | ||||||
| 
 |  | ||||||
|   (export procedure? |  | ||||||
|           apply |  | ||||||
|           attribute) |  | ||||||
| 
 |  | ||||||
|   (export read) |  | ||||||
| 
 |  | ||||||
|   (export write |  | ||||||
|           write-simple |  | ||||||
|           write-shared |  | ||||||
|           display) |  | ||||||
| 
 |  | ||||||
|   (export eval) |  | ||||||
| 
 |  | ||||||
|   (export features)) |  | ||||||
|  | @ -1,3 +0,0 @@ | ||||||
| (define-library (picrin control) |  | ||||||
|   (import (picrin base)) |  | ||||||
|   (export escape)) |  | ||||||
|  | @ -1,37 +0,0 @@ | ||||||
| (define-library (picrin experimental lambda) |  | ||||||
|   (import (picrin base) |  | ||||||
|           (picrin macro)) |  | ||||||
| 
 |  | ||||||
|   (define-syntax (destructuring-let formal value . body) |  | ||||||
|     (cond |  | ||||||
|      ((variable? formal) |  | ||||||
|       #`(let ((#,formal #,value)) |  | ||||||
|           #,@body)) |  | ||||||
|      ((pair? formal) |  | ||||||
|       #`(let ((value #,value)) |  | ||||||
|           (destructuring-let #,(car formal) (car value) |  | ||||||
|             (destructuring-let #,(cdr formal) (cdr value) |  | ||||||
|               #,@body)))) |  | ||||||
|      ((vector? formal) |  | ||||||
|       ;; TODO |  | ||||||
|       (error "fixme")) |  | ||||||
|      (else |  | ||||||
|       #`(if (equal? #,value '#,formal) |  | ||||||
|             (begin |  | ||||||
|               #,@body) |  | ||||||
|             (error "match failure" #,value '#,formal))))) |  | ||||||
| 
 |  | ||||||
|   (define-syntax (destructuring-lambda formal . body) |  | ||||||
|     #`(lambda args |  | ||||||
|         (destructuring-let #,formal args #,@body))) |  | ||||||
| 
 |  | ||||||
|   (define-syntax (destructuring-define formal . body) |  | ||||||
|     (if (variable? formal) |  | ||||||
|         #`(define #,formal #,@body) |  | ||||||
|         #`(destructuring-define #,(car formal) |  | ||||||
|             (destructuring-lambda #,(cdr formal) |  | ||||||
|               #,@body)))) |  | ||||||
| 
 |  | ||||||
|   (export (rename destructuring-let let) |  | ||||||
|           (rename destructuring-lambda lambda) |  | ||||||
|           (rename destructuring-define define))) |  | ||||||
|  | @ -1,59 +0,0 @@ | ||||||
| (define-library (picrin record) |  | ||||||
|   (import (picrin base) |  | ||||||
|           (picrin macro)) |  | ||||||
| 
 |  | ||||||
|   ;; record meta type |  | ||||||
| 
 |  | ||||||
|   (define ((boot-make-record-type <meta-type>) name) |  | ||||||
|     (let ((rectype (make-record <meta-type>))) |  | ||||||
|       (record-set! rectype 'name name) |  | ||||||
|       rectype)) |  | ||||||
| 
 |  | ||||||
|   (define <record-type> |  | ||||||
|     (let ((<record-type> ((boot-make-record-type #t) 'record-type))) |  | ||||||
|       (record-set! <record-type> '@@type <record-type>) |  | ||||||
|       <record-type>)) |  | ||||||
| 
 |  | ||||||
|   (define make-record-type (boot-make-record-type <record-type>)) |  | ||||||
| 
 |  | ||||||
|   ;; define-record-type |  | ||||||
| 
 |  | ||||||
|   (define-syntax (define-record-constructor type name . fields) |  | ||||||
|     (let ((record #'record)) |  | ||||||
|       #`(define (#,name . #,fields) |  | ||||||
|           (let ((#,record (make-record #,type))) |  | ||||||
|             #,@(map (lambda (field) #`(record-set! #,record '#,field #,field)) fields) |  | ||||||
|             #,record)))) |  | ||||||
| 
 |  | ||||||
|   (define-syntax (define-record-predicate type name) |  | ||||||
|     #`(define (#,name obj) |  | ||||||
|         (and (record? obj) |  | ||||||
|              (eq? (record-type obj) #,type)))) |  | ||||||
| 
 |  | ||||||
|   (define-syntax (define-record-accessor pred field accessor) |  | ||||||
|     #`(define (#,accessor record) |  | ||||||
|         (if (#,pred record) |  | ||||||
|             (record-ref record '#,field) |  | ||||||
|             (error (string-append (symbol->string  '#,accessor) ": wrong record type") record)))) |  | ||||||
| 
 |  | ||||||
|   (define-syntax (define-record-modifier pred field modifier) |  | ||||||
|     #`(define (#,modifier record val) |  | ||||||
|         (if (#,pred record) |  | ||||||
|             (record-set! record '#,field val) |  | ||||||
|             (error (string-append (symbol->string '#,modifier) ": wrong record type")  record)))) |  | ||||||
| 
 |  | ||||||
|   (define-syntax (define-record-field pred field accessor . modifier-opt) |  | ||||||
|     (if (null? modifier-opt) |  | ||||||
|         #`(define-record-accessor #,pred #,field #,accessor) |  | ||||||
|         #`(begin |  | ||||||
|             (define-record-accessor #,pred #,field #,accessor) |  | ||||||
|             (define-record-modifier #,pred #,field #,(car modifier-opt))))) |  | ||||||
| 
 |  | ||||||
|   (define-syntax (define-record-type name ctor pred . fields) |  | ||||||
|     #`(begin |  | ||||||
|         (define #,name (make-record-type '#,name)) |  | ||||||
|         (define-record-constructor #,name #,@ctor) |  | ||||||
|         (define-record-predicate #,name #,pred) |  | ||||||
|         #,@(map (lambda (field) #`(define-record-field #,pred #,@field)) fields))) |  | ||||||
| 
 |  | ||||||
|   (export define-record-type)) |  | ||||||
|  | @ -1,244 +0,0 @@ | ||||||
| (define-library (picrin syntax-rules) |  | ||||||
|   (import (picrin base) |  | ||||||
|           (picrin macro)) |  | ||||||
| 
 |  | ||||||
|   (define-syntax (define-auxiliary-syntax var) |  | ||||||
|     #`(define-macro #,var |  | ||||||
|         (lambda _ |  | ||||||
|           (error "invalid use of auxiliary syntax" '#,var)))) |  | ||||||
| 
 |  | ||||||
|   (define-auxiliary-syntax _) |  | ||||||
|   (define-auxiliary-syntax ...) |  | ||||||
| 
 |  | ||||||
|   (define (succ n) |  | ||||||
|     (+ n 1)) |  | ||||||
| 
 |  | ||||||
|   (define (pred n) |  | ||||||
|     (if (= n 0) |  | ||||||
|         0 |  | ||||||
|         (- n 1))) |  | ||||||
| 
 |  | ||||||
|   (define (every? args) |  | ||||||
|     (if (null? args) |  | ||||||
|         #t |  | ||||||
|         (if (car args) |  | ||||||
|             (every? (cdr args)) |  | ||||||
|             #f))) |  | ||||||
| 
 |  | ||||||
|   (define (filter f list) |  | ||||||
|     (if (null? list) |  | ||||||
|         '() |  | ||||||
|         (if (f (car list)) |  | ||||||
|             (cons (car list) |  | ||||||
|                   (filter f (cdr list))) |  | ||||||
|             (filter f (cdr list))))) |  | ||||||
| 
 |  | ||||||
|   (define (take-tail n list) |  | ||||||
|     (let drop ((n (- (length list) n)) (list list)) |  | ||||||
|       (if (= n 0) |  | ||||||
|           list |  | ||||||
|           (drop (- n 1) (cdr list))))) |  | ||||||
| 
 |  | ||||||
|   (define (drop-tail n list) |  | ||||||
|     (let take ((n (- (length list) n)) (list list)) |  | ||||||
|       (if (= n 0) |  | ||||||
|           '() |  | ||||||
|           (cons (car list) (take (- n 1) (cdr list)))))) |  | ||||||
| 
 |  | ||||||
|   (define (map-keys f assoc) |  | ||||||
|     (map (lambda (s) `(,(f (car s)) . ,(cdr s))) assoc)) |  | ||||||
| 
 |  | ||||||
|   (define (map-values f assoc) |  | ||||||
|     (map (lambda (s) `(,(car s) . ,(f (cdr s)))) assoc)) |  | ||||||
| 
 |  | ||||||
|   ;; TODO |  | ||||||
|   ;; - placeholder |  | ||||||
|   ;; - vector |  | ||||||
|   ;; - (... template) pattern |  | ||||||
| 
 |  | ||||||
|   ;; p ::= constant |  | ||||||
|   ;;     | var |  | ||||||
|   ;;     | (p ... . p)      (in input pattern, tail p should be a proper list) |  | ||||||
|   ;;     | (p . p) |  | ||||||
| 
 |  | ||||||
|   (define (compile ellipsis literals rules) |  | ||||||
| 
 |  | ||||||
|     (define (constant? obj) |  | ||||||
|       (and (not (pair? obj)) |  | ||||||
|            (not (variable? obj)))) |  | ||||||
| 
 |  | ||||||
|     (define (literal? obj) |  | ||||||
|       (and (variable? obj) |  | ||||||
|            (memq obj literals))) |  | ||||||
| 
 |  | ||||||
|     (define (many? pat) |  | ||||||
|       (and (pair? pat) |  | ||||||
|            (pair? (cdr pat)) |  | ||||||
|            (variable? (cadr pat)) |  | ||||||
|            (variable=? (cadr pat) ellipsis))) |  | ||||||
| 
 |  | ||||||
|     (define (pattern-validator pat)      ; pattern -> validator |  | ||||||
|       (letrec |  | ||||||
|           ((pattern-validator |  | ||||||
|             (lambda (pat form) |  | ||||||
|               (cond |  | ||||||
|                ((constant? pat) |  | ||||||
|                 #`(equal? '#,pat #,form)) |  | ||||||
|                ((literal? pat) |  | ||||||
|                 #`(and (variable? #,form) (variable=? #'#,pat #,form))) |  | ||||||
|                ((variable? pat) |  | ||||||
|                 #t) |  | ||||||
|                ((many? pat) |  | ||||||
|                 (let ((head #`(drop-tail #,(length (cddr pat)) #,form)) |  | ||||||
|                       (tail #`(take-tail #,(length (cddr pat)) #,form))) |  | ||||||
|                   #`(and (list? #,form) |  | ||||||
|                          (>= (length #,form) #,(length (cddr pat))) |  | ||||||
|                          (every? (map (lambda (#,'it) #,(pattern-validator (car pat) 'it)) #,head)) |  | ||||||
|                          #,(pattern-validator (cddr pat) tail)))) |  | ||||||
|                ((pair? pat) |  | ||||||
|                 #`(and (pair? #,form) |  | ||||||
|                        #,(pattern-validator (car pat) #`(car #,form)) |  | ||||||
|                        #,(pattern-validator (cdr pat) #`(cdr #,form)))) |  | ||||||
|                (else |  | ||||||
|                 #f))))) |  | ||||||
|         (pattern-validator pat 'it))) |  | ||||||
| 
 |  | ||||||
|     (define (pattern-variables pat)       ; pattern -> (freevar) |  | ||||||
|       (cond |  | ||||||
|        ((constant? pat) |  | ||||||
|         '()) |  | ||||||
|        ((literal? pat) |  | ||||||
|         '()) |  | ||||||
|        ((variable? pat) |  | ||||||
|         `(,pat)) |  | ||||||
|        ((many? pat) |  | ||||||
|         (append (pattern-variables (car pat)) |  | ||||||
|                 (pattern-variables (cddr pat)))) |  | ||||||
|        ((pair? pat) |  | ||||||
|         (append (pattern-variables (car pat)) |  | ||||||
|                 (pattern-variables (cdr pat)))))) |  | ||||||
| 
 |  | ||||||
|     (define (pattern-levels pat)          ; pattern -> ((var * int)) |  | ||||||
|       (cond |  | ||||||
|        ((constant? pat) |  | ||||||
|         '()) |  | ||||||
|        ((literal? pat) |  | ||||||
|         '()) |  | ||||||
|        ((variable? pat) |  | ||||||
|         `((,pat . 0))) |  | ||||||
|        ((many? pat) |  | ||||||
|         (append (map-values succ (pattern-levels (car pat))) |  | ||||||
|                 (pattern-levels (cddr pat)))) |  | ||||||
|        ((pair? pat) |  | ||||||
|         (append (pattern-levels (car pat)) |  | ||||||
|                 (pattern-levels (cdr pat)))))) |  | ||||||
| 
 |  | ||||||
|     (define (pattern-selectors pat)       ; pattern -> ((var * selector)) |  | ||||||
|       (letrec |  | ||||||
|           ((pattern-selectors |  | ||||||
|             (lambda (pat form) |  | ||||||
|               (cond |  | ||||||
|                ((constant? pat) |  | ||||||
|                 '()) |  | ||||||
|                ((literal? pat) |  | ||||||
|                 '()) |  | ||||||
|                ((variable? pat) |  | ||||||
|                 `((,pat . ,form))) |  | ||||||
|                ((many? pat) |  | ||||||
|                 (let ((head #`(drop-tail #,(length (cddr pat)) #,form)) |  | ||||||
|                       (tail #`(take-tail #,(length (cddr pat)) #,form))) |  | ||||||
|                   (let ((envs (pattern-selectors (car pat) 'it))) |  | ||||||
|                     (append |  | ||||||
|                      (map-values (lambda (s) #`(map (lambda (#,'it) #,s) #,head)) envs) |  | ||||||
|                      (pattern-selectors (cddr pat) tail))))) |  | ||||||
|                ((pair? pat) |  | ||||||
|                 (append (pattern-selectors (car pat) #`(car #,form)) |  | ||||||
|                         (pattern-selectors (cdr pat) #`(cdr #,form)))))))) |  | ||||||
|         (pattern-selectors pat 'it))) |  | ||||||
| 
 |  | ||||||
|     (define (template-representation pat levels selectors) |  | ||||||
|       (cond |  | ||||||
|        ((constant? pat) |  | ||||||
|         pat) |  | ||||||
|        ((variable? pat) |  | ||||||
|         (let ((it (assq pat levels))) |  | ||||||
|           (if it |  | ||||||
|               (if (= 0 (cdr it)) |  | ||||||
|                   (cdr (assq pat selectors)) |  | ||||||
|                   (error "unmatched pattern variable level" pat)) |  | ||||||
|               #`(#,'rename '#,pat)))) |  | ||||||
|        ((many? pat) |  | ||||||
|         (letrec* |  | ||||||
|             ((inner-pat |  | ||||||
|               (car pat)) |  | ||||||
|              (inner-levels |  | ||||||
|               (map (lambda (s) `(,(car s) . ,(pred (cdr s)))) levels)) |  | ||||||
|              (inner-freevars |  | ||||||
|               (filter (lambda (v) (assq v levels)) (pattern-variables inner-pat))) |  | ||||||
|              (inner-vars |  | ||||||
|               ;; select only vars declared with ellipsis |  | ||||||
|               (filter (lambda (v) (> (cdr (assq v levels)) 0)) inner-freevars)) |  | ||||||
|              (inner-tmps |  | ||||||
|               (map (lambda (v) #'it) inner-vars)) |  | ||||||
|              (inner-selectors |  | ||||||
|               ;; first env '(map cons ...)' shadows second env 'selectors' |  | ||||||
|               (append (map cons inner-vars inner-tmps) selectors)) |  | ||||||
|              (inner-rep |  | ||||||
|               (template-representation inner-pat inner-levels inner-selectors)) |  | ||||||
|              (sorted-selectors |  | ||||||
|               (map (lambda (v) (assq v selectors)) inner-vars)) |  | ||||||
|              (list-of-selectors |  | ||||||
|               ;; ((a . xs) (b . ys) (c . zs)) -> (xs ys zs) |  | ||||||
|               (map cdr sorted-selectors))) |  | ||||||
|           (let ((rep1 #`(map (lambda #,inner-tmps #,inner-rep) #,@list-of-selectors)) |  | ||||||
|                 (rep2 (template-representation (cddr pat) levels selectors))) |  | ||||||
|             #`(append #,rep1 #,rep2)))) |  | ||||||
|        ((pair? pat) |  | ||||||
|         #`(cons #,(template-representation (car pat) levels selectors) |  | ||||||
|                 #,(template-representation (cdr pat) levels selectors))))) |  | ||||||
| 
 |  | ||||||
|     (define (compile-rule pattern template) |  | ||||||
|       (let ((levels |  | ||||||
|              (pattern-levels pattern)) |  | ||||||
|             (selectors |  | ||||||
|              (pattern-selectors pattern))) |  | ||||||
|         (template-representation template levels selectors))) |  | ||||||
| 
 |  | ||||||
|     (define (compile-rules rules) |  | ||||||
|       (if (null? rules) |  | ||||||
|           #`(error "unmatch") |  | ||||||
|           (let ((pattern (car (car rules))) |  | ||||||
|                 (template (cadr (car rules)))) |  | ||||||
|             #`(if #,(pattern-validator pattern) |  | ||||||
|                   #,(compile-rule pattern template) |  | ||||||
|                   #,(compile-rules (cdr rules)))))) |  | ||||||
| 
 |  | ||||||
|     (define (compile rules) |  | ||||||
|       #`(call-with-current-environment |  | ||||||
|          (lambda (env) |  | ||||||
|            (letrec |  | ||||||
|                ((#,'rename (let ((reg (make-register))) |  | ||||||
|                              (lambda (x) |  | ||||||
|                                (if (undefined? (reg x)) |  | ||||||
|                                    (let ((id (make-identifier x env))) |  | ||||||
|                                      (reg x id) |  | ||||||
|                                      id) |  | ||||||
|                                    (reg x)))))) |  | ||||||
|              (lambda #,'it |  | ||||||
|                #,(compile-rules rules)))))) |  | ||||||
| 
 |  | ||||||
|     (let ((rules (map-keys cdr rules))) ; TODO: check pattern head is a variable |  | ||||||
|       (compile rules))) |  | ||||||
| 
 |  | ||||||
|   (define-syntax (syntax-rules . args) |  | ||||||
|     (if (list? (car args)) |  | ||||||
|         #`(syntax-rules ... #,@args) |  | ||||||
|         (let ((ellipsis (car args)) |  | ||||||
|               (literals (car (cdr args))) |  | ||||||
|               (rules    (cdr (cdr args)))) |  | ||||||
|           (compile ellipsis literals rules)))) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|   (export syntax-rules |  | ||||||
|           _ |  | ||||||
|           ...)) |  | ||||||
							
								
								
									
										42
									
								
								t/array.scm
								
								
								
								
							
							
						
						
									
										42
									
								
								t/array.scm
								
								
								
								
							|  | @ -1,42 +0,0 @@ | ||||||
| (import (scheme base) |  | ||||||
|         (scheme write) |  | ||||||
|         (picrin array)) |  | ||||||
| 
 |  | ||||||
| (define ary (make-array)) |  | ||||||
| 
 |  | ||||||
| (write ary) |  | ||||||
| (newline) |  | ||||||
| (array-push! ary 1) |  | ||||||
| (write ary) |  | ||||||
| (newline) |  | ||||||
| (array-push! ary 2) |  | ||||||
| (write ary) |  | ||||||
| (newline) |  | ||||||
| (array-push! ary 3) |  | ||||||
| (write ary) |  | ||||||
| (newline) |  | ||||||
| (write (array-pop! ary)) |  | ||||||
| (newline) |  | ||||||
| (write (array-pop! ary)) |  | ||||||
| (newline) |  | ||||||
| (write (array-pop! ary)) |  | ||||||
| (newline) |  | ||||||
| 
 |  | ||||||
| (write ary) |  | ||||||
| (newline) |  | ||||||
| (array-unshift! ary 1) |  | ||||||
| (write ary) |  | ||||||
| (newline) |  | ||||||
| (array-unshift! ary 2) |  | ||||||
| (write ary) |  | ||||||
| (newline) |  | ||||||
| (array-unshift! ary 3) |  | ||||||
| (write ary) |  | ||||||
| (newline) |  | ||||||
| (write (array-shift! ary)) |  | ||||||
| (newline) |  | ||||||
| (write (array-shift! ary)) |  | ||||||
| (newline) |  | ||||||
| (write (array-shift! ary)) |  | ||||||
| (newline) |  | ||||||
| 
 |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Yuichi Nishiwaki
						Yuichi Nishiwaki