1 /* 2 * gloc.h - Public API for Scheme glocs 3 * 4 * Copyright (c) 2000-2020 Shiro Kawai <shiro@acm.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the authors nor the names of its contributors 18 * may be used to endorse or promote products derived from this 19 * software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* This file is included from gauche.h */ 35 36 #ifndef GAUCHE_GLOC_H 37 #define GAUCHE_GLOC_H 38 39 struct ScmGlocRec { 40 SCM_HEADER; 41 ScmSymbol *name; 42 ScmModule *module; 43 ScmObj value; /* The actual value. Have to be accessed 44 via SCM_GLOC_{GET|SET} macros. */ 45 char hidden; /* TRUE if this is a "negative binding", 46 see below. */ 47 ScmObj (*getter)(ScmGloc *); /* see 'hooks' below */ 48 ScmObj (*setter)(ScmGloc *, ScmObj); /* see 'hooks' below */ 49 }; 50 51 /* About negative binding: 52 * 53 * Negative binding is a dummy binding inserted in an intermediate 54 * anonymous module created by 'import' form, to realize :except 55 * and :rename modifiers. It *never* occurs in modules created 56 * explicitly by define-module form or make-module procedure. 57 * 58 * While Scm_FindBinding searches imported modules and parent modules, 59 * if it finds negative binding, it stop searching for the MPL chain 60 * currently it is looking at. In other word, a negative binding 61 * has an effect to remove the inherited binding from the exported list. 62 * 63 * About phantom binding. 64 * 65 * A binding may be inserted either by definition or export special 66 * forms. We don't know which comes first. If we've seen only an 67 * 'export' form but not an actual definition, the GLOC of the binding 68 * has value SCM_UNBOUND, and indicates it is a phantom binding. 69 * 70 * When we meet a phantom binding during searching a binding of a symbol, 71 * we recursively search the symbol from the module where the phantom 72 * bindings are in, and returns bound GLOC if found. 73 * 74 * Example: 75 * (define-module a (export foo) (define foo 1)) 76 * (define-module b (import a) (export foo)) 77 * Suppose we (import b) and then access 'foo'. We search the import 78 * chain and find a phantom binding of 'foo' in #<module b>. 79 * In this case, we search 'foo' from #<module b>, and find a gloc 80 * from #<module a>, which is returned as the result of the search. 81 * 82 * This makes it easy to create a transitive module, that doesn't 83 * define bindings by itself, but exports subset of imported bindings. 84 * 85 * Hooks (getter and setter) 86 * All reference and modification of toplevel binding go through 87 * SCM_GLOC_GET/SET macros, which check getter and setter handlers. 88 * These handlers allow to hook global variable reference. They 89 * are reserved for internal use; its' not for application-level 90 * abstraction. As of 0.9, getter is not used, and setter is only 91 * used to check the attempt of modifying constant bindings. 92 * Future plans include some kind of debugging facility. 93 */ 94 95 SCM_CLASS_DECL(Scm_GlocClass); 96 #define SCM_CLASS_GLOC (&Scm_GlocClass) 97 98 #define SCM_GLOC(obj) ((ScmGloc*)(obj)) 99 #define SCM_GLOCP(obj) SCM_XTYPEP(obj, SCM_CLASS_GLOC) 100 101 #define SCM_GLOC_GET(gloc) \ 102 ((gloc)->getter? (gloc)->getter(gloc) : (gloc)->value) 103 #define SCM_GLOC_SET(gloc, val) \ 104 ((gloc)->setter? (gloc)->setter((gloc), (val)) : ((gloc)->value = (val))) 105 106 #define SCM_GLOC_PHANTOM_BINDING_P(gloc) SCM_UNBOUNDP((gloc)->value) 107 108 SCM_EXTERN int Scm_GlocConstP(ScmGloc *g); 109 SCM_EXTERN int Scm_GlocInlinableP(ScmGloc *g); 110 111 /* INTERNAL */ 112 113 SCM_EXTERN ScmObj Scm_MakeGloc(ScmSymbol *sym, ScmModule *module); 114 /* flags may be 0, SCM_BINDING_CONST, or SCM_BINDING_INLINABLE. */ 115 SCM_EXTERN void Scm_GlocMark(ScmGloc *g, int flags); 116 SCM_EXTERN ScmObj Scm_GlocConstSetter(ScmGloc *g, ScmObj val); 117 SCM_EXTERN ScmObj Scm_GlocInlinableSetter(ScmGloc *g, ScmObj val); 118 119 /* For ABI compatibility. Should be gone at api1.0. */ 120 #define SCM_GLOC_CONST_P(gloc) ((gloc)->setter == Scm_GlocConstSetter) 121 SCM_EXTERN ScmObj Scm_GlocMarkConst(ScmGloc *g); 122 SCM_EXTERN ScmObj Scm_GlocUnmarkConst(ScmGloc *g); 123 124 #endif /* GAUCHE_GLOC_H */ 125 126