Skip to content

Instantly share code, notes, and snippets.

@fcard
Last active February 7, 2017 20:39
Show Gist options
  • Select an option

  • Save fcard/4b887503a6313c410292c243d7223717 to your computer and use it in GitHub Desktop.

Select an option

Save fcard/4b887503a6313c410292c243d7223717 to your computer and use it in GitHub Desktop.
Muladd macro revised
macro muladd(ex)
esc(to_muladd(ex))
end
function to_muladd(ex)
is_add_operation(ex) || return ex
all_operands = ex.args[2:end]
mul_operands = filter(is_mul_operation, all_operands)
odd_operands = filter(x->!is_mul_operation(x), all_operands)
muladd_operands = collect(zip(
to_muladd.((x->x.args[2]).(mul_operands)),
to_muladd.((x->x.args[3]).(mul_operands))))
if isempty(odd_operands)
to_be_muladded = muladd_operands[1:end-1]
last_operation = :($(muladd_operands[end][1]) * $(muladd_operands[end][2]))
else
to_be_muladded = muladd_operands
last_operation = make_addition(odd_operands)
end
foldr(last_operation, to_be_muladded) do xs, r
:($(Base.muladd)($(xs[1]), $(xs[2]), $r))
end
end
is_operation(ex::Expr, op::Symbol) = ex.head == :call && !isempty(ex.args) && ex.args[1] == op
is_operation(ex, op::Symbol) = false
is_add_operation(ex) = is_operation(ex, :+)
is_mul_operation(ex) = is_operation(ex, :*)
make_addition(args) = length(args) == 1 ? args[1] : Expr(:call, :+, args...)
using Base.Test
macro test_muladd(expr, expected)
esc(
quote
@test $(muladd_string(expected)) == $(string(macroexpand(:(@muladd($expr)))))
@test @muladd($expr) == $expr
end
)
end
function muladd_string(expr)
replacement = replace(string(:($muladd(1,2,3))), r"^(..*?)\(.*\)$", s"\1")
replace(string(expr), "muladd", replacement)
end
let a=1,b=2,c=3,d=4, x=10,y=20,z=30
@test_muladd (a*b) (a*b)
@test_muladd (a*b + c*d) (muladd(a,b,c*d))
@test_muladd (a*b + c*d + x*y) (muladd(a,b, muladd(c,d, x*y)))
@test_muladd (a*b + z*(c*d + x*y)) (muladd(a,b, z*(muladd(c,d,x*y))))
@test_muladd (a*b + c*d + z) (muladd(a,b, muladd(c, d, z)))
end
@fcard

fcard commented Feb 2, 2017 •

Copy link
Copy Markdown
Author

^^^under MIT license

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment