概要
paiza.ioでelixirやってみた。
俺言語のインタープリタ、書いてみた。
九九、書いてみた。
投入したソースコード
10 a=1
20 b=1
30 ?=a*b
40 a=a+1
50 #=a<10*30
60 b=b+1
70 a=1
80 #=b<10*30
90 #=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 c(s) do
Agent.update(__MODULE__, fn v ->
ex = "[" <> s <> "]"
{[d], _} = Code.eval_string(ex, v)
v = List.keyreplace(v, :c, 0, {:c, 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})
#v
end)
end
def jmp(s) do
Agent.update(__MODULE__, fn v ->
if String.match?(s, ~r/\*/) do
p = String.split(s, "*")
g = Enum.at(p, 0)
ex = "[" <> g <> "]"
{[d], _} = Code.eval_string(ex, v)
#IO.puts(">")
#IO.puts(d)
if d == true do
x = String.to_integer(Enum.at(p, 1))
#IO.puts(x)
List.keyreplace(v, :pc, 0, {:pc, x})
#v
#|> IO.inspect
#v
else
List.keyreplace(v, :pc, 0, {:pc, 777})
#v
end
else
List.keyreplace(v, :pc, 0, {:pc, 777})
#v
end
#v
#|> IO.inspect
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=1
20 b=1
30 ?=a*b
40 a=a+1
50 #=a<10*30
60 b=b+1
70 a=1
80 #=b<10*30
90 #=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)
#|> IO.inspect
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.jmp(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))
Enum.at(s, 1) == "c" ->
Sim.c(Enum.at(s, 2))
true ->
IO.puts ""
end
#IO.inspect(Sim.test)
#IO.inspect(Sim.pc)
cond do
Sim.pc == 777 ->
run(pc + 10)
true ->
run(Sim.pc)
end
end)
end
end
Sim.start_link
Main.run(10)
実行結果
1
2
3
4
5
6
7
8
9
2
4
6
8
10
12
14
16
18
3
6
9
12
15
18
21
24
27
4
8
12
16
20
24
28
32
36
5
10
15
20
25
30
35
40
45
6
12
18
24
30
36
42
48
54
7
14
21
28
35
42
49
56
63
8
16
24
32
40
48
56
64
72
9
18
27
36
45
54
63
72
81
成果物
以上。