Awhile ago I posted about brainf*ck in Haskell. Since that unsuccessful attempt, I've spent some time (3 days) learning Erlang, and have, to some extent, written a somewhat functioning interpreter in it.
Code: Select all
-module(bf).
-export([bf/1, test/0]).
-include_lib("kernel/include/file.hrl").
jump(reverse, [[DH | DT], D, [EH | ET]]) ->
if
D =:= '[' -> [DT, DH, [D | [EH] ++ ET]];
true -> jump(reverse, [[D | [DH] ++ DT], EH, ET])
end;
jump(forward, [[DH | DT], D, [EH | ET]]) ->
if
D =:= ']' -> [DT, DH, [D | [EH] ++ ET]];
true -> jump(forward, [DT, DH, [D | [EH] ++ ET]])
end.
bf({[[IHH | IHT], I, [ITH | ITT]], [[AHH | AHT], A, [ATH | ATT]]}) ->
bf(case I of
'+' -> {[IHT, IHH, [I | [ITH] ++ ITT]], [[AHH | AHT], A + 1, [ATH | ATT]]};
'-' -> {[IHT, IHH, [I | [ITH] ++ ITT]], [[AHH | AHT], A - 1, [ATH | ATT]]};
'>' -> {[IHT, IHH, [I | [ITH] ++ ITT]], [AHT, AHH, [A | [ATH] ++ ATT]]};
'<' -> {[IHT, IHH, [I | [ITH] ++ ITT]], [[A | [AHH] ++ AHT], ATH, ATT]};
'.' ->
io:format("~s", [[A]]),
{[IHT, IHH, [I | [ITH] ++ ITT]], [[AHH | AHT], A, [ATH | ATT]]};
',' ->
[O | _] = io:get_chars('', 1),
{[IHT, IHH, [I | [ITH] ++ ITT]], [[AHH | AHT], O, [ATH | ATT]]};
'[' -> {if
A == 0 -> jump(forward, [[IHH | IHT], I, [ITH | ITT]]);
true -> [IHT, IHH, [I | [ITH] ++ ITT]]
end,
[[AHH | AHT], A, [ATH | ATT]]};
']' -> {if
A =/= 0 -> jump(reverse, [[IHH | IHT], I, [ITH | ITT]]);
true -> [IHT, IHH, [I | [ITH] ++ ITT]]
end, [[AHH | AHT], A, [ATH | ATT]]};
_ -> {[IHT, IHH, [I | [ITH] ++ ITT]], [[AHH | AHT], A, [ATH | ATT]]}
end);
bf(_) -> [].
test() ->
bf({[['>','+','+','+','+','+','+','[','<','-','-','-',
'-','-','-','-','-','>','-',']',',','[','<','+','>','-',']','<','.', eoi], ',', [0]], [[0, 0], 0, [0, 0]]}).
I'm not really concerned if its functioning properly or anything, I just thought I'd share my enthusiasm. If I get really creative I could even make it a server like module.
Yeah, so that's all. Erlang is an interesting language, no?
Toodles.