-- file: MFMathImpl1.mesa
-- Pascal-to-Mesa translator output, translated at October 31, 1985 4:28:00 pm PST
DIRECTORY
PascalBasic,
PascalWizardFiles,
MFTypes,
MFInteraction,
MFMath;
MFMathImpl1: PROGRAM IMPORTS PascalBasic, MFInteraction EXPORTS MFMath = PUBLIC
BEGIN OPEN PascalBasic, PascalWizardFiles, MFTypes, MFInteraction, MFMath;
--:91----97:--
ArithError: PascalBoolean;
--:97----129:
TwoToThe: LONG POINTER TO ARRAY PascalInteger[0..30] OF PascalInteger ← PascalStaticZone.NEW[ARRAY PascalInteger[0..30] OF PascalInteger];
SpecLog: LONG POINTER TO ARRAY PascalInteger[1..28] OF PascalInteger ← PascalStaticZone.NEW[ARRAY PascalInteger[1..28] OF PascalInteger];
--:129
--137:--SpecAtan: LONG POINTER TO ARRAY PascalInteger[1..26] OF Angle ← PascalStaticZone.NEW[ARRAY PascalInteger[1..26] OF Angle];
--:137----144:--
NSin: Fraction;
NCos: Fraction;
--:144----148:--Randoms: LONG POINTER TO ARRAY PascalInteger[0..54] OF Fraction ← PascalStaticZone.NEW[ARRAY PascalInteger[0..54] OF Fraction];
JRandom: PascalInteger[0..54];
ClearArith: PROCEDURE
=
BEGIN BEGIN IF Interaction=3 THEN NULL;PrintNl[133];Print[173]; END;
BEGIN HelpPtr←4;HelpLine↑[3]←174;HelpLine↑[2]←175;HelpLine↑[1]←176;
HelpLine↑[0]←177; END;Error[];ArithError←FALSE; END;--:99----100:
RoundDecimals: PROCEDURE[K: SmallNumber] RETURNS[RoundDecimalsResult: Scaled] =
BEGIN A:PascalInteger; A←0;
WHILE INT[K]>0 DO BEGIN K←K-1;A← (A+Dig↑[K]*131072)/10; END ENDLOOP ;
RoundDecimalsResult← PascalDIVPower2[(A+1),1]; END;--:102----107:
MakeFraction: PROCEDURE[P,Q: PascalInteger] RETURNS[MakeFractionResult: Fraction] =
BEGIN F:PascalInteger;N:PascalInteger;
Negative:PascalBoolean;BeCareful:PascalInteger;
IF P>=0 THEN Negative←FALSE ELSE BEGIN P←-P;Negative←TRUE; END;
IF Q<=0 THEN BEGIN IF Q=0 THEN Confusion[47];Q←-Q;
Negative← NOT Negative; END;N← P /Q;P← P MOD Q;
IF N>=8 THEN BEGIN ArithError←TRUE;
IF Negative THEN MakeFractionResult←-2147483647 ELSE MakeFractionResult←
2147483647; END ELSE BEGIN N←(N-1)*268435456;--108:--F←1;
DO BeCareful←P-Q;P←BeCareful+P;
IF P>=0 THEN F←F+F+1 ELSE BEGIN F←F+F;P←P+Q; END; IF F>=268435456 THEN EXIT; ENDLOOP;
BeCareful←P-Q;IF BeCareful+P>=0 THEN F←F+1--:108--;
IF Negative THEN MakeFractionResult←-(F+N) ELSE MakeFractionResult←F+N; END; END;
--:107----109:-- TakeFraction: PROCEDURE[Q: PascalInteger,F: Fraction] RETURNS[TakeFractionResult: PascalInteger]
=
BEGIN P:PascalInteger;Negative:PascalBoolean;N:PascalInteger;BeCareful:PascalInteger;--110:
IF F>=0 THEN Negative←FALSE ELSE BEGIN F←-F;Negative←TRUE; END;
IF Q<0 THEN BEGIN Q←-Q;Negative← NOT Negative; END;--:110--IF F<268435456 THEN N←0 ELSE BEGIN N← PascalDIVPower2[F ,28];
F← PascalMODPower2Mask[F ,268435455];
IF Q<=2147483647 /N THEN N←N*Q ELSE BEGIN ArithError←TRUE;
N←2147483647; END; END;F←F+268435456;--111:--P←134217728;
IF Q<1073741824 THEN DO IF PascalODD[F] THEN P← PascalDIVPower2[(P+Q),1] ELSE P← PascalDIVPower2[(P),1];F← PascalDIVPower2[(F),1];
IF F=1 THEN EXIT; ENDLOOP ELSE DO IF PascalODD[F] THEN P← P+PascalDIVPower2[(Q-P),1] ELSE P← PascalDIVPower2[(P),1];
F← PascalDIVPower2[(F),1]; IF F=1--:111-- THEN EXIT; ENDLOOP;BeCareful←N-2147483647;
IF BeCareful+P>0 THEN BEGIN ArithError←TRUE;N←2147483647-P; END;
IF Negative THEN TakeFractionResult←-(N+P) ELSE TakeFractionResult←N+P; END;--:109
--112:-- TakeScaled: PROCEDURE[Q: PascalInteger,F: Scaled] RETURNS[TakeScaledResult: PascalInteger] =
BEGIN P:PascalInteger;
Negative:PascalBoolean;N:PascalInteger;BeCareful:PascalInteger;--110:
IF F>=0 THEN Negative←FALSE ELSE BEGIN F←-F;Negative←TRUE; END;
IF Q<0 THEN BEGIN Q←-Q;Negative← NOT Negative; END;--:110--IF F<65536 THEN N←0 ELSE BEGIN N← PascalDIVPower2[F ,16];F← PascalMODPower2Mask[F ,65535];
IF Q<=2147483647 /N THEN N←N*Q ELSE BEGIN ArithError←TRUE;
N←2147483647; END; END;F←F+65536;--113:--P←32768;
IF Q<1073741824 THEN DO IF PascalODD[F] THEN P← PascalDIVPower2[(P+Q),1] ELSE P← PascalDIVPower2[(P),1];F← PascalDIVPower2[(F),1];
IF F=1 THEN EXIT; ENDLOOP ELSE DO IF PascalODD[F] THEN P← P+PascalDIVPower2[(Q-P),1] ELSE P← PascalDIVPower2[(P),1];
F← PascalDIVPower2[(F),1]; IF F=1--:113-- THEN EXIT; ENDLOOP;BeCareful←N-2147483647;
IF BeCareful+P>0 THEN BEGIN ArithError←TRUE;N←2147483647-P; END;
IF Negative THEN TakeScaledResult←-(N+P) ELSE TakeScaledResult←N+P; END;--:112
--114:-- MakeScaled: PROCEDURE[P,Q: PascalInteger] RETURNS[MakeScaledResult: Scaled] =
BEGIN F:PascalInteger;N:PascalInteger;
Negative:PascalBoolean;BeCareful:PascalInteger;
IF P>=0 THEN Negative←FALSE ELSE BEGIN P←-P;Negative←TRUE; END;
IF Q<=0 THEN BEGIN IF Q=0 THEN Confusion[47];Q←-Q;
Negative← NOT Negative; END;N← P /Q;P← P MOD Q;
IF N>=32768 THEN BEGIN ArithError←TRUE;
IF Negative THEN MakeScaledResult←-2147483647 ELSE MakeScaledResult←2147483647;
END ELSE BEGIN N←(N-1)*65536;--115:--F←1;DO BeCareful←P-Q;
P←BeCareful+P;IF P>=0 THEN F←F+F+1 ELSE BEGIN F←F+F;P←P+Q; END;
IF F>=65536 THEN EXIT; ENDLOOP;BeCareful←P-Q;IF BeCareful+P>=0 THEN F←F+1--:115--;
IF Negative THEN MakeScaledResult←-(F+N) ELSE MakeScaledResult←F+N; END; END;--:114
--116:-- Velocity: PROCEDURE[St,Ct,Sf,Cf: Fraction,T: Scaled] RETURNS[VelocityResult: Fraction]
=
BEGIN Acc, Num, Denom:PascalInteger;
Acc←TakeFraction[St-( PascalDIVPower2[Sf ,4]),Sf-( PascalDIVPower2[St ,4])];
Acc←TakeFraction[Acc,Ct-Cf];
Num←536870912+TakeFraction[Acc,379625062];
Denom←805306368+TakeFraction[Ct,497706707]+TakeFraction[Cf,307599661]
;IF T#65536 THEN Num←MakeScaled[Num,T];
IF PascalDIVPower2[Num ,2]>=Denom THEN VelocityResult←1073741824 ELSE VelocityResult←
MakeFraction[Num,Denom]; END;--:116----117:
AbVsCd: PROCEDURE[A,B,C,D: PascalInteger] RETURNS[AbVsCdResult: PascalInteger] =
BEGIN Q, R:PascalInteger;
--118:--IF A<0 THEN BEGIN A←-A;B←-B; END;IF C<0 THEN BEGIN C←-C;
D←-D; END;
{IF D<=0 THEN BEGIN IF B>=0 THEN IF((A=0)OR (B=0))AND ((C=0)OR (D=0)) THEN
BEGIN AbVsCdResult←0; GOTO Label10; END ELSE BEGIN AbVsCdResult←1; GOTO Label10; END;
IF D=0 THEN IF A=0 THEN BEGIN AbVsCdResult←0; GOTO Label10;
END ELSE BEGIN AbVsCdResult←-1; GOTO Label10; END;Q←A;A←C;C←Q;Q←-B;B←-D;D←Q;
END ELSE IF B<=0 THEN BEGIN IF B<0 THEN IF A>0 THEN BEGIN AbVsCdResult←-1;
GOTO Label10; END;IF C=0 THEN BEGIN AbVsCdResult←0; GOTO Label10;
END ELSE BEGIN AbVsCdResult←-1; GOTO Label10; END; END--:118--;
WHILE TRUE DO BEGIN Q← A /D;R← C /B;
IF Q#R THEN IF Q>R THEN BEGIN AbVsCdResult←1; GOTO Label10;
END ELSE BEGIN AbVsCdResult←-1; GOTO Label10; END;Q← A MOD D;R← C MOD B;
IF R=0 THEN IF Q=0 THEN BEGIN AbVsCdResult←0; GOTO Label10;
END ELSE BEGIN AbVsCdResult←1; GOTO Label10; END;IF Q=0 THEN BEGIN AbVsCdResult←-1;
GOTO Label10; END;A←B;B←Q;C←D;D←R; END ENDLOOP ;EXITS Label10 => NULL}; END;--:117----119:
FloorScaled: PROCEDURE[X: Scaled] RETURNS[FloorScaledResult: Scaled] =
BEGIN BeCareful:PascalInteger;
IF X>=0 THEN FloorScaledResult←X-( PascalMODPower2Mask[X ,65535]) ELSE BEGIN BeCareful←X
+1;FloorScaledResult←X+( PascalMODPower2Mask[(-BeCareful),65535])-65535; END; END;
FloorUnscaled: PROCEDURE[X: Scaled] RETURNS[FloorUnscaledResult: PascalInteger] =
BEGIN BeCareful:PascalInteger;
IF X>=0 THEN FloorUnscaledResult← PascalDIVPower2[X ,16] ELSE BEGIN BeCareful←X
+1;FloorUnscaledResult←-(1+( PascalDIVPower2[(-BeCareful),16])); END; END;
RoundUnscaled: PROCEDURE[X: Scaled] RETURNS[RoundUnscaledResult: PascalInteger] =
BEGIN BeCareful:PascalInteger;
IF X>=32768 THEN RoundUnscaledResult←1+( PascalDIVPower2[(X-32768),16]) ELSE IF
X>=- INT[32768 ] THEN RoundUnscaledResult←0 ELSE BEGIN BeCareful←X+1;
RoundUnscaledResult←-(1+( PascalDIVPower2[(-BeCareful-32768),16])); END; END;
END.