paiza.ioでelixir その269

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

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

# サンプルコード

```


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 sub() do
    
    end
    def mul() do
    
    end
    def div() do
    
    end
    def rem() do
    
    end
    def eq() do
        Stack.push("==")
    end
    def rnd() do
    
    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 #{v2} #{v0} #{v1} do
	    	    loop(0)
            else
        """)
	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, 1) == "+" ->
				add()
			Enum.at(s, 1) == "-" ->
				sub()
			Enum.at(s, 1) == "*" ->
				mul()
			Enum.at(s, 1) == "/" ->
				div()
			Enum.at(s, 1) == "%" ->
				rem()
			Enum.at(s, 1) == "=" ->
				eq()
			Enum.at(s, 1) == "rnd" ->
				rnd()
			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) == "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

"""
  1
  set  a
loop  
  get  a
  100
  >
  if  end
  get  a
  out
  get  a
  1
  +
  set  a
  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 = 1
Va.set(a)
    loop(1)
end
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
end

Main.main()



```

# 成果物

https://paiza.io/projects/XRr-rxujawlvSenCZ33S3Q


以上。