Last active
October 18, 2017 22:35
-
-
Save ggggggggg/31fbf2adc5a1d2a582ab9dffe196be64 to your computer and use it in GitHub Desktop.
macros to parse code to use different types
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using MacroTools, Base.Test | |
"@parsetype T ex | |
replace all numeric literals that are supertypes of `T` with type `T`" | |
macro parsetype(Tsym, ex) | |
T=getfield(Main, Tsym) | |
ST=parsesuper(T) | |
parsetype(T, ST, ex) | |
end | |
"@parsetype (T1,T2,..) ex | |
as @parsetype for each type in first argument, which must be a tuple" | |
macro parsetypes(tuple_ex, ex) | |
for Tsym in tuple_ex.args | |
T=getfield(Main, Tsym) | |
ST=parsesuper(T) | |
ex = parsetype(T,ST,ex) | |
end | |
ex | |
end | |
parsesuper(::Type{T}) where T= supertype(T) | |
parsesuper(::Type{T<:Integer}) where T = Integer | |
function parsetype(::Type{T},::Type{ST},ex::Expr) where {ST,T<:ST} | |
MacroTools.postwalk(x->typeof(x)<:ST ? T(x) : x, ex) | |
end | |
"@parsefunction f T ex | |
places T as the first argument of all calls to `f` | |
doesn't yet check if it already has a type as first argument | |
or even check if `f` matches `fin`" | |
macro parsefunction(fin,Tsym,ex) | |
dump(ex) | |
T=getfield(Main, Tsym) | |
MacroTools.postwalk(ex) do x | |
@capture(x, f_(xs__)) || return x | |
return quote $f($Tsym,$(xs...)) end | |
end | |
end | |
@test 2 == @parsetype Int8 1+1 | |
@test Int8 == typeof(@parsetype Int8 1+1) | |
@test 2 == @parsetype Float16 1.0+1.0 | |
@test Float16 == typeof(@parsetype Float16 1.0+1.0) | |
@test (Float16,Int8) == @parsetypes (Int8,Float16) typeof(1.0),typeof(1) | |
@test eltype(@parsefunction rand Float32 rand(3,3)) == Float32 | |
@test size(@parsefunction rand Float32 rand(3,3)) == (3,3) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment