Execute HQ9+: Difference between revisions

Content added Content deleted
No edit summary
Line 299: Line 299:
<lang Erlang>% hq9+ Erlang implementation (JWL)
<lang Erlang>% hq9+ Erlang implementation (JWL)
% http://www.erlang.org/
% http://www.erlang.org/

-module(hq9p).
-module(hq9p).
-export([main/1]).
-export([main/1]).


hello() ->
%% Helper function printing bottles
io:format("Hello world!~n", []).
bottle(N) ->
case N of
1 -> io:format("One bottle ");
_ -> io:format("~w bottles ", [N])
end.


prog(Prog) ->
%% Implementation of machine instructions
io:format("~s~n", [Prog]).


hello() ->
bottle(0) ->
io:format("Hello world!~n").
io:format("No more bottles of beer ");

bottle(1) ->
io:format("1 bottle of beer ");


bottle(N) when N > 0 ->
prog(Prog) ->
io:format("~s~n", [Prog]).
io:format("~w bottles of beer ", [N]).
beer(0) ->
beer(0) ->
bottle(0), io:format("on the wall~n"),
io:format("No more bottles of beer on the wall~nNo more bottles of beer on the wall~nGo to the store and buy some more~n99 bottles of beer on the wall.~n");
bottle(0), io:format("on the wall~nGo to the store and buy some more~n"),
io:format("99 bottles of beer on the wall.~n");
beer(N) ->
beer(N) ->
io:format("~n"),
bottle(N), io:format("on the wall~n"),
bottle(N), io:format("of beer on the wall~n"),
bottle(N), io:format("~nTake one down and pass it around~n"),
bottle(N), io:format("of beer~nTake one down and pass it around~n"),
bottle(N-1), io:format("on the wall~n~n"),
beer(N-1).
bottle(N-1), io:format("of beer on the wall~n"),
beer(N-1).


inc(Acc) ->
inc(Acc) ->
Acc+1.
Acc+1.

%% Execute a single instruction

execute(Instruction, Prog, Acc) ->
execute(Instruction, Prog, Acc) ->
case Instruction of
case Instruction of
$H -> hello(), Acc;
$H -> hello(), Acc;
$Q -> prog(Prog), Acc;
$Q -> prog(Prog), Acc;
$9 -> beer(99), Acc;
$9 -> beer(99), Acc;
$+ -> inc(Acc);
$+ -> inc(Acc);
_ -> io:format("Invalid instruction: ~c~n", [Instruction]),
_ -> io:format("Invalid instruction: ~c~n", [Instruction]), Acc
end.
Acc
end.

%% Empty program, Program string, Accu
main([], _Prog, Acc) ->
main([], _Prog, Acc) ->
Acc;
Acc;

%% Instruction, Rest of program, Program string, Accu
main([Instruction | Rest], Prog, Acc) ->
main([Instruction | Rest], Prog, Acc) ->
NewAcc = execute(Instruction, Prog, Acc),
NewAcc = execute(Instruction, Prog, Acc),
main(Rest, Prog, NewAcc).
main(Rest, Prog, NewAcc).

%% Compile and execute
main(Prog) ->
main(Prog) ->
Compiled = string:to_upper(Prog),
Compiled = string:to_upper(Prog),
main(Compiled, Prog, 0).
main(Compiled, Prog, 0).

}</lang>


</lang>


=={{header|Forth}}==
=={{header|Forth}}==