概要
paiza.ioでelixirやってみた。
練習問題やってみた。
練習問題
Forthインタープリタを書け。
forthで数9を4個つかって1から15までの数を表す式を実行せよ。
Listを使え。
サンプルコード
defmodule Forth do
def start_link do
Agent.start_link(fn ->
[]
end, name: __MODULE__)
end
def add do
Agent.update(__MODULE__, fn stack ->
po = length(stack) - 2
top = List.last(stack)
stack = List.update_at(stack, po, &(&1 + top))
stack = List.delete_at(stack, po + 1)
end)
end
def sub do
Agent.update(__MODULE__, fn stack ->
po = length(stack) - 2
top = List.last(stack)
stack = List.update_at(stack, po, &(&1 - top))
stack = List.delete_at(stack, po + 1)
end)
end
def mul do
Agent.update(__MODULE__, fn stack ->
po = length(stack) - 2
top = List.last(stack)
stack = List.update_at(stack, po, &(&1 * top))
stack = List.delete_at(stack, po + 1)
end)
end
def div do
Agent.update(__MODULE__, fn stack ->
po = length(stack) - 2
top = List.last(stack)
stack = List.update_at(stack, po, &(&1 / top))
stack = List.delete_at(stack, po + 1)
end)
end
def dup do
Agent.update(__MODULE__, fn stack ->
top = List.last(stack)
stack ++ [top]
end)
end
def drop do
Agent.update(__MODULE__, fn stack ->
po = length(stack) - 2
stack = List.delete_at(stack, po + 1)
end)
end
def get do
Agent.get(__MODULE__, fn stack ->
List.last(stack)
end)
end
def push(n) do
Agent.update(__MODULE__, fn stack ->
{v, _} = Integer.parse(n)
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
成果物
以上。