LoginSignup
1
0

paiza.ioでelixir その269

Last updated at Posted at 2023-12-21

概要

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()



成果物

以上。

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