internal static LambdaNode ParseAndBindLambda(IHostEnvironment env, string expression, int ivec, DataViewType[] inputTypes, out int[] perm) { perm = Utils.GetIdentityPermutation(inputTypes.Length); if (ivec >= 0) { if (ivec > 0) { perm[0] = ivec; for (int i = 1; i <= ivec; i++) { perm[i] = i - 1; } } } CharCursor chars = new CharCursor(expression); var node = LambdaParser.Parse(out List <Error> errors, out List <int> lineMap, chars, perm, inputTypes); if (Utils.Size(errors) > 0) { throw env.ExceptParam(nameof(expression), $"parsing failed: {errors[0].GetMessage()}"); } using (var ch = env.Start("LabmdaBinder.Run")) LambdaBinder.Run(env, ref errors, node, msg => ch.Error(msg)); if (Utils.Size(errors) > 0) { throw env.ExceptParam(nameof(expression), $"binding failed: {errors[0].GetMessage()}"); } return(node); }
private void Run(string name) { string outDir = "ExprParser"; string text = GetResText(InResName(name)); string inName = name + "Input.txt"; string outName = name + "Output.txt"; string outNameAssem = name + "Output.Assem.txt"; string outPath = DeleteOutputPath(outDir, outName); string outPathAssem = DeleteOutputPath(outDir, outNameAssem); using (var wr = OpenWriter(outPath)) { var wrt = new IndentedTextWriter(wr, " "); // Individual scripts are separated by $. // Inputs start after #. int count = 0; int ichLim = 0; int lineLim = 1; for (; ichLim < text.Length; ichLim++) { int ichMin = ichLim; int lineMin = lineLim; while (ichLim < text.Length && text[ichLim] != '$') { if (text[ichLim] == '\n') { lineLim++; } ichLim++; } while (ichMin < ichLim && char.IsWhiteSpace(text[ichMin])) { if (text[ichMin] == '\n') { lineMin++; } ichMin++; } if (ichMin >= ichLim) { continue; } // Process the script. count++; string scriptName = string.Format("Script {0}, lines {1} to {2}", count, lineMin, lineLim); wrt.WriteLine("===== Start {0} =====", scriptName); var types = ParseTypes(text, ref ichMin, ichLim); int ichLimChars = text.IndexOf('#', ichMin); if (ichLimChars < 0 || ichLimChars >= ichLim) { ichLimChars = ichLim; } else { Contracts.Assert(ichMin < ichLimChars && ichLimChars < ichLim); } CharCursor chars = new CharCursor(text, ichMin, ichLimChars); Delegate del = null; lock (_sync) { try { LambdaNode node; List <Error> errors; List <int> lineMap; var perm = Utils.GetIdentityPermutation(types.Length); using (wrt.Nest()) { node = LambdaParser.Parse(out errors, out lineMap, chars, perm, types); } Check(node != null, "Null LambdaNode"); if (Utils.Size(errors) > 0) { DumpErrors(wrt, lineMap, lineMin, inName, "Parsing", errors); goto LDone; } LambdaBinder.Run(Env, ref errors, node, msg => wr.WriteLine(msg)); if (Utils.Size(errors) > 0) { DumpErrors(wrt, lineMap, lineMin, inName, "Binding", errors); goto LDone; } wrt.WriteLine("Binding succeeded. Output type: {0}", node.ResultType); del = LambdaCompiler.Compile(out errors, node); Contracts.Assert(TestFuncs1.Writer == null); TestFuncs1.Writer = wr; if (Utils.Size(errors) > 0) { DumpErrors(wrt, lineMap, lineMin, inName, "Compiling", errors); goto LDone; } wrt.WriteLine("Compiling succeeded."); if (ichLimChars < ichLim) { Evaluate(wrt, del, node.ResultType, types, text, ichLimChars + 1, ichLim); } } catch (Exception ex) { if (!ex.IsMarked()) { wrt.WriteLine("Unknown Exception: {0}!", del != null ? del.GetMethodInfo().DeclaringType : (object)"<null>"); } wrt.WriteLine("Exception: {0}", ex.Message); } finally { TestFuncs1.Writer = null; } LDone: wrt.WriteLine("===== End {0} =====", scriptName); } } } CheckEquality(outDir, outName, digitsOfPrecision: 6); Done(); }