s) 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. ;;; (define (module-locally-bound? m v) "Is symbol V bound (interned and defined) locally in module M?" (let ((var (module-local-variable m v))) (and var (variable-bound? var)))) (define (module-bound? m v) "Is symbol V bound (interned and defined) anywhere in module M or its uses?" (let ((var (module-variable m v))) (and var (variable-bound? var)))) ;;; {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)) (define (module-symbol-locally-interned? m v) "Is symbol V interned (not neccessarily defined) locally in module M or its uses? Interned symbols shadow inherited bindings even if they are not themselves bound to a defined value." (not (not (module-obarray-get-handle (module-obarray m) v)))) (define (module-symbol-interned? m v) "Is symbol V interned (not neccessarily defined) anywhere in module M or its uses? Interned symbols shadow inherited bindings even if they are not themselves bound to a defined value." (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. ;;; ;;; (This is now written in C, see `modules.c'.) ;;; ;;; {Mapping modules x symbols --> bindings} ;;; ;;; These are similar to the mapping to variables, except that the ;;; variable is dereferenced. ;;; (define (module-symbol-local-binding m v . opt-val) "Return the binding of variable V specified by name within module M, signalling an error if the variable is unbound. If the OPT-VALUE is passed, then instead of signalling an error, return OPT-VALUE." (let ((var (module-local-variable m v))) (if (and var (variable-bound? var)) (variable-ref var) (if (not (null? opt-val)) (car opt-val) (error "Locally unbound variable." v))))) (define (module-symbol-binding m v . opt-val) "Return the binding of variable V specified by name within module M, signalling an error if the variable is unbound. If the OPT-VALUE is passed, then instead of signalling an error, return OPT-VALUE." (let ((var (module-variable m v))) (if (and var (variable-bound? var)) (variable-ref var) (if (not (null? opt-val)) (car opt-val) (error "Unbound variable." v)))))