accessors.scm 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. (define (push-box! place val)
  2. (set-box! place (cons val (unbox place))))
  3. (define (fold kons knil lst)
  4. (if (null? lst)
  5. knil
  6. (kons (car lst)
  7. (fold kons knil (cdr lst)))))
  8. (define (throw-a-chunk-into span l thunk)
  9. (let loop ((span span) (chunk '()) (l l))
  10. (cond ((null? l)
  11. (thunk (reverse chunk) #f))
  12. ((= 0 span)
  13. (thunk (reverse chunk) l))
  14. (else (loop (- span 1) (cons (car l) chunk) (cdr l))))))
  15. (define (chunks span l)
  16. (throw-a-chunk-into span l
  17. (lambda (chunk rest)
  18. (if rest
  19. (cons chunk (chunks span rest))
  20. (list chunk)))))
  21. (define (->string x)
  22. (cond ((string? x) x)
  23. ((symbol? x) (symbol->string x))
  24. (else (error '->string "?" x))))
  25. (define (symbol-append s1 s2)
  26. (string->symbol (string-append (->string s1) (->string s2))))
  27. (define ^ symbol-append)
  28. (define (string-concat ss) (fold string-append "" ss))
  29. (define (cxr acc var) (cxr* (chunks 3 acc) var))
  30. (define (cxr* acc var)
  31. (if (null? acc)
  32. var
  33. (list (string->symbol (string-append "c" (string-append (string-concat (car acc)) "r")))
  34. (cxr* (cdr acc) var))))
  35. (define (go name exp)
  36. (let ((accessors (box '())))
  37. (pretty-print
  38. `(define (,(symbol-append name "?") exp)
  39. (and . ,(let loop ((exp exp) (place '()))
  40. (cond ((symbol? exp)
  41. (list `(eq? ',exp ,(cxr place 'exp))))
  42. ((pair? exp)
  43. (let* ((chk (list `(pair? ,(cxr place 'exp))))
  44. (kar (loop (car exp) (cons "a" place)))
  45. (kdr (loop (cdr exp) (cons "d" place))))
  46. (append chk kar kdr)))
  47. ((null? exp)
  48. (list `(null? ,(cxr place 'exp))))
  49. ((string? exp)
  50. (push-box! accessors
  51. `(define (,(^ name (^ "-get-" exp)) exp)
  52. ,(cxr place 'exp)))
  53. '()))))))
  54. (for-each pretty-print (reverse (unbox accessors)))))