LoginSignup
1
0

More than 1 year has passed since last update.

paiza.ioでelixir その48

Last updated at Posted at 2022-11-07

概要

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


成果物

以上。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0