Skip to content

Instantly share code, notes, and snippets.

@wstucco
Last active October 9, 2022 01:47
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save wstucco/bc6a5037fe8b1fbf1cf0 to your computer and use it in GitHub Desktop.
defmodule Brainfuck do
# opcodes
@op_vinc "+" # increment value at memory address
@op_vdec "-" # decrement value at memory address
@op_pinc ">" # increment memory address
@op_pdec "<" # decrement memory address
@op_putc "." # output byte at memory address
@op_getc "," # input byte into memory address
@op_lbeg "[" # loop begin
@op_lend "]" # loop end
@empty ""
def run(program), do: run(program, 0, [0], @empty)
# final condition
defp run(@empty, addr, mem, output), do: {addr, mem, output}
# commands
defp run(@op_vinc <> rest, addr, mem, output) do
run(rest, addr, mem |> inc_at(addr), output)
end
defp run(@op_vdec <> rest, addr, mem, output) do
run(rest, addr, mem |> dec_at(addr), output)
end
defp run(@op_pinc <> rest, addr, mem, output) do
run(rest, addr+1, mem, output)
end
defp run(@op_pdec <> rest, addr, mem, output) do
run(rest, addr-1, mem, output)
end
defp run(@op_putc <> rest, addr, mem, output) do
run(rest, addr, mem, output <> (mem |> char_at addr))
end
defp run(@op_getc <> rest, addr, mem, output) do
val = case IO.getn("Input\n", 1) do
:eof -> 0
c -> c
end
run(rest, addr, mem |> put_at(addr, val), output)
end
# drop every other character
defp run(<<_>> <> rest, addr, mem, output), do: run(rest, addr, mem, output)
# helpers
defp inc_at(list, addr), do: List.update_at(list, addr, &(&1+1 |> rem 255))
defp dec_at(list, addr), do: List.update_at(list, addr, &(&1-1 |> rem 255))
defp put_at(list, addr, val), do: List.replace_at(list, addr, val)
defp byte_at(list, addr), do: list |> Enum.at addr
defp char_at(list, addr), do: [list |> byte_at addr] |> to_string
end
@mtwtkman
Copy link

Thanks for your reply!
And i'm glad to read next part this topic :)

I can feel that pattern matching and guard clauses are really elegant, beautiful.

@wstucco
Copy link
Author

wstucco commented Nov 11, 2014

Thanks to you!
the second part is out, you can read it at http://dev.mikamai.com/post/102283561929/elixir-as-a-parsing-tool-writing-a-brainfuck

@ylluminate
Copy link

@wstucco you might consider adding elixir benchmarks to: https://github.com/kostya/benchmarks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment