Skip to content

Instantly share code, notes, and snippets.

@Lysxia
Created September 26, 2017 01:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lysxia/6532318fb26f985eeae06eae5b50c0cf to your computer and use it in GitHub Desktop.
Save Lysxia/6532318fb26f985eeae06eae5b50c0cf to your computer and use it in GitHub Desktop.
-module(sm).
-export([multi_step/2
]).
-type lint() :: {low|high, integer()}.
-type instr() :: {push, lint()} | {pop, pos_integer()} | add.
-type state() :: {non_neg_integer(), [lint()]}.
-type prog() :: [instr()].
-spec step(state(), prog()) -> state() | halt | {err, string()}.
step({PC, S}, Is) ->
case nth(PC, Is) of
none when PC =:= length(Is) -> halt;
none -> {err, "pc out"};
{push, X} -> {PC+1, [X|S]};
{pop, N} ->
case delete(N, S) of
err -> {err, "pop"};
S1 -> {PC+1, S1}
end;
add ->
case S of
[{_, X},{_,Y}|S2] -> {PC+1, [{low,X+Y}|S2]};
_ -> {err, "add"}
end
end.
nth(0, [X|_]) -> X;
nth(N, [_|Xs]) -> nth(N-1, Xs);
nth(_, []) -> none.
-spec delete(pos_integer(), list()) -> list() | err.
delete(N, Xs) -> delete_(N, [], Xs).
delete_(0, Ys, [_|Xs]) -> Ys ++ Xs;
delete_(N, Ys, [X|Xs]) -> delete_(N-1, [X|Ys], Xs);
delete_(_, _, _) -> err.
-spec multi_step(state(), prog()) -> [integer()] | err.
multi_step(St = {_, S}, Is) ->
case step(St, Is) of
{err, _} -> err;
halt -> S;
St2 -> multi_step(St2, Is)
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment