概要
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()
成果物
以上。