;; Defines a language to be used by info.rkt files. ;; This module cannot use #lang, because reading ;; an "info.rkt" file tries to load this module, and a reader ;; guard disallows anything but `setup/infotab'. (module infotab racket/base (require (for-syntax racket/base)) (define-syntax info-module-begin (lambda (stx) (syntax-case stx () [(mod-beg defn ...) (let ([names (let loop ([defns (syntax->list (syntax (defn ...)))] [r '()]) (if (null? defns) (reverse r) (loop (cdr defns) (syntax-case (car defns) (define) [(define var val) (cons (syntax var) r)] ;; In case it gets expanded: [(define-values (var) val) (cons (syntax var) r)] [(require lib) r] ; ignore these (see below) [_else (raise-syntax-error 'infotab-module "not a well-formed definition" stx (car defns))]))))]) (let ([dup (check-duplicate-identifier names)]) (when dup (raise-syntax-error 'infotab-module "duplicate definition" stx dup))) (with-syntax ([(name ...) names]) (syntax (#%plain-module-begin defn ... (define #%info-lookup (case-lambda [(n) (#%info-lookup n (lambda () (error 'info.rkt "no info for ~a" n)))] [(n fail) (unless (and (procedure? fail) (procedure-arity-includes? fail 0)) (error 'info.rkt "expected second argument to be a procedure that takes no arguments, got: ~e" fail)) (case n [(name) name] ... [else (fail)])])) (define (#%info-domain) '(name ...)) (provide #%info-lookup #%info-domain)))))]))) (define-syntax (limited-require stx) (syntax-case stx () [(_ lib) (member (syntax->datum #'lib) '((lib "string-constant.ss" "string-constants") (lib "string-constants/string-constant.ss") string-constants/string-constant string-constants)) (syntax/loc stx (require lib))])) (provide (rename-out [info-module-begin #%module-begin]) #%app #%datum #%top define quote list cons car cdr quasiquote unquote unquote-splicing list* append reverse string-append path->string build-path collection-path system-library-subpath (rename-out [limited-require require]) lib))