### Perform operations on Roman numerals

```This program converts two roman numerals into integers, performs the user's
choice of calculation, and outputs the answer in roman.
------------------------------------------------------

procedure Roman is

-- Declare variables which will be used in main program out here

LEN1 : Integer:=0;
LEN2 : Integer:=0;

MaxRomanLength : CONSTANT integer := 20;
subtype RomanNumeralType is String(1..MaxRomanLength);

RomanNumeral1 : RomanNumeralType;
RomanNumeral2 : RomanNumeralType;

Input1 : Integer:=0;
Input2 : Integer:=0;

UserChoice : Integer:=0;

FinalInteger : Integer:=0;

--------------------------------------------------------------------------------

-- Function for checking Valid Input from the user
-- This function returns a boolean value
Function ValidRomanNumeral (PossibleNumeral : RomanNumeralType) Return
Boolean is

Position : Natural := 1; -- position we are checking in the input

begin -- ValidRomanNumeral
loop
If Position = MaxRomanLength Then
Return True;  -- we have reached the maximum length without
problems
Elsif PossibleNumeral(Position) = ' ' Then
Return True;   -- we have reached the actual end without
problems
Elsif PossibleNumeral(Position) = 'I' OR
PossibleNumeral(Position) = 'V'
OR PossibleNumeral(Position) = 'X' OR
PossibleNumeral(Position) = 'L'
OR PossibleNumeral(Position) = 'C' OR
PossibleNumeral(Position) = 'D'
OR PossibleNumeral(Position) = 'M' Then
Position := Position + 1;
Else
Return False;  -- we have a problem, so return false
end if;
end loop;
-- This will never happen, but it makes the compiler happy.
Return False;
end ValidRomanNumeral;

--------------------------------------------------------------------------------

-- Procedure for getting a valid roman numeral from the user
Procedure GetValidRomanNumeral (RomanNumeral1 : OUT RomanNumeralType;
RomanNumeral2 : OUT RomanNumeralType)
is

Length1 : Natural; -- Number of chars in first entry
Length2 : Natural; -- Number of chars in second entry

begin -- GetValidRomanNumeral
loop
RomanNumeral1 := (others => ' ');
RomanNumeral2 := (others => ' ');
Put(Item =>"Please enter the FIRST Roman numeral: ");
Get_Line(Item => RomanNumeral1, Last => Length1);

Put(Item =>"Please enter the SECOND Roman numeral: ");
Get_Line(Item => RomanNumeral2, Last => Length2);

LEN1 := Length1;
LEN2 := Length2;

-- Code to check the validity of the two user inputs
--exit when ValidRomanNumeral1(PossibleNumeral1 =>
RomanNumeral1); AND
--         ValidRomanNumeral2(PossibleNumeral2 =>
RomanNumeral2);

If ValidRomanNumeral(PossibleNumeral=>RomanNumeral1) then
If ValidRomanNumeral(PossibleNumeral=>RomanNumeral2)
then
Exit;
end if;
end if;

Put(Item => "Please make sure BOTH the Roman Numerals are
valid and try again");
New_Line;
end loop;
end GetValidRomanNumeral;

--------------------------------------------------------------------------------

Function RomanToNatural (RomanNumeral : RomanNumeralType) Return Natural is
Result : Natural := 0;  -- result variable
CurrentPosition : Natural := 1; -- the current position in
RomanNumeral being examined.
Value : Integer:=0; -- Value of the corresponding roman numeral
First  : Integer:=0;
Next : Integer:=0;

begin --RomanToNatural

ProcessValue: -- Loop to process the appropriate value from the user
Loop

If RomanNumeral(CurrentPosition) = 'M' then
Value := 1000;
elsif RomanNumeral(CurrentPosition) = 'D' then
Value := 500;
elsif RomanNumeral(CurrentPosition) = 'C' then
Value := 100;
elsif RomanNumeral(CurrentPosition) = 'L' then
Value := 50;
elsif RomanNumeral(CurrentPosition) = 'X' then
Value := 10;
elsif RomanNumeral(CurrentPosition) = 'V' then
Value := 5;
elsif RomanNumeral(CurrentPosition) = 'I' then
Value := 1;
elsif RomanNumeral(CurrentPosition) = ' ' then

exit;
end if;

-- If this is the first character then store the value
-- of it in the variable 'First'
If CurrentPosition = 1 then
First := Value;
end if;

Next := Value; -- Store the second value in this variable(2nd
iteration)

-- This is for the second Iteration. Check if the second value
-- is greater than the first value and perform the nescassary
-- steps.
if First < Next then
Result := (Next - First) + (Result - First);
else
Result := Result + Next;
end if;

-- Assign the value of first to next
-- for comparison in later cases
First := Next;

CurrentPosition := CurrentPosition + 1; -- Increment the counter
Variable

--exit when CurrentPosition = (LEN + 1); -- Exit the loop after the

end loop ProcessValue; -- End the loop here

Return Result; -- Return the final result to where function is being
called

end RomanToNatural; -- End the function

--------------------------------------------------------------------------------
-- This Function Gets a valid choice from the user
-- The user can chooose to perform arithmetic operations on the
-- Roman numerals. The choices are 1 through 4.
-- Will keep looping till the user gives correct Choice
Procedure GetValidChoice(ValidChoice : OUT Integer)is

Choice : Integer:=1;

begin

BotherUser:
loop
New_Line;
Put("Please choose one of the following operations to be
performed:");
New_line;
Put("1) Add the two Roman Numerals.");
New_line;
Put("2) Subtract the two Roman Numerals.");
New_Line;
Put("3) Multiply the two Roman Numerals.1");
New_Line;
Put("4)Divide the two Roman Numerals.");
New_Line;
Put("----------------------------------------------------");
New_Line;

If (choice>0) or (choice<=4) then
exit;
else
New_Line;
New_Line;
end if;

end loop BotherUser;

ValidChoice := Choice;

end GetValidChoice;
--------------------------------------------------------------------------------

-- This procedure process the valid choice and performs the
-- nescassary calculations on the Two user inputs
Procedure ProcessChoice(UserInput1 : IN Integer;
UserInput2 : IN Integer;
Choice     : IN Integer;
Output     : OUT Integer) IS

-- Write this procedure in the morning
-- what this essentially does is
-- it takes in userinput1 and userinput2 and Choice as IN Variables
-- According to the user's specified choice we can then compute the
possible
-- values and return Output
-- This value of output will the in turn be stored in a variable called
-- FinalInteger

-- declare variables here

Plus     : Integer:=0;
Minus    : Integer:=0;
Multiply : Integer:=0;
Divide   : Integer:=0;

begin -- ProcessChoice

-- Start checking for user choice and perform nescassary action

If (Choice = 1) then

Plus := UserInput1 + UserInput2;
Output := Plus;

elsif (Choice = 2) then

Minus := UserInput1 - UserInput2;
Output := Minus;

elsif (Choice = 3) then

Multiply := UserInput1 * UserInput2;
Output := Multiply;

elsif (Choice = 4) then

Divide := UserInput1 / UserInput2;
Output := Divide;
else
put("SOMETHING HAS GONE WRONG");

end if;

end ProcessChoice;
-------------------------------------------------------------------------
Procedure ConvertBack(ConvertWhat : IN Integer) is

Value : Integer;

begin

Value := ConvertWhat;
for I in 1..20 loop
if Value<=4000 and Value>=1 then

while Value>=1000 loop

Value:=Value - 1000;

end loop;

while Value>=500 loop

Value:=Value - 500;
end loop;

while Value>=100 loop
Value:=Value - 100;
end loop;

while Value>=50 loop
Value:=Value - 50;
end loop;

while Value>=10 loop
Value:=Value - 10;
end loop;

while Value>=5 loop
Value:=Value - 5;
end loop;

while Value>=1 loop
Value:=Value - 1;
end loop;

end if;
end loop;
end ConvertBack;
--------------------------------------------------------------------------------
begin -- Procedure Roman

Put("Welcome to the Roman Numeral Calculator program:");
New_Line(2);

-- Get the valid roman numeral from the user
-- This function returns two integer values in RomanInteger1 and
RomanInteger2
-- These values are the corresponding integer values of the entered roman
numerals
GetValidRomanNumeral(RomanNumeral1=>RomanNumeral1,
RomanNumeral2=>RomanNumeral2);

Input1 := RomanToNatural(RomanNumeral=>RomanNumeral1);
Input2 := RomanToNatural(RomanNumeral=>RomanNumeral2);

GetValidChoice(ValidChoice=>UserChoice);

ProcessChoice(UserInput1=>Input1,UserInput2=>Input2,Choice=>UserChoice,Output=>FinalInteger);

ConvertBack(ConvertWhat=>FinalInteger);
end Roman;
```

Contributed by: Samir
Contributed on: December 7, 2001