Compare commits
No commits in common. "a096774fa82598dcc67d31f78b43ef4475b9f8c9" and "2a1c657b9c1fde42c1726f12f3158e1584b7b06c" have entirely different histories.
a096774fa8
...
2a1c657b9c
|
@ -98,8 +98,8 @@ defmodule Day5 do
|
||||||
# IO.inspect(memory)
|
# IO.inspect(memory)
|
||||||
|
|
||||||
case eval(Enum.drop(memory, ip), memory, parent) do
|
case eval(Enum.drop(memory, ip), memory, parent) do
|
||||||
{memory, :halt} ->
|
{_memory, :halt} ->
|
||||||
send(parent, {:halt, self(), memory})
|
send(parent, {:halt, self()})
|
||||||
|
|
||||||
{memory, :cont, offset} ->
|
{memory, :cont, offset} ->
|
||||||
run(memory, parent, ip + offset)
|
run(memory, parent, ip + offset)
|
||||||
|
@ -109,8 +109,8 @@ defmodule Day5 do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def run(memory, parent, _) do
|
def run(_memory, parent, _) do
|
||||||
send(parent, {:ok, self(), memory})
|
send(parent, {:ok, self()})
|
||||||
end
|
end
|
||||||
|
|
||||||
defmacro opcode(op, expected) do
|
defmacro opcode(op, expected) do
|
||||||
|
|
|
@ -214,11 +214,6 @@ defmodule Assembler do
|
||||||
add #{a}, $#{dest}, #{dest}
|
add #{a}, $#{dest}, #{dest}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
assemble_macro ["not", src, dest],
|
|
||||||
"""
|
|
||||||
sub 1, #{src}, #{dest}
|
|
||||||
"""
|
|
||||||
|
|
||||||
assemble_macro ["cle", a, b, dest],
|
assemble_macro ["cle", a, b, dest],
|
||||||
"""
|
"""
|
||||||
clt #{a}, #{b}, #{dest}
|
clt #{a}, #{b}, #{dest}
|
||||||
|
@ -229,15 +224,17 @@ defmodule Assembler do
|
||||||
"""
|
"""
|
||||||
|
|
||||||
assemble_macro ["cgt", a, b, dest],
|
assemble_macro ["cgt", a, b, dest],
|
||||||
"""
|
|
||||||
cle #{a}, #{b}, #{dest}
|
|
||||||
not $#{dest}, #{dest}
|
|
||||||
"""
|
|
||||||
|
|
||||||
assemble_macro ["cge", a, b, dest],
|
|
||||||
"""
|
"""
|
||||||
clt #{a}, #{b}, #{dest}
|
clt #{a}, #{b}, #{dest}
|
||||||
not $#{dest}, #{dest}
|
jnz $#{dest}, false
|
||||||
|
ceq #{a}, #{b}, #{dest}
|
||||||
|
jnz $#{dest}, false
|
||||||
|
mov 1, #{dest}
|
||||||
|
jmp end
|
||||||
|
|
||||||
|
false:
|
||||||
|
mov 0, #{dest}
|
||||||
|
end:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
@ -265,9 +262,9 @@ defmodule Assembler do
|
||||||
iex> Assembler.parse_params(["$1", "2", "3"], [:read, :read, :write])
|
iex> Assembler.parse_params(["$1", "2", "3"], [:read, :read, :write])
|
||||||
{[1, 2, 3], 1000}
|
{[1, 2, 3], 1000}
|
||||||
iex> Assembler.parse_params(["$label", "2", "3"], [:read, :read, :write])
|
iex> Assembler.parse_params(["$label", "2", "3"], [:read, :read, :write])
|
||||||
{[{:expr, ["label"]}, 2, 3], 1000}
|
{[{:expr, "label"}, 2, 3], 1000}
|
||||||
iex> Assembler.parse_params(["1", "label", "3"], [:read, :read, :write])
|
iex> Assembler.parse_params(["1", "label", "3"], [:read, :read, :write])
|
||||||
{[1, {:expr, ["label"]}, 3], 1100}
|
{[1, {:expr, "label"}, 3], 1100}
|
||||||
"""
|
"""
|
||||||
def parse_params(params, param_types) do
|
def parse_params(params, param_types) do
|
||||||
params
|
params
|
||||||
|
|
|
@ -28,31 +28,6 @@ defmodule AssemblerTest do
|
||||||
assert assemble("mov 1, 2") == [1101, 0, 1, 2]
|
assert assemble("mov 1, 2") == [1101, 0, 1, 2]
|
||||||
assert assemble("jmp 2") == [1105, 1, 2]
|
assert assemble("jmp 2") == [1105, 1, 2]
|
||||||
assert assemble("sub 5, 3, res\nres: 0") == [1102, 3, -1, 8, 101, 5, 8, 8, 0]
|
assert assemble("sub 5, 3, res\nres: 0") == [1102, 3, -1, 8, 101, 5, 8, 8, 0]
|
||||||
assert assemble("not 4, 4") == [1102, 4, -1, 4, 101, 1, 4, 4]
|
|
||||||
assert assemble("cle 1, 2, res\nres: 0") == [1107, 1, 2, 11, 1005, 11, 11, 1108, 1, 2, 11, 0]
|
|
||||||
|
|
||||||
assert assemble("cgt 1, 2, res\nres: 0") == [
|
|
||||||
1107,
|
|
||||||
1,
|
|
||||||
2,
|
|
||||||
19,
|
|
||||||
1005,
|
|
||||||
19,
|
|
||||||
11,
|
|
||||||
1108,
|
|
||||||
1,
|
|
||||||
2,
|
|
||||||
19,
|
|
||||||
1002,
|
|
||||||
19,
|
|
||||||
-1,
|
|
||||||
19,
|
|
||||||
101,
|
|
||||||
1,
|
|
||||||
19,
|
|
||||||
19,
|
|
||||||
0
|
|
||||||
]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "assembles simple program" do
|
test "assembles simple program" do
|
||||||
|
|
|
@ -1,120 +0,0 @@
|
||||||
defmodule VMTest do
|
|
||||||
use ExUnit.Case
|
|
||||||
doctest Day5
|
|
||||||
|
|
||||||
def run(prog, io \\ []) do
|
|
||||||
parent = self()
|
|
||||||
|
|
||||||
pid =
|
|
||||||
spawn(fn ->
|
|
||||||
Day5.run(prog, parent)
|
|
||||||
end)
|
|
||||||
|
|
||||||
handle_io(pid, io)
|
|
||||||
|
|
||||||
receive do
|
|
||||||
{:halt, ^pid, memory} ->
|
|
||||||
{:halt, memory}
|
|
||||||
|
|
||||||
{:ok, ^pid, memory} ->
|
|
||||||
{:ok, memory}
|
|
||||||
|
|
||||||
msg ->
|
|
||||||
IO.inspect(msg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_io(_, []), do: :ok
|
|
||||||
|
|
||||||
def handle_io(pid, [head | rest]) do
|
|
||||||
case head do
|
|
||||||
{:in, input} ->
|
|
||||||
receive do
|
|
||||||
{:in, ^pid} -> send(pid, {:in, input})
|
|
||||||
end
|
|
||||||
|
|
||||||
{:out, expected} ->
|
|
||||||
receive do
|
|
||||||
{:out, ^pid, output} -> assert output == expected
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
handle_io(pid, rest)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "exits" do
|
|
||||||
assert run([]) == {:ok, []}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "halts" do
|
|
||||||
assert run([99]) == {:halt, [99]}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "basic position mode instructions" do
|
|
||||||
assert run([1, 3, 2, 3]) == {:ok, [1, 3, 2, 5]}
|
|
||||||
assert run([2, 3, 2, 3]) == {:ok, [2, 3, 2, 6]}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "basic immediate mode instructions" do
|
|
||||||
assert run([1101, 1, 2, 0]) == {:ok, [3, 1, 2, 0]}
|
|
||||||
assert run([1102, 4, 2, 0]) == {:ok, [8, 4, 2, 0]}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "receives input" do
|
|
||||||
assert run([3, 1], in: 1234) == {:ok, [3, 1234]}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "produces output" do
|
|
||||||
assert run([104, 77], out: 77) == {:ok, [104, 77]}
|
|
||||||
assert run([4, 0], out: 4) == {:ok, [4, 0]}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "jump if non-zero" do
|
|
||||||
prog = [1105, 1, 4, 99, 1101, 1, 2, 7]
|
|
||||||
assert run(prog) == {:ok, List.replace_at(prog, 7, 3)}
|
|
||||||
prog = [1105, 0, 4, 99, 1101, 1, 2, 7]
|
|
||||||
assert run(prog) == {:halt, prog}
|
|
||||||
|
|
||||||
prog = [1005, 0, 4, 99, 1101, 1, 2, 7]
|
|
||||||
assert run(prog) == {:ok, List.replace_at(prog, 7, 3)}
|
|
||||||
|
|
||||||
prog = [5, 0, 9, 99, 1101, 1, 2, 7, 99, 4]
|
|
||||||
assert run(prog) == {:halt, List.replace_at(prog, 7, 3)}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "jump if zero" do
|
|
||||||
prog = [1106, 0, 4, 99, 1101, 1, 2, 7]
|
|
||||||
assert run(prog) == {:ok, List.replace_at(prog, 7, 3)}
|
|
||||||
prog = [1106, 42, 4, 99, 1101, 1, 2, 7]
|
|
||||||
assert run(prog) == {:halt, prog}
|
|
||||||
|
|
||||||
prog = [1006, 9, 4, 99, 1101, 1, 2, 7, 99, 0]
|
|
||||||
assert run(prog) == {:halt, List.replace_at(prog, 7, 3)}
|
|
||||||
prog = [6, 9, 10, 99, 1101, 1, 2, 7, 99, 0, 4]
|
|
||||||
assert run(prog) == {:halt, List.replace_at(prog, 7, 3)}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "compare less than" do
|
|
||||||
prog = [1107, 3, 8, 3]
|
|
||||||
assert run(prog) == {:ok, List.replace_at(prog, 3, 1)}
|
|
||||||
prog = [1107, 12, 8, 3]
|
|
||||||
assert run(prog) == {:ok, List.replace_at(prog, 3, 0)}
|
|
||||||
|
|
||||||
prog = [1007, 3, 8, 3]
|
|
||||||
assert run(prog) == {:ok, List.replace_at(prog, 3, 1)}
|
|
||||||
prog = [7, 3, 0, 3]
|
|
||||||
assert run(prog) == {:ok, List.replace_at(prog, 3, 1)}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "compare equal to" do
|
|
||||||
prog = [1108, 4, 4, 3]
|
|
||||||
assert run(prog) == {:ok, List.replace_at(prog, 3, 1)}
|
|
||||||
prog = [1108, 5, 4, 3]
|
|
||||||
assert run(prog) == {:ok, List.replace_at(prog, 3, 0)}
|
|
||||||
|
|
||||||
prog = [1008, 0, 1008, 3]
|
|
||||||
assert run(prog) == {:ok, List.replace_at(prog, 3, 1)}
|
|
||||||
prog = [8, 2, 2, 3]
|
|
||||||
assert run(prog) == {:ok, List.replace_at(prog, 3, 1)}
|
|
||||||
end
|
|
||||||
end
|
|
Loading…
Reference in New Issue