Add assembler support for relative mode parameters
This commit is contained in:
parent
968c3ebf95
commit
1add491851
|
@ -47,7 +47,7 @@ defmodule Assembler do
|
||||||
def test do
|
def test do
|
||||||
File.read!("test/intcode/cmp8.asm")
|
File.read!("test/intcode/cmp8.asm")
|
||||||
|> assemble()
|
|> assemble()
|
||||||
|> Day5.run_cli()
|
|> Day9.run_cli()
|
||||||
end
|
end
|
||||||
|
|
||||||
def assemble(asm) do
|
def assemble(asm) do
|
||||||
|
@ -190,6 +190,11 @@ defmodule Assembler do
|
||||||
[dest, b, a, 8 + modes | memory]
|
[dest, b, a, 8 + modes | memory]
|
||||||
end
|
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
|
def assemble_insn(["hlt"], memory) do
|
||||||
[99 | memory]
|
[99 | memory]
|
||||||
end
|
end
|
||||||
|
@ -281,7 +286,7 @@ defmodule Assembler do
|
||||||
|> Enum.with_index()
|
|> Enum.with_index()
|
||||||
|> Enum.map_reduce(0, fn {{param, type}, index}, modes ->
|
|> Enum.map_reduce(0, fn {{param, type}, index}, modes ->
|
||||||
val =
|
val =
|
||||||
case Regex.run(~r/^\$?(\d+)$/, param) do
|
case Regex.run(~r/^[\$#]?(\d+)$/, param) do
|
||||||
[_, digits] ->
|
[_, digits] ->
|
||||||
String.to_integer(digits)
|
String.to_integer(digits)
|
||||||
|
|
||||||
|
@ -290,6 +295,9 @@ defmodule Assembler do
|
||||||
"$" <> param ->
|
"$" <> param ->
|
||||||
{:expr, parse_param_expr(param)}
|
{:expr, parse_param_expr(param)}
|
||||||
|
|
||||||
|
"#" <> param ->
|
||||||
|
{:expr, parse_param_expr(param)}
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
{:expr, parse_param_expr(param)}
|
{:expr, parse_param_expr(param)}
|
||||||
end
|
end
|
||||||
|
@ -298,15 +306,26 @@ defmodule Assembler do
|
||||||
modes =
|
modes =
|
||||||
case type do
|
case type do
|
||||||
:read ->
|
:read ->
|
||||||
if String.starts_with?(param, "$") do
|
cond do
|
||||||
|
String.starts_with?(param, "$") ->
|
||||||
modes
|
modes
|
||||||
else
|
|
||||||
|
String.starts_with?(param, "#") ->
|
||||||
|
modes + 2 * pow(10, index + 2)
|
||||||
|
|
||||||
|
true ->
|
||||||
modes + pow(10, index + 2)
|
modes + pow(10, index + 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
_ ->
|
:write ->
|
||||||
|
cond do
|
||||||
|
String.starts_with?(param, "#") ->
|
||||||
|
modes + 2 * pow(10, index + 2)
|
||||||
|
|
||||||
|
true ->
|
||||||
modes
|
modes
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
{val, modes}
|
{val, modes}
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -21,6 +21,7 @@ defmodule AssemblerTest do
|
||||||
assert assemble("clt $1, $2, $3") == [7, 1, 2, 3]
|
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") == [1108, 1, 2, 3]
|
||||||
assert assemble("ceq $1, $2, $3") == [8, 1, 2, 3]
|
assert assemble("ceq $1, $2, $3") == [8, 1, 2, 3]
|
||||||
|
assert assemble("srel 1234") == [109, 1234]
|
||||||
assert assemble("hlt") == [99]
|
assert assemble("hlt") == [99]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -140,4 +141,9 @@ defmodule AssemblerTest do
|
||||||
label: 42
|
label: 42
|
||||||
""") == [101, 1, 6, 3, 42]
|
""") == [101, 1, 6, 3, 42]
|
||||||
end
|
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
|
end
|
||||||
|
|
Loading…
Reference in New Issue