1 /*
2  * module.h - Modules
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 #ifndef GAUCHE_MODULE_H
35 #define GAUCHE_MODULE_H
36 
37 /*
38  * A module keeps "toplevel environment", which maps names of free
39  * variables (symbols) to a location (GLOCs).
40  *
41  * Note on anonymous wrapper modules:  Sometimes, the system
42  * implicitly creates an anonymous module to wrap an original
43  * module to manipulate visibility of bindings.
44  */
45 
46 struct ScmModuleRec {
47     SCM_HEADER;
48     ScmObj name;                /* symbol or #f */
49     ScmObj imported;            /* list of imported modules. */
50     int    exportAll;           /* TRUE if (export-all) */
51     ScmObj parents;             /* direct parent modules */
52     ScmObj mpl;                 /* module precedence list */
53     ScmObj depended;            /* list of modules that are depended by this
54                                    module for compilation */
55     ScmHashTable *internal;     /* Symbol -> GLoc, looked up from this module
56                                    itself and inherited ones */
57     ScmHashTable *external;     /* Symbol -> GLoc, looked up from the modules
58                                    that imports this module.  This table only
59                                    holds exported symbols (it may have
60                                    different name if export renaming is in
61                                    effect) */
62     ScmObj origin;              /* if this module is an anonymous wrapper
63                                    module, this holds a original module.
64                                    this isn't used for resolving bindings,
65                                    but used to avoid duplicating imports. */
66     ScmObj prefix;              /* if symbol, all bindings in this module
67                                    appear to have the prefix.  used in an
68                                    anonymous wrapper modules. */
69     ScmObj info;                /* alist of metainfo; e.g.
70                                    (source-info . <string>) */
71     int    sealed;              /* if true, no modification is allowed */
72     int    placeholding;        /* if true, this module is created just for
73                                    hygienic identifiers, and the module body
74                                    isn't loaded. */
75 };
76 
77 #define SCM_MODULE(obj)       ((ScmModule*)(obj))
78 #define SCM_MODULEP(obj)      SCM_XTYPEP(obj, SCM_CLASS_MODULE)
79 
80 SCM_CLASS_DECL(Scm_ModuleClass);
81 #define SCM_CLASS_MODULE     (&Scm_ModuleClass)
82 
83 SCM_EXTERN ScmObj Scm_MakeModule(ScmSymbol *name, int error_if_exists);
84 
85 /* Flags for Scm_FindBinding (F), MakeBinding (M)
86    and Scm_GlobalVariableRef (R)*/
87 enum {
88     SCM_BINDING_STAY_IN_MODULE = (1L<<0), /*(F,R) do not search parent/imported*/
89     SCM_BINDING_CONST = (1L<<1),          /*(M) constant binding */
90     SCM_BINDING_INLINABLE = (1L<<2),      /*(M) inlinable binding */
91     SCM_BINDING_EXTERNAL = (1L<<3)        /*(F) only search externally visible
92                                             bindings, as if we're importing
93                                             the module.  Currently used to
94                                             create alias binding. */
95 };
96 
97 SCM_EXTERN ScmGloc *Scm_FindBinding(ScmModule *module, ScmSymbol *symbol,
98                                     int flags);
99 SCM_EXTERN ScmGloc *Scm_MakeBinding(ScmModule *module, ScmSymbol *symbol,
100                                     ScmObj value, int flags);
101 SCM_EXTERN ScmObj Scm_GlobalVariableRef(ScmModule *module,
102                                         ScmSymbol *symbol,
103                                         int flags);
104 SCM_EXTERN void   Scm_HideBinding(ScmModule *module, ScmSymbol *symbol);
105 SCM_EXTERN int    Scm_AliasBinding(ScmModule *target, ScmSymbol *targetName,
106                                    ScmModule *origin, ScmSymbol *originName);
107 
108 /* Convenience API.  Wrapper of Scm_MakeBinding. */
109 SCM_EXTERN ScmObj Scm_Define(ScmModule *module,
110                              ScmSymbol *symbol,
111                              ScmObj value);
112 SCM_EXTERN ScmObj Scm_DefineConst(ScmModule *module,
113                                   ScmSymbol *symbol,
114                                   ScmObj value);
115 
116 
117 SCM_EXTERN ScmObj Scm_ExtendModule(ScmModule *module, ScmObj supers);
118 SCM_EXTERN ScmObj Scm_ImportModule(ScmModule *module, ScmObj imported,
119                                    ScmObj prefix, u_long flags);
120 SCM_EXTERN ScmObj Scm_ImportModules(ScmModule *module, ScmObj list);/*deprecated*/
121 SCM_EXTERN ScmObj Scm_ExportSymbols(ScmModule *module, ScmObj list);
122 SCM_EXTERN ScmObj Scm_ExportAll(ScmModule *module);
123 SCM_EXTERN ScmModule *Scm_FindModule(ScmSymbol *name, int flags);
124 SCM_EXTERN ScmObj Scm_AllModules(void);
125 SCM_EXTERN void   Scm_SelectModule(ScmModule *mod);
126 SCM_EXTERN ScmObj Scm_ModuleExports(ScmModule *mod);
127 
128 SCM_EXTERN void   Scm_ModuleSeal(ScmModule *mod);
129 
130 /* Flags for Scm_FindModule
131    NB: Scm_FindModule's second arg has been changed since 0.8.6;
132    before, it was just a boolean value to indicate whether a new
133    module should be created (TRUE) or not (FALSE).  We added a
134    new flag value to make Scm_FindModule raises an error if the named
135    module doesn't exist.  This change should be transparent as far
136    as the caller's using Gauche's definition of TRUE. */
137 enum {
138     SCM_FIND_MODULE_CREATE = (1L<<0), /* Create if there's no named module */
139     SCM_FIND_MODULE_QUIET  = (1L<<1), /* Do not signal an error if there's no
140                                          named module, but return NULL
141                                          instead. */
142     SCM_FIND_MODULE_PLACEHOLDING = (1L<<2) /* If module is newly created,
143                                               mark it as placeholding. */
144 };
145 
146 #define SCM_FIND_MODULE(name, flags) \
147     Scm_FindModule(SCM_SYMBOL(SCM_INTERN(name)), flags)
148 
149 SCM_EXTERN ScmObj Scm_ModuleNameToPath(ScmSymbol *name);
150 SCM_EXTERN ScmObj Scm_PathToModuleName(ScmString *path);
151 
152 SCM_EXTERN ScmModule *Scm_NullModule(void);
153 SCM_EXTERN ScmModule *Scm_SchemeModule(void);
154 SCM_EXTERN ScmModule *Scm_GaucheModule(void);
155 SCM_EXTERN ScmModule *Scm_UserModule(void);
156 SCM_EXTERN ScmModule *Scm_CurrentModule(void);
157 
158 #define SCM_DEFINE(module, cstr, val)           \
159     Scm_Define(SCM_MODULE(module),              \
160                SCM_SYMBOL(SCM_INTERN(cstr)),    \
161                SCM_OBJ(val))
162 
163 /* OBSOLETED */
164 #define Scm_SymbolValue(m, s) Scm_GlobalVariableRef(m, s, FALSE)
165 /* OBSOLETED */
166 #define SCM_SYMBOL_VALUE(module_name, symbol_name)                      \
167     Scm_SymbolValue(SCM_FIND_MODULE(module_name, 0),                    \
168                     SCM_SYMBOL(SCM_INTERN(symbol_name)))
169 
170 
171 #endif /*GAUCHE_MODULE_H*/
172 
173