summaryrefslogtreecommitdiffstats
path: root/external/scheme-builtins-generator.scm
diff options
context:
space:
mode:
Diffstat (limited to 'external/scheme-builtins-generator.scm')
-rw-r--r--external/scheme-builtins-generator.scm116
1 files changed, 116 insertions, 0 deletions
diff --git a/external/scheme-builtins-generator.scm b/external/scheme-builtins-generator.scm
new file mode 100644
index 0000000..5c260b8
--- /dev/null
+++ b/external/scheme-builtins-generator.scm
@@ -0,0 +1,116 @@
+;; 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)