using CommandLine; using MultiversalDiplomacy.Script; namespace MultiversalDiplomacy; internal class Program { static void Main(string[] args) { var parser = Parser.Default; var parseResult = parser.ParseArguments(args, typeof(ReplOptions)); parseResult .WithParsed(ExecuteRepl); } static void ExecuteRepl(ReplOptions args) { // Create a writer to the output file, if specified. StreamWriter? outputWriter = null; if (args.OutputFile is not null) { string fullPath = Path.GetFullPath(args.OutputFile); string outputPath = Directory.Exists(fullPath) ? Path.Combine(fullPath, $"{DateTime.UtcNow.ToString("yyyyMMddHHmmss")}.log") : fullPath; Console.WriteLine($"Echoing to {outputPath}"); outputWriter = File.AppendText(outputPath); } // Define an enumerator for live repl commands. static IEnumerable GetReplInputs() { // Read user input until it stops (i.e. is null). string? input = null; do { input = Console.ReadLine(); yield return input; } while (input is not null); // The last null is returned because an EOF means we should quit the repl. } // Define an enumerator for input file commands, if specified. static IEnumerable GetFileInputs(string inputFile) { // Read all lines from the input file. var fullPath = Path.GetFullPath(inputFile); var fileName = Path.GetFileName(fullPath); foreach (string line in File.ReadLines(fullPath)) { var trimmed = line.Trim(); Console.WriteLine($"{fileName}> {trimmed.TrimEnd()}"); yield return trimmed; } // Don't return a null, since this will be followed by GetReplInputs. } // Set up the input enumerator. IEnumerable inputs; if (args.InputFile is not null) { Console.WriteLine($"Reading from {args.InputFile}"); inputs = GetFileInputs(args.InputFile).Concat(GetReplInputs()); } else { inputs = GetReplInputs(); } IScriptHandler? handler = new ReplScriptHandler(); Console.Write(handler.Prompt); foreach (string? nextInput in inputs) { // Handle quitting directly. if (nextInput is null || nextInput == "quit" || nextInput == "exit") { break; } string input = nextInput.Trim(); outputWriter?.WriteLine(input); outputWriter?.Flush(); // Delegate all other command parsing to the handler. handler = handler.HandleInput(input); // Quit if the handler ends processing, otherwise prompt for the next command. if (handler is null) { break; } Console.Write(handler.Prompt); } Console.WriteLine("exiting"); } }