-
+ DFE0396CAE073DABBBFB280A5075344B9CD5149F062004DB94D849558575AF12C61A992BB68133968E76A864065186714E97C146373FFCC769E20B4EF50A4859
ffa/ffacalc/peh.adb
(0 . 0)(1 . 173)
870 ------------------------------------------------------------------------------
871 ------------------------------------------------------------------------------
872 -- This file is part of 'Finite Field Arithmetic', aka 'FFA'. --
873 -- --
874 -- (C) 2019 Stanislav Datskovskiy ( www.loper-os.org ) --
875 -- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html --
876 -- --
877 -- You do not have, nor can you ever acquire the right to use, copy or --
878 -- distribute this software ; Should you use this software for any purpose, --
879 -- or copy and distribute it to anyone or in any manner, you are breaking --
880 -- the laws of whatever soi-disant jurisdiction, and you promise to --
881 -- continue doing so for the indefinite future. In any case, please --
882 -- always : read and understand any software ; verify any PGP signatures --
883 -- that you use - for any purpose. --
884 -- --
885 -- See also http://trilema.com/2015/a-new-software-licensing-paradigm . --
886 ------------------------------------------------------------------------------
887 ------------------------------------------------------------------------------
888
889 with OS; use OS;
890 with CmdLine; use CmdLine;
891 with FFA_RNG; use FFA_RNG;
892 with FFA_Calc; use FFA_Calc;
893
894
895 -- This is the 'main' procedure of Peh for all Unixlike OS.
896 procedure Peh is
897
898 PehDim : Peh_Dimensions; -- Operator-specified spacetime footprint.
899
900 RNG : RNG_Device; -- The selected RNG device. Peh requires a RNG.
901
902 begin
903
904 -- If a valid number of command line params was NOT given, print a likbez :
905 if Arg_Count < 5 or Arg_Count > 6 then
906 Eggog("Usage: ./peh WIDTH HEIGHT TAPESPACE LIFE [/dev/rng]");
907 end if;
908
909 declare
910 Arg1 : CmdLineArg;
911 Arg2 : CmdLineArg;
912 Arg3 : CmdLineArg;
913 Arg4 : CmdLineArg;
914 begin
915
916 -- Get commandline args:
917 Get_Argument(1, Arg1); -- First mandatory arg : Width
918 Get_Argument(2, Arg2); -- Second mandatory arg : Height
919 Get_Argument(3, Arg3); -- Third mandatory arg : TapeSpace
920 Get_Argument(4, Arg4); -- Fourth mandatory arg : Life
921
922 if Arg_Count = 6 then
923
924 -- A RNG was specified (Arg_Count includes program name itself)
925 declare
926 Arg5 : CmdLineArg;
927 begin
928 Get_Argument(5, Arg5); -- Fifth arg (optional) : RNG device
929
930 -- Ada.Sequential_IO chokes on paths with trailing whitespace!
931 -- So we have to give it a trimmed path. But we can't use
932 -- Ada.Strings.Fixed.Trim, because it suffers from
933 -- SecondaryStackism-syphilis. Instead we are stuck doing this:
934 Init_RNG(RNG, Arg5(Arg5'First .. Len_Arg(5)));
935 end;
936
937 else
938
939 -- If RNG was NOT explicitly specified:
940 Init_RNG(RNG); -- Use the machine default. The '?' Op requires a RNG.
941
942 -- Warn the operator that we are going to use the default system RNG:
943 Achtung("WARNING: The '?' command will use DEFAULT entropy source : "
944 & Default_RNG_Path & " !");
945 -- Generally, you do NOT want this, outside of noob exploration/tests.
946
947 end if;
948
949 -- Parse the four mandatory arguments into Positives:
950 PehDim.Width := Positive'Value( Arg1 );
951 PehDim.Height := Positive'Value( Arg2 );
952 PehDim.TapeSpace := Peh_Tape_Range'Value( Arg3 );
953 PehDim.Life := Natural'Value( Arg4 );
954
955 exception
956
957 -- There was an attempt to parse garbage in the init parameters:
958 when others =>
959 Eggog("Invalid arguments!");
960
961 end;
962
963 -- Validate requested Peh Dimensions. If invalid, program will terminate.
964 Validate_Peh_Dimensions(PehDim);
965
966 -- Read, from Unix 'standard input' , and then execute, the Tape:
967 declare
968
969 -- The current Tape input symbol
970 Tape_Read_Char : Character;
971
972 -- The TapeSpace
973 TapeSpace : Peh_Tapes(1 .. PehDim.TapeSpace) := (others => ' ');
974
975 -- 'End of File' condition when reading :
976 EOF : Boolean := False;
977
978 -- Will contain the Verdict produced by the Tape:
979 Verdict : Peh_Verdicts;
980
981 begin
982
983 -- Attempt to read the entire expected Tapespace length, and no more:
984 for TapePosition in TapeSpace'Range loop
985
986 -- Attempt to receive a symbol from the standard input:
987 if Read_Char(Tape_Read_Char) then
988
989 -- Save the successfully-read symbol to the TapeSpace:
990 TapeSpace(TapePosition) := Tape_Read_Char;
991
992 else
993
994 -- Got an EOF instead of a symbol:
995 EOF := True;
996 if TapePosition /= TapeSpace'Length then
997 Achtung("WARNING: Short Tape: Tapespace filled to position:" &
998 Peh_Tape_Range'Image(TapePosition) & " of" &
999 Peh_Tape_Range'Image(TapeSpace'Last) & ".");
1000 end if;
1001
1002 end if;
1003
1004 exit when EOF; -- When EOF, halt reading, and proceed to execution.
1005
1006 end loop;
1007
1008 -- Execute Peh over the given Tape, on Peh Machine with given dimensions:
1009 Verdict := Peh_Machine(Dimensions => PehDim,
1010 Tape => TapeSpace,
1011 RNG => RNG);
1012
1013 -- A correctly-written Peh Tape is expected to produce a Verdict.
1014 -- On Unix, we will give it to the caller process via the usual means:
1015 case Verdict is
1016
1017 -- Tape produced a Verdict of 'Yes' :
1018 when Yes =>
1019 Quit(Yes_Code);
1020
1021 -- Tape produced a Verdict of 'No' :
1022 when No =>
1023 Quit(No_Code);
1024
1025 -- Tape ran to completion without producing any Verdict at all.
1026 -- Outside of simple test scenarios, noob explorations, etc.,
1027 -- this usually means that there is a logical mistake in the
1028 -- Tape somewhere, and we will warn the operator:
1029 when Mu =>
1030 Achtung("WARNING: Tape terminated without a Verdict.");
1031 Quit(Mu_Code);
1032
1033 end case;
1034
1035 -- If the Tape aborted on account of a fatal error condition (e.g. div0)
1036 -- Peh will Quit(Sad_Code) (see E(..) in ffa_calc.adb .)
1037 -- Therefore, Peh ALWAYS returns one of FOUR possible Unix return-codes:
1038 -- -2, -1, 0, 1. (see os.ads .)
1039
1040 end;
1041
1042 end Peh;