概要
paiza.ioでelixirやってみた。
練習問題やってみた。
構想編
練習問題
俺cpuのアセンブラをコンパイルしてelixirのソースコードを生成せよ。
方針
- loopは、再帰で実現。
- agentで、変数を実現。
- stackは、backendで使う。
俺cpu 命令セット
| ニーモニック | 意味 | スタックの状態 | プログラムカウンタの状態 |
|---|---|---|---|
| jmp i | 無条件でi番地へ飛ぶ。 | 変化無し | i番地になる。 |
| 1-255 | stackに整数を積む。 | 1個増える | 1つ増える |
| get a | stackに変数aの値を入れる。 | 1個増える | 1つ増える |
| set b | 変数bにstackを入れる。 | 1個減る | 1つ増える |
| out | stackをそのまま出力する。 | 1個減る | 1つ増える |
| if i | stackが真ならi番地へ飛ぶ。 | 1個減る | 場合によりi番地になる |
| if! i | stackが偽ならi番地へ飛ぶ。 | 1個減る | 場合によりi番地になる |
| dup | stackにコピーを積む。 | 1個増える | 1つ増える |
| rnd | stackに乱数を積む。 | 1個増える | 1つ増える |
| drop | stackを一個減らす。 | 1個減る | 1つ増える |
| + | stack-1,stackの加算を求める。 | 1個減る | 1つ増える |
| - | stack-1,stackの減算を求める。 | 1個減る | 1つ増える |
| * | stack-1,stackの乗算を求める。 | 1個減る | 1つ増える |
| / | stack-1,stackの除算を求める。 | 1個減る | 1つ増える |
| % | stack-1,stackの剰余を求める。 | 1個減る | 1つ増える |
| = | stack-1,stackの等しいを求める。 | 1個減る | 1つ増える |
| > | stack-1,stackの大小を求める。 | 1個減る | 1つ増える |
| end | stopする。 | 変化無し | 変化無し |
投入する、俺cpuのソースコード
1から100まで、印字する。
1
set a
loop
get a
100
>
if end
get a
out
get a
1
+
set a
jmp loop
生成を期待する、elixirのソースコード
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 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
def main do
a = 1
Va.set(a)
loop(1)
end
end
Main.main()
成果物
以上。