static string TypeToString(QNode type) { var childType = type.QValue().AsString(); if (childType == null) { return(type.AsString()); } return($"{type.AsString()}<{childType}>"); }
public static QNode Typified(QNode node, Dictionary <string, QNode[]> functionIndex) { var type = "-"; string childType = null; string interType = null; string[] interTypes = null; var s = node.AsString(); QNode prefix = null; switch (s) { case "id": return(q.Q(s, MetaType("id", interType: "s-literal"), q.Q(node.QValue().RawValue(), MetaType("s-literal", interType: "void")))); case "делитель": case "кратный": case "кроме": case "n-значный": case "четный": case "нечетный": case ">": case "<": case "больше": case "меньше": type = "set"; childType = "int"; interType = "int"; break; case "is?": return(q.Q(s, q.Q("meta", q.Q("type", "bool"), q.Q("inter-type", "int", q.Q("set", "int"))), node.Nodes().Select(child => Typified(child, functionIndex)))); case "true": case "false": type = "bool"; interType = "void"; break; case "частное": //TODO synonym div case "add": case "subtract": case "div": case "mul": type = "number"; interType = "number"; break; case "mod": case "idiv": type = "int"; interType = "int"; break; case "sum": case "count": case "min": case "max": type = "int"; interType = "int-s"; break; case "число": type = "number"; break; case "enumerate": type = "int-s"; interType = "set"; break; case "take": type = "int-s"; interTypes = new[] { "int-s", "int" }; break; default: { var functions = functionIndex.Find(s); if (functions.OrEmpty().Any()) { var function = functions[0]; type = function.P_("result", "type", "*").AsString(); childType = function.P_("result", "type", "*", "*").AsString(); interType = function.P_("arg", 0, "type", "*").AsString(); } else if (!string.IsNullOrEmpty(s) && char.IsDigit(s[0]) && s.All(ch => char.IsDigit(ch) || ch == '-' || ch == '.' || ch == ',')) { type = "s-literal"; interType = "void"; var numberType = s.Any(ch => ch == ',' || ch == '.') ? "number" : "int"; prefix = q.Q("to-" + numberType, MetaType(numberType, interType: "s-literal")); } else { var structureTypes = new[] { "point", "task", "expected", "skip" }; if (structureTypes.Contains(s)) { type = s; if (s == "point") { interType = "structure"; } if (s == "skip") { interType = "s-literal"; } } } } break; } var v = node.RawValue(); object n = MetaType(type, childType, interType: interType, interTypes: interTypes); var childs = node.Nodes().Select(child => Typified(child, functionIndex)).ToArray(); var res = q.Q(v, n, childs); if (prefix != null) { return(prefix.W(res)); } return(res); }