Skip to content

Instantly share code, notes, and snippets.

@belmarca
Created June 8, 2020 19:33
Show Gist options
  • Save belmarca/4b58454629c9f2acb9de5721d5245de0 to your computer and use it in GitHub Desktop.
Save belmarca/4b58454629c9f2acb9de5721d5245de0 to your computer and use it in GitHub Desktop.
A very hacky exploratory doc macro
(import (for-syntax :std/stxutil))
(defsyntax (describe stx)
(syntax-case stx ()
((macro thing)
(with-syntax ((thing-doc (format-id #'macro "%%doc%%~a" #'thing)))
#'(displayln thing-doc)))))
(defsyntax (doc stx)
(def (gen-var-docs stx)
(let (vars (syntax->datum stx))
(let lp ((rest vars)
(acc '()))
(cond
((null? rest)
(reverse acc))
((pair? (car rest))
(cond
((eq? 'string (caar rest))
(lp (cdr rest)
(cons (string-append " " (symbol->string (cadar rest)) ": string") acc)))
((eq? 'number (caar rest))
(lp (cdr rest)
(cons (string-append " " (symbol->string (cadar rest)) ": number") acc)))))
(else
(lp (cdr rest)
(cons (string-append " " (symbol->string (car rest)) ": any") acc)))))))
(def (gen-signature stx)
(call-with-output-string
(lambda (p)
(write (syntax->datum stx) p))))
(syntax-case stx (any)
((macro (thing vars ...) doc)
(with-syntax ((thing-doc (format-id #'macro "%%doc%%~a" #'thing))
(vars-doc (string-join (gen-var-docs #'(vars ...)) "\n"))
(signature (gen-signature #'(thing vars ...)))
(doc* (syntax->datum #'doc)))
#'(begin
(define thing-doc
(string-append signature "\n" vars-doc "\n" doc*)))))
((macro thing doc)
(with-syntax ((thing-doc (format-id #'macro "%%doc%%~a" #'thing)))
#'(begin
(define thing-doc doc ))))))
;; You would want code and doc in separate files.
(def x 0)
(doc x "This value is 0")
;; > (describe x)
;; This value is 0
(def (this x) x)
(doc (this x) "This is the identity function.")
;; > (describe this)
;; (this x)
;; x: any
;; This is the identity function.
(def (foo x y z)
(+ x y z))
(doc (foo (number x) (number y) (number z)) ;; type qualifiers shouldn't appear in signature
"Sum of three numbers.")
;; > (describe foo)
;; (foo (number x) (number y) (number z))
;; x: number
;; y: number
;; z: number
;; Sum of three numbers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment