1 ------------------------------------------------------------------------------ 2 ------------------------------------------------------------------------------ 3 -- This file is part of 'Finite Field Arithmetic', aka 'FFA'. -- 4 -- -- 5 -- (C) 2019 Stanislav Datskovskiy ( www.loper-os.org ) -- 6 -- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html -- 7 -- -- 8 -- You do not have, nor can you ever acquire the right to use, copy or -- 9 -- distribute this software ; Should you use this software for any purpose, -- 10 -- or copy and distribute it to anyone or in any manner, you are breaking -- 11 -- the laws of whatever soi-disant jurisdiction, and you promise to -- 12 -- continue doing so for the indefinite future. In any case, please -- 13 -- always : read and understand any software ; verify any PGP signatures -- 14 -- that you use - for any purpose. -- 15 -- -- 16 -- See also http://trilema.com/2015/a-new-software-licensing-paradigm . -- 17 ------------------------------------------------------------------------------ 18 ------------------------------------------------------------------------------ 19 20 with OS; use OS; 21 with CmdLine; use CmdLine; 22 with FFA_RNG; use FFA_RNG; 23 with FFA_Calc; use FFA_Calc; 24 25 26 -- This is the 'main' procedure of Peh for all Unixlike OS. 27 procedure Peh is 28 29 PehDim : Peh_Dimensions; -- Operator-specified spacetime footprint. 30 31 RNG : RNG_Device; -- The selected RNG device. Peh requires a RNG. 32 33 begin 34 35 -- If a valid number of command line params was NOT given, print a likbez : 36 if Arg_Count < 5 or Arg_Count > 6 then 37 Eggog("Usage: ./peh WIDTH HEIGHT TAPESPACE LIFE [/dev/rng]"); 38 end if; 39 40 declare 41 Arg1 : CmdLineArg; 42 Arg2 : CmdLineArg; 43 Arg3 : CmdLineArg; 44 Arg4 : CmdLineArg; 45 begin 46 47 -- Get commandline args: 48 Get_Argument(1, Arg1); -- First mandatory arg : Width 49 Get_Argument(2, Arg2); -- Second mandatory arg : Height 50 Get_Argument(3, Arg3); -- Third mandatory arg : TapeSpace 51 Get_Argument(4, Arg4); -- Fourth mandatory arg : Life 52 53 if Arg_Count = 6 then 54 55 -- A RNG was specified (Arg_Count includes program name itself) 56 declare 57 Arg5 : CmdLineArg; 58 begin 59 Get_Argument(5, Arg5); -- Fifth arg (optional) : RNG device 60 61 -- Ada.Sequential_IO chokes on paths with trailing whitespace! 62 -- So we have to give it a trimmed path. But we can't use 63 -- Ada.Strings.Fixed.Trim, because it suffers from 64 -- SecondaryStackism-syphilis. Instead we are stuck doing this: 65 Init_RNG(RNG, Arg5(Arg5'First .. Len_Arg(5))); 66 end; 67 68 else 69 70 -- If RNG was NOT explicitly specified: 71 Init_RNG(RNG); -- Use the machine default. The '?' Op requires a RNG. 72 73 -- Warn the operator that we are going to use the default system RNG: 74 Achtung("WARNING: The '?' command will use DEFAULT entropy source : " 75 & Default_RNG_Path & " !"); 76 -- Generally, you do NOT want this, outside of noob exploration/tests. 77 78 end if; 79 80 -- Parse the four mandatory arguments into Positives: 81 PehDim.Width := Positive'Value( Arg1 ); 82 PehDim.Height := Positive'Value( Arg2 ); 83 PehDim.TapeSpace := Peh_Tape_Range'Value( Arg3 ); 84 PehDim.Life := Natural'Value( Arg4 ); 85 86 exception 87 88 -- There was an attempt to parse garbage in the init parameters: 89 when others => 90 Eggog("Invalid arguments!"); 91 92 end; 93 94 -- Validate requested Peh Dimensions. If invalid, program will terminate. 95 Validate_Peh_Dimensions(PehDim); 96 97 -- Read, from Unix 'standard input' , and then execute, the Tape: 98 declare 99 100 -- The current Tape input symbol 101 Tape_Read_Char : Character; 102 103 -- The TapeSpace 104 TapeSpace : Peh_Tapes(1 .. PehDim.TapeSpace) := (others => ' '); 105 106 -- 'End of File' condition when reading : 107 EOF : Boolean := False; 108 109 -- Will contain the Verdict produced by the Tape: 110 Verdict : Peh_Verdicts; 111 112 begin 113 114 -- Attempt to read the entire expected Tapespace length, and no more: 115 for TapePosition in TapeSpace'Range loop 116 117 -- Attempt to receive a symbol from the standard input: 118 if Read_Char(Tape_Read_Char) then 119 120 -- Save the successfully-read symbol to the TapeSpace: 121 TapeSpace(TapePosition) := Tape_Read_Char; 122 123 else 124 125 -- Got an EOF instead of a symbol: 126 EOF := True; 127 if TapePosition /= TapeSpace'Length then 128 Achtung("WARNING: Short Tape: Tapespace filled to position:" & 129 Peh_Tape_Range'Image(TapePosition) & " of" & 130 Peh_Tape_Range'Image(TapeSpace'Last) & "."); 131 end if; 132 133 end if; 134 135 exit when EOF; -- When EOF, halt reading, and proceed to execution. 136 137 end loop; 138 139 -- Execute Peh over the given Tape, on Peh Machine with given dimensions: 140 Verdict := Peh_Machine(Dimensions => PehDim, 141 Tape => TapeSpace, 142 RNG => RNG); 143 144 -- A correctly-written Peh Tape is expected to produce a Verdict. 145 -- On Unix, we will give it to the caller process via the usual means: 146 case Verdict is 147 148 -- Tape produced a Verdict of 'Yes' : 149 when Yes => 150 Quit(Yes_Code); 151 152 -- Tape produced a Verdict of 'No' : 153 when No => 154 Quit(No_Code); 155 156 -- Tape ran to completion without producing any Verdict at all. 157 -- Outside of simple test scenarios, noob explorations, etc., 158 -- this usually means that there is a logical mistake in the 159 -- Tape somewhere, and we will warn the operator: 160 when Mu => 161 Achtung("WARNING: Tape terminated without a Verdict."); 162 Quit(Mu_Code); 163 164 end case; 165 166 -- If the Tape aborted on account of a fatal error condition (e.g. div0) 167 -- Peh will Quit(Sad_Code) (see E(..) in ffa_calc.adb .) 168 -- Therefore, Peh ALWAYS returns one of FOUR possible Unix return-codes: 169 -- -2, -1, 0, 1. (see os.ads .) 170 171 end; 172 173 end Peh;