@@ -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