generic.scm 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. (module (arguile generic)
  2. #:export (gen gen-fn? xtnd type
  3. len rev join cpy clr! map))
  4. (use (arguile base)
  5. (arguile data)
  6. (arguile guile)
  7. (arguile loop)
  8. ((srfi srfi-1) #:select (unzip2)))
  9. ;;; TODO: generic macros?
  10. (mac gen
  11. ((_ name) (id? #'name)
  12. #`(def name (%gen-fn 'name (ret t (mke-tbl)
  13. #,(when (defd? (-> dat #'name))
  14. #'(t 'def name)))))))
  15. (trans gen-fn (name tbl)
  16. #:init (%gen-fn name tbl)
  17. #:app (fn args
  18. (apply (resolve-fn (gen-fn-tbl self) args)
  19. args)))
  20. ;;; This version works, but needs cleanup
  21. (def resolve-fn (tbl args)
  22. (loop lp ((for arg (in-list args))
  23. (where t tbl (and=> t (\\ _ (type arg)))))
  24. => (cond (t (t 'fun) (t 'fun))
  25. (t (t 'rst) (t 'rst))
  26. ((tbl 'def) (tbl 'def))
  27. (else (err "No generic fn for args1:" args)))
  28. ;; This handles rest case
  29. (if t
  30. (aif (t 'rst) it (lp))
  31. (aif (tbl 'def) it
  32. (err "No generic fn for args:" args)))))
  33. (def type (x)
  34. (if (data? x) (data-type x)
  35. (base-type x)))
  36. ;;; Going to straight cpy for this version
  37. (mac xtnd x
  38. (def split (lst)
  39. (c/vals (fn () (unzip2 (grp lst 2))) list))
  40. ((_ name (arg1 ... . rest) body ...) (~(nil? #'rest))
  41. (let-syn (args types) (split #'(arg1 ...))
  42. #`(loop ((for type (in-list 'types))
  43. (where tbl (gen-fn-tbl name)
  44. (if (tbl type) (tbl type)
  45. (tbl type (mke-tbl)))))
  46. => (tbl 'rst (fn (#,@#'args . rest) body ...)))))
  47. ((_ name (arg1 ...) body ...) (defd? (-> dat #'name))
  48. (let-syn (args types) (split #'(arg1 ...))
  49. ;; TODO: refactor
  50. #`(loop ((for type (in-list 'types))
  51. (where tbl (gen-fn-tbl name)
  52. (if (tbl type) (tbl type)
  53. (tbl type (mke-tbl)))))
  54. => (tbl 'fun (fn args body ...))))))
  55. (eval-when (expand load eval)
  56. (def len length)
  57. (def rev reverse)
  58. (def join append)
  59. (def cpy lst-cpy)
  60. (def clr! (lst) (set-cdr! lst '()))
  61. (def map (@ (ice-9 r5rs) map)))
  62. (gen len)
  63. (gen rev)
  64. (gen join)
  65. (gen cpy)
  66. (gen clr!)
  67. (gen map)
  68. (xtnd len (t tbl) (tbl-cnt (const #t) t))
  69. (xtnd len (v vec) (vec-len v))
  70. (xtnd len (q q) (q-len q))
  71. (xtnd rev (v vec) (ret v* (mke-vec (vec-len v))
  72. (vec<-! v 0 (vec-len v) v* 0)))
  73. (xtnd join (s1 str . rest) (apply str-join s1 rest))
  74. (xtnd join (v1 vec v2 vec) (w/ (l1 (vec-len v1) l2 (vec-len v2))
  75. (ret v (mke-vec (+ l1 l2))
  76. (vec->! v1 0 l1 v 0)
  77. (vec->! v2 0 l2 v l1))))
  78. (xtnd cpy (v vec) (vec-cpy v))
  79. (xtnd cpy (q q) (%mke-q (q-len q) (q-hd q) (q-tl q)))
  80. (xtnd clr! (t tbl) (tbl-clr! t))
  81. (xtnd clr! (q q) (q-hd! q '()) (q-tl! q '()) (q-len! q 0))
  82. (xtnd map (f fn v vec . rest) (apply vec-map f v rest))
  83. (xtnd map (f fn s str . rest) (apply str-map f s rest))
  84. (xtnd map (f fn t tbl) (tbl-map->lst f t))