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 | ||||
| PICRIN_OBJS = \
 | ||||
| 	$(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_OBJS = $(CONTRIB_SRCS:.c=.o) | ||||
|  | @ -40,8 +31,8 @@ debug: bin/picrin | |||
| bin/picrin: $(PICRIN_OBJS) $(CONTRIB_OBJS) lib/libbenz.a | ||||
| 	$(CC) $(CFLAGS) -o $@ $(PICRIN_OBJS) $(CONTRIB_OBJS) lib/libbenz.a $(LDFLAGS) | ||||
| 
 | ||||
| src/load_piclib.c: $(PICRIN_LIBS) $(CONTRIB_LIBS) | ||||
| 	perl etc/mkloader.pl $(PICRIN_LIBS) $(CONTRIB_LIBS) > $@ | ||||
| src/load_piclib.c: $(CONTRIB_LIBS) | ||||
| 	perl etc/mkloader.pl $(CONTRIB_LIBS) > $@ | ||||
| 
 | ||||
| src/init_contrib.c: | ||||
| 	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) | ||||
|   (import (picrin base) | ||||
|           (picrin macro) | ||||
|           (picrin record) | ||||
|           (picrin syntax-rules) | ||||
|           (picrin string) | ||||
|           (scheme file)) | ||||
| 
 | ||||
|  | @ -76,43 +74,37 @@ | |||
| 
 | ||||
|   ;; 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-aux reraise . clauses) | ||||
|     (letrec | ||||
|         ((else? | ||||
|           (lambda (clause) | ||||
|             (and (list? clause) (equal? #'else (car clause))))) | ||||
|          (=>? | ||||
|           (lambda (clause) | ||||
|             (and (list? clause) (= (length clause) 3) (equal? #'=> (list-ref clause 1)))))) | ||||
|       (if (null? clauses) | ||||
|           reraise | ||||
|           (let ((clause (car clauses)) | ||||
|                 (rest (cdr clauses))) | ||||
|             (cond | ||||
|              ((else? clause) | ||||
|               #`(begin #,@(cdr clause))) | ||||
|              ((=>? clause) | ||||
|               #`(let ((tmp #,(list-ref clause 0))) | ||||
|                   (if tmp | ||||
|                       (#,(list-ref clause 2) tmp) | ||||
|                       (guard-aux #,reraise #,@rest)))) | ||||
|              ((= (length clause) 1) | ||||
|               #`(or #,(car clause) (guard-aux #,reraise #,@rest))) | ||||
|              (else | ||||
|               #`(if #,(car clause) | ||||
|                     (begin #,@(cdr clause)) | ||||
|                     (guard-aux #,reraise #,@rest)))))))) | ||||
| 
 | ||||
|   (define-syntax guard | ||||
|     (syntax-rules () | ||||
|       ((guard (var clause ...) e1 e2 ...) | ||||
|        ((call/cc | ||||
|   (define-syntax (guard formal . body) | ||||
|     (let ((var (car formal)) | ||||
|           (clauses (cdr formal))) | ||||
|       #`((call/cc | ||||
|           (lambda (guard-k) | ||||
|             (with-exception-handler | ||||
|              (lambda (condition) | ||||
|  | @ -120,19 +112,19 @@ | |||
|                  (lambda (handler-k) | ||||
|                    (guard-k | ||||
|                     (lambda () | ||||
|                      (let ((var condition)) | ||||
|                       (let ((#,var condition)) | ||||
|                         (guard-aux | ||||
|                          (handler-k | ||||
|                           (lambda () | ||||
|                             (raise-continuable condition))) | ||||
|                         clause ...)))))))) | ||||
|                          #,@clauses)))))))) | ||||
|              (lambda () | ||||
|                (call-with-values | ||||
|                   (lambda () e1 e2 ...) | ||||
|                    (lambda () #,@body) | ||||
|                  (lambda args | ||||
|                    (guard-k | ||||
|                     (lambda () | ||||
|                      (apply values args))))))))))))) | ||||
|                       (apply values args)))))))))))) | ||||
| 
 | ||||
|   (export guard) | ||||
| 
 | ||||
|  | @ -149,6 +141,242 @@ | |||
| 
 | ||||
|   ;; 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 | ||||
|           _ | ||||
|           ...) | ||||
|  | @ -171,6 +399,56 @@ | |||
| 
 | ||||
|   ;; 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) | ||||
| 
 | ||||
|   ;; 6.1. Equivalence predicates | ||||
|  |  | |||
|  | @ -1,8 +1,7 @@ | |||
| (import (picrin base) | ||||
|         (picrin syntax-rules) | ||||
| (import (scheme base) | ||||
|         (picrin test)) | ||||
| 
 | ||||
| (test-begin) | ||||
| (test-begin "syntax-rules") | ||||
| 
 | ||||
| (define-syntax extract? | ||||
|   (syntax-rules () | ||||
|  | @ -2,7 +2,7 @@ | |||
|         (picrin readline history) | ||||
|         (picrin test)) | ||||
|    | ||||
| (define testfile "picrin_readline_test_file") | ||||
| (define testfile "/tmp/picrin_readline_test_file") | ||||
| (test-begin) | ||||
| 
 | ||||
| (test 0 (history-length)) | ||||
|  |  | |||
|  | @ -0,0 +1 @@ | |||
| CONTRIB_LIBS += $(wildcard contrib/30.test/*.scm) | ||||
|  | @ -1,6 +1,6 @@ | |||
| (define-library (picrin test) | ||||
|   (import (picrin base) | ||||
|           (picrin syntax-rules)) | ||||
|   (import (scheme base) | ||||
|           (scheme write)) | ||||
| 
 | ||||
|   (define test-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) | ||||
|   (import (picrin base) | ||||
|           (picrin record)) | ||||
|   (import (scheme base)) | ||||
| 
 | ||||
|   (define-record-type <array> | ||||
|     (create-array data size head tail) | ||||
|  | @ -10,11 +9,6 @@ | |||
|     (head array-head set-array-head!) | ||||
|     (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) | ||||
|     (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)))))) | ||||
|       (for-each export (cdr form))))) | ||||
| 
 | ||||
| (export define-library | ||||
|         cond-expand | ||||
|         import | ||||
|         export) | ||||
| 
 | ||||
| (export define lambda quote set! if begin define-macro | ||||
|         let let* letrec letrec* | ||||
|         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", | ||||
| "rt\")))))\n         (export\n           (lambda (spec)\n             (let ((slot (co", | ||||
| "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      ", | ||||
| "  import\n        export)\n\n(export define lambda quote set! if begin define-macro", | ||||
| "\n        let let* letrec letrec*\n        let-values let*-values define-values\n  ", | ||||
| "      quasiquote unquote unquote-splicing\n        and or\n        cond case else ", | ||||
| "=>\n        do when unless\n        parameterize\n        define-syntax\n        syn", | ||||
| "tax-quote syntax-unquote\n        syntax-quasiquote syntax-unquote-splicing\n     ", | ||||
| "or-each export (cdr form)))))\n\n(export define lambda quote set! if begin define-", | ||||
| "macro\n        let let* letrec letrec*\n        let-values let*-values define-valu", | ||||
| "es\n        quasiquote unquote unquote-splicing\n        and or\n        cond case ", | ||||
| "else =>\n        do when unless\n        parameterize\n        define-syntax\n      ", | ||||
| "  syntax-quote syntax-unquote\n        syntax-quasiquote syntax-unquote-splicing\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