This enriches the space of recognized builtins. Note that this also fixes the space after a builtin being included in the token.
116 lines
3.4 KiB
Scheme
116 lines
3.4 KiB
Scheme
;; Autogenerate a list of Scheme keywords (i.e., macros) and built-in
|
|
;; functions. This is written for the Guile implementation. The
|
|
;; principle of autogenerating this has the advantage of catching many
|
|
;; builtins that would be tedious to maintain by hand, and the
|
|
;; disadvantage that some builtins very specific to Guile and not
|
|
;; relevant to other implementations are caught as well. However,
|
|
;; since Scheme builtin function names tend to be rather specific,
|
|
;; this should not be a significant problem.
|
|
|
|
(define port (open-output-file "../pygments/lexers/_scheme_builtins.py"))
|
|
|
|
(display
|
|
"\"\"\"
|
|
pygments.lexers._scheme_builtins
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Scheme builtins.
|
|
|
|
:copyright: Copyright 2006-2022 by the Pygments team, see AUTHORS.
|
|
:license: BSD, see LICENSE for details.
|
|
\"\"\"
|
|
"
|
|
port)
|
|
|
|
(format port
|
|
"\n# Autogenerated by external/scheme-builtins-generator.scm\n\
|
|
# using Guile ~a.\n\n"
|
|
(version))
|
|
|
|
(use-modules (srfi srfi-1)
|
|
(ice-9 match))
|
|
|
|
(define relevant-modules
|
|
;; This is a nightmare. Scheme builtins are split in
|
|
;; gazillions of standards, SRFIs and implementation
|
|
;; extensions. With so many sources, it's hard to define
|
|
;; what is really a Scheme builtin. This is a rather
|
|
;; conservative list of Guile modules that might be used
|
|
;; the most frequently (somewhat subjective, admittedly).
|
|
'(
|
|
;; The real builtins.
|
|
(guile)
|
|
;; Let's include the fundamental list library.
|
|
(srfi srfi-1)
|
|
;; define-record-type
|
|
(srfi srfi-9)
|
|
;; let-values, let*-values
|
|
(srfi srfi-11)
|
|
;; case-lambda
|
|
(srfi srfi-16)
|
|
;; Pattern matching
|
|
(ice-9 match)
|
|
;; Included for compatibility with files written for R5RS
|
|
(rnrs r5rs)))
|
|
|
|
(define (get-all-bindings module)
|
|
;; Need to recurse to find all public bindings. module-map
|
|
;; only considers the module's own bindings.
|
|
(let* ((own (module-map cons module))
|
|
(uses (module-uses module)))
|
|
(append own (append-map get-all-bindings uses))))
|
|
|
|
(define all-bindings
|
|
(append-map
|
|
;; Need to use module-public-interface to restrict to
|
|
;; public bindings. Note that module-uses already
|
|
;; returns public interfaces.
|
|
(lambda (mod-path)
|
|
(let* ((mod-object (resolve-module mod-path))
|
|
(iface (module-public-interface mod-object)))
|
|
(get-all-bindings iface)))
|
|
relevant-modules))
|
|
|
|
(define (filter-for pred)
|
|
(filter-map
|
|
(match-lambda
|
|
((key . variable)
|
|
(and (variable-bound? variable)
|
|
(let ((value (variable-ref variable)))
|
|
(and (pred value)
|
|
key)))))
|
|
all-bindings))
|
|
|
|
(define (sort-and-uniq lst pred)
|
|
(let loop ((lst (sort lst pred))
|
|
(acc '()))
|
|
(match lst
|
|
(() (reverse! acc))
|
|
((one . rest)
|
|
(loop (drop-while (lambda (elt)
|
|
(equal? elt one))
|
|
rest)
|
|
(cons one acc))))))
|
|
|
|
(define (dump-py-list lst)
|
|
(string-join
|
|
(map
|
|
(lambda (name)
|
|
(format #f " \"~a\"," name))
|
|
(sort-and-uniq
|
|
(map symbol->string lst)
|
|
string<?))
|
|
"\n"))
|
|
|
|
(define (dump-builtins name pred extra)
|
|
(format port
|
|
"~a = {\n~a\n}\n\n"
|
|
name
|
|
(dump-py-list (append extra (filter-for pred)))))
|
|
|
|
(define extra-procedures
|
|
;; These are found in RnRS but not implemented by Guile.
|
|
'(load transcript-off transcript-on))
|
|
|
|
(dump-builtins 'scheme_keywords macro? '())
|
|
(dump-builtins 'scheme_builtins procedure? extra-procedures)
|