📄 boot-9.scm
字号:
(make-string (- 30 (string-length left-part)) #\ ) "\n\t"))) (display left-part) (display middle-part) (display help) (newline)))) kw-desc))(define (transform-usage-lambda cases) (let* ((raw-usage (delq! 'else (map car cases))) (usage-sans-specials (map (lambda (x) (or (and (not (list? x)) x) (and (symbol? (car x)) #t) (and (boolean? (car x)) #t) x)) raw-usage)) (usage-desc (delq! #t usage-sans-specials)) (kw-desc (map car usage-desc)) (kw-opts (apply append (map (lambda (x) (and (not (string? (car x))) x)) kw-desc))) (kw-args (apply append (map (lambda (x) (and (string? (car x)) (cdr x))) kw-desc))) (transmogrified-cases (map (lambda (case) (cons (let ((opts (car case))) (if (or (boolean? opts) (eq? 'else opts)) opts (cond ((symbol? (car opts)) opts) ((boolean? (car opts)) opts) ((string? (caar opts)) (cdar opts)) (else (car opts))))) (cdr case))) cases))) `(let ((%display-usage (lambda () (display-usage-report ',usage-desc)))) (lambda (%argv) (let %next-arg ((%argv %argv)) (get-option %argv ',kw-opts ',kw-args (lambda (%opt %arg %new-argv) (case %opt ,@ transmogrified-cases))))))));;; {Low Level Modules};;;;;; These are the low level data structures for modules.;;;;;; !!! warning: The interface to lazy binder procedures is going;;; to be changed in an incompatible way to permit all the basic;;; module ops to be virtualized.;;;;;; (make-module size use-list lazy-binding-proc) => module;;; module-{obarray,uses,binder}[|-set!];;; (module? obj) => [#t|#f];;; (module-locally-bound? module symbol) => [#t|#f];;; (module-bound? module symbol) => [#t|#f];;; (module-symbol-locally-interned? module symbol) => [#t|#f];;; (module-symbol-interned? module symbol) => [#t|#f];;; (module-local-variable module symbol) => [#<variable ...> | #f];;; (module-variable module symbol) => [#<variable ...> | #f];;; (module-symbol-binding module symbol opt-value);;; => [ <obj> | opt-value | an error occurs ];;; (module-make-local-var! module symbol) => #<variable...>;;; (module-add! module symbol var) => unspecified;;; (module-remove! module symbol) => unspecified;;; (module-for-each proc module) => unspecified;;; (make-scm-module) => module ; a lazy copy of the symhash module;;; (set-current-module module) => unspecified;;; (current-module) => #<module...>;;;;;;;;; {Printing Modules};; This is how modules are printed. You can re-define it.;; (Redefining is actually more complicated than simply redefining;; %print-module because that would only change the binding and not;; the value stored in the vtable that determines how record are;; printed. Sigh.)(define (%print-module mod port) ; unused args: depth length style table) (display "#<" port) (display (or (module-kind mod) "module") port) (let ((name (module-name mod))) (if name (begin (display " " port) (display name port)))) (display " " port) (display (number->string (object-address mod) 16) port) (display ">" port));; module-type;;;; A module is characterized by an obarray in which local symbols;; are interned, a list of modules, "uses", from which non-local;; bindings can be inherited, and an optional lazy-binder which;; is a (CLOSURE module symbol) which, as a last resort, can provide;; bindings that would otherwise not be found locally in the module.;;;; NOTE: If you change here, you also need to change libguile/modules.h.;;(define module-type (make-record-type 'module '(obarray uses binder eval-closure transformer name kind observers weak-observers observer-id) %print-module));; make-module &opt size uses binder;;;; Create a new module, perhaps with a particular size of obarray,;; initial uses list, or binding procedure.;;(define make-module (lambda args (define (parse-arg index default) (if (> (length args) index) (list-ref args index) default)) (if (> (length args) 3) (error "Too many args to make-module." args)) (let ((size (parse-arg 0 1021)) (uses (parse-arg 1 '())) (binder (parse-arg 2 #f))) (if (not (integer? size)) (error "Illegal size to make-module." size)) (if (not (and (list? uses) (and-map module? uses))) (error "Incorrect use list." uses)) (if (and binder (not (procedure? binder))) (error "Lazy-binder expected to be a procedure or #f." binder)) (let ((module (module-constructor (make-vector size '()) uses binder #f #f #f #f '() (make-weak-value-hash-table 31) 0))) ;; We can't pass this as an argument to module-constructor, ;; because we need it to close over a pointer to the module ;; itself. (set-module-eval-closure! module (standard-eval-closure module)) module))))(define module-constructor (record-constructor module-type))(define module-obarray (record-accessor module-type 'obarray))(define set-module-obarray! (record-modifier module-type 'obarray))(define module-uses (record-accessor module-type 'uses))(define set-module-uses! (record-modifier module-type 'uses))(define module-binder (record-accessor module-type 'binder))(define set-module-binder! (record-modifier module-type 'binder));; NOTE: This binding is used in libguile/modules.c.(define module-eval-closure (record-accessor module-type 'eval-closure))(define module-transformer (record-accessor module-type 'transformer))(define set-module-transformer! (record-modifier module-type 'transformer))(define module-name (record-accessor module-type 'name))(define set-module-name! (record-modifier module-type 'name))(define module-kind (record-accessor module-type 'kind))(define set-module-kind! (record-modifier module-type 'kind))(define module-observers (record-accessor module-type 'observers))(define set-module-observers! (record-modifier module-type 'observers))(define module-weak-observers (record-accessor module-type 'weak-observers))(define module-observer-id (record-accessor module-type 'observer-id))(define set-module-observer-id! (record-modifier module-type 'observer-id))(define module? (record-predicate module-type))(define set-module-eval-closure! (let ((setter (record-modifier module-type 'eval-closure))) (lambda (module closure) (setter module closure) ;; Make it possible to lookup the module from the environment. ;; This implementation is correct since an eval closure can belong ;; to maximally one module. (set-procedure-property! closure 'module module))))(begin-deprecated (define (eval-in-module exp mod) (issue-deprecation-warning "`eval-in-module' is deprecated. Use `eval' instead.") (eval exp mod)));;; {Observer protocol};;;(define (module-observe module proc) (set-module-observers! module (cons proc (module-observers module))) (cons module proc))(define (module-observe-weak module proc) (let ((id (module-observer-id module))) (hash-set! (module-weak-observers module) id proc) (set-module-observer-id! module (+ 1 id)) (cons module id)))(define (module-unobserve token) (let ((module (car token)) (id (cdr token))) (if (integer? id) (hash-remove! (module-weak-observers module) id) (set-module-observers! module (delq1! id (module-observers module))))) *unspecified*)(define (module-modified m) (for-each (lambda (proc) (proc m)) (module-observers m)) (hash-fold (lambda (id proc res) (proc m)) #f (module-weak-observers m)));;; {Module Searching in General};;;;;; We sometimes want to look for properties of a symbol;;; just within the obarray of one module. If the property;;; holds, then it is said to hold ``locally'' as in, ``The symbol;;; DISPLAY is locally rebound in the module `safe-guile'.'';;;;;;;;; Other times, we want to test for a symbol property in the obarray;;; of M and, if it is not found there, try each of the modules in the;;; uses list of M. This is the normal way of testing for some;;; property, so we state these properties without qualification as;;; in: ``The symbol 'fnord is interned in module M because it is;;; interned locally in module M2 which is a member of the uses list;;; of M.'';;;;; module-search fn m;;;; return the first non-#f result of FN applied to M and then to;; the modules in the uses of m, and so on recursively. If all applications;; return #f, then so does this function.;;(define (module-search fn m v) (define (loop pos) (and (pair? pos) (or (module-search fn (car pos) v) (loop (cdr pos))))) (or (fn m v) (loop (module-uses m))));;; {Is a symbol bound in a module?};;;;;; Symbol S in Module M is bound if S is interned in M and if the binding;;; of S in M has been set to some well-defined value.;;;;; module-locally-bound? module symbol;;;; Is a symbol bound (interned and defined) locally in a given module?;;(define (module-locally-bound? m v) (let ((var (module-local-variable m v))) (and var (variable-bound? var))));; module-bound? module symbol;;;; Is a symbol bound (interned and defined) anywhere in a given module;; or its uses?;;(define (module-bound? m v) (module-search module-locally-bound? m v));;; {Is a symbol interned in a module?};;;;;; Symbol S in Module M is interned if S occurs in;;; of S in M has been set to some well-defined value.;;;;;; It is possible to intern a symbol in a module without providing;;; an initial binding for the corresponding variable. This is done;;; with:;;; (module-add! module symbol (make-undefined-variable));;;;;; In that case, the symbol is interned in the module, but not;;; bound there. The unbound symbol shadows any binding for that;;; symbol that might otherwise be inherited from a member of the uses list.;;;(define (module-obarray-get-handle ob key) ((if (symbol? key) hashq-get-handle hash-get-handle) ob key))(define (module-obarray-ref ob key) ((if (symbol? key) hashq-ref hash-ref) ob key))(define (module-obarray-set! ob key val) ((if (symbol? key) hashq-set! hash-set!) ob key val))(define (module-obarray-remove! ob key) ((if (symbol? key) hashq-remove! hash-remove!) ob key));; module-symbol-locally-interned? module symbol;;;; is a symbol interned (not neccessarily defined) locally in a given module;; or its uses? Interned symbols shadow inherited bindings even if;; they are not themselves bound to a defined value.;;(define (module-symbol-locally-interned? m v) (not (not (module-obarray-get-handle (module-obarray m) v))));; module-symbol-interned? module symbol;;;; is a symbol interned (not neccessarily defined) anywhere in a given module;; or its uses? Interned symbols shadow inherited bindings even if;; they are not themselves bound to a defined value.;;(define (module-symbol-interned? m v) (module-search module-symbol-locally-interned? m v));;; {Mapping modules x symbols --> variables};;;;; module-local-variable module symbol;; return the local variable associated with a MODULE and SYMBOL.;;;;; This function is very important. It is the only function that can;;; return a variable from a module other than the mutators that store;;; new variables in modules. Therefore, this function is the location;;; of the "lazy binder" hack.;;;;;; If symbol is defined in MODULE, and if the definition binds symbol;;; to a variable, return that variable object.;;;;;; If the symbols is not found at first, but the module has a lazy binder,;;; then try the binder.;;;;;; If the symbol is not found at all, return #f.;;;(define (module-local-variable m v); (caddr; (list m v (let ((b (module-obarray-ref (module-obarray m) v))) (or (and (variable? b) b) (and (module-binder m) ((module-binder m) m v #f)))));));; module-variable module symbol;;;; like module-local-variable, except search the uses in the;; case V is not found in M.;;;; NOTE: This function is superseded with C code (see modules.c);;; when using the standard eval closure.;;(define (module-variable m v) (module-search module-local-variable m v));;; {Mapping modules x symbols --> bindings};;;;;; These are similar to the mapping to variables, except that the;;; variable is dereferenced.;;;;; module-symbol-binding module symbol opt-value;;;; return the binding of a variable specified by name within;; a given module, signalling an error if the variable is unbound.;; If the OPT-VALUE is passed, then instead of signalling an error,;; return OPT-VALUE.;;(define (module-symbol-local-binding m v . opt-val) (let ((var (module-local-variable m v))) (if var (variable-ref var) (if (not (null? opt-val)) (car opt-val) (error "Locally unbound variable." v)))));; module-symbol-binding module symbol opt-value;;;; return the binding of a variable specified by name within;; a given module, signalling an error if the variable is unbound.;; If the OPT-VALUE is passed, then instead of signalling an error,;; return OPT-VALUE.;;(define (module-symbol-binding m v . opt-val) (let ((var (module-variable m v))) (if var (variable-ref var) (if (not (null? opt-val)) (car opt-val) (error "Unbound variable." v)))));;; {Adding Variables to Modules};;;;;;;; module-make-local-var! module symbol;;;; ensure a variable for V in the local namespace of M.;; If no variable was already there, then create a new and uninitialzied;; variable.;;(define (module-make-local-var! m v) (or (let ((b (module-obarray-ref (module-obarray m) v))) (and (variable? b) (begin (module-modified m) b))) (and (module-binder m) ((module-binder m) m v #t)) (begin (let ((answer (make-undefined-variable))) (variable-set-name-hint! answer v) (module-obarray-set! (module-obarray m) v answer) (module-modified m) answer))));; module-ensure-local-variable! module symbol;;;; Ensure that there is a local variable in MODULE for SYMBOL. If;; there is no binding for SYMBOL, create a new uninitialized;; variable. Return the local variable.;;(define (module-ensure-local-variable! module symbol) (or (module-local-variable module symbol) (let ((var (make-undefined-variable))) (variable-set-name-hint! var symbol) (module-add! module symbol var) var)))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -