Add assembler support for relative mode parameters

This commit is contained in:
Shadowfacts 2019-12-09 11:41:33 -05:00
parent 968c3ebf95
commit 1add491851
2 changed files with 33 additions and 8 deletions

View File

@ -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,15 +306,26 @@ defmodule Assembler do
modes =
case type do
:read ->
if String.starts_with?(param, "$") do
cond do
String.starts_with?(param, "$") ->
modes
else
String.starts_with?(param, "#") ->
modes + 2 * pow(10, index + 2)
true ->
modes + pow(10, index + 2)
end
_ ->
:write ->
cond do
String.starts_with?(param, "#") ->
modes + 2 * pow(10, index + 2)
true ->
modes
end
end
{val, modes}
end)

View File

@ -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