/* (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