Skip to content

Instantly share code, notes, and snippets.

@ggggggggg
Last active October 18, 2017 22:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ggggggggg/31fbf2adc5a1d2a582ab9dffe196be64 to your computer and use it in GitHub Desktop.
Save ggggggggg/31fbf2adc5a1d2a582ab9dffe196be64 to your computer and use it in GitHub Desktop.
macros to parse code to use different types
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