Compare commits
1 Commits
b60c9a9a63
...
e3b8847e24
Author | SHA1 | Date |
---|---|---|
Shadowfacts | e3b8847e24 |
|
@ -66,11 +66,12 @@ defmodule Day5 do
|
||||||
def run(memory, ip \\ 0)
|
def run(memory, ip \\ 0)
|
||||||
|
|
||||||
def run(memory, ip) when ip < length(memory) do
|
def run(memory, ip) when ip < length(memory) do
|
||||||
|
IO.puts("IP: #{ip}")
|
||||||
IO.inspect(memory)
|
IO.inspect(memory)
|
||||||
|
|
||||||
case eval(Enum.drop(memory, ip), memory) do
|
case eval(Enum.drop(memory, ip), memory) do
|
||||||
{memory, :halt} ->
|
{_memory, :halt} ->
|
||||||
memory
|
:halt
|
||||||
|
|
||||||
{memory, :cont, offset} ->
|
{memory, :cont, offset} ->
|
||||||
run(memory, ip + offset)
|
run(memory, ip + offset)
|
||||||
|
@ -78,6 +79,8 @@ defmodule Day5 do
|
||||||
{memory, :jump, ip} ->
|
{memory, :jump, ip} ->
|
||||||
run(memory, ip)
|
run(memory, ip)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
def run(memory, _ip), do: memory
|
def run(memory, _ip), do: memory
|
||||||
|
@ -146,7 +149,8 @@ defmodule Day5 do
|
||||||
|
|
||||||
# output
|
# output
|
||||||
def eval([op, param | _], memory) when opcode(op, 4) do
|
def eval([op, param | _], memory) when opcode(op, 4) do
|
||||||
get_param(op, 0, param, memory) |> IO.inspect()
|
out = get_param(op, 0, param, memory)
|
||||||
|
IO.puts("Output: #{out}")
|
||||||
|
|
||||||
{memory, :cont, 2}
|
{memory, :cont, 2}
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
defmodule Assembler do
|
||||||
|
@asm """
|
||||||
|
in #30
|
||||||
|
clt 30 #8 #31
|
||||||
|
jnz 31 #lessThan
|
||||||
|
ceq 30 #8 #31
|
||||||
|
jnz 31 #equal
|
||||||
|
out #1001
|
||||||
|
hlt
|
||||||
|
|
||||||
|
lessThan:
|
||||||
|
out #999
|
||||||
|
hlt
|
||||||
|
|
||||||
|
equal:
|
||||||
|
out #1000
|
||||||
|
hlt
|
||||||
|
"""
|
||||||
|
def test do
|
||||||
|
@asm
|
||||||
|
|> IO.inspect()
|
||||||
|
|> assemble(32)
|
||||||
|
end
|
||||||
|
|
||||||
|
def assemble(asm, pad_length \\ 0) do
|
||||||
|
{memory, labels} =
|
||||||
|
asm
|
||||||
|
|> String.split("\n")
|
||||||
|
|> Enum.reject(&(String.length(&1) == 0))
|
||||||
|
|> Enum.reduce({[], %{}}, fn line, {memory, labels} ->
|
||||||
|
cond do
|
||||||
|
Regex.match?(~r/^\s+$/, line) ->
|
||||||
|
{memory, labels}
|
||||||
|
|
||||||
|
String.starts_with?(line, " ") ->
|
||||||
|
{
|
||||||
|
assemble_instruction(String.slice(line, 2..-1), memory),
|
||||||
|
labels
|
||||||
|
}
|
||||||
|
|
||||||
|
String.ends_with?(line, ":") ->
|
||||||
|
{
|
||||||
|
memory,
|
||||||
|
Map.put(labels, String.slice(line, 0..-2), length(memory))
|
||||||
|
}
|
||||||
|
|
||||||
|
true ->
|
||||||
|
IO.inspect("Ignoring line: #{line}")
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
memory =
|
||||||
|
Enum.map(memory, fn
|
||||||
|
{:label, name} -> Map.fetch!(labels, name)
|
||||||
|
it -> it
|
||||||
|
end)
|
||||||
|
|
||||||
|
memory =
|
||||||
|
if pad_length > length(memory) do
|
||||||
|
repeat(0, pad_length - length(memory)) ++ memory
|
||||||
|
else
|
||||||
|
memory
|
||||||
|
end
|
||||||
|
|
||||||
|
IO.inspect(labels)
|
||||||
|
Enum.reverse(memory)
|
||||||
|
end
|
||||||
|
|
||||||
|
def repeat(_, 0), do: []
|
||||||
|
def repeat(n, count), do: [n | repeat(n, count - 1)]
|
||||||
|
|
||||||
|
def pow(base, 1), do: base
|
||||||
|
def pow(base, exp), do: base * pow(base, exp - 1)
|
||||||
|
|
||||||
|
def parse_params(params, param_types) do
|
||||||
|
params
|
||||||
|
|> String.split(" ")
|
||||||
|
|> Enum.zip(param_types)
|
||||||
|
|> Enum.with_index()
|
||||||
|
|> Enum.map_reduce(0, fn {{param, type}, index}, modes ->
|
||||||
|
val =
|
||||||
|
case Regex.run(~r/^#?(\d+)$/, param) do
|
||||||
|
[_, digits] ->
|
||||||
|
String.to_integer(digits)
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
[_, name] = Regex.run(~r/^#(\w+)$/, param)
|
||||||
|
{:label, name}
|
||||||
|
end
|
||||||
|
|
||||||
|
modes =
|
||||||
|
if type == :read && String.starts_with?(param, "#") do
|
||||||
|
modes + pow(10, index + 2)
|
||||||
|
else
|
||||||
|
modes
|
||||||
|
end
|
||||||
|
|
||||||
|
{val, modes}
|
||||||
|
# case type do
|
||||||
|
# :write ->
|
||||||
|
# {String.to_integer(param), modes}
|
||||||
|
|
||||||
|
# _ ->
|
||||||
|
# cond do
|
||||||
|
# String.starts_with?(param, "$") ->
|
||||||
|
# {
|
||||||
|
# param |> String.slice(1..-1) |> String.to_integer(),
|
||||||
|
# modes
|
||||||
|
# }
|
||||||
|
|
||||||
|
# Regex.match?(~r/\d+/, param) ->
|
||||||
|
# {
|
||||||
|
# String.to_integer(param),
|
||||||
|
# modes + pow(10, index + 2)
|
||||||
|
# }
|
||||||
|
|
||||||
|
# true ->
|
||||||
|
# {{:label, param}, modes + pow(10, index + 2)}
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def assemble_instruction(insn, memory \\ [])
|
||||||
|
|
||||||
|
def assemble_instruction("add " <> params, memory) do
|
||||||
|
{[a, b, dest], modes} = parse_params(params, [:read, :read, :write])
|
||||||
|
|
||||||
|
[dest, b, a, 1 + modes | memory]
|
||||||
|
end
|
||||||
|
|
||||||
|
def assemble_instruction("mul " <> params, memory) do
|
||||||
|
{[a, b, dest], modes} = parse_params(params, [:read, :read, :write])
|
||||||
|
|
||||||
|
[dest, b, a, 2 + modes | memory]
|
||||||
|
end
|
||||||
|
|
||||||
|
def assemble_instruction("hlt", memory) do
|
||||||
|
[99 | memory]
|
||||||
|
end
|
||||||
|
|
||||||
|
def assemble_instruction("in " <> params, memory) do
|
||||||
|
{[dest], modes} = parse_params(params, [:write])
|
||||||
|
|
||||||
|
[dest, 3 + modes | memory]
|
||||||
|
end
|
||||||
|
|
||||||
|
def assemble_instruction("out " <> params, memory) do
|
||||||
|
{[val], modes} = parse_params(params, [:read])
|
||||||
|
|
||||||
|
[val, 4 + modes | memory]
|
||||||
|
end
|
||||||
|
|
||||||
|
def assemble_instruction("jnz " <> params, memory) do
|
||||||
|
{[target, dest], modes} = parse_params(params, [:read, :read])
|
||||||
|
|
||||||
|
[dest, target, 5 + modes | memory]
|
||||||
|
end
|
||||||
|
|
||||||
|
def assemble_instruction("jez " <> params, memory) do
|
||||||
|
{[target, dest], modes} = parse_params(params, [:read, :read])
|
||||||
|
|
||||||
|
[dest, target, 6 + modes | memory]
|
||||||
|
end
|
||||||
|
|
||||||
|
def assemble_instruction("clt " <> params, memory) do
|
||||||
|
{[a, b, dest], modes} = parse_params(params, [:read, :read, :write])
|
||||||
|
|
||||||
|
[dest, b, a, 7 + modes | memory]
|
||||||
|
end
|
||||||
|
|
||||||
|
def assemble_instruction("ceq " <> params, memory) do
|
||||||
|
{[a, b, dest], modes} = parse_params(params, [:read, :read, :write])
|
||||||
|
|
||||||
|
[dest, b, a, 8 + modes | memory]
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue