/// <summary> /// Read Eval Print Loop. Run the given source until it either terminates, /// or hits the given time limit. When it terminates, if we have new /// implicit output, print that to the implicitOutput stream. /// </summary> /// <param name="sourceLine">Source line.</param> /// <param name="timeLimit">Time limit.</param> public void REPL(string sourceLine, double timeLimit = 60) { if (parser == null) { parser = new Parser(); } if (vm == null) { vm = parser.CreateVM(standardOutput); vm.interpreter = new WeakReference(this); } else if (vm.done && !parser.NeedMoreInput()) { // Since the machine and parser are both done, we don't really need the // previously-compiled code. So let's clear it out, as a memory optimization. vm.GetTopContext().ClearCodeAndTemps(); parser.PartialReset(); } if (sourceLine == "#DUMP") { vm.DumpTopContext(); return; } double startTime = vm.runTime; int startImpResultCount = vm.globalContext.implicitResultCounter; vm.storeImplicit = (implicitOutput != null); try { if (sourceLine != null) { parser.Parse(sourceLine, true); } if (!parser.NeedMoreInput()) { while (!vm.done && !vm.yielding) { if (vm.runTime - startTime > timeLimit) { return; // time's up for now! } vm.Step(); } if (implicitOutput != null && vm.globalContext.implicitResultCounter > startImpResultCount) { Value result = vm.globalContext.GetVar(ValVar.implicitResult.identifier); if (result != null) { implicitOutput.Invoke(result.ToString(vm)); } } } } catch (MiniscriptException mse) { ReportError(mse); // Attempt to recover from an error by jumping to the end of the code. vm.GetTopContext().JumpToEnd(); } }
/// <summary> /// Read Eval Print Loop. Run the given source until it either terminates, /// or hits the given time limit. When it terminates, if we have new /// implicit output, print that to the implicitOutput stream. /// </summary> /// <param name="sourceLine">Source line.</param> /// <param name="timeLimit">Time limit.</param> public void REPL(string sourceLine, double timeLimit = 60) { if (parser == null) { parser = new Parser(); } if (vm == null) { vm = parser.CreateVM(standardOutput); vm.interpreter = new WeakReference(this); } if (sourceLine == "#DUMP") { vm.DumpTopContext(); return; } double startTime = vm.runTime; int startImpResultCount = vm.globalContext.implicitResultCounter; vm.storeImplicit = (implicitOutput != null); try { if (sourceLine != null) { parser.Parse(sourceLine, true); } if (!parser.NeedMoreInput()) { while (!vm.done) { if (vm.runTime - startTime > timeLimit) { return; // time's up for now! } vm.Step(); } if (implicitOutput != null && vm.globalContext.implicitResultCounter > startImpResultCount) { Value result = vm.globalContext.GetVar(ValVar.implicitResult.identifier); if (result != null) { implicitOutput.Invoke(result.ToString(vm)); } } } } catch (MiniscriptException mse) { ReportError(mse); // Attempt to recover from an error by jumping to the end of the code. vm.GetTopContext().JumpToEnd(); } }