Current section
Files
Jump to
Current section
Files
lib/constant_propagation.ex
defmodule Honey.ConstantPropagation do
def is_constant(item) do
is_number(item) or is_bitstring(item) or is_atom(item) or is_binary(item) or is_boolean(item) or
is_nil(item)
end
def run(ast) do
# {_version, _kind, _metadata, [clause | _other_clauses]} = fun_def
# {_metadata, _arguments, _guards, ast} = clause
# IO.puts("======== Printing using Macro.postwalk\n")
{new_ast, _constants} =
Macro.postwalk(ast, Keyword.new(), fn segment, constants ->
# IO.inspect(segment)
{new_segment, constants} =
case segment do
{:=, _meta, [lhs, rhs]} ->
if(is_constant(rhs)) do
{var_name, meta, context} = lhs
var_version =
String.to_atom(
Atom.to_string(var_name) <> to_string(meta[:version]) <> to_string(context)
)
constants = Keyword.put(constants, var_version, rhs)
{rhs, constants}
else
{segment, constants}
end
{{:., _, [:erlang, :+]}, _, [lhs, rhs]} ->
if(is_constant(lhs) and is_constant(rhs)) do
{lhs + rhs, constants}
else
{segment, constants}
end
{{:., _, [:erlang, :-]}, _, [lhs, rhs]} ->
if(is_constant(lhs) and is_constant(rhs)) do
{lhs - rhs, constants}
else
{segment, constants}
end
{{:., _, [:erlang, :*]}, _, [lhs, rhs]} ->
if(is_constant(lhs) and is_constant(rhs)) do
{lhs * rhs, constants}
else
{segment, constants}
end
{{:., _, [:erlang, :/]}, _, [lhs, rhs]} ->
if(is_constant(lhs) and is_constant(rhs)) do
{lhs / rhs, constants}
else
{segment, constants}
end
{{:., _, [:erlang, :==]}, _, [lhs, rhs]} ->
if(is_constant(lhs) and is_constant(rhs)) do
{lhs == rhs, constants}
else
{segment, constants}
end
{var_name, meta, context} ->
if(is_atom(var_name) and is_atom(context)) do
var_version =
String.to_atom(
Atom.to_string(var_name) <> to_string(meta[:version]) <> to_string(context)
)
case Keyword.fetch(constants, var_version) do
{:ok, const} ->
{const, constants}
:error ->
{segment, constants}
end
else
{segment, constants}
end
_ ->
{segment, constants}
end
# IO.write(" AST: ")
# IO.inspect(new_segment)
{new_segment, constants}
end)
# IO.puts("\n =======New AST after Constant propagation:")
# IO.inspect(new_ast)
new_ast
end
end