Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

190 Zeilen
6.1 KiB

  1. (import "cxr.slime")
  2. ;; alist:
  3. ;; [ |/]
  4. ;; |
  5. ;; V
  6. ;; [ | ]------------->[ | ]-------------> ...
  7. ;; | |
  8. ;; V V
  9. ;; [ | ]->value1 [ | ]->value2
  10. ;; | |
  11. ;; V V
  12. ;; key1 key2
  13. ;;
  14. ;; '(((key1 . value1) (key2 . value2)))
  15. ;; plist:
  16. ;; [ |/]
  17. ;; |
  18. ;; V
  19. ;; [ | ]------------->[ | ]-------------> ...
  20. ;; | |
  21. ;; V V
  22. ;; :key1 value1
  23. ;;
  24. ;; '((:key1 value1 :key2 value2))
  25. (define key-not-found-index -1)
  26. (define (make-alist)
  27. (set-type
  28. '(())
  29. :alist))
  30. (define (make-plist)
  31. (set-type
  32. '(())
  33. :plist))
  34. (define (pprint-alist alist)
  35. (let ((associations (first alist)))
  36. (define (pprint-intern associations)
  37. (when associations
  38. (printf " "
  39. (caar associations) "->"
  40. (cdar associations))
  41. (pprint-intern (rest associations))))
  42. (print "(")
  43. (when associations
  44. (print "\n")
  45. (pprint-intern associations))
  46. (print ")\n")))
  47. (define (pprint-plist plist)
  48. (let ((props (first plist)))
  49. (define (pprint-intern props)
  50. (when props
  51. (printf " "
  52. (car props) "->"
  53. (cadr props))
  54. (pprint-intern (cddr props))))
  55. (print "(")
  56. (when props
  57. (print "\n")
  58. (pprint-intern props))
  59. (print ")\n")))
  60. (define (alist-get alist key)
  61. (let ((associations (first alist)))
  62. (define (alist-get-intern associations key)
  63. (cond ((null? associations)
  64. (error "key was not found in alist"))
  65. ((= (caar associations) key)
  66. (cdar associations))
  67. (else (alist-get-intern (rest associations) key))))
  68. (alist-get-intern associations key)))
  69. (define (alist-find alist key)
  70. (let ((associations (first alist)))
  71. (define (alist-find-intern associations key current-index)
  72. (cond ((null? associations) key-not-found-index)
  73. ((= (caar associations) key) current-index)
  74. (else (alist-find-intern (rest associations)
  75. key
  76. (+ 1 current-index)))))
  77. (alist-find-intern associations key 0)))
  78. (define (alist-key-exists? alist key)
  79. (not (= (alist-find alist key)
  80. key-not-found-index)))
  81. (define (alist-remove! alist key)
  82. (let ((index (alist-find alist key)))
  83. (define (alist-remove!-internal asociations index)
  84. ;; reminder: we only get called if we are not replacing the
  85. ;; first element in the alist
  86. ;; reminder2: we know that the key exists
  87. (if (= index 1)
  88. ;; we want to remove the next one, so we set our
  89. ;; cdr to the next next one
  90. (mutate associations (pair (first associations)
  91. (rest (rest associations))))
  92. ;; else cdr-recurse
  93. (alist-remove!-internal (rest asociations) (- index 1))))
  94. (cond ((= index key-not-found-index) (error "key to remove was not found"))
  95. ((= index 0) (mutate alist (pair (cdar alist) ())))
  96. (else (alist-remove!-internal alist index))))
  97. alist)
  98. (define (alist-set! alist key value)
  99. (mutate alist (set-type (pair (pair (pair key value)
  100. (car alist))
  101. ())
  102. :alist)))
  103. (define (alist-set-overwrite! alist key value)
  104. (let ((associations (first alist)))
  105. (define (alist-set-overwrite-intern associations key value)
  106. (cond ((= (caar associations) key)
  107. (mutate (car associations) (pair key value)))
  108. ((null? associations) (alist-set! alist key value))
  109. (else (alist-set-overwrite-intern
  110. (rest associations) key value))))
  111. (alist-set-overwrite-intern associations key value))
  112. alist)
  113. (define (plist-get plist prop)
  114. (let ((props (first plist)))
  115. (define (plist-get-intern props prop)
  116. (cond ((null? props)
  117. (error "property was not found in plist"))
  118. ((= (car props) prop)
  119. (cadr props))
  120. (else (plist-get-intern (cddr props) prop))))
  121. (plist-get-intern props prop)))
  122. (define (plist-set! plist prop value)
  123. (mutate plist (set-type (pair (pair prop (pair value (first plist))) ())
  124. :plist)))
  125. (define (plist-set-overwrite! plist prop value)
  126. (let ((props (first plist)))
  127. (define (plist-set-overwrite-intern props prop value)
  128. (cond ((= (car props) prop)
  129. (mutate (cdr props) (pair value (cddr props))))
  130. ((null? props) (plist-set! plist prop value))
  131. (else (plist-set-overwrite-intern
  132. (cddr props) prop value))))
  133. (plist-set-overwrite-intern props prop value))
  134. plist)
  135. (define (plist-find plist prop)
  136. (let ((props (first plist)))
  137. (define (plist-find-intern props prop current-index)
  138. (cond ((null? props) key-not-found-index)
  139. ((= (car props) prop) current-index)
  140. (else (plist-find-intern (cddr props) prop
  141. (+ 1 current-index)))))
  142. (plist-find-intern props prop 0)))
  143. (define (plist-prop-exists? plist prop)
  144. (not (= (plist-find plist prop)
  145. key-not-found-index)))
  146. (define (plist-remove! plist prop)
  147. (let ((index (plist-find plist prop)))
  148. (define (plist-remove!-internal props index)
  149. ;; reminder: we only get called if we are not replacing the
  150. ;; first element in the alist
  151. ;; reminder2: we know that the key exists
  152. (if (= index 1)
  153. ;; we want to remove the next one, so we set our
  154. ;; cdr to the next next one
  155. (mutate (cdar props) (pair (cadar props) ;; xD nice meme dude!!!
  156. (cdr (cdr (cdr (cdar props))))))
  157. ;; else cdr-recurse
  158. (plist-remove!-internal (cddr props) (- index 1))))
  159. (cond ((= index key-not-found-index) (error "prop to remove was not found"))
  160. ((= index 0) (mutate plist (pair (cddar plist) ())))
  161. (else (plist-remove!-internal plist index))))
  162. plist)