rewrite (picrin record) and (picrin experimental lambda)
This commit is contained in:
parent
4d9f5bfbcf
commit
d741efe294
|
@ -3,47 +3,36 @@
|
|||
(picrin base)
|
||||
(picrin macro))
|
||||
|
||||
(define-syntax destructuring-bind
|
||||
(ir-macro-transformer
|
||||
(lambda (form inject compare)
|
||||
(let ((formal (car (cdr form)))
|
||||
(value (car (cdr (cdr form))))
|
||||
(body (cdr (cdr (cdr form)))))
|
||||
(define-syntax (destructuring-let formal value . body)
|
||||
(cond
|
||||
((symbol? formal)
|
||||
`(let ((,formal ,value))
|
||||
,@body))
|
||||
((variable? formal)
|
||||
#`(let ((#,formal #,value))
|
||||
#,@body))
|
||||
((pair? formal)
|
||||
`(let ((value# ,value))
|
||||
(destructuring-bind ,(car formal) (car value#)
|
||||
(destructuring-bind ,(cdr formal) (cdr value#)
|
||||
,@body))))
|
||||
#`(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)
|
||||
#`(if (equal? #,value '#,formal)
|
||||
(begin
|
||||
,@body)
|
||||
(error "match failure" ,value ',formal))))))))
|
||||
#,@body)
|
||||
(error "match failure" #,value '#,formal)))))
|
||||
|
||||
(define-syntax destructuring-lambda
|
||||
(ir-macro-transformer
|
||||
(lambda (form inject compare)
|
||||
(let ((args (car (cdr form)))
|
||||
(body (cdr (cdr form))))
|
||||
`(lambda formal# (destructuring-bind ,args formal# ,@body))))))
|
||||
(define-syntax (destructuring-lambda formal . body)
|
||||
#`(lambda args
|
||||
(destructuring-let #,formal args #,@body)))
|
||||
|
||||
(define-syntax destructuring-define
|
||||
(ir-macro-transformer
|
||||
(lambda (form inject compare)
|
||||
(let ((maybe-formal (cadr form)))
|
||||
(if (symbol? maybe-formal)
|
||||
`(define ,@(cdr form))
|
||||
`(destructuring-define ,(car maybe-formal)
|
||||
(destructuring-lambda ,(cdr maybe-formal)
|
||||
,@(cddr form))))))))
|
||||
(define-syntax (destructuring-define formal . body)
|
||||
(if (variable? formal)
|
||||
#`(define #,formal #,@body)
|
||||
#`(destructuring-define #,(car formal)
|
||||
(destructuring-lambda #,(cdr formal)
|
||||
#,@body))))
|
||||
|
||||
(export (rename destructuring-bind bind)
|
||||
(export (rename destructuring-let let)
|
||||
(rename destructuring-lambda lambda)
|
||||
(rename destructuring-define define)))
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
(import (picrin base)
|
||||
(picrin macro))
|
||||
|
||||
;; define-record-type
|
||||
;; record meta type
|
||||
|
||||
(define ((boot-make-record-type <meta-type>) name)
|
||||
(let ((rectype (make-record <meta-type>)))
|
||||
|
@ -10,70 +10,50 @@
|
|||
rectype))
|
||||
|
||||
(define <record-type>
|
||||
(let ((<record-type>
|
||||
((boot-make-record-type #t) '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
|
||||
(ir-macro-transformer
|
||||
(lambda (form inject compare?)
|
||||
(let ((rectype (car (cdr form)))
|
||||
(name (car (cdr (cdr form))))
|
||||
(fields (cdr (cdr (cdr form)))))
|
||||
`(define (,name ,@fields)
|
||||
(let ((record (make-record ,rectype)))
|
||||
,@(map (lambda (field)
|
||||
`(record-set! record ',field ,field))
|
||||
fields)
|
||||
record))))))
|
||||
;; define-record-type
|
||||
|
||||
(define-syntax define-record-predicate
|
||||
(ir-macro-transformer
|
||||
(lambda (form inject compare?)
|
||||
(let ((rectype (car (cdr form)))
|
||||
(name (car (cdr (cdr form)))))
|
||||
`(define (,name obj)
|
||||
(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)
|
||||
,rectype)))))))
|
||||
(eq? (record-type obj) #,type))))
|
||||
|
||||
(define-syntax define-record-field
|
||||
(ir-macro-transformer
|
||||
(lambda (form inject compare?)
|
||||
(let ((pred (car (cdr form)))
|
||||
(field-name (car (cdr (cdr form))))
|
||||
(accessor (car (cdr (cdr (cdr form)))))
|
||||
(modifier? (cdr (cdr (cdr (cdr form))))))
|
||||
(if (null? modifier?)
|
||||
`(define (,accessor record)
|
||||
(if (,pred record)
|
||||
(record-ref record ',field-name)
|
||||
(error (string-append (symbol->string ',accessor) ": wrong record type") record)))
|
||||
`(begin
|
||||
(define (,accessor record)
|
||||
(if (,pred record)
|
||||
(record-ref record ',field-name)
|
||||
(error (string-append (symbol->string ',accessor) ": wrong record type") record)))
|
||||
(define (,(car modifier?) record val)
|
||||
(if (,pred record)
|
||||
(record-set! record ',field-name val)
|
||||
(error (string-append (symbol->string ',(car modifier?)) ": wrong record type") record)))))))))
|
||||
(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-type
|
||||
(ir-macro-transformer
|
||||
(lambda (form inject compare?)
|
||||
(let ((name (car (cdr form)))
|
||||
(ctor (car (cdr (cdr form))))
|
||||
(pred (car (cdr (cdr (cdr form)))))
|
||||
(fields (cdr (cdr (cdr (cdr form))))))
|
||||
`(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))))))
|
||||
(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))
|
||||
|
|
Loading…
Reference in New Issue