Toolset for modifying Julia AST
This package is a general purpose toolkit intended for manipulations of Julia's AST. It contains methods like linefilter!
, callcount
, genfun
, genlatest
, and exprval
.
Certain useful expression transformations are also possible, such as the SyntaxTree.sub
method to convert scalar values to a single type, SyntaxTree.abs
to apply Base.abs
to all scalars and operations, and also SyntaxTree.alg
to introduce an algebraic machine epsilon bound at each operation.
The exprval
method to compute the expression value is defined in "Optimal polynomial characteristic methods" by Michael Reed in 2018 with the supporting expravg
and exprdev
methods to compute scalar averages and standard deviations for expressions. The expression value can be used to order equivalent forms of an expression, where lower values are more optimal and computationally efficient.
Recursively filter out :LineNumberNode
from Expr
objects:
julia> expr = quote
x = 7
y = x^2
end
quote
#= REPL[3]:2 =#
x = 7
#= REPL[3]:3 =#
y = x ^ 2
end
julia> linefilter!(expr)
quote
x = 7
y = x ^ 2
end
Substitute numerical values with type conversion:
julia> SyntaxTree.sub(Float64,:(2x^2-1//2))
:(2.0 * x ^ 2 - 1.0 // 2.0)
Apply abs
to an expression recursively:
julia> SyntaxTree.abs(:(2x^2-1//2))
:(2 * x ^ 2 + 1 // 2)
Recursively insert a machine epsilon bound (1+ϵ)
per call:
julia> SyntaxTree.alg(:(2x^2-1//2))
:((1 + ϵ) * ((1 + ϵ) * (2 * ((1 + ϵ) * x ^ 2)) - (1 + ϵ) * 1 // 2))
Return an anonymous function given expr
and args
julia> a = @genfun x^2-y^2 x y
#3 (generic function with 1 method)
julia> a(5,4)
9
julia> b = genfun(:(x^2-y^2),[:x,:y])
#1 (generic function with 1 method)
julia> b(5,4)
9
Optionally, genlatest
or @genlatest
can be used if Base.invokelatest
is needed.
Obtain the number of call
operations in an expression:
julia> callcount(:(2x^2-1//2))
4
Recursively obtain the number of scalars in an expression, the average of those scalars, the number of non-trivial exponents in the expression, and the average of the exponents.
julia> SyntaxTree.expravg(:(2x^2-1//2))
(3, 0.7954314537066303, 1, 2.0)
Get the standard deviation of the logarithm of the scalars in an expression:
julia> SyntaxTree.exprdev(:(2x^2-1//2))
0.22136580504842668
Compute the expression value and other characteristics:
julia> SyntaxTree.exprval(:(2x^2-1//2))
(4.89405674908118, 4, 0.4704952763295575, 0.7954314537066303, 2.0)
The first value is the expression value, the second is the number of operations, the third is the standard deviation of the logarithms of the scalars, the fourth is the average of the logarithms of the scalars, and the fifth is the average of the exponents.