1 defmodule Mix
.Tasks
.Step3Env
do
10 {:ok
, env
} = Mal
.Env
.initialize()
11 Mal
.Env
.merge(env
, @initial_env
)
16 IO
.write(:stdio
, "user> ")
17 IO
.read(:stdio
, :line
)
18 |
> read_eval_print(env
)
23 def
eval_ast(ast
, env
) when
is_list(ast
) do
24 Enum
.map(ast
, fn elem
-> eval(elem
, env
) end)
27 def
eval_ast({:symbol
, symbol
}, env
) do
28 case Mal
.Env
.get(env
, symbol
) do
30 :not_found
-> throw({:error
, "invalid symbol #{symbol}"})
34 def
eval_ast(ast
, _env
), do: ast
37 Mal
.Reader
.read_str(input
)
40 defp
eval_bindings([], _env
), do: _env
41 defp
eval_bindings([{:symbol
, key
}, binding | tail
], env
) do
42 evaluated
= eval(binding
, env
)
43 Mal
.Env
.set(env
, key
, evaluated
)
44 eval_bindings(tail
, env
)
46 defp
eval_bindings(_bindings
, _env
), do: throw({:error
, "Unbalanced let* bindings"})
49 def
eval([{:symbol
, "def!"}, {:symbol
, key
}, value], env
) do
50 evaluated
= eval(value, env
)
51 Mal
.Env
.set(env
, key
, evaluated
)
55 def
eval([{:symbol
, "let*"}, bindings
, body
], env
) do
56 {:ok
, let_env
} = Mal
.Env
.initialize(env
)
57 eval_bindings(bindings
, let_env
)
61 def
eval(ast
, env
) when
is_list(ast
) do
62 [func | args
] = eval_ast(ast
, env
)
66 def
eval(ast
, env
), do: eval_ast(ast
, env
)
69 IO
.puts(Mal
.Printer
.print_str(value))
72 def
read_eval_print(:eof
, _env
), do: exit(0)
73 def
read_eval_print(line
, env
) do
78 {:error
, message
} -> IO
.puts("Error: #{message}")