概要
paiza.ioでelixirやってみた。
練習問題やってみた。
完結編
練習問題
俺cpuのアセンブラをコンパイルしてelixirのソースコードを生成せよ。
サンプルコード
defmodule Stack do
use Agent
def start_link do
Agent.start_link(fn ->
[]
end, name: __MODULE__)
end
def pop do
v = Agent.get(__MODULE__, fn stack ->
stack
|> List.last()
end)
Agent.update(__MODULE__, fn stack ->
po = length(stack) - 1
List.delete_at(stack, po)
end)
v
end
def push(v) do
Agent.update(__MODULE__, fn stack ->
stack ++ [v]
end)
end
end
defmodule Va do
use Agent
def start_link() do
Agent.start_link(fn ->
0
end, name: __MODULE__)
end
def get() do
Agent.get(__MODULE__, fn v ->
v
end)
end
def set(x) do
Agent.update(__MODULE__, fn v ->
x
end)
end
end
defmodule Main do
def loop0() do
IO.puts("""
loop(1)
end
def loop(v) do
if v == 0 do
else
""")
end
def add() do
v0 = Stack.pop()
v1 = Stack.pop()
Stack.push("#{v1} + #{v0}")
end
def sub() do
end
def mul() do
end
def div() do
end
def rem() do
end
def eq() do
Stack.push("==")
end
def rnd() do
end
def gt() do
Stack.push(">")
end
def out() do
IO.puts("IO.puts(#{Stack.pop()})")
end
def push(s) do
Stack.push(s)
end
def if_(s) do
v0 = Stack.pop()
v1 = Stack.pop()
v2 = Stack.pop()
IO.puts("""
if #{v2} #{v0} #{v1} do
loop(0)
else
""")
end
def jmp(s) do
end
def set(s) do
IO.puts("#{s} = #{Stack.pop()}")
IO.puts("Va.set(#{s})")
Stack.push(s)
end
def get(s) do
IO.puts("#{s} = Va.get()")
Stack.push(s)
end
def asm(str) do
Enum.map(String.split(str, "\n"), fn st ->
s = String.split(st, " ")
cond do
Enum.at(s, 0) == "loop" ->
loop0()
Enum.at(s, 1) == "+" ->
add()
Enum.at(s, 1) == "-" ->
sub()
Enum.at(s, 1) == "*" ->
mul()
Enum.at(s, 1) == "/" ->
div()
Enum.at(s, 1) == "%" ->
rem()
Enum.at(s, 1) == "=" ->
eq()
Enum.at(s, 1) == "rnd" ->
rnd()
Enum.at(s, 1) == "out" ->
out()
Enum.at(s, 1) == ">" ->
gt()
Enum.at(s, 1) == "jmp" ->
jmp(Enum.at(s, 2))
Enum.at(s, 1) == "if" ->
if_(Enum.at(s, 2))
Enum.at(s, 1) == "set" ->
set(Enum.at(s, 2))
Enum.at(s, 1) == "get" ->
get(Enum.at(s, 2))
true ->
push(Enum.at(s, 1))
end
end)
end
def start(str) do
IO.puts("""
defmodule Va do
use Agent
def start_link() do
Agent.start_link(fn ->
0
end, name: __MODULE__)
end
def get() do
Agent.get(__MODULE__, fn v ->
v
end)
end
def set(x) do
Agent.update(__MODULE__, fn v ->
x
end)
end
end
Va.start_link
defmodule Main do
def main do
""")
asm(str)
IO.puts("""
loop(1)
end
end
end
end
Main.main()
""")
end
end
Va.start_link
Stack.start_link
"""
1
set a
loop
get a
100
>
if end
get a
out
get a
1
+
set a
jmp loop
"""
|> Main.start()
実行結果
defmodule Va do
use Agent
def start_link() do
Agent.start_link(fn ->
0
end, name: __MODULE__)
end
def get() do
Agent.get(__MODULE__, fn v ->
v
end)
end
def set(x) do
Agent.update(__MODULE__, fn v ->
x
end)
end
end
Va.start_link
defmodule Main do
def main do
a = 1
Va.set(a)
loop(1)
end
def loop(v) do
if v == 0 do
else
a = Va.get()
if a > 100 do
loop(0)
else
a = Va.get()
IO.puts(a)
a = Va.get()
a = a + 1
Va.set(a)
loop(1)
end
end
end
end
Main.main()
成果物
以上。