/* (c) 1999-2005, Rony G. Flatscher, Wirtschaftsuniversitaet Wien, Austria Europe
A *possible* solution to excercise # 12
*/
/* declare USER Exceptions which should get trapped (intercepted) */
SIGNAL ON USER UNKNOWN_INPUT_CURRENCY NAME tell_user
SIGNAL ON USER UNKNOWN_OUTPUT_CURRENCY NAME tell_user
SIGNAL ON USER AMOUNT_NOT_NUMERIC NAME tell_user
CALL euro ARG(1) /* call routine, pass first argument (string) to it */
EXIT /* at this point, exit program */
Tell_User : /* inform user of exception */
SAY "Aborting with the exception:" WORD( CONDITION( "C" ), 2 )
EXIT
/* routine named "euro" */
::ROUTINE euro PUBLIC /* "PUBLIC" makes this routine visible outside this module */
/* parse first three words, translate them into uppercase */
PARSE UPPER ARG InputCurrency Amount OutputCurrency .
CALL initialize /* initialize the "euro."-stem */
IF InputCurrency = "" THEN /* no amount given, show table of rate of exchange */
CALL DumpRates 1
ELSE IF Amount = "" THEN /* only one argument, presume it is an amount in EURO */
DO
IF DATATYPE( InputCurrency, "Number" ) = .false THEN
RAISE USER AMOUNT_NOT_NUMERIC /* raise user exception */
CALL DumpRates InputCurrency /* "InputCurrency" contains the EURO-amount */
END
ELSE IF OutputCurrency = "" THEN /* either no input or no output currency given */
DO
IF DATATYPE( Amount, "Number" ) THEN /* input currency is given */
DO
IF WORDPOS( InputCurrency, euro.eOrder ) = 0 THEN /* unknown currency */
RAISE USER UNKNOWN_INPUT_CURRENCY /* raise user exception */
EUR_Amount = Amount / euro.InputCurrency /* calc EUR-value */
CALL DumpRates EUR_Amount
END
ELSE /* output currency is given, input EUR */
DO
OutputCurrency = Amount /* shift arguments */
EUR_Amount = InputCurrency
InputCurrency = ""
IF DATATYPE( EUR_Amount, "Number" ) = .false THEN
RAISE USER AMOUNT_NOT_NUMERIC /* raise user exception */
IF WORDPOS( OutputCurrency, euro.eOrder ) = 0 THEN /* unknown currency */
RAISE USER UNKNOWN_OUTPUT_CURRENCY RETURN /* raise user exception */
SAY FORMAT( EUR_Amount, ,2) "EUR" "=" ,
FORMAT( EUR_Amount*euro.OutputCurrency, , 6 ) OutputCurrency
END
END
ELSE /* all arguments given */
DO
IF WORDPOS( InputCurrency, euro.eOrder ) = 0 THEN /* unknown currency */
RAISE USER UNKNOWN_INPUT_CURRENCY /* raise user exception */
IF DATATYPE( Amount, "Number" ) = .false THEN /* amount not a number */
RAISE USER AMOUNT_NOT_NUMERIC /* raise user exception */
IF WORDPOS( OutputCurrency, euro.eOrder ) = 0 THEN /* unknown currency */
RAISE USER UNKNOWN_OUTPUT_CURRENCY /* raise user exception */
EUR_Amount = Amount / euro.InputCurrency
SAY FORMAT( Amount ) InputCurrency "=" ,
FORMAT( EUR_Amount, ,2) "EUR" "=" ,
FORMAT( EUR_Amount*euro.OutputCurrency, , 6 ) OutputCurrency
END
EXIT /* at this point, exit program */
/* set a stem-array with the rates of exchanges */
Initialize : PROCEDURE EXPOSE euro. /* expose stem, i.e. belongs to caller */
euro.ats = 13.760300; euro.ATS.eCountry = "Austria (Schilling)"
euro.bef = 40.339900; euro.BEF.eCountry = "Belgium (Franc)"
euro.dem = 1.955830; euro.DEM.eCountry = "Germany (Mark)"
euro.eur = 1.000000; euro.EUR.eCountry = "Europe (Euro)"
euro.fim = 5.945730; euro.FIM.eCountry = "Finnland (Mark)"
euro.frf = 6.559570; euro.FRF.eCountry = "France (Franc)"
euro.iep = 0.787564; euro.IEP.eCountry = "Ireland (Pound)"
euro.itl = 1936.270000; euro.ITL.eCountry = "Italy (Lire)"
euro.luf = 40.339900; euro.LUF.eCountry = "Luxembourg (Franc)"
euro.nlg = 2.203710; euro.NLG.eCountry = "Netherlands (Gulden)"
euro.pte = 200.482000; euro.PTE.eCountry = "Portugal (Escudo)"
euro.esp = 166.386000; euro.ESP.eCountry = "Spain (Peseta)"
euro.grd = 340.750000; euro.GRD.eCountry = "Greece (Drachmen)"
/* determine processing order of currencies, will also be used as index
into "euro."-stem, hence UPPERCASE (!) spelling */
euro.eOrder = "ATS BEF DEM ESP FIM FRF IEP ITL LUF NLG PTE GRD"
RETURN
/* dump a list of values for the given EUR-amount */
DumpRates : PROCEDURE EXPOSE euro. /* expose stem, i.e. belongs to caller */
USE ARG EUR_Amount
/* number of digits in integer part, account for additional digits for ITL */
length = LENGTH( EUR_Amount % 1 ) + 4
DO i=1 TO WORDS( euro.eOrder )
index = WORD( euro.eOrder, i ) /* retrieve currency string */
SAY FORMAT( EUR_Amount, ,2) "EUR" "=" ,
FORMAT( EUR_Amount*euro.index, length, 6 ) index euro.index.eCountry
END
RETURN