------------------------------------------------------------------------------ ------------------------------------------------------------------------------ -- This file is part of 'Finite Field Arithmetic', aka 'FFA'. -- -- -- -- (C) 2019 Stanislav Datskovskiy ( www.loper-os.org ) -- -- http://wot.deedbot.org/17215D118B7239507FAFED98B98228A001ABFFC7.html -- -- -- -- You do not have, nor can you ever acquire the right to use, copy or -- -- distribute this software ; Should you use this software for any purpose, -- -- or copy and distribute it to anyone or in any manner, you are breaking -- -- the laws of whatever soi-disant jurisdiction, and you promise to -- -- continue doing so for the indefinite future. In any case, please -- -- always : read and understand any software ; verify any PGP signatures -- -- that you use - for any purpose. -- -- -- -- See also http://trilema.com/2015/a-new-software-licensing-paradigm . -- ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ with OS; use OS; with CmdLine; use CmdLine; with FFA_RNG; use FFA_RNG; with FFA_Calc; use FFA_Calc; -- This is the 'main' procedure of Peh for all Unixlike OS. procedure Peh is PehDim : Peh_Dimensions; -- Operator-specified spacetime footprint. RNG : RNG_Device; -- The selected RNG device. Peh requires a RNG. begin -- If a valid number of command line params was NOT given, print a likbez : if Arg_Count < 5 or Arg_Count > 6 then Eggog("Usage: ./peh WIDTH HEIGHT TAPESPACE LIFE [/dev/rng]"); end if; declare Arg1 : CmdLineArg; Arg2 : CmdLineArg; Arg3 : CmdLineArg; Arg4 : CmdLineArg; begin -- Get commandline args: Get_Argument(1, Arg1); -- First mandatory arg : Width Get_Argument(2, Arg2); -- Second mandatory arg : Height Get_Argument(3, Arg3); -- Third mandatory arg : TapeSpace Get_Argument(4, Arg4); -- Fourth mandatory arg : Life if Arg_Count = 6 then -- A RNG was specified (Arg_Count includes program name itself) declare Arg5 : CmdLineArg; begin Get_Argument(5, Arg5); -- Fifth arg (optional) : RNG device -- Ada.Sequential_IO chokes on paths with trailing whitespace! -- So we have to give it a trimmed path. But we can't use -- Ada.Strings.Fixed.Trim, because it suffers from -- SecondaryStackism-syphilis. Instead we are stuck doing this: Init_RNG(RNG, Arg5(Arg5'First .. Len_Arg(5))); end; else -- If RNG was NOT explicitly specified: Init_RNG(RNG); -- Use the machine default. The '?' Op requires a RNG. -- Warn the operator that we are going to use the default system RNG: Achtung("WARNING: The '?' command will use DEFAULT entropy source : " & Default_RNG_Path & " !"); -- Generally, you do NOT want this, outside of noob exploration/tests. end if; -- Parse the four mandatory arguments into Positives: PehDim.Width := Positive'Value( Arg1 ); PehDim.Height := Positive'Value( Arg2 ); PehDim.TapeSpace := Peh_Tape_Range'Value( Arg3 ); PehDim.Life := Natural'Value( Arg4 ); exception -- There was an attempt to parse garbage in the init parameters: when others => Eggog("Invalid arguments!"); end; -- Validate requested Peh Dimensions. If invalid, program will terminate. Validate_Peh_Dimensions(PehDim); -- Read, from Unix 'standard input' , and then execute, the Tape: declare -- The current Tape input symbol Tape_Read_Char : Character; -- The TapeSpace TapeSpace : Peh_Tapes(1 .. PehDim.TapeSpace) := (others => ' '); -- 'End of File' condition when reading : EOF : Boolean := False; -- Will contain the Verdict produced by the Tape: Verdict : Peh_Verdicts; begin -- Attempt to read the entire expected Tapespace length, and no more: for TapePosition in TapeSpace'Range loop -- Attempt to receive a symbol from the standard input: if Read_Char(Tape_Read_Char) then -- Save the successfully-read symbol to the TapeSpace: TapeSpace(TapePosition) := Tape_Read_Char; else -- Got an EOF instead of a symbol: EOF := True; if TapePosition /= TapeSpace'Length then Achtung("WARNING: Short Tape: Tapespace filled to position:" & Peh_Tape_Range'Image(TapePosition) & " of" & Peh_Tape_Range'Image(TapeSpace'Last) & "."); end if; end if; exit when EOF; -- When EOF, halt reading, and proceed to execution. end loop; -- Execute Peh over the given Tape, on Peh Machine with given dimensions: Verdict := Peh_Machine(Dimensions => PehDim, Tape => TapeSpace, RNG => RNG); -- A correctly-written Peh Tape is expected to produce a Verdict. -- On Unix, we will give it to the caller process via the usual means: case Verdict is -- Tape produced a Verdict of 'Yes' : when Yes => Quit(Yes_Code); -- Tape produced a Verdict of 'No' : when No => Quit(No_Code); -- Tape ran to completion without producing any Verdict at all. -- Outside of simple test scenarios, noob explorations, etc., -- this usually means that there is a logical mistake in the -- Tape somewhere, and we will warn the operator: when Mu => Achtung("WARNING: Tape terminated without a Verdict."); Quit(Mu_Code); end case; -- If the Tape aborted on account of a fatal error condition (e.g. div0) -- Peh will Quit(Sad_Code) (see E(..) in ffa_calc.adb .) -- Therefore, Peh ALWAYS returns one of FOUR possible Unix return-codes: -- -2, -1, 0, 1. (see os.ads .) end; end Peh;