paiza.ioでelixir その320

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

# 練習問題
俺言語を俺cpuに変換するコンパイラを書け。

# 投入するソース

```
10 a=1
20 b=0
30 b=b+a
40 a=a+1
50 #=a<11*30
60 ?=b
70 #=0
```

# 期待するコード

```
  1
  set  a
  0
  set  b
loop  get  b
  get  a
  +
  set  b
  get  a
  1
  +
  set  a
  get  a
  11
  <
  if  loop
  get  b
  outn
  jmp  end

```

# サンプルコード

```

defmodule Cpu do
	def start_link do
		Agent.start_link(fn ->
			%{loop: "", u: ""}
		end, name: __MODULE__)
	end
    def a(n, s) do
		Agent.update(__MODULE__, fn v ->
		    cond do
			String.at(s, 0) == "a" ->
                cond do
			    String.at(s, 1) == "+" ->
                    cond do
                    n == v.loop ->
    	                str = "loop  get  a\n  " <> String.slice(s, 2, 2) <> "\n  +\n  set  a\n"
                        %{v | u: v.u <> str}
                    true ->
    	                str = "  get  a\n  " <> String.slice(s, 2, 2) <> "\n  +\n  set  a\n"
                        %{v | u: v.u <> str}
                    end
                true ->
                    str = "ok"
                    %{v | u: v.u <> str}
                end
			String.at(s, 0) == "b" ->
                cond do
			    String.at(s, 1) == "+" ->
                    cond do
                    n == v.loop ->
    	                str = "loop  get  b\n  " <> String.slice(s, 2, 2) <> "\n  +\n  set  a\n"
                        %{v | u: v.u <> str}
                    true ->
    	                str = "  get  b\n  " <> String.slice(s, 2, 2) <> "\n  +\n  set  a\n"
                        %{v | u: v.u <> str}
                    end
                true ->
                    str = "ok"
                    %{v | u: v.u <> str}
                end
			true ->
    	        str = "  " <> String.slice(s, 0, 2) <> "\n  set  a\n"
                %{v | u: v.u <> str}
			end
		end)
    end
    def b(n, s) do
		Agent.update(__MODULE__, fn v ->
		    cond do
			String.at(s, 0) == "a" ->
                cond do
			    String.at(s, 1) == "+" ->
                    cond do
                    n == v.loop ->
    	                str = "loop  get  a\n  " <> String.slice(s, 2, 2) <> "\n  +\n  set  b\n"
                        %{v | u: v.u <> str}
                    true ->
    	                str = "  get  a\n  " <> String.slice(s, 2, 2) <> "\n  +\n  set  b\n"
                        %{v | u: v.u <> str}
                    end
                true ->
                    str = "ok"
                    %{v | u: v.u <> str}
                end
			String.at(s, 0) == "b" ->
                cond do
			    String.at(s, 1) == "+" ->
                    cond do
                    n == v.loop ->
    	                str = "loop  get  b\n  get  " <> String.slice(s, 2, 2) <> "\n  +\n  set  b\n"
                        %{v | u: v.u <> str}
                    true ->
    	                str = "  get  b\n  " <> String.slice(s, 2, 2) <> "\n  +\n  set  b\n"
                        %{v | u: v.u <> str}
                    end
                true ->
                    str = "ok"
                    %{v | u: v.u <> str}
                end
			true ->
    	        str = "  " <> String.slice(s, 0, 2) <> "\n  set  b\n"
                %{v | u: v.u <> str}
			end
		end)
    end
    def pc(s) do
		Agent.update(__MODULE__, fn v ->
		    cond do
			String.at(s, 0) == "a" ->
                cond do
			    String.at(s, 1) == "<" ->
	                str = "  get  a\n  " <> String.slice(s, 2, 2) <> "\n  <\n  if  loop\n"
                    %{v | u: v.u <> str}
                true ->
                    str = "ok"
                    %{v | u: v.u <> str}
                end
			String.at(s, 0) == "b" ->
                cond do
			    String.at(s, 1) == "<" ->
	                str = "  get  b\n  " <> String.slice(s, 2, 2) <> "\n  <\n  if  loop\n"
                    %{v | u: v.u <> str}
                true ->
                    str = "ok"
                    %{v | u: v.u <> str}
                end
			String.at(s, 0) == "0" ->
    	        str = "  jmp  end\n"
                %{v | u: v.u <> str}
			true ->
    	        str = "  ok pc\n"
                %{v | u: v.u <> str}
			end
		end)
    end
    def pr(n, s) do
		Agent.update(__MODULE__, fn v ->
		    cond do
			String.at(s, 0) == "a" ->
                cond do
                n == v.loop ->
	                str = "loop  get  a\n  outn\n"
                    %{v | u: v.u <> str}
                true ->
	                str = "  get  a\n  outn\n"
                    %{v | u: v.u <> str}
                end
			String.at(s, 0) == "b" ->
                cond do
                n == v.loop ->
	                str = "loop  get  b\n  outn\n"
                    %{v | u: v.u <> str}
                true ->
	                str = "  get  b\n  outn\n"
                    %{v | u: v.u <> str}
                end
			true ->
    	        str = "  ok pr\n"
                %{v | u: v.u <> str}
			end
		end)
    end
    def loop("0") do
        #IO.puts("ok")
    end
    def loop(l) do
		Agent.update(__MODULE__, fn v ->
		    s = String.split(l, "*")
            %{v | loop: Enum.at(s, 1)}
		end)
	end
    def print() do
		Agent.get(__MODULE__, fn v ->
            #IO.inspect(v)
            IO.puts(v.u)
		end)
	end
end


defmodule Main do
    def line() do
        str = """
10 a=1
20 b=0
30 b=b+a
40 a=a+1
50 #=a<11*30
60 ?=b
70 #=0
"""
        Enum.map(String.split(str, "\n", trim: true), fn l ->
		    s = String.split(l, " ")
		    cond do
  		    String.first(Enum.at(s, 1)) == "a" ->
  		        v = String.split(Enum.at(s, 1), "=")
	  	        Cpu.a(Enum.at(s, 0), Enum.at(v, 1))
  		    String.first(Enum.at(s, 1)) == "b" ->
  		        v = String.split(Enum.at(s, 1), "=")
	  	        Cpu.b(Enum.at(s, 0), Enum.at(v, 1))
  		    String.first(Enum.at(s, 1)) == "#" ->
  		        v = String.split(Enum.at(s, 1), "=")
	  	        Cpu.pc(Enum.at(v, 1))
  		    String.first(Enum.at(s, 1)) == "?" ->
  		        v = String.split(Enum.at(s, 1), "=")
	  	        Cpu.pr(Enum.at(s, 0), Enum.at(v, 1))
		    true ->
		        nil
	        end
	    end)
	    Cpu.print()
    end
    def loop() do
        str = """
10 a=1
20 b=0
30 b=b+a
40 a=a+1
50 #=a<11*30
60 ?=b
70 #=0
"""
        Enum.map(String.split(str, "\n", trim: true), fn l ->
		    s = String.split(l, " ")
		    cond do
  		    String.first(Enum.at(s, 1)) == "#" ->
  		        v = String.split(Enum.at(s, 1), "=")
	  	        Cpu.loop(Enum.at(v, 1))
		    true ->
		        nil
	        end
	    end)
    end
end

Cpu.start_link
Main.loop()
Main.line()





```

# 成果物

https://paiza.io/projects/dbRTqzXvdx3JaqI2aWPp9Q


以上。