我正在尝试使用Julia的宏。我特别感兴趣的一件事是,能够在不完全编译代码的情况下提取函数的可达调用图。所谓“可达调用图”,是指在一个函数体内找到的所有潜在可到达的函数,以及这些函数中的函数,依此类推。
例如:
do_something(x::Int) = println(x*2)
do_something(x::String) = println(x)
function foo(a, b)::Bool
do_something_with(a)
do_something_with(b)
return true
end
# Ideally something like this would be accessible from Base
functions_in_codebase = [:do_something, :foo]
# Not correct, but gets the idea across
macro access_call_graph(f)
tokens = f.text.tokens
graph = [f]
for t in tokens
go_deeper = t in functions_in_codebase
!go_deeper && append!(graph, access_call_graph(get_function_for(t))...)
end
return graph
end
access_call_graph(foo)
# Should get something like the following, nesting notwithstanding:
# foo
# do_something, do_something
这个方法有些不够完善,但是能够在解析时访问调用图谱,即使只是潜在可访问的函数,对于我想要做的事情非常有用。如果我必须完全编译代码才能使这种方法起作用,那将会大大削弱其效益。
这种方法是否可行?
@access_call_graph(foo)
。另外,宏只在解析时看到表达式,所以该调用只看到符号:foo
,而不是函数。:foo
肯定不会有.text.tokens
字段。你编写的access_call_graph
的方式更像是运行时操作的函数。这让我想起了函数code_warntype
。宏@code_warntype
更为人所知,但这个宏所做的就是将一个表达式处理成调用函数版本的表达式。 - BatWannaBe