public void RunProgram(List<Opcode> program, bool silent) { if (!program.Any()) return; var newContext = new ProgramContext(false, program) { Silent = silent }; PushContext(newContext); }
public void Boot() { // break all running programs currentContext = null; contexts.Clear(); PushInterpreterContext(); currentStatus = Status.Running; currentTime = 0; maxUpdateTime = 0.0; maxExecutionTime = 0.0; // clear stack (which also orphans all local variables so they can get garbage collected) stack.Clear(); // clear global variables globalVariables.Variables.Clear(); // clear interpreter if (shared.Interpreter != null) shared.Interpreter.Reset(); // load functions if (shared.FunctionManager != null) shared.FunctionManager.Load(); // load bindings if (shared.BindingMgr != null) shared.BindingMgr.Load(); // Booting message if (shared.Screen != null) { shared.Screen.ClearScreen(); string bootMessage = string.Format("kOS Operating System\n" + "KerboScript v{0}\n(manual at {1})\n \n" + "Proceed.\n", SafeHouse.Version, SafeHouse.DocumentationURL); List<string> nags = Debug.GetPendingNags(); if (nags.Count > 0) { bootMessage += "##################################################\n" + "# NAG MESSAGES #\n" + "##################################################\n" + "# Further details about these important messages #\n" + "# can be found in the KSP error log. If you see #\n" + "# this, then read the error log. It's important.#\n" + "--------------------------------------------------\n"; bootMessage = nags.Aggregate(bootMessage, (current, msg) => current + (msg + "\n")); bootMessage += "##################################################\n"; shared.Processor.SetMode(Module.ProcessorModes.OFF); } shared.Screen.Print(bootMessage); } if (!shared.Processor.CheckCanBoot()) return; string filename = shared.Processor.BootFilename; // Check to make sure the boot file name is valid, and then that the boot file exists. if (string.IsNullOrEmpty(filename)) { SafeHouse.Logger.Log("Boot file name is empty, skipping boot script"); } else if (filename.Equals("None", StringComparison.InvariantCultureIgnoreCase)) { SafeHouse.Logger.Log("Boot file name is \"None\", skipping boot script"); } else if (shared.VolumeMgr.CurrentVolume.Open(filename) == null) { SafeHouse.Logger.Log(string.Format("Boot file \"{0}\" is missing, skipping boot script", filename)); } else { var bootContext = "program"; string bootCommand = string.Format("run {0}.", filename); var options = new CompilerOptions { LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager, IsCalledFromRun = false }; shared.ScriptHandler.ClearContext(bootContext); List<CodePart> parts = shared.ScriptHandler.Compile( "sys:boot", 1, bootCommand, bootContext, options); IProgramContext programContext = SwitchToProgramContext(); programContext.Silent = true; programContext.AddParts(parts); } }
private void PushInterpreterContext() { var interpreterContext = new ProgramContext(true); // initialize the context with an empty program interpreterContext.AddParts(new List<CodePart>()); PushContext(interpreterContext); }
private void PushContext(ProgramContext context) { SafeHouse.Logger.Log("Pushing context staring with: " + context.GetCodeFragment(0).FirstOrDefault()); SaveAndClearPointers(); contexts.Add(context); currentContext = contexts.Last(); if (contexts.Count > 1) { shared.Interpreter.SetInputLock(true); } }
private void PopContext() { SafeHouse.Logger.Log("Popping context " + contexts.Count); if (contexts.Any()) { // remove the last context ProgramContext contextRemove = contexts.Last(); contexts.Remove(contextRemove); contextRemove.DisableActiveFlyByWire(shared.BindingMgr); SafeHouse.Logger.Log("Removed Context " + contextRemove.GetCodeFragment(0).FirstOrDefault()); if (contexts.Any()) { currentContext = contexts.Last(); currentContext.EnableActiveFlyByWire(shared.BindingMgr); RestorePointers(); SafeHouse.Logger.Log("New current context " + currentContext.GetCodeFragment(0).FirstOrDefault()); } else { currentContext = null; } if (contexts.Count == 1) { shared.Interpreter.SetInputLock(false); } } }
public void Boot() { // break all running programs currentContext = null; contexts.Clear(); PushInterpreterContext(); currentRunSection = Section.Main; currentTime = 0; maxUpdateTime = 0.0; maxExecutionTime = 0.0; // clear stack (which also orphans all local variables so they can get garbage collected) stack.Clear(); // clear global variables globalVariables.Variables.Clear(); // clear interpreter if (shared.Interpreter != null) shared.Interpreter.Reset(); // load functions if (shared.FunctionManager != null) shared.FunctionManager.Load(); // load bindings if (shared.BindingMgr != null) shared.BindingMgr.Load(); // Booting message if (shared.Screen != null) { shared.Screen.ClearScreen(); string bootMessage = string.Format("kOS Operating System\n" + "KerboScript v{0}\n(manual at {1})\n \n" + "Proceed.\n", SafeHouse.Version, SafeHouse.DocumentationURL); List<string> nags = Debug.GetPendingNags(); if (nags.Count > 0) { bootMessage += "##################################################\n" + "# NAG MESSAGES #\n" + "##################################################\n" + "# Further details about these important messages #\n" + "# can be found in the KSP error log. If you see #\n" + "# this, then read the error log. It's important.#\n" + "--------------------------------------------------\n"; bootMessage = nags.Aggregate(bootMessage, (current, msg) => current + (msg + "\n")); bootMessage += "##################################################\n"; shared.Processor.SetMode(Module.ProcessorModes.OFF); } shared.Screen.Print(bootMessage); } if (!shared.Processor.CheckCanBoot()) return; VolumePath path = shared.Processor.BootFilePath; // Check to make sure the boot file name is valid, and then that the boot file exists. if (path == null) { SafeHouse.Logger.Log("Boot file name is empty, skipping boot script"); } else { // Boot is only called once right after turning the processor on, // the volume cannot yet have been changed from that set based on // Config.StartOnArchive, and Processor.CheckCanBoot() has already // handled the range check for the archive. Volume sourceVolume = shared.VolumeMgr.CurrentVolume; var file = shared.VolumeMgr.CurrentVolume.Open(path); if (file == null) { SafeHouse.Logger.Log(string.Format("Boot file \"{0}\" is missing, skipping boot script", path)); } else { var bootContext = "program"; string bootCommand = string.Format("run \"{0}\".", file.Path); var options = new CompilerOptions { LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager, IsCalledFromRun = false }; shared.ScriptHandler.ClearContext(bootContext); List<CodePart> parts = shared.ScriptHandler.Compile(new BootGlobalPath(bootCommand), 1, bootCommand, bootContext, options); IProgramContext programContext = SwitchToProgramContext(); programContext.Silent = true; programContext.AddParts(parts); } } }