Skip to content

Instantly share code, notes, and snippets.

@mendess

mendess/match.jl Secret

Last active May 21, 2020 21:11
Show Gist options
  • Save mendess/fbb980026431e4d07a9cf30ea2daea25 to your computer and use it in GitHub Desktop.
Save mendess/fbb980026431e4d07a9cf30ea2daea25 to your computer and use it in GitHub Desktop.
match julia
module Match
export @match
macro match(item, arms)
var = gensym(:var)
quote
let $var = $(esc(item))
$(begin
code = :nothing
for e in reverse(filter((e) -> e isa Expr, arms.args))
code = make_match(var, e, code, item) # need to pass the original expr for a comparison in make_match
end
code
end)
end
end
end
function make_match(item, e, code, original)
(pattern, value) = e.args[2:3]
value = replace_underscore(value, item)
test = if pattern == :_ || pattern == original
:true
elseif hasproperty(pattern, :args) && pattern.args[1] == :(:)
(lower, upper) = pattern.args[2:3]
:($(esc(lower)) <= $(item) && $(item) <= $(esc(upper)))
else
:($(item) == $(esc(pattern)))
end
quote
if $test
$(esc(value))
else
$code
end
end
end
replace_underscore(value, item) = value == :_ ? item : value
replace_underscore(values::AbstractArray, item) = [replace_underscore(x, item) for x in values]
replace_underscore(value::Expr, item) = begin
Expr(replace_underscore(value.head, item), replace_underscore(value.args, item)...)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment