Skip to content

Commit

Permalink
cleanup (#17)
Browse files Browse the repository at this point in the history
* cleanup

* get rid of canonicalize
  • Loading branch information
jw3126 authored Feb 8, 2018
1 parent 75b6a98 commit 0a637bc
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 57 deletions.
59 changes: 18 additions & 41 deletions src/ArgCheck.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,13 @@ function myfunction(k,n,A,B)
end
```
"""
macro argcheck(code,args...)
argcheck(code, args...)
end

function argcheck(ex, args...)
macro argcheck(ex, options...)
if isexpr(ex, :comparison)
argcheck_comparison(ex, args...)
argcheck_comparison(ex, options...)
elseif is_simple_call(ex)
argcheck_call(ex, args...)
argcheck_call(ex, options...)
else
argcheck_fallback(ex, args...)
argcheck_fallback(ex, options...)
end
end

Expand All @@ -41,16 +37,18 @@ function is_simple_call(ex)
true
end

function argcheck_fallback(ex, args...)
function argcheck_fallback(ex, options...)
quote
if !$(esc(ex))
err = ArgCheck.build_error($(QuoteNode(ex)), $(esc.(args)...))
if $(esc(ex))
nothing
else
err = ArgCheck.build_error($(QuoteNode(ex)), $(esc.(options)...))
throw(err)
end
end
end

function argcheck_call(ex, args...)
function argcheck_call(ex, options...)
variables = [gensym() for _ in 1:length(ex.args)]
assignments = map(variables, ex.args) do vi, exi
Expr(:(=), vi, esc(exi))
Expand All @@ -62,7 +60,7 @@ function argcheck_call(ex, args...)
QuoteNode(ex),
QuoteNode(ex.args),
values,
esc.(args)...
esc.(options)...
)
quote
$(assignments...)
Expand All @@ -74,7 +72,7 @@ function argcheck_call(ex, args...)
end
end

function argcheck_comparison(ex, args...)
function argcheck_comparison(ex, options...)
exprs = ex.args[1:2:end]
ops = ex.args[2:2:end]
variables = [gensym() for _ in 1:length(exprs)]
Expand All @@ -94,7 +92,7 @@ function argcheck_comparison(ex, args...)
code = Expr(:call, op, lhs, rhs)
err = Expr(:call, :(ArgCheck.build_error_comparison),
QuoteNode(code), QuoteNode(lhs), QuoteNode(rhs),
vlhs, vrhs, esc.(args)...)
vlhs, vrhs, esc.(options)...)
reti = quote
$assignment
if $condition
Expand All @@ -108,9 +106,9 @@ function argcheck_comparison(ex, args...)
Expr(:block, ret...)
end

function build_error(code, T::Type{<:Exception}, args...)
ret = T(args...)
warn("`@argcheck condition $T $(join(args, ' ')...)` is deprecated. Use `@argcheck condition $ret` instead")
function build_error(code, T::Type{<:Exception}, options...)
ret = T(options...)
warn("`@argcheck condition $T $(join(options, ' ')...)` is deprecated. Use `@argcheck condition $ret` instead")
ret
end
function build_error(code, msg::AbstractString)
Expand All @@ -119,12 +117,12 @@ end
build_error(code, T::Type{<:Exception}=ArgumentError) = T("$code must hold.")
build_error(code, err::Exception) = err

build_error_comparison(code, lhs, rhs, vlhs, vrhs, args...) = build_error(code, args...)
build_error_comparison(code, lhs, rhs, vlhs, vrhs, options...) = build_error(code, options...)
@noinline function build_error_comparison(code, lhs, rhs, vlhs, vrhs, T::Type{<:Exception}=ArgumentError)
build_error_with_fancy_message(code, [lhs, rhs], [vlhs, vrhs], T)
end

build_error_with_fancy_message(code, variables, values, args...) = build_error(code, args...)
build_error_with_fancy_message(code, variables, values, options...) = build_error(code, options...)
@noinline function build_error_with_fancy_message(code, variables, values,
T::Type{<:Exception}=ArgumentError)
msg = fancy_error_message(code, variables, values)
Expand All @@ -148,25 +146,4 @@ function fancy_error_message(code, exprs, values)
unshift!(lines, firstline)
join(lines, '\n')
end

function is_comparison_call(ex)
isexpr(ex, :call) &&
length(ex.args) == 3 &&
is_comparison_op(ex.args[1])
end
is_comparison_op(op) = false
function is_comparison_op(op::Symbol)
precedence = 6 # does this catch all comparisons?
Base.operator_precedence(op) == precedence
end

canonicalize(x) = x
function canonicalize(ex::Expr)
if is_comparison_call(ex)
op, lhs, rhs = ex.args
Expr(:comparison, lhs, op, rhs)
else
ex
end
end
end
16 changes: 0 additions & 16 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,6 @@ macro catch_exception_object(code)
end
end

import ArgCheck: is_comparison_call, canonicalize
@testset "helper functions" begin
@test is_comparison_call(:(1==2))
@test is_comparison_call(:(f(2x) + 1 f(x)))
@test is_comparison_call(:(<(2,3)))
@test is_comparison_call(:(1 2))
@test !is_comparison_call(:(f(1,1)))

ex = :(x1 < x2)
@test canonicalize(ex) != ex
@test canonicalize(ex) == Expr(:comparison, :x1, :(<), :x2)

ex = :(det(x) < y < z)
@test canonicalize(ex) == ex
end

@testset "Chained comparisons" begin
#6
x=y=z = 1
Expand Down

0 comments on commit 0a637bc

Please sign in to comment.