/// <summary> /// Change a C# parse tree to a F# AST /// </summary> public static FSharpTransform.Formula CreateFSharpTree(this ParseTreeNode input) { if (input.IsParentheses()) { return(FSharpTransform.Formula.NewFunction("", ListModule.OfSeq(new [] { CreateFSharpTree(input.ChildNodes[0]) }))); } input = input.SkipToRelevant(); switch (input.Type()) { case GrammarNames.FunctionCall: case GrammarNames.ReferenceFunctionCall: case GrammarNames.UDFunctionCall: var fname = input.GetFunction() + (input.IsNamedFunction()?"(":""); var args = ListModule.OfSeq(input.GetFunctionArguments().Select(CreateFSharpTree)); // Check for range if (fname == ":") { return(makeFSharpRange(input)); } return(FSharpTransform.makeFormula(fname, args)); case GrammarNames.Reference: // ignore prefix return(CreateFSharpTree(input.ChildNodes.Count == 1 ? input.ChildNodes[0] : input.ChildNodes[1])); case GrammarNames.Cell: var L = new Location(input.Print()); return(FSharpTransform.makeSuperCell(FSharpTransform.makeCell(L.Column, L.Row))); case GrammarNames.NamedRange: return(FSharpTransform.makeNamedRange(input.Print())); case TransformationRuleGrammar.Names.DynamicCell: //get variables from dynamic cell return(FSharpTransform.makeSuperCell(GetDynamicCell(input))); case TransformationRuleGrammar.Names.DynamicRange: var letter = input // DynamicRange .ChildNodes[0] // LowLetter .Token.ValueString[0]; return(FSharpTransform.makeDRange(letter)); case GrammarNames.Constant: case GrammarNames.Number: case GrammarNames.Text: case GrammarNames.Bool: case GrammarNames.Error: case GrammarNames.RefError: return(FSharpTransform.makeConstant(input.Print())); case TransformationRuleGrammar.Names.DynamicConstant: return(FSharpTransform.makeDArgument(input.ChildNodes[0].Token.ValueString[1])); default: throw new ArgumentException($"Can't convert node type {input.Type()}", nameof(input)); } }
protected override IEnumerable <Index> VisitFunctionCall(ParseTreeNode node) { var function = node.GetFunction().ToUpper(); switch (function) { case "+": return(VisitNodes(node.GetFunctionArguments())); case "-": return(VisitNodes(node.GetFunctionArguments())); case "*": return(VisitNodes(node.GetFunctionArguments())); case "/": return(VisitNodes(node.GetFunctionArguments())); case "SUM": return(VisitNodes(node.GetFunctionArguments())); default: throw new ArgumentException("node"); } }
private static bool IsTargetFunction(ParseTreeNode node) { return // Not interested in not-functions (node.IsNamedFunction() // Or functions without arguments && node.ChildNodes[1].ChildNodes.Any() && (varargsFunctions.Contains(node.GetFunction()) // Functions have an arrayasargument parameter || node.GetFunctionArguments().Any(n => n.SkipToRelevant().IsUnion()) ) ); }
private static bool checkRowAndColumns(ParseTreeNode node, out PrefixInfo prefix, out bool columnEqual, out List <int> columns, out bool rowEqual, out List <int> rows) { var fargs = node.GetFunctionArguments().Select(arg => arg.SkipToRelevant()).ToList(); prefix = null; columnEqual = true; columns = new List <int>(); rowEqual = true; rows = new List <int>(); // Check if all arguments are single-cell references // And if all ar in the same column/row and prefix // Check first cell for initial values to compare if (!fargs[0].Is(GrammarNames.Reference)) { return(false); } if (!(fargs[0].ChildNodes[fargs[0].ChildNodes.Count == 1 ? 0 : 1]).Is(GrammarNames.Cell)) { return(false); } prefix = (fargs[0].ChildNodes.Count == 1 ? null : fargs[0].ChildNodes[0])?.GetPrefixInfo(); var loc = new Location((fargs[0].ChildNodes[fargs[0].ChildNodes.Count == 1 ? 0 : 1]).Print()); var column = loc.Column1; var row = loc.Row1; foreach (var refnode in fargs) { if (!refnode.Is(GrammarNames.Reference)) { return(false); } var index = refnode.ChildNodes.Count == 1 ? 0 : 1; // Check if it is a cell if (!refnode.ChildNodes[index].Is(GrammarNames.Cell)) { return(false); } // Check if all prefixes are equal if (index == 0 && prefix != null) { return(false); } if (index == 1 && !refnode.ChildNodes[0].GetPrefixInfo().Equals(prefix)) { return(false); } loc = new Location(refnode.ChildNodes[index].Print()); // Add rows/columns to the list and check if they are equal if (columnEqual && column != loc.Column1) { columnEqual = false; } if (rowEqual && row != loc.Row1) { rowEqual = false; } if (!columnEqual && !rowEqual) { return(false); } rows.Add(loc.Row1); columns.Add(loc.Column1); } return(true); }