Skip to content

Commit

Permalink
Add @! macro
Browse files Browse the repository at this point in the history
  • Loading branch information
tkf committed Aug 27, 2019
1 parent 91c6ac7 commit 6c73b66
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/BangBang.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module BangBang
@doc read(joinpath(dirname(@__DIR__), "README.md"), String) BangBang

export
@!,
append!!,
delete!!,
empty!!,
Expand All @@ -29,6 +30,7 @@ include("core.jl")
include("base.jl")
include("linearalgebra.jl")
include("initials.jl")
include("macro.jl")

function __init__()
@require StaticArrays="90137ffa-7385-5640-81b9-e52037218182" begin
Expand Down
10 changes: 10 additions & 0 deletions src/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ pure(::typeof(pushfirst!)) = NoBang.pushfirst
pure(::typeof(_setproperty!)) = NoBang.setproperty
pure(::typeof(mul!)) = NoBang.mul

_maybb(mutate) = something(_asbb(mutate), mutate)
_asbb(::Any) = nothing

_asbb(::typeof(push!)) = push!!
_asbb(::typeof(append!)) = append!!
_asbb(::typeof(pushfirst!)) = pushfirst!!
_asbb(::typeof(mul!)) = mul!!
_asbb(::typeof(delete!)) = delete!!
_asbb(::typeof(empty!)) = empty!!

const MaybeMutableContainer = Union{
AbstractArray,
AbstractDict,
Expand Down
24 changes: 24 additions & 0 deletions src/macro.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""
@! expr
Convert all supported mutating calls to double bang equivalent.
# Examples
```jldoctest
julia> using BangBang
julia> @! push!(empty!((0, 1)), 2, 3)
(2, 3)
```
"""
macro !(expr)
foldexpr(expr) do x
if Meta.isexpr(x, :call)
return Expr(:call, Expr(:call, _maybb, x.args[1]), x.args[2:end]...)
end
return x
end |> esc
end

foldexpr(f, x) = x
foldexpr(f, ex::Expr) = f(Expr(ex.head, foldexpr.(f, ex.args)...))
10 changes: 10 additions & 0 deletions test/test_macro.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module TestMacro

include("preamble.jl")

@testset begin
@test (@! push!(empty!([0, 1]), 2, 3)) == [2, 3]
@test (@! push!(empty!((0, 1)), 2, 3)) == (2, 3)
end

end # module

0 comments on commit 6c73b66

Please sign in to comment.