private static void Execute_Worker(bool doParse, bool doAST, bool doScope, bool autoContinue, bool chartOutput) { KGui.gui.GuiBeginningExecution(); lastExecution = null; KGui.gui.GuiSaveInput(); KGui.gui.GuiOutputClear(); DateTime startTime = DateTime.Now; if (TheParser.Parser().Parse(KGui.gui.GuiInputGetText(), out IReduction root)) { if (doParse) { root.DrawReductionTree(); } else { Netlist netlist = new Netlist(autoContinue); try { Statements statements = Parser.ParseTop(root); if (doAST) { KGui.gui.GuiOutputAppendText(statements.Format()); } else { SampleValue vessel = Vessel(KControls.SelectNoiseSelectedItem != Noise.None); Env initialEnv = new ValueEnv("vessel", Type.Sample, vessel, new BuiltinEnv(new NullEnv())); Scope initialScope = initialEnv.ToScope(); Scope scope = statements.Scope(initialScope); if (doScope) { KGui.gui.GuiOutputAppendText(scope.Format()); } else { Style style = new Style(varchar: scopeVariants ? defaultVarchar : null, new SwapMap(), map: remapVariants ? new AlphaMap() : null, numberFormat: "G4", dataFormat: "full", // we want it full for samples, but maybe only headers for functions/networks? exportTarget: ExportTarget.Standard, traceFull: false, chartOutput: chartOutput); KChartHandler.ChartClear("", "s", "M", style); KChartHandler.LegendUpdate(style); KScoreHandler.ScoreClear(); KControls.ParametersClear(style); KDeviceHandler.Clear(style); KDeviceHandler.Sample(vessel, style); netlist.Emit(new SampleEntry(vessel)); DateTime evalTime = DateTime.Now; lastExecution = new ExecutionInstance(vessel, netlist, style, startTime, evalTime); lastExecution.environment = statements.EvalReject(initialEnv, netlist, style, 0); if (lastExecution.environment == null) { throw new Error("Top level reject"); } lastExecution.EndTime(); if (style.chartOutput) { foreach (ParameterEntry parameter in netlist.Parameters()) { KControls.AddParameter(parameter.symbol.Format(style), (parameter.value as NumberValue).value, parameter.distribution, style); } KGui.gui.GuiParametersUpdate(); // calls back KControls.ParametersUpdate, but only on Win/Mac } KGui.gui.GuiProcessOutput(); } } } catch (ExecutionEnded) { lastExecution.EndTime(); KGui.gui.GuiOutputAppendText(lastExecution.ElapsedTime()); } catch (ConstantEvaluation ex) { string cat = "Does not have a value: "; netlist.Emit(new CommentEntry(cat + ": " + ex.Message)); KGui.gui.GuiInputSetErrorSelection(-1, -1, 0, cat, ex.Message); } catch (Error ex) { netlist.Emit(new CommentEntry(ex.Message)); KGui.gui.GuiInputSetErrorSelection(-1, -1, 0, "Error", ex.Message); try { KGui.gui.GuiProcessOutput(); } catch { }; } catch (StackOverflowException ex) { netlist.Emit(new CommentEntry(ex.Message)); KGui.gui.GuiInputSetErrorSelection(-1, -1, 0, "Stack Overflow", ex.Message); } catch (Exception ex) { string cat = "Something happened"; netlist.Emit(new CommentEntry(cat + ": " + ex.Message)); KGui.gui.GuiInputSetErrorSelection(-1, -1, 0, cat, ex.Message); } } } else { KGui.gui.GuiInputSetErrorSelection(TheParser.Parser().FailLineNumber(), TheParser.Parser().FailColumnNumber(), TheParser.Parser().FailLength(), TheParser.Parser().FailCategory(), TheParser.Parser().FailMessage()); } EndingExecution(); }
public Env ExtendValue <T>(Pattern pattern, T argument, Netlist netlist, string source, Style style, int s) where T : Value // bounded polymorphism :) { Env env = this; if (pattern is SinglePattern) { SinglePattern parameter = pattern as SinglePattern; env = new ValueEnv(parameter.name, parameter.type, argument, netlist, env); } else if (pattern is ListPattern) { List <Pattern> subPatterns = (pattern as ListPattern).list.parameters; if (!(argument is ListValue <T>)) { throw new Error("A list pattern is bound to a non-list value: '" + source + "'"); } List <T> subArguments = (argument as ListValue <T>).elements; env = env.ExtendValues(subPatterns, subArguments, netlist, source, style, s + 1); } else if (pattern is HeadConsPattern) { List <Pattern> headPatterns = (pattern as HeadConsPattern).list.parameters; Pattern singlePattern = (pattern as HeadConsPattern).single; if (!(argument is ListValue <T>)) { throw new Error("A list pattern is bound to a non-list value: '" + source + "'"); } List <T> subArguments = (argument as ListValue <T>).elements; if (headPatterns.Count > subArguments.Count) { throw new Error("In a list pattern variables exceed values: '" + source + "'"); } List <T> headArguments = subArguments.Take(headPatterns.Count).ToList(); List <T> tailArguments = subArguments.Skip(headPatterns.Count).ToList(); env = env.ExtendValues(headPatterns, headArguments, netlist, source, style, s + 1); env = env.ExtendValue(singlePattern, new ListValue <T>(tailArguments), netlist, source, style, s + 1); } else if (pattern is TailConsPattern) { Pattern singlePattern = (pattern as TailConsPattern).single; List <Pattern> tailPatterns = (pattern as TailConsPattern).list.parameters; if (!(argument is ListValue <T>)) { throw new Error("A list pattern is bound to a non-list value: '" + source + "'"); } List <T> subArguments = (argument as ListValue <T>).elements; if (tailPatterns.Count > subArguments.Count) { throw new Error("In a list pattern variables exceed values: '" + source + "'"); } List <T> headArguments = subArguments.Take(subArguments.Count - tailPatterns.Count).ToList(); List <T> tailArguments = subArguments.Skip(subArguments.Count - tailPatterns.Count).ToList(); env = env.ExtendValue(singlePattern, new ListValue <T>(headArguments), netlist, source, style, s + 1); env = env.ExtendValues(tailPatterns, tailArguments, netlist, source, style, s + 1); } else { throw new Error("Pattern"); } return(env); }