;; 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