diff --git a/lib/intcode/assembler.ex b/lib/intcode/assembler.ex index 4acbf32..506eed3 100644 --- a/lib/intcode/assembler.ex +++ b/lib/intcode/assembler.ex @@ -47,7 +47,7 @@ defmodule Assembler do def test do File.read!("test/intcode/cmp8.asm") |> assemble() - |> Day5.run_cli() + |> Day9.run_cli() end def assemble(asm) do @@ -190,6 +190,11 @@ defmodule Assembler do [dest, b, a, 8 + modes | memory] end + def assemble_insn(["srel", val], memory) do + {[val], modes} = parse_params([val], [:read]) + [val, 9 + modes | memory] + end + def assemble_insn(["hlt"], memory) do [99 | memory] end @@ -281,7 +286,7 @@ defmodule Assembler do |> Enum.with_index() |> Enum.map_reduce(0, fn {{param, type}, index}, modes -> val = - case Regex.run(~r/^\$?(\d+)$/, param) do + case Regex.run(~r/^[\$#]?(\d+)$/, param) do [_, digits] -> String.to_integer(digits) @@ -290,6 +295,9 @@ defmodule Assembler do "$" <> param -> {:expr, parse_param_expr(param)} + "#" <> param -> + {:expr, parse_param_expr(param)} + _ -> {:expr, parse_param_expr(param)} end @@ -298,14 +306,25 @@ defmodule Assembler do modes = case type do :read -> - if String.starts_with?(param, "$") do - modes - else - modes + pow(10, index + 2) + cond do + String.starts_with?(param, "$") -> + modes + + String.starts_with?(param, "#") -> + modes + 2 * pow(10, index + 2) + + true -> + modes + pow(10, index + 2) end - _ -> - modes + :write -> + cond do + String.starts_with?(param, "#") -> + modes + 2 * pow(10, index + 2) + + true -> + modes + end end {val, modes} diff --git a/test/intcode/assembler_test.exs b/test/intcode/assembler_test.exs index 1bd3005..ff51c20 100644 --- a/test/intcode/assembler_test.exs +++ b/test/intcode/assembler_test.exs @@ -21,6 +21,7 @@ defmodule AssemblerTest do assert assemble("clt $1, $2, $3") == [7, 1, 2, 3] assert assemble("ceq 1, 2, 3") == [1108, 1, 2, 3] assert assemble("ceq $1, $2, $3") == [8, 1, 2, 3] + assert assemble("srel 1234") == [109, 1234] assert assemble("hlt") == [99] end @@ -140,4 +141,9 @@ defmodule AssemblerTest do label: 42 """) == [101, 1, 6, 3, 42] end + + test "assembles relative mode parameters" do + assert assemble("add #1, #2, #3") == [22201, 1, 2, 3] + assert assemble("in #4") == [203, 4] + end end