@@ -80,23 +80,28 @@ const _cur_mod = V6_COMPAT ? :( current_module() ) : :( @__MODULE__ )
8080"""
8181macro api (cmd:: Symbol )
8282 cmd == :init && return _api_init ()
83- cmd == :freeze && return _api_freeze ()
83+ cmd == :freeze && return esc ( _api_freeze () )
8484 cmd == :list && return _api_list ()
8585 error (" @api unrecognized command: $cmd " )
8686end
8787
88+ function _api_display (api, chain)
89+ show (api)
90+ println ()
91+ show (chain)
92+ println ()
93+ end
94+
8895function _api_display (mod)
89- if isdefined (mod, :__api__ )
90- show (eval (mod, :__api__ ))
91- show (eval (mod, :__chain__ ))
92- end
93- if isdefined (mod, :__tmp_api__ )
94- show (eval (mod, :__tmp_api__ ))
95- show (eval (mod, :__tmp_chain__ ))
96- end
96+ isdefined (mod, :__api__ ) &&
97+ _api_display (eval (mod, :__api__ ), eval (mod, :__chain__ ))
98+ isdefined (mod, :__tmp_api__ ) &&
99+ _api_display (eval (mod, :__tmp_api__ ), eval (mod, :__tmp_chain__ ))
97100 nothing
98101end
99102
103+ _api_freeze (mod, api, chain) = APIList (push! (chain, API (mod, api)))
104+
100105_api_init () =
101106 quote
102107 export @api , APITools
@@ -105,14 +110,13 @@ _api_init() =
105110 end
106111
107112_api_freeze () =
108- esc (quote
109- const __api__ = APITools. API ($ _cur_mod, __tmp_api__)
110- push! (__tmp_chain__, __api__)
111- const __chain__ = APITools. APIList (__tmp_chain__)
112- __tmp_chain__ = _tmp_api__ = nothing
113- end )
113+ quote
114+ global const __chain__ = APITools. _api_freeze ($ _cur_mod, __tmp_api__, __tmp_chain__)
115+ global const __api__ = __chain__[end ]
116+ __tmp_chain__ = __tmp_api__ = nothing
117+ end
114118
115- _api_list (mod = _cur_mod) = :( _api_display ($ mod) )
119+ _api_list (mod = _cur_mod) = :( APITools . _api_display ($ mod) )
116120
117121const _cmduse = (:use , :test , :extend , :export )
118122const _cmdadd =
@@ -121,30 +125,43 @@ const _cmdadd =
121125@static V6_COMPAT && (const _ff = findfirst)
122126@static V6_COMPAT || (_ff (lst, val) = coalesce (findfirst (isequal (val), lst), 0 ))
123127
124- _add_def! (deflst, explst, sym) = (push! (deflst, sym); push! (explst, esc (:(function $ sym end ))))
125-
126- """ Conditionally define functions, or import from Base"""
127- function _maybe_public (exprs)
128- implst = Symbol[]
129- deflst = Symbol[]
130- explst = isdefined (eval (_cur_mod), :__tmp_api__ ) ? Expr[] : Expr[_api_init ()]
131- for ex in exprs
132- if isa (ex, Expr) && ex. head == :tuple
133- for sym in ex. args
134- isa (sym, Symbol) || error (" @api $grp : $sym not a Symbol" )
135- isdefined (Base, sym) ? push! (implst, sym) : _add_def! (deflst, explst, sym)
136- end
137- elseif isa (ex, Symbol)
138- isdefined (Base, ex) ? push! (implst, ex) : _add_def! (deflst, explst, ex)
139- else
140- error (" @api $grp : syntax error $ex " )
141- end
128+ function _add_def! (deflst, implst, explst, sym)
129+ if isdefined (Base, sym)
130+ push! (implst, sym)
131+ else
132+ push! (deflst, sym)
133+ push! (explst, esc (:(function $ sym end )))
142134 end
143- isempty (deflst) || push! (explst, esc (:( append! (__tmp_api__. public, $ deflst))))
144- Expr (:toplevel , _add_symbols (:base , implst)... , explst... )
145135end
146136
137+ """ Add symbols"""
147138function _add_symbols (grp, exprs)
139+ print (" _add_symbols($grp , $exprs )" )
140+ outlst = Expr[:(isdefined ($ _cur_mod, :__tmp_api__ ) || APITools. _api_init ())]
141+ println (" => " , outlst)
142+ outlst = Expr[]
143+ if grp == :maybe_public
144+ implst = Symbol[]
145+ deflst = Symbol[]
146+ for ex in exprs
147+ if isa (ex, Expr) && ex. head == :tuple
148+ for sym in ex. args
149+ isa (sym, Symbol) || error (" @api $grp : $sym not a Symbol" )
150+ _add_def! (deflst, implst, outlst, sym)
151+ end
152+ elseif isa (ex, Symbol)
153+ _add_def! (deflst, implst, outlst, ex)
154+ else
155+ error (" @api $grp : syntax error $ex " )
156+ end
157+ end
158+ isempty (deflst) ||
159+ push! (outlst, Expr (:call , :push! ,
160+ Expr (:., :__tmp_api__ , QuoteNode (:public )),
161+ QuoteNode .(deflst)... ))
162+ exprs = implst
163+ grp = :base
164+ end
148165 symbols = Symbol[]
149166 for ex in exprs
150167 if isa (ex, Expr) && ex. head == :tuple
@@ -155,46 +172,52 @@ function _add_symbols(grp, exprs)
155172 error (" @api $grp : syntax error $ex " )
156173 end
157174 end
158- lst = isdefined ( eval (_cur_mod), :__tmp_api__ ) ? Expr[] : Expr[ _api_init ()]
175+ println ( " symbols: " , symbols)
159176 if grp == :base
160177 syms = SymList (symbols)
161178 expr = " APITools._make_list($(QuoteNode (:import )) , $(QuoteNode (:Base )) , $syms )"
162- push! (lst, :(eval ($ _cur_mod, $ (Meta. parse (expr)))))
179+ push! (outlst, esc ( :(eval ($ _cur_mod, $ (Meta. parse (expr) )))))
163180 end
164- Expr (:toplevel , lst... , esc (:( append! (__tmp_api__.$ grp, $ symbols) )))
181+ push! (outlst, Expr (:call , :push! ,
182+ Expr (:., :__tmp_api__ , QuoteNode (grp)), QuoteNode .(symbols)... ))
183+ println (outlst)
184+ outlst
165185end
166186
167- function _make_modules (exprs)
187+ function _make_modules (cmd, exprs)
168188 uselst = Expr[]
169189 modlst = Symbol[]
170190 for ex in exprs
171191 if isa (ex, Expr) && ex. head == :tuple
172192 append! (modlst, ex. args)
173- for sym in ex. args ; push! (uselst, :(using $ sym)) ; end
193+ for sym in ex. args ; push! (uselst, :(import $ sym)) ; end
174194 elseif isa (ex, Symbol)
175195 push! (modlst, ex)
176- push! (uselst, :(using $ ex))
196+ push! (uselst, :(import $ ex))
177197 else
178198 error (" @api $cmd : syntax error $ex " )
179199 end
180200 end
181201 uselst, modlst
182202end
183203
184- macro api (cmd:: Symbol , exprs... )
204+ function _api (cmd, exprs)
185205 ind = _ff (_cmdadd, cmd)
186- ind == 0 || return cmd == :maybe_public ? _maybe_public (exprs) : _add_symbols (cmd, exprs)
206+ ind == 0 || return esc ( Expr ( :toplevel , _add_symbols (cmd, exprs), nothing ) )
187207
188208 ind = _ff (_cmduse, cmd)
189209
190- lst, modules = _make_modules (exprs)
210+ lst, modules = _make_modules (cmd, exprs)
191211
192212 cmd == :export &&
193213 return esc (Expr (:toplevel , lst... ,
194- [:(eval (Expr ( :export , $ mod. __api__.$ grp... )))
195- for mod in modules, grp in (:define_module , :define_public , :public )]. .. ))
214+ [:(eval ($ _cur_mod, Expr ( :export , $ mod. __api__.$ grp... )))
215+ for mod in modules, grp in (:define_module , :define_public , :public )]. .. ,
216+ nothing ))
196217 cmd == :list &&
197- return Expr (:toplevel , [:(eval (Expr (:call , :_api_display , $ mod))) for mod in modules]. .. )
218+ return Expr (:toplevel ,
219+ [:(eval ($ _cur_mod, APITools. _api_display ($ mod))) for mod in modules]. .. ,
220+ nothing )
198221
199222 for mod in modules
200223 push! (lst, _make_module_exprs (mod))
@@ -209,7 +232,8 @@ macro api(cmd::Symbol, exprs...)
209232 grplst = (:define_public , :define_develop )
210233 # should add unique modules to __tmp_chain__
211234 for mod in modules
212- push! (lst, :(in ($ mod. __api__, __tmp_chain__) || push! (__tmp_chain__, $ mod. __api__)))
235+ push! (lst,
236+ esc (:(in ($ mod. __api__, __tmp_chain__) || push! (__tmp_chain__, $ mod. __api__))))
213237 end
214238 for mod in modules, grp in (:base , :public , :develop )
215239 push! (lst, _make_exprs (:import , mod, grp))
@@ -220,19 +244,21 @@ macro api(cmd::Symbol, exprs...)
220244 for mod in modules, grp in grplst
221245 push! (lst, _make_exprs (:using , mod, grp))
222246 end
223- esc (Expr (:toplevel , lst... ))
247+ esc (Expr (:toplevel , lst... , nothing ))
224248end
225249
250+ macro api (cmd:: Symbol , exprs... ) ; _api (cmd, exprs) ; end
251+
226252# We need Expr(:toplevel, (Expr($cmd, $mod, $sym) for sym in $mod.__api__.$grp)...)
227253
228254function _make_module_list (mod, lst)
229255 isempty (lst) && return nothing
230256 length (lst) == 1 ? :(import $ mod.$ (lst[1 ])) :
231- Expr (:toplevel , [:(import $ mod.$ nam) for nam in lst]. .. )
257+ Expr (:toplevel , [:(import $ mod.$ nam) for nam in lst]. .. , nothing )
232258end
233259
234260_make_module_exprs (mod) =
235- :(eval ($ (Meta. parse (" APITools._make_module_list($(QuoteNode (mod)) , $mod .__api__.define_module)" ))))
261+ :(eval ($ _cur_mod, $ (Meta. parse (" APITools._make_module_list($(QuoteNode (mod)) , $mod .__api__.define_module)" ))))
236262
237263function _make_list (cmd, mod, lst)
238264 isempty (lst) && return nothing
246272
247273function _make_exprs (cmd, mod, grp)
248274 from = QuoteNode (grp == :base ? :Base : mod)
249- :(eval ($ (Meta. parse (" APITools._make_list($(QuoteNode (cmd)) , $from , $mod .__api__.$grp )" ))))
275+ :(eval ($ _cur_mod,
276+ $ (Meta. parse (" APITools._make_list($(QuoteNode (cmd)) , $from , $mod .__api__.$grp )" ))))
250277end
251278
252279end # module APITools
0 commit comments