Skip to content

Commit

Permalink
Add @iv_str macro (#177)
Browse files Browse the repository at this point in the history
* add `iv_str` macro

* add tests for `iv_str` macro

* add more tests
  • Loading branch information
hyrodium authored Feb 6, 2024
1 parent bf4c78b commit 3d6c446
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/IntervalSets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ using Base: @pure
import Base: eltype, convert, show, in, length, isempty, isequal, isapprox, issubset, ==, hash,
union, intersect, minimum, maximum, extrema, range, clamp, mod, float, , ,

export AbstractInterval, Interval, OpenInterval, ClosedInterval,
export AbstractInterval, Interval, OpenInterval, ClosedInterval, @iv_str,
, .., ±, ordered, width, leftendpoint, rightendpoint, endpoints,
isopenset, isclosedset, isleftclosed, isrightclosed,
isleftopen, isrightopen, closedendpoints,
Expand Down
27 changes: 27 additions & 0 deletions src/interval.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,33 @@ Interval(i::AbstractInterval) = Interval{isleftclosed(i) ? (:closed) : (:open),
isrightclosed(i) ? (:closed) : (:open)}(i)
Interval(i::TypedEndpointsInterval{L,R}) where {L,R} = Interval{L,R}(i)

macro iv_str(s)
msg = "Invalid expresson `$s`"
for (reg, f) (
(r"^\[(.*)\)$", Interval{:closed, :open}),
(r"^\((.*)\)$", Interval{:open, :open}),
(r"^\((.*)\]$", Interval{:open, :closed}),
(r"^\[(.*)\]$", Interval{:closed, :closed}),
)
m = match(reg, s)
if !isnothing(m)
try
args = Meta.parse("("*m.captures[1]*",)")
if args.head === :incomplete
return :(throw(ErrorException("$($msg)")))
elseif length(args.args) 2
return :(throw(ErrorException("$($msg)")))
else
return :($f($(esc(args))...))
end
catch
return :(throw(ErrorException("$($msg)")))
end
end
end
return :(throw(ErrorException("$($msg)")))
end

endpoints(i::Interval) = (i.left, i.right)

for L in (:(:open),:(:closed)), R in (:(:open),:(:closed))
Expand Down
24 changes: 24 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,30 @@ struct IncompleteInterval <: AbstractInterval{Int} end
@test ordered(1, 2) == (1, 2)
@test ordered(Float16(1), 2) == (1, 2)

@testset "iv_str macro" begin
@test iv"[1,2]" === 1..2
@test iv"[1,2)" === Interval{:closed, :open}(1, 2)
@test iv"(1,2]" === Interval{:open, :closed}(1, 2)
@test iv"(1,2)" === OpenInterval(1, 2)

for (a,b) in ((1,2), (1.4,3.9), (ℯ,π))
@test iv"[a,b]" === a..b
@test iv"[a,b)" === Interval{:closed, :open}(a, b)
@test iv"(a,b]" === Interval{:open, :closed}(a, b)
@test iv"(a,b)" === OpenInterval(a, b)
end

@test_throws Exception iv"[(1,2)]"
@test_throws Exception iv"[1,2,]"
@test_throws Exception iv"[(1,2]"
@test_throws Exception iv"[(1,,2]"
@test_throws Exception iv"[1..2]"
@test_throws Exception iv"(1..2)"
@test_throws Exception iv"[1...2]"
@test_throws Exception iv"(1...2)"
@test_throws Exception iv"1..2"
end

@testset "Basic Closed Sets" begin
@test_throws ErrorException :a .. "b"
@test_throws ErrorException 1 .. missing
Expand Down

0 comments on commit 3d6c446

Please sign in to comment.