From fe5bc1de7ccadd7da123c252791579f6b677edf0 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Fri, 6 Dec 2019 11:48:28 -0500 Subject: [PATCH] Intcode assembler: add _self label --- lib/intcode/assembler.ex | 36 ++++++++++++++++++++++++++------- test/intcode/assembler_test.exs | 8 ++++++++ 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/lib/intcode/assembler.ex b/lib/intcode/assembler.ex index c51036a..c0116a0 100644 --- a/lib/intcode/assembler.ex +++ b/lib/intcode/assembler.ex @@ -61,14 +61,36 @@ defmodule Assembler do end end) - memory = - Enum.map(memory, fn - {:label, name} -> Map.fetch!(labels, name) - it -> it - end) - # IO.inspect(labels) - Enum.reverse(memory) + + memory + |> Enum.reverse() + |> Enum.with_index() + |> Enum.map(fn + {{:label, name}, index} -> get_label(name, index, labels) + {it, _} -> it + end) + end + + @doc """ + Get the address of a label. + + `_self` is a special label that resolves to the address of where it's being inserted into the program. + + ## Examples + iex> Assembler.get_label("test", 1, %{"test" => 14}) + 14 + iex> Assembler.get_label("_self", 1, %{}) + 1 + """ + def get_label(name, index, labels) + + def get_label("_self", index, _) do + index + end + + def get_label(name, _, labels) do + Map.fetch!(labels, name) end @doc """ diff --git a/test/intcode/assembler_test.exs b/test/intcode/assembler_test.exs index df526d9..509087e 100644 --- a/test/intcode/assembler_test.exs +++ b/test/intcode/assembler_test.exs @@ -68,4 +68,12 @@ defmodule AssemblerTest do 0 ] end + + test "assembles a program with a _self label" do + program = """ + add 1 2 _self + """ + + assert Assembler.assemble(program) == [1101, 1, 2, 3] + end end