乐趣区

关于java:用java写lisp-解释器-7-defstruct-用宏实现-源码

defstruct

(define-macro defstruct (lambda (x  .  ff) (
            (let ((i -1)
                     (j -1)
                     (struct-name (symbol->string x))
                     (keys (map (lambda (x) (if (pair? x) (car x) (x))) ff))) (
                        `((define ,(string->symbol (string-append 'mark-' struct-name)) (lambda (,@keys) (
                                    (cons
                                     (vector 'struct' ,struct-name)
                                     (vector ,@keys)))))
                             (define ,(string->symbol (string-append 'verify-struct-' struct-name)) (lambda (o) (
                                (if
                                    (not (and (eqv? 'struct' (vector-ref (car o) 0)) (eqv? ,struct-name (vector-ref (car o) 1)) ))
                                    (error ,(string-append 'not-struct' struct-name))))))
                             ,@(map (lambda (n) ((set! i (+ i 1))
                                (`(define ,(string->symbol (string-append struct-name '.' (symbol->string n))) (lambda (o) ((,(string->symbol (string-append 'verify-struct-' struct-name)) o)
                                       (vector-ref (cdr o) ,i)
                                    )))
                                )
                             )) keys)
                             ,@(map  (lambda (n) ((set! j (+ j 1))
                                 (`(define ,(string->symbol (string-append struct-name '.' (symbol->string n) '-set!')) (lambda (o v) ((,(string->symbol (string-append 'verify-struct-' struct-name)) o)
                                        (vector-set! (cdr o) ,j v)
                                     )))
                                 )
                              )) keys) ))))))

应用

((defstruct box (name width height size))
    (define x (mark-box 'name' 2 3 5))
    (display (box.width x))
    (newline)
    (box.width-set! x 15)
    (display (box.width x))
)
=> 2
=> 15

目前还暂不反对初始化操作 如这种模式:

(defstruct box (name width height(size 5)))
退出移动版