概要
paiza.ioでelixirやってみた。
練習問題やってみた。
練習問題
Forthインタープリタを書け。
forthで数9を4個つかって1から15までの数を表す式を実行せよ。
Tupleを使え。
サンプルコード
defmodule Forth do
def start_link do
Agent.start_link(fn ->
{}
end, name: __MODULE__)
end
def add do
Agent.update(__MODULE__, fn stack ->
po = tuple_size(stack) - 1
top = elem(stack, po)
nd = elem(stack, po - 1)
stack = put_elem(stack, po - 1, nd + top)
stack = Tuple.delete_at(stack, po)
end)
end
def sub do
Agent.update(__MODULE__, fn stack ->
po = tuple_size(stack) - 1
top = elem(stack, po)
nd = elem(stack, po - 1)
stack = put_elem(stack, po - 1, nd - top)
stack = Tuple.delete_at(stack, po)
end)
end
def mul do
Agent.update(__MODULE__, fn stack ->
po = tuple_size(stack) - 1
top = elem(stack, po)
nd = elem(stack, po - 1)
stack = put_elem(stack, po - 1, nd * top)
stack = Tuple.delete_at(stack, po)
end)
end
def div do
Agent.update(__MODULE__, fn stack ->
po = tuple_size(stack) - 1
top = elem(stack, po)
nd = elem(stack, po - 1)
stack = put_elem(stack, po - 1, nd / top)
stack = Tuple.delete_at(stack, po)
end)
end
def dup do
Agent.update(__MODULE__, fn stack ->
po = tuple_size(stack) - 1
top = elem(stack, po)
stack = Tuple.append(stack, top)
end)
end
def drop do
Agent.update(__MODULE__, fn stack ->
po = tuple_size(stack) - 1
stack = Tuple.delete_at(stack, po)
end)
end
def get do
Agent.get(__MODULE__, fn stack ->
po = tuple_size(stack) - 1
elem(stack, po)
end)
end
def push(n) do
Agent.update(__MODULE__, fn stack ->
{v, _} = Integer.parse(n)
stack = Tuple.append(stack, v)
end)
end
end
defmodule Main do
def run(str) do
Enum.map(String.split(str, " "), fn s ->
cond do
s == "+" ->
Forth.add
s == "-" ->
Forth.sub
s == "*" ->
Forth.mul
s == "/" ->
Forth.div
s == "dup" ->
Forth.dup
s == "drop" ->
Forth.drop
s == "." ->
IO.inspect Forth.get
true ->
Forth.push(s)
end
end)
end
end
Forth.start_link
Main.run("9 9 - 9 9 / .")
Main.run("9 9 / 9 9 / + .")# 2 ok
Main.run("9 9 + 9 + 9 / .")# 3 ok
Main.run("9 9 9 + 9 / dup + .")# 4 ok
Main.run("9 9 9 + 9 / dup + - .")# 5 ok
Main.run("9 dup 9 + 9 + 9 / - .")# 6 ok
Main.run("9 9 9 + 9 / - .")# 7 ok
Main.run("9 9 9 drop 9 / - .")# 8 ok
Main.run("9 9 - 9 * 9 + .")# 9 ok
Main.run("9 9 / 9 dup 9 / + .")# 10 ok
Main.run("9 9 9 + 9 / + .")# 11 ok
Main.run("9 dup 9 9 + + 9 / + .")# 12 ok
Main.run("9 9 9 + 9 / dup + + .")# 13 ok
Main.run("9 dup 9 9 + 9 / dup + - + .")# 14 ok
Main.run("9 dup dup 9 + 9 + 9 / - + .")# 15 ok
実行結果
1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
9
10.0
11.0
12.0
13.0
14.0
15.0
成果物
以上。