diff --git a/Makefile b/Makefile index 5fb89222..3c0b4623 100644 --- a/Makefile +++ b/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) > $@ diff --git a/piclib/picrin/macro.scm b/contrib/10.macro/macro.scm similarity index 100% rename from piclib/picrin/macro.scm rename to contrib/10.macro/macro.scm diff --git a/contrib/10.macro/nitro.mk b/contrib/10.macro/nitro.mk new file mode 100644 index 00000000..a426ad2a --- /dev/null +++ b/contrib/10.macro/nitro.mk @@ -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 diff --git a/t/ir-macro.scm b/contrib/10.macro/t/ir-macro.scm similarity index 100% rename from t/ir-macro.scm rename to contrib/10.macro/t/ir-macro.scm diff --git a/contrib/20.r7rs/scheme/base.scm b/contrib/20.r7rs/scheme/base.scm index 927643aa..e2e70a80 100644 --- a/contrib/20.r7rs/scheme/base.scm +++ b/contrib/20.r7rs/scheme/base.scm @@ -1,8 +1,6 @@ (define-library (scheme base) (import (picrin base) (picrin macro) - (picrin record) - (picrin syntax-rules) (picrin string) (scheme file)) @@ -76,63 +74,57 @@ ;; 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 - (lambda (guard-k) - (with-exception-handler - (lambda (condition) - ((call/cc - (lambda (handler-k) - (guard-k - (lambda () - (let ((var condition)) - (guard-aux - (handler-k - (lambda () - (raise-continuable condition))) - clause ...)))))))) - (lambda () - (call-with-values - (lambda () e1 e2 ...) - (lambda args - (guard-k - (lambda () - (apply values args))))))))))))) + (define-syntax (guard formal . body) + (let ((var (car formal)) + (clauses (cdr formal))) + #`((call/cc + (lambda (guard-k) + (with-exception-handler + (lambda (condition) + ((call/cc + (lambda (handler-k) + (guard-k + (lambda () + (let ((#,var condition)) + (guard-aux + (handler-k + (lambda () + (raise-continuable condition))) + #,@clauses)))))))) + (lambda () + (call-with-values + (lambda () #,@body) + (lambda args + (guard-k + (lambda () + (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 ) name) + (let ((rectype (make-record ))) + (record-set! rectype 'name name) + rectype)) + + (define + (let (( ((boot-make-record-type #t) 'record-type))) + (record-set! '@@type ) + )) + + (define make-record-type (boot-make-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 diff --git a/t/syntax-rules.scm b/contrib/20.r7rs/t/syntax-rules.scm similarity index 94% rename from t/syntax-rules.scm rename to contrib/20.r7rs/t/syntax-rules.scm index 12b16a95..ef55a5ed 100644 --- a/t/syntax-rules.scm +++ b/contrib/20.r7rs/t/syntax-rules.scm @@ -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 () diff --git a/contrib/30.readline/t/test.scm b/contrib/30.readline/t/test.scm index 2fb65181..ed9163ae 100644 --- a/contrib/30.readline/t/test.scm +++ b/contrib/30.readline/t/test.scm @@ -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)) diff --git a/contrib/30.test/nitro.mk b/contrib/30.test/nitro.mk new file mode 100644 index 00000000..d2c2199d --- /dev/null +++ b/contrib/30.test/nitro.mk @@ -0,0 +1 @@ +CONTRIB_LIBS += $(wildcard contrib/30.test/*.scm) diff --git a/piclib/picrin/test.scm b/contrib/30.test/test.scm similarity index 97% rename from piclib/picrin/test.scm rename to contrib/30.test/test.scm index f3fd920e..919a8b49 100644 --- a/piclib/picrin/test.scm +++ b/contrib/30.test/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) diff --git a/contrib/50.destructuring-bind/lambda.scm b/contrib/50.destructuring-bind/lambda.scm new file mode 100644 index 00000000..c3fc9872 --- /dev/null +++ b/contrib/50.destructuring-bind/lambda.scm @@ -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)) diff --git a/contrib/50.destructuring-bind/nitro.mk b/contrib/50.destructuring-bind/nitro.mk new file mode 100644 index 00000000..101e7bc7 --- /dev/null +++ b/contrib/50.destructuring-bind/nitro.mk @@ -0,0 +1 @@ +CONTRIB_LIBS += $(wildcard contrib/50.destructuring-bind/*.scm) diff --git a/piclib/picrin/array.scm b/contrib/90.array/array.scm similarity index 94% rename from piclib/picrin/array.scm rename to contrib/90.array/array.scm index 6412d136..7cd2ccdf 100644 --- a/piclib/picrin/array.scm +++ b/contrib/90.array/array.scm @@ -1,6 +1,5 @@ (define-library (picrin array) - (import (picrin base) - (picrin record)) + (import (scheme base)) (define-record-type (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))) diff --git a/contrib/90.array/nitro.mk b/contrib/90.array/nitro.mk new file mode 100644 index 00000000..dc914f06 --- /dev/null +++ b/contrib/90.array/nitro.mk @@ -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 diff --git a/contrib/90.array/t/array.scm b/contrib/90.array/t/array.scm new file mode 100644 index 00000000..b89615cf --- /dev/null +++ b/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) diff --git a/extlib/benz/boot.c b/extlib/benz/boot.c index c64c56c3..7a681cba 100644 --- a/extlib/benz/boot.c +++ b/extlib/benz/boot.c @@ -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,13 +996,12 @@ 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 ", -" let-syntax letrec-syntax\n syntax-error)\n\n\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", "", "" }; diff --git a/piclib/picrin/base.scm b/piclib/picrin/base.scm deleted file mode 100644 index f88c33ca..00000000 --- a/piclib/picrin/base.scm +++ /dev/null @@ -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>=?) - - (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>=?) - - (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)) diff --git a/piclib/picrin/control.scm b/piclib/picrin/control.scm deleted file mode 100644 index 5798655d..00000000 --- a/piclib/picrin/control.scm +++ /dev/null @@ -1,3 +0,0 @@ -(define-library (picrin control) - (import (picrin base)) - (export escape)) diff --git a/piclib/picrin/experimental/lambda.scm b/piclib/picrin/experimental/lambda.scm deleted file mode 100644 index 8bbcce40..00000000 --- a/piclib/picrin/experimental/lambda.scm +++ /dev/null @@ -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))) diff --git a/piclib/picrin/record.scm b/piclib/picrin/record.scm deleted file mode 100644 index 20d75f77..00000000 --- a/piclib/picrin/record.scm +++ /dev/null @@ -1,59 +0,0 @@ -(define-library (picrin record) - (import (picrin base) - (picrin macro)) - - ;; record meta type - - (define ((boot-make-record-type ) name) - (let ((rectype (make-record ))) - (record-set! rectype 'name name) - rectype)) - - (define - (let (( ((boot-make-record-type #t) 'record-type))) - (record-set! '@@type ) - )) - - (define make-record-type (boot-make-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)) diff --git a/piclib/picrin/syntax-rules.scm b/piclib/picrin/syntax-rules.scm deleted file mode 100644 index 3e5496a3..00000000 --- a/piclib/picrin/syntax-rules.scm +++ /dev/null @@ -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 - _ - ...)) diff --git a/t/array.scm b/t/array.scm deleted file mode 100644 index 22593546..00000000 --- a/t/array.scm +++ /dev/null @@ -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) -