r6rs-arity.ss 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. ;;; Copyright © 2016 Federico Beffa
  2. ;;;
  3. ;;; This program is free software; you can redistribute it and/or modify it
  4. ;;; under the terms of the GNU General Public License as published by
  5. ;;; the Free Software Foundation; either version 3 of the License, or (at
  6. ;;; your option) any later version.
  7. ;;;
  8. ;;; This program is distributed in the hope that it will be useful, but
  9. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. ;;; GNU General Public License for more details.
  12. ;;;
  13. ;;; You should have received a copy of the GNU General Public License
  14. ;;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. ;;; Comments
  16. ;; This file provides procedures used to extract the arity of
  17. ;; procedures from the R6RS Standard and Chez Scheme User Guide (LaTeX
  18. ;; files).
  19. ;;; Code
  20. (import (irregex) (matchable)
  21. (only (srfi :1) delete-duplicates))
  22. (define rx-proc-name 'proc)
  23. (define rx-args-name 'args)
  24. (define r6rs-proto-rx
  25. (irregex
  26. `(seq (or "\\proto{" "\\rproto{") (* white)
  27. (submatch-named ,rx-proc-name (+ (~ #\}))) ; proc name
  28. (* white) "}" (* white) "{" (* white)
  29. (submatch-named ,rx-args-name (* any)) ; proc args
  30. (* white) "}" (* white) "{" (* white) "procedure" (* white) "}")))
  31. (define r6rs-dots-rx
  32. (irregex '(or "\\dotsfoo"
  33. "$\\ldots$"
  34. (seq "\\dotsfoo{" (* space) "}"))))
  35. (define csug-formdef-rx
  36. (irregex
  37. `(seq "\\formdef{" (* white)
  38. (submatch-named ,rx-proc-name (+ (~ #\}))) ; proc name
  39. (* white) "}" (* white)
  40. "{" (* white) "\\categoryprocedure" (* white) "}"
  41. (* white) "{" (* white) "(" (+ (~ white)) (+ white)
  42. (submatch-named ,rx-args-name (* any)) ; proc args
  43. (* white) ")" (* white) "}")))
  44. (define csug-dots-rx
  45. (irregex '(: "\\dots")))
  46. (define procdef-rx (make-parameter r6rs-proto-rx))
  47. (define dots-rx (make-parameter r6rs-dots-rx))
  48. (define (get-proc-name m)
  49. (string->symbol (irregex-match-substring m rx-proc-name)))
  50. (define (args-has-dots? str)
  51. (irregex-search (dots-rx) str))
  52. (define (args-split-at-dots str)
  53. (irregex-split (dots-rx) str))
  54. (define (args-split str)
  55. (irregex-split '(: (+ space)) str))
  56. (define (args-count ls)
  57. (length ls))
  58. (define (proc-args->arity str)
  59. (if (args-has-dots? str)
  60. (let ((ls-req/rest (args-split-at-dots str)))
  61. (cons (- (args-count (args-split (car ls-req/rest))) 1) #f))
  62. (let* ((ls-req (args-split str))
  63. (req-no (args-count ls-req)))
  64. (cons req-no req-no))))
  65. (define (alist-keys alist)
  66. (map car alist))
  67. (define (alist-values alist)
  68. (map cdr alist))
  69. (define (%arities-union a1 a2)
  70. (match (cons a1 a2)
  71. (((a1-min . a1-max) . (a2-min . a2-max))
  72. (let ((a-max (if (or (not a1-max) (not a2-max)) #f (max a1-max a2-max))))
  73. (cons (min a1-min a2-min) a-max)))))
  74. ;; XXX: this is of course an approximation, but backed by common-sense.
  75. (define (union-arities key alist)
  76. (let ((arities (filter (lambda (e) (eq? key (car e))) alist)))
  77. (if (> (length arities) 1)
  78. (cons key
  79. (fold-left %arities-union `(,(greatest-fixnum) . 0)
  80. (alist-values arities)))
  81. (car arities))))
  82. (define (union-arities-all alist)
  83. (map (lambda (k) (union-arities k alist))
  84. (delete-duplicates (alist-keys alist))))
  85. (define (get-proc-args m)
  86. (irregex-match-substring m rx-args-name))
  87. (define (make-proc-entry m)
  88. (cons (get-proc-name m) (proc-args->arity (get-proc-args m))))
  89. ;; XXX: This relies on the definition not being split on multiple
  90. ;; lines.
  91. (define (extract-arities-from-file fn)
  92. (with-input-from-file fn
  93. (lambda ()
  94. (let loop ((acc '())
  95. (line (get-line (current-input-port))))
  96. (if (eof-object? line)
  97. (union-arities-all acc)
  98. (let ((m (irregex-search (procdef-rx) line)))
  99. (loop (if (irregex-match-data? m)
  100. (cons (make-proc-entry m) acc)
  101. acc)
  102. (get-line (current-input-port)))))))))
  103. ;;; Files
  104. (define r6rs-doc-dir "/home/beffa/Downloads/r6rs/document")
  105. (define r6rs-doc-files
  106. (list "base.tex"
  107. "unicode.tex"
  108. "bytevector.tex"
  109. "list.tex"
  110. "sort.tex"
  111. "control.tex"
  112. "records.tex"
  113. "exc.tex"
  114. "io.tex"
  115. "files.tex"
  116. "programlib.tex"
  117. "arith.tex"
  118. "syntax-case.tex"
  119. "hashtable.tex"
  120. "enum.tex"
  121. "complib.tex"
  122. "eval.tex"
  123. "setcar.tex"
  124. "stringset.tex"
  125. "r5rscompat.tex"))
  126. (define csug-doc-dir "/home/beffa/src/chez-git/ChezScheme/csug")
  127. (define csug-doc-files
  128. (list "debug.stex"
  129. "foreign.stex"
  130. "binding.stex"
  131. "control.stex"
  132. "objects.stex"
  133. "numeric.stex"
  134. "io.stex"
  135. "libraries.stex"
  136. "syntax.stex"
  137. "system.stex"
  138. "smgmt.stex"
  139. "expeditor.stex"
  140. "threads.stex"))
  141. (define (file-absolute-path dir fn)
  142. (string-append dir "/" fn))
  143. ;;; Main function
  144. (define (r6rs-doc-arities-all)
  145. (parameterize ((procdef-rx r6rs-proto-rx)
  146. (dots-rx r6rs-dots-rx))
  147. (let ((files-ls
  148. (map (lambda (f) (file-absolute-path r6rs-doc-dir f))
  149. r6rs-doc-files)))
  150. (apply append (map extract-arities-from-file files-ls)))))
  151. (define (csug-doc-arities-all)
  152. (parameterize ((procdef-rx csug-formdef-rx)
  153. (dots-rx csug-dots-rx))
  154. (let ((files-ls
  155. (map (lambda (f) (file-absolute-path csug-doc-dir f))
  156. csug-doc-files)))
  157. (apply append (map extract-arities-from-file files-ls)))))