-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathMetaModule.jl
More file actions
78 lines (61 loc) · 2.11 KB
/
MetaModule.jl
File metadata and controls
78 lines (61 loc) · 2.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
module MetaModule
using ...Dispatch.Applications
using ...Dispatch.TopMetaTables
using ...Dispatch
import Base.Meta: quot
export @metamodule
const MM = Dispatch.Applications.MACROMETHODS
const MF = Dispatch.Applications.METAFUNCTIONS
#-----------------------------------------------------------------------------------
# @metamodule
#-----------------------------------------------------------------------------------
@macromethod metamodule(:R{:import, *{path}}) esc(importcode(path, __module__))
@macromethod metamodule(:R{:importall, *{path}}) esc(importallcode(path))
@macromethod metamodule(:R{:export, *{names}}) esc(exportcode(names, __module__))
@macromethod metamodule(:R{:toplevel}) nothing
@macromethod metamodule(:R{:toplevel,x,*{xs}}) esc(quote
@metamodule $x
@metamodule $(Expr(:toplevel, xs...))
end)
#-----------------------------------------------------------------------------------
# Code generation.
#-----------------------------------------------------------------------------------
function importcode(path, mod)
name = last(path)
top = gettable(path[end])
quote
import $(path...)
import $(path[1:end-1]...).($(path[end-1]))
$(import_metatable!)($top, $(quot(name)), $(path[end-1]), $mod)
end
end
exportcode(names, mod) = quote
eval(:(export $($names...)))
for name in $names
top = $gettable(name)
$(export_metatable!)(top, name, $mod)
end
end
function importallcode(path)
M = path[end]
quote
eval(Expr(:import, $path..., $(quot(M))))
metafun_exports = $metatable_exports($MM, $M)
macromet_exports = $metatable_exports($MF, $M)
for exp in $union(metafun_exports, macromet_exports)
imp = Expr(:import, $vcat($path, exp)...)
eval($macrocall_ex("@metamodule", imp))
end
end
end
#-----------------------------------------------------------------------------------
# Utility functions.
#-----------------------------------------------------------------------------------
gettable(name) =
startswith(string(name), "@") ? MM : MF
function macrocall_ex(name, args...)
ex = :(@x $(args...))
ex.args[1] = Symbol(name)
ex
end
end