summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@dashbit.co>2021-12-03 18:56:24 +0100
committerJosé Valim <jose.valim@dashbit.co>2021-12-03 18:56:32 +0100
commitabc23d00c4a9bbafcf08237ed64f93e175196bfa (patch)
tree5cb263ac838e31aa26508ed63e1f36a62bc00a46
parent0db4f426c7deca2cf5db8206dfc80b472e90e465 (diff)
downloadelixir-abc23d00c4a9bbafcf08237ed64f93e175196bfa.tar.gz
Decouple parser state from buffer in IEx
-rw-r--r--lib/iex/lib/iex/evaluator.ex16
-rw-r--r--lib/iex/lib/iex/server.ex18
-rw-r--r--lib/iex/test/iex/autocomplete_test.exs2
3 files changed, 18 insertions, 18 deletions
diff --git a/lib/iex/lib/iex/evaluator.ex b/lib/iex/lib/iex/evaluator.ex
index ed03059a8..9c8d36ae8 100644
--- a/lib/iex/lib/iex/evaluator.ex
+++ b/lib/iex/lib/iex/evaluator.ex
@@ -166,8 +166,8 @@ defmodule IEx.Evaluator do
defp loop(%{server: server, ref: ref} = state) do
receive do
{:eval, ^server, code, iex_state} ->
- {result, state} = eval(code, iex_state, state)
- send(server, {:evaled, self(), result})
+ {result, status, state} = eval(code, iex_state, state)
+ send(server, {:evaled, self(), status, result})
loop(state)
{:fields_from_env, ^server, ref, receiver, fields} ->
@@ -270,27 +270,27 @@ defmodule IEx.Evaluator do
defp eval(code, iex_state, state) do
try do
{parser_module, parser_fun, args} = IEx.Config.parser()
- args = [code, [line: iex_state.counter, file: "iex"], iex_state.buffer | args]
+ args = [code, [line: iex_state.counter, file: "iex"], iex_state.parser_state | args]
do_eval(apply(parser_module, parser_fun, args), iex_state, state)
catch
kind, error ->
print_error(kind, error, __STACKTRACE__)
- {%{iex_state | buffer: ""}, state}
+ {%{iex_state | parser_state: ""}, :ok, state}
end
end
- defp do_eval({:ok, forms, buffer}, iex_state, state) do
+ defp do_eval({:ok, forms, parser_state}, iex_state, state) do
put_history(state)
put_whereami(state)
state = handle_eval(forms, iex_state.counter, state)
- {%{iex_state | buffer: buffer, counter: iex_state.counter + 1}, state}
+ {%{iex_state | parser_state: parser_state, counter: iex_state.counter + 1}, :ok, state}
after
Process.delete(:iex_history)
Process.delete(:iex_whereami)
end
- defp do_eval({:incomplete, buffer}, iex_state, state) do
- {%{iex_state | buffer: buffer}, state}
+ defp do_eval({:incomplete, parser_state}, iex_state, state) do
+ {%{iex_state | parser_state: parser_state}, :incomplete, state}
end
defp put_history(%{history: history}) do
diff --git a/lib/iex/lib/iex/server.ex b/lib/iex/lib/iex/server.ex
index bd465b626..5e4fe2c1a 100644
--- a/lib/iex/lib/iex/server.ex
+++ b/lib/iex/lib/iex/server.ex
@@ -2,7 +2,7 @@ defmodule IEx.State do
@moduledoc false
# This state is exchanged between IEx.Server and
# IEx.Evaluator which is why it is a struct.
- defstruct buffer: "",
+ defstruct parser_state: "",
counter: 1,
prefix: "iex",
on_eof: :stop_evaluator,
@@ -89,7 +89,7 @@ defmodule IEx.Server do
)
evaluator = start_evaluator(opts)
- loop(iex_state(opts), evaluator, Process.monitor(evaluator))
+ loop(iex_state(opts), :ok, evaluator, Process.monitor(evaluator))
end
# Starts an evaluator using the provided options.
@@ -121,12 +121,12 @@ defmodule IEx.Server do
run_without_registration(opts)
end
- defp loop(state, evaluator, evaluator_ref) do
+ defp loop(state, prompt, evaluator, evaluator_ref) do
self_pid = self()
counter = state.counter
{prompt_type, prefix} =
- if state.buffer != "" do
+ if prompt == :incomplete do
{:continuation_prompt, "..."}
else
{:prompt, state.prefix}
@@ -151,7 +151,7 @@ defmodule IEx.Server do
# Triggered by pressing "i" as the job control switch
{:input, ^input, {:error, :interrupted}} ->
io_error("** (EXIT) interrupted")
- loop(%{state | buffer: ""}, evaluator, evaluator_ref)
+ loop(%{state | parser_state: ""}, :new, evaluator, evaluator_ref)
# Triggered when IO dies while waiting for input
{:input, ^input, {:error, :terminated}} ->
@@ -166,8 +166,8 @@ defmodule IEx.Server do
defp wait_eval(state, evaluator, evaluator_ref) do
receive do
- {:evaled, ^evaluator, new_state} ->
- loop(new_state, evaluator, evaluator_ref)
+ {:evaled, ^evaluator, status, new_state} ->
+ loop(new_state, status, evaluator, evaluator_ref)
msg ->
handle_take_over(msg, state, evaluator, evaluator_ref, nil, fn state ->
@@ -204,7 +204,7 @@ defmodule IEx.Server do
if take_over?(take_pid, take_ref, true) do
kill_input(input)
take_opts = Keyword.put(take_opts, :previous_state, state)
- loop(iex_state(take_opts), evaluator, evaluator_ref)
+ loop(iex_state(take_opts), :ok, evaluator, evaluator_ref)
else
callback.(state)
end
@@ -233,7 +233,7 @@ defmodule IEx.Server do
Process.exit(evaluator, :kill)
Process.demonitor(evaluator_ref, [:flush])
evaluator = start_evaluator(state.evaluator_options)
- loop(%{state | buffer: ""}, evaluator, Process.monitor(evaluator))
+ loop(%{state | parser_state: ""}, :ok, evaluator, Process.monitor(evaluator))
end
defp handle_take_over(
diff --git a/lib/iex/test/iex/autocomplete_test.exs b/lib/iex/test/iex/autocomplete_test.exs
index e35ea0b52..876ba2ce5 100644
--- a/lib/iex/test/iex/autocomplete_test.exs
+++ b/lib/iex/test/iex/autocomplete_test.exs
@@ -14,7 +14,7 @@ defmodule IEx.AutocompleteTest do
evaluator = Process.get(:evaluator)
Process.group_leader(evaluator, Process.group_leader())
send(evaluator, {:eval, self(), line <> "\n", %IEx.State{}})
- assert_receive {:evaled, _, _}
+ assert_receive {:evaled, _, _, _}
end)
end