Task

Create a stack-based evaluator for an expression in   reverse Polish notation (RPN)   that also shows the changes in the stack as each individual token is processed as a table.



 Assume an input of a correct, space separated, string of tokens of an RPN expression
 Test with the RPN expression generated from the   Parsing/Shunting-yard algorithm   task: 

         3 4 2 * 1 5 - 2 3 ^ ^ / + 

 Print or display the output here


Notes

    ^    means exponentiation in the expression above.
    /    means division.


See also

   Parsing/Shunting-yard algorithm for a method of generating an RPN from an infix expression.
   Several solutions to 24 game/Solve make use of RPN evaluators (although tracing how they work is not a part of that task).
   Parsing/RPN to infix conversion.
   Arithmetic evaluation.


rpn(L) :-
	writeln('Token  Action                             Stack'),
	parse(L, [],[X] ,[]),
	format('~nThe final output value is ~w~n', [X]).
 
% skip spaces
parse([X|L], St) -->
	{char_type(X, white)},
	parse(L, St).
 
% detect operators
parse([Op|L], [Y, X | St]) -->
	{ is_op(Op, X, Y, V),
	  writef('    %s', [[Op]]),
	  with_output_to(atom(Str2), writef('Apply %s on top of stack', [[Op]])),
	  writef('  %35l', [Str2]),
	  writef('%w\n', [[V | St]])},
	parse(L, [V | St]).
 
% detect number
parse([N|L], St) -->
	{char_type(N, digit)},
	parse_number(L, [N], St).
 
% string is finished
parse([], St) --> St.
 
% compute numbers
parse_number([N|L], NC, St) -->
	{char_type(N, digit)},
	parse_number(L, [N|NC], St).
 
parse_number(S, NC, St) -->
	{ reverse(NC, RNC),
	  number_chars(V, RNC),
	  writef('%5r', [V]),
	  with_output_to(atom(Str2), writef('Push num %w on top of stack', [V])),
	  writef('  %35l', [Str2]),
	  writef('%w\n', [[V | St]])},
	parse(S, [V|St]).
 
% defining operations
is_op(42, X, Y, V) :-	V is X*Y.
is_op(43, X, Y, V) :-	V is X+Y.
is_op(45, X, Y, V) :-	V is X-Y.
is_op(47, X, Y, V) :-	V is X/Y.
is_op(94, X, Y, V) :-	V is X**Y.