rpn('+', [B, A | R], [Res | R]) :- Res is A + B.
rpn('-', [B, A | R], [Res | R]) :- Res is A - B.
rpn('*', [B, A | R], [Res | R]) :- Res is A * B.
rpn('/', [B, A | R], [Res | R]) :- Res is A / B.
rpn('', Stack, Stack).
rpn(A, Instack, [Num | Instack]) :- atom_number(A, Num).
rpn(_, Stack, Stack) :- write(error), nl.

top(_, C) :- not(newline(C)).
top([], _) :- nl.
top([X | _], _) :- write(X), nl.

last_char([L], [], L).
last_char([F | R], [F | R2], L) :- last_char(R, R2, L).

gettoken(Token, LastChar) :-
        gettoken1(Chars),
        last_char(Chars, TokenChars, LastChar),
        string_to_list(S, TokenChars),
        string_to_atom(S, Token)
    .
gettoken1(Token) :- get0(C), gettoken2(C, Token).
gettoken2(C, [C]) :- whitespace(C).
gettoken2(C, [C | Token]) :- gettoken1(Token).

whitespace(C) :- newline(C); space(C).
newline(10).
newline(13).
space(32).

exec(Instack) :- 
        gettoken(Token, LastChar),
        rpn(Token, Instack, Outstack),
        top(Outstack, LastChar),
        exec(Outstack)
    .

main :- exec([]).

