概要
paiza.ioでelixirやってみた。
俺言語のインタープリタ、書いてみた。
練習問題やってみた。
練習問題
zundokoを書け。
投入したソースコード
10 a=0
20 b=:rand.uniform(2)
30 #=b<2*80
40 ?="zun"
50 a=a+1
60 #=a>3*110
70 #=20
80 ?="doko"
90 a=0
100 #=20
110 ?="doko"
120 ?="kiyosi!!"
130 #=0
サンプルコード
defmodule Sim do
def start_link do
Agent.start_link(fn ->
[a: 0, b: 0, c: 0, pc: 0]
end, name: __MODULE__)
end
def a(s) do
Agent.update(__MODULE__, fn v ->
ex = "[" <> s <> "]"
{[d], _} = Code.eval_string(ex, v)
v = List.keyreplace(v, :a, 0, {:a, d})
List.keyreplace(v, :pc, 0, {:pc, 777})
end)
end
def b(s) do
Agent.update(__MODULE__, fn v ->
ex = "[" <> s <> "]"
{[d], _} = Code.eval_string(ex, v)
v = List.keyreplace(v, :b, 0, {:b, d})
List.keyreplace(v, :pc, 0, {:pc, 777})
end)
end
def print(s) do
Agent.update(__MODULE__, fn v ->
ex = "[" <> s <> "]"
{[d], _} = Code.eval_string(ex, v)
IO.puts(d)
List.keyreplace(v, :pc, 0, {:pc, 777})
end)
end
def loop(s) do
Agent.update(__MODULE__, fn v ->
if String.match?(s, ~r/\*/) do
s = String.replace(s, "@", "==")
p = String.split(s, "*")
g = Enum.at(p, 0)
ex = "[" <> g <> "]"
{[d], _} = Code.eval_string(ex, v)
if d == true do
x = String.to_integer(Enum.at(p, 1))
List.keyreplace(v, :pc, 0, {:pc, x})
else
List.keyreplace(v, :pc, 0, {:pc, 777})
end
else
x = String.to_integer(s)
List.keyreplace(v, :pc, 0, {:pc, x})
end
end)
end
def pc() do
Agent.get(__MODULE__, fn v ->
v[:pc]
end)
end
def test() do
Agent.get(__MODULE__, fn v ->
v
end)
end
end
defmodule Main do
def src(n) do
str = """
10 a=0
20 b=:rand.uniform(2)
30 #=b<2*80
40 ?="zun"
50 a=a+1
60 #=a>3*110
70 #=20
80 ?="doko"
90 a=0
100 #=20
110 ?="doko"
120 ?="kiyosi!!"
130 #=0
"""
Enum.map(String.split(str, "\n", trim: true), fn l ->
s = String.split(l, " ")
cond do
String.to_integer(Enum.at(s, 0)) == n ->
l
true ->
nil
end
end)
end
def run(0) do
end
def run(pc) do
m = src(pc)
m = Enum.reject(m, fn(x) ->
x == nil
end)
Enum.map(m, fn l ->
#IO.puts(l)
b = String.replace(l, "=", " ")
s = String.split(b, " ")
cond do
Enum.at(s, 1) == "?" ->
Sim.print(Enum.at(s, 2))
Enum.at(s, 1) == "#" ->
Sim.loop(Enum.at(s, 2))
Enum.at(s, 1) == "a" ->
Sim.a(Enum.at(s, 2))
Enum.at(s, 1) == "b" ->
Sim.b(Enum.at(s, 2))
true ->
IO.puts ""
end
#IO.inspect(Sim.test)
cond do
Sim.pc == 777 ->
run(pc + 10)
true ->
run(Sim.pc)
end
end)
end
end
Sim.start_link
Main.run(10)
実行結果
doko
doko
zun
zun
zun
doko
doko
doko
doko
doko
doko
zun
zun
doko
zun
zun
doko
doko
doko
zun
doko
doko
zun
doko
doko
zun
doko
doko
zun
doko
doko
doko
doko
zun
zun
zun
doko
zun
zun
zun
zun
doko
kiyosi!!
成果物
以上。