1 defmodule Mix
.Tasks
.Step3Env
do
13 env
= Mal
.Env
.initialize()
14 Mal
.Env
.merge(env
, @initial_env
)
19 IO
.write(:stdio
, "user> ")
20 IO
.read(:stdio
, :line
)
21 |
> read_eval_print(env
)
27 defp
eval_ast({:list
, ast
, meta
}, env
) when
is_list(ast
) do
28 {:list
, Enum
.map(ast
, fn elem
-> eval(elem
, env
) end), meta
}
31 defp
eval_ast({:map
, ast
, meta
}, env
) do
32 map
= for {key
, value} <- ast
, into
: %{} do
33 {eval(key
, env
), eval(value, env
)}
39 defp
eval_ast({:vector
, ast
, meta
}, env
) do
40 {:vector
, Enum
.map(ast
, fn elem
-> eval(elem
, env
) end), meta
}
43 defp
eval_ast({:symbol
, symbol
}, env
) do
44 case Mal
.Env
.get(env
, symbol
) do
46 :not_found
-> throw({:error
, "'#{symbol}' not found"})
50 defp
eval_ast(ast
, _env
), do: ast
53 Mal
.Reader
.read_str(input
)
56 defp
eval_bindings([], _env
), do: _env
57 defp
eval_bindings([{:symbol
, key
}, binding | tail
], env
) do
58 evaluated
= eval(binding
, env
)
59 Mal
.Env
.set(env
, key
, evaluated
)
60 eval_bindings(tail
, env
)
62 defp
eval_bindings(_bindings
, _env
), do: throw({:error
, "Unbalanced let* bindings"})
64 defp
eval({:list
, ast
, meta
}, env
), do: eval_list(ast
, env
, meta
)
65 defp
eval(ast
, env
), do: eval_ast(ast
, env
)
67 defp
eval_list([{:symbol
, "def!"}, {:symbol
, key
}, value], env
, _
) do
68 evaluated
= eval(value, env
)
69 Mal
.Env
.set(env
, key
, evaluated
)
73 defp
eval_list([{:symbol
, "let*"}, {list_type
, bindings
, _
}, body
], env
, _
)
74 when list_type
== :list
or list_type
== :vector
do
75 let_env
= Mal
.Env
.initialize(env
)
76 eval_bindings(bindings
, let_env
)
80 defp
eval_list(ast
, env
, meta
) do
81 {:list
, [func | args
], _
} = eval_ast({:list
, ast
, meta
}, env
)
86 Mal
.Printer
.print_str(value)
89 defp
read_eval_print(:eof
, _env
), do: exit(:normal
)
90 defp
read_eval_print(line
, env
) do
95 {:error
, message
} -> IO
.puts("Error: #{message}")