private static QNode ResolveFunction(QNode qs_function) { var cs_name = qs_function.P_("cs", "name", "*").AsString(); var assemblyName = qs_function.P_("cs", "assembly", "*").AsString(); QNode q_method = null; QNode error = null; if (cs_name != null && assemblyName != null) { try { var index = cs_name.LastIndexOf('.'); if (index < 0) { throw new Exception($"Invalid name: '{cs_name}'"); } var argCount = qs_function.P_s("arg", "*").Count(); //var fullName = $"{cs_name.Substring(0, index)}, {assemblyName}"; var fullName = cs_name.Substring(0, index); var type = Type.GetType(fullName); if (type == null) { throw new Exception($"Не найден тип '{fullName}'"); } var methodName = cs_name.Substring(index + 1); var methods = type.GetMethods(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public) .Where(_method => _method.Name == methodName) .Where(_method => _method.GetParameters().Length == argCount) .ToArray(); var method = methods.FirstOrDefault(); var argType = qs_function.P_("arg", 0, "cs-type", "*").AsString(); if (argType != null) { var argCsType = Type.GetType(argType); method = methods.FirstOrDefault(_method => _method.GetParameters().FirstOrDefault()?.ParameterType == argCsType) ?? method; } if (method == null) { throw new Exception($"Не найден метод '{methodName}' в типе '{fullName}'"); } q_method = q.Q("method", method); } catch (Exception exc) { error = q.Q("error", exc.ToDisplayMessage()); } } if (q_method != null) { qs_function = qs_function.To_s().W_s(new object[] { "cs", q.Q("method", "+") }, q_method).FirstOrDefault(); } if (error != null) { qs_function = qs_function.To_s().W_s(new object[] { "cs", q.Q("error", "+") }, error).FirstOrDefault(); } return(qs_function); }
public static QNode Normalizator5_Lift(QNode typedNode, Func <QNode, QNode> normalize) { var s = typedNode.AsString(); switch (s) { case "eq": case "and": case "sum": case "min": case "max": case "count": case "is?": case "take": { var interTypes = typedNode.P_s(0, "inter-type", "*").OrEmpty().Select(interType => interType.AsString()).ToArray(); var childs = typedNode.Nodes().Skip(1) .Select((child, i) => { var interType = interTypes.ElementAtOrDefault(i) ?? interTypes.FirstOrDefault(); var type = child.P_(0, "type", "*").AsString(); return(new { child, nchild = Lift(interType, type, normalize(child) ?? child) }); }); if (childs.Any(pair => pair.child != pair.nchild)) { return(q.Q(typedNode.RawValue(), typedNode.C(0), childs.Select(pair => pair.nchild))); } } break; //case "::query": // { // var childs = typedNode.Nodes.Skip(1); // var prev = childs.FirstOrDefault(); // List<QNode> nchilds = null; // foreach (var pair in childs.Select((c, i) => new { child = c, i })) // { // var child = pair.child; // var sourceType = prev.P_(0, "type", "*").AsString(); // var targetType = child.AsString() == "take" ? "int-s" : null; // var nchild = Lift(targetType, sourceType, normalize(prev)); // if (nchild != child && childs == null) // { // nchilds = new List<QNode>(typedNode.Nodes.Take(pair.i + 1)); // } // if (nchilds != null) // nchilds.Add(nchild); // } // if (nchilds != null) // return q.Q(typedNode.Value, nchilds); // } // break; } return(typedNode); }
static HElement View(QNode node, IDictionary <Guid, QCalculator.Function> functionIndex) { var functionId = ConvertHlp.ToGuid(node.C(0).P_("function-id", "*").AsString()); var f = functionId.Maybe(_ => functionIndex.Find(functionId.Value)); return(h.Div ( h.@class("q"), h.Span(h.@class("q-type"), $" ({TypeToString(node.C(0).P("type").QValue().FirstOrDefault())}) "), h.Span(node.RawValue()), h.Span(h.@class("q-inter-type"), $" ({node.P_s(0, "inter-type", "*").Select(interType => TypeToString(interType)).JoinToString(", ")}) "), functionId.Maybe(_ => h.A(h.style("font-size:75%"), h.href($"#f-{_}"), "f-" + f?.Index, h.title(FunctionFullName(f.RawDescription)))), node.Nodes().OrEmpty().Skip(1).Select(n => View(n, functionIndex)) )); }
static string FunctionFullName(QNode fdesc) { var args = fdesc.P_s("arg", "*").Select(arg => arg.P_("type", "*").AsString()).JoinToString(","); return($"{fdesc.P_("name", "*").AsString()}({args}) -> {fdesc.P_("result", "type", "*").AsString()}"); }