data.scm 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. (module (arguile data)
  2. #:export (data trans data? data-type? data-type))
  3. (use (arguile base)
  4. (arguile data records)
  5. (arguile data immutable)
  6. ((srfi srfi-1) #:select (first)))
  7. ;;; TODO: add #:init to field specs
  8. ;;; order fields in printer
  9. (mac data x
  10. ((_ name (field ...)
  11. #:init (mke arg ...)
  12. spec ...
  13. #:app fn)
  14. (%data x #t #'(_ name (field ...) #:init (mke arg ...) spec ... #:app fn)))
  15. ((_ name (field ...) spec ... #:app fn)
  16. (%data x #t #`(_ name (field ...) #:init (#,(std-mke #'name x) field ...)
  17. spec ... #:app fn)))
  18. ((_ name (field ...) #:init (mke arg ...) spec ...)
  19. (%data x #t #`(_ name (field ...) #:init (mke arg ...) spec ... #:app (not-app 'name))))
  20. ((_ name (field ...) spec ...)
  21. (%data x #t #`(_ name (field ...) #:init (#,(std-mke #'name x) field ...)
  22. spec ... #:app (not-app 'name)))))
  23. ;;; TODO: copying for now
  24. (mac trans x
  25. ((_ name (field ...)
  26. #:init (mke arg ...)
  27. spec ...
  28. #:app fn)
  29. (%data x #f #'(_ name (field ...) #:init (mke arg ...) spec ... #:app fn)))
  30. ((_ name (field ...) spec ... #:app fn)
  31. (%data x #f #`(_ name (field ...) #:init (#,(std-mke #'name x) field ...)
  32. spec ... #:app fn)))
  33. ((_ name (field ...) #:init (mke arg ...) spec ...)
  34. (%data x #f #`(_ name (field ...) #:init (mke arg ...) spec ... #:app (not-app 'name))))
  35. ((_ name (field ...) spec ...)
  36. (%data x #f #`(_ name (field ...) #:init (#,(std-mke #'name x) field ...)
  37. spec ... #:app (not-app 'name)))))
  38. (def data-type? record-type?)
  39. (def data? record?)
  40. (def data-type (obj)
  41. (struct-ref (struct-vtable obj) vtable-offset-user))
  42. (eval-when (expand load eval)
  43. (def %data (ctx imm? syn-exp)
  44. (syn-case syn-exp ()
  45. ((_ name (field ...) #:init (mke arg ...) spec ... #:app fn)
  46. (let name' (dat #'name)
  47. (w/syn (type (syn (+ '< name' '>) ctx)
  48. %mke (syn (+ '% (dat #'mke)) ctx)
  49. pred (syn (+ name' '?) ctx)
  50. (app app: app!) (mke-app-spec name' ctx)
  51. self (syn 'self ctx))
  52. #`(do (#,(if imm? #'define-immutable-record-type
  53. #'define-record-type)
  54. type
  55. (%mke arg ...) pred
  56. (app app: app!)
  57. #,@(mke-field-specs name' #'(field ...) #'(spec ...) ctx)
  58. spec ...)
  59. (def mke args
  60. (#,(if imm? #'let #'ret)
  61. self (apply %mke args) (app! self fn)))))))))
  62. (def std-mke (name ctx) (syn (dat name) ctx))
  63. (def mke-app-spec (name ctx)
  64. (-> syn (mke-field-spec name 'fn) ctx))
  65. (def mke-field-spec (name field)
  66. `(,field ,@(map (\\ + name '- field _)
  67. `(,(symbol) !))))
  68. (def mke-field-specs (name fields specs ctx)
  69. (-> syn (map (\\ mke-field-spec name _)
  70. (set\ eq? (-> dat fields)
  71. (map first (-> dat specs)))) ctx))
  72. (def not-app (name)
  73. (fn args (err "Wrong type to apply:" name
  74. "data-type not applicable"))))
  75. (use (arguile data tbl)
  76. (arguile data vec)
  77. (arguile data q))
  78. (re-export-modules (arguile data tbl)
  79. (arguile data vec)
  80. (arguile data q))