paiza.ioでelixir その276

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
俺cpuのアセンブラをコンパイルしてelixirのソースコードを生成せよ。
fizzbuzzを解け。

# サンプルコード

```

defmodule Stack do
	use Agent
	def start_link do
		Agent.start_link(fn ->
			[]
		end, name: __MODULE__)
	end
	def pop do
		v =	Agent.get(__MODULE__, fn stack ->
			stack
			|> List.last()
		end)
		Agent.update(__MODULE__, fn stack ->
			po = length(stack) - 1
			List.delete_at(stack, po)
		end)
		v
	end
	def push(v) do
		Agent.update(__MODULE__, fn stack ->
			stack ++ [v]
		end)
	end
end

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

defmodule Main do
    def loop0() do
    IO.puts("""
        loop(1)
	end
	def loop(v) do
        if v == 0 do
	    else
    """)
    end
    def add() do
        v0 = Stack.pop()
        v1 = Stack.pop()
        Stack.push("#{v1} + #{v0}")
    end
    def rem() do
        v0 = Stack.pop()
        v1 = Stack.pop()
        Stack.push("rem(#{v1}, #{v0})")
    end
    def eq() do
        Stack.push("==")
    end
    def skip() do
        IO.puts("        loop(1)")
        IO.puts("    end")
    end
    def gt() do
        Stack.push(">")
	end
	def out() do
        IO.puts("        IO.puts(#{Stack.pop()})")
	end
	def push(s) do
        Stack.push(s)
	end	
	def if_(s) do
        v0 = Stack.pop()
        v1 = Stack.pop()
        v2 = Stack.pop()
        IO.puts("""
            if #{v1} #{v0} #{v2} do
	    	        loop(0)
            else
        """)
	end
	def nf(s) do
        v0 = Stack.pop()
        v1 = Stack.pop()
        v2 = Stack.pop()
        IO.puts("        if #{v2} #{v0} #{v1} do")
	end
	def jmp(s) do

	end
	def set(s) do
        IO.puts("        #{s} = #{Stack.pop()}")
        IO.puts("        Va.set(#{s})")
        Stack.push(s)
	end
	def get(s) do
        IO.puts("        #{s} = Va.get()")
        Stack.push(s)
	end
	def asm(str) do
		Enum.map(String.split(str, "\n"), fn st ->
			s = String.split(st, "  ")
			cond do
			Enum.at(s, 0) == "loop" ->
				loop0()
			Enum.at(s, 0) == "skip0" ->
				skip()
			Enum.at(s, 0) == "skip1" ->
				skip()
			Enum.at(s, 0) == "skip2" ->
				skip()
			Enum.at(s, 1) == "+" ->
				add()
			Enum.at(s, 1) == "%" ->
				rem()
			Enum.at(s, 1) == "=" ->
				eq()
			Enum.at(s, 1) == "out" ->
				out()
			Enum.at(s, 1) == ">" ->
				gt()
			Enum.at(s, 1) == "jmp" ->
				jmp(Enum.at(s, 2))
			Enum.at(s, 1) == "if" ->
				if_(Enum.at(s, 2))
			Enum.at(s, 1) == "nf" ->
				nf(Enum.at(s, 2))
			Enum.at(s, 1) == "set" ->
				set(Enum.at(s, 2))
			Enum.at(s, 1) == "get" ->
				get(Enum.at(s, 2))
			true ->
				push(Enum.at(s, 1))
			end
		end)
	end
	def start(str) do
        IO.puts("""
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 main do
""")
		asm(str)
IO.puts("""
                loop(1)
		    end
		end
	end
end
Main.main()
""")
    end		
end
Va.start_link
Stack.start_link

"""
  0
  set  a
loop
  get  a
  1
  +
  set  a
  get  a
  15
  %
  0
  =
  nf  skip0
  "FizzBuzz"
  out
skip0
  get  a
  5
  %
  0
  =
  nf  skip1
  "Buzz"
  out
skip1
  get  a
  3
  %
  0
  =
  nf  skip2
  "Fizz"
  out
skip2
  100
  get  a
  >
  if  end
  get  a
  out
  jmp  loop
"""
|> Main.start()





```

# 実行結果

```
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 main do

        a = 0
        Va.set(a)
    loop(1)
end
def loop(v) do
    if v == 0 do
 else

        a = Va.get()
        a = a + 1
        Va.set(a)
        a = Va.get()
        if rem(a, 15) == 0 do
        IO.puts("FizzBuzz")
        loop(1)
    end
        a = Va.get()
        if rem(a, 5) == 0 do
        IO.puts("Buzz")
        loop(1)
    end
        a = Va.get()
        if rem(a, 3) == 0 do
        IO.puts("Fizz")
        loop(1)
    end
        a = Va.get()
    if a > 100 do
      loop(0)
    else

        a = Va.get()
        IO.puts(a)
                loop(1)
		    end
		end
	end
end
Main.main()
```

# 生成したコードを実行

https://paiza.io/projects/iaGanEW5DWcEOGhAH3jEcg

# 成果物

https://paiza.io/projects/SCNlI3P1PD1b70puAoxC0g



以上。