diff --git a/src/SwapSort.jl b/src/SwapSort.jl index afcb5e3..644d453 100644 --- a/src/SwapSort.jl +++ b/src/SwapSort.jl @@ -6,6 +6,7 @@ export swapsort, tuplesort include("consts.jl") include("utils.jl") +include("core.jl") """ swapsort(a...; lt=isless, by=identity) diff --git a/src/core.jl b/src/core.jl new file mode 100644 index 0000000..3573a77 --- /dev/null +++ b/src/core.jl @@ -0,0 +1,26 @@ +macro makesorter(expr) + path = string(eval(expr)) + sorterdict = JSON.parsefile(path) + N = sorterdict["N"] + L = sorterdict["L"] + D = sorterdict["D"] + funname = "swapsort$(N)_$(L)_$(D)" + ret = Meta.parse("function $funname(;kw...) end") + for k in 0:N-1 + push!(ret.args[1].args, localval(k)) + end + functionbody = ret.args[2].args + for (a,b) in sorterdict["nw"] + push!(functionbody, compswap(a,b)) + end + push!(functionbody, returnvals(N)) + return ret +end + +macro registersorter(expr) + (N,L,D) = eval(expr) + ret = Expr(:block) + push!(ret.args, Meta.parse("swapsort($(varstring(N)); kw...) = swapsort$(N)_$(L)_$(D)($(varstring(N)); kw...)")) + push!(ret.args, Meta.parse("tuplesort(I::Tuple{Vararg{Any, $N}}; kw...) = swapsort$(N)_$(L)_$(D)(I...; kw...)")) + esc(ret) +end \ No newline at end of file diff --git a/src/utils.jl b/src/utils.jl index 5ab2f41..0708481 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -5,10 +5,32 @@ The same as `Base.minmax`, but supports `lt` and `by` keywords which works as th """ min_max(x, y; lt=isless, by=identity) = lt(by(x), by(y)) ? (x,y) : (y,x) +""" + varstring(N) + +Returns the string of argument list "a0,a1,...,a(N-1)". +""" varstring(N) = string("a0", [",a$k" for k in 1:N-1]...) + +""" + _filename(N,L,D) + +The file that contains the infomation of constructing `swapsortN_L_D`. +""" _filename(N,L,D) = "Sort_$(N)_$(L)_$(D).json" + +""" + keywords() + +The expression `kw...` in a function definition. +""" keywords() = Expr(:parameters, Expr(:(...), :kw)) +""" + returnvals(N) + +The expression `return a1, a2, ..., a(N-1)`. +""" function returnvals(N) ret = Expr(:return, Expr(:tuple)) for k in 0:N-1 @@ -16,32 +38,18 @@ function returnvals(N) end ret end + +""" + localval(i) + +The `i`-th variable name `ai`. +""" localval(i) = Symbol("a$i") -compswap(i,j) = Expr(:(=), Expr(:tuple, localval(i), localval(j)), Expr(:call, :min_max, keywords(), localval(i), localval(j))) -macro makesorter(expr) - path = string(eval(expr)) - sorterdict = JSON.parsefile(path) - N = sorterdict["N"] - L = sorterdict["L"] - D = sorterdict["D"] - funname = "swapsort$(N)_$(L)_$(D)" - ret = Meta.parse("function $funname(;kw...) end") - for k in 0:N-1 - push!(ret.args[1].args, localval(k)) - end - functionbody = ret.args[2].args - for (a,b) in sorterdict["nw"] - push!(functionbody, compswap(a,b)) - end - push!(functionbody, returnvals(N)) - return ret -end +""" + compswap(i,j) + +The expression `ai, aj = min_max(ai, aj; kw...)` +""" +compswap(i,j) = Expr(:(=), Expr(:tuple, localval(i), localval(j)), Expr(:call, :min_max, keywords(), localval(i), localval(j))) -macro registersorter(expr) - (N,L,D) = eval(expr) - ret = Expr(:block) - push!(ret.args, Meta.parse("swapsort($(varstring(N)); kw...) = swapsort$(N)_$(L)_$(D)($(varstring(N)); kw...)")) - push!(ret.args, Meta.parse("tuplesort(I::Tuple{Vararg{Any, $N}}; kw...) = swapsort$(N)_$(L)_$(D)(I...; kw...)")) - esc(ret) -end \ No newline at end of file