Intcode assembler: allow data label values to be expressions
This commit is contained in:
parent
a096774fa8
commit
431af67bb1
|
@ -63,7 +63,7 @@ defmodule Day5 do
|
|||
])
|
||||
end
|
||||
|
||||
def run_cli(memory) do
|
||||
def run_cli(memory, opts \\ []) do
|
||||
parent = self()
|
||||
|
||||
proc =
|
||||
|
@ -71,23 +71,33 @@ defmodule Day5 do
|
|||
run(memory, parent)
|
||||
end)
|
||||
|
||||
Process.monitor(proc)
|
||||
handle_cli_messages(proc)
|
||||
handle_cli_messages(proc, opts)
|
||||
end
|
||||
|
||||
def handle_cli_messages(proc) do
|
||||
def handle_cli_messages(proc, opts) do
|
||||
receive do
|
||||
{:DOWN, _, _, _, _} ->
|
||||
IO.puts("Exited")
|
||||
{:halt, _, memory} ->
|
||||
if Keyword.get(opts, :memory, false) do
|
||||
memory
|
||||
else
|
||||
:ok
|
||||
end
|
||||
|
||||
{:ok, _, memory} ->
|
||||
if Keyword.get(opts, :memory, false) do
|
||||
memory
|
||||
else
|
||||
:ok
|
||||
end
|
||||
|
||||
{:in, _} ->
|
||||
res = IO.gets("intcode> ") |> String.trim() |> String.to_integer()
|
||||
send(proc, {:in, res})
|
||||
handle_cli_messages(proc)
|
||||
handle_cli_messages(proc, opts)
|
||||
|
||||
{:out, _, out} ->
|
||||
IO.puts("Output: #{out}")
|
||||
handle_cli_messages(proc)
|
||||
handle_cli_messages(proc, opts)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -18,20 +18,15 @@ defmodule Assembler do
|
|||
|> ignore(ascii_char([?:]))
|
||||
|> ignore(repeat(ascii_char([?\s])))
|
||||
|
||||
data_label =
|
||||
label
|
||||
|> choice([
|
||||
integer(min: 1),
|
||||
ignore(ascii_char([?-]))
|
||||
|> integer(min: 1)
|
||||
|> tag(:neg)
|
||||
])
|
||||
|> tag(:data_label)
|
||||
|
||||
param =
|
||||
optional(ignore(ascii_string([?\s], min: 1)))
|
||||
|> ascii_string([{:not, ?,}], min: 1)
|
||||
|
||||
data_label =
|
||||
label
|
||||
|> concat(param)
|
||||
|> tag(:data_label)
|
||||
|
||||
instruction =
|
||||
ignore(ascii_string([?\s, ?\t], min: 0))
|
||||
|> ascii_string([?a..?z], min: 1)
|
||||
|
@ -63,7 +58,13 @@ defmodule Assembler do
|
|||
|> Enum.with_index()
|
||||
|> Enum.map(fn
|
||||
{{:expr, expr}, index} ->
|
||||
expr_tokens = if is_binary(expr), do: ExpressionEvaluator.parse(expr), else: expr
|
||||
expr_tokens =
|
||||
if is_binary(expr) do
|
||||
{:ok, tokens, _, _, _, _} = ExpressionEvaluator.parse(expr)
|
||||
tokens
|
||||
else
|
||||
expr
|
||||
end
|
||||
|
||||
ExpressionEvaluator.do_eval(expr_tokens, fn
|
||||
"_self" -> index
|
||||
|
@ -134,11 +135,7 @@ defmodule Assembler do
|
|||
end
|
||||
|
||||
def assemble_line([data_label: [name, value]], {memory, labels}) do
|
||||
value =
|
||||
case value do
|
||||
{:neg, [val]} -> -val
|
||||
val when is_integer(val) -> val
|
||||
end
|
||||
value = {:expr, value}
|
||||
|
||||
{
|
||||
[value | memory],
|
||||
|
@ -197,6 +194,15 @@ defmodule Assembler do
|
|||
[99 | memory]
|
||||
end
|
||||
|
||||
def assemble_insn(["data" | data], memory) do
|
||||
data =
|
||||
data
|
||||
|> Enum.map(&String.to_integer/1)
|
||||
|> Enum.reverse()
|
||||
|
||||
data ++ memory
|
||||
end
|
||||
|
||||
# macros
|
||||
assemble_macro ["mov", src, dest],
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue