WITH Integer_Stacks; USE Integer_Stacks;
WITH VStrings; USE VStrings;
FUNCTION Evaluate_RPN (X : IN VString) RETURN Integer IS
-- Pre: X is defined and represents an RPN arithmetic expression
-- of single digits and operators
-- Post: returns the value of the expression.
ZeroPos : Integer := Character'Pos ('0');
C : Character;
T : VString(MaxLength(X)) := X;
S : Stack(Capacity => 100);
Y, Z : Integer;
BEGIN -- Evaluate_RPN
IF IsEmpty (T) THEN
RETURN 0;
END IF;
LOOP
C := Head (T);
IF C IN '0' .. '9' THEN
Push (S, Character'POS (C) - ZeroPos); -- convert to integer first
ELSE
Y := Top (S);
Pop (S);
Z := Top (S);
Pop (S);
CASE C IS
WHEN '+' =>
Push (S, Z + Y);
WHEN '-' =>
Push (S, Z - Y);
WHEN '*' =>
Push (S, Z * Y);
WHEN '/' =>
Push (S, Z / Y);
WHEN OTHERS =>
NULL; -- skip bad characters, if any
END CASE;
END IF;
T := Tail (T);
EXIT WHEN IsEmpty (T);
END LOOP;
RETURN Top (S);
END Evaluate_RPN;