public void Trace(string expr, object value, string path) { if (string.IsNullOrEmpty(expr)) { Store(path, value); return; } var i = expr.IndexOf(';'); var atom = i >= 0 ? expr.Substring(0, i) : expr; var tail = i >= 0 ? expr.Substring(i + 1) : string.Empty; if (value != null && _system.HasMember(value, atom)) { Trace(tail, Index(value, atom), path + ";" + atom); } else if (atom == "*") { Walk(atom, tail, value, path, WalkWild); } else if (atom == "..") { Trace(tail, value, path); Walk(atom, tail, value, path, WalkTree); } else if (atom.Length > 2 && atom[0] == '(' && atom[atom.Length - 1] == ')') { Trace(_eval(atom, value, path.Substring(path.LastIndexOf(';') + 1)) + ";" + tail, value, path); } else if (atom.Length > 3 && atom[0] == '?' && atom[1] == '(' && atom[atom.Length - 1] == ')') { Walk(atom, tail, value, path, WalkFiltered); } else if (RegExp(@"^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$").IsMatch(atom)) { Slice(atom, tail, value, path); } else { if (atom.IndexOf(',') >= 0) { foreach (string part in RegExp(@"'?,'?").Split(atom)) { Trace(part + ";" + tail, value, path); } } } }
public void Trace(string expr, object value, string path) { if (expr == null || expr.Length == 0) { Store(path, value); return; } int i = expr.IndexOf(';'); string atom = i >= 0 ? expr.Substring(0, i) : expr; string tail = i >= 0 ? expr.Substring(i + 1) : string.Empty; if (value != null && system.HasMember(value, atom)) { Trace(tail, Index(value, atom), path + ";" + atom); } else if (atom == "*") { Walk(atom, tail, value, path, new WalkCallback(WalkWild)); } else if (atom == "..") { Trace(tail, value, path); Walk(atom, tail, value, path, new WalkCallback(WalkTree)); } else if (atom.IndexOf(',') >= 0) // [name1,name2,...] { foreach (string part in RegExp(@"'?,'?").Split(atom)) { Trace(part + ";" + tail, value, path); } } else if (atom.Length > 2 && atom[0] == '(' && atom[atom.Length - 1] == ')') // [(exp)] { Trace(eval(atom, value, path.Substring(path.LastIndexOf(';') + 1)) + ";" + tail, value, path); } else if (atom.Length > 3 && atom[0] == '?' && atom[1] == '(' && atom[atom.Length - 1] == ')') // [?(exp)] { Walk(atom, tail, value, path, new WalkCallback(WalkFiltered)); } else if (RegExp(@"^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$").IsMatch(atom)) // [start:end:step] Phyton slice syntax { Slice(atom, tail, value, path); } }
#pragma warning disable S1541 // Ignore complexity for the switch method private void Trace(object value, string path, string atom, string tail) #pragma warning restore S1541 // Methods and properties should not be too complex { if (value != null && _system.HasMember(value, atom)) { StoreExpressionTreeLeafNodes(tail, Index(value, atom), path + ";" + atom); } else if (atom == "*") { Walk(atom, tail, value, path, WalkWild); } else if (atom == "..") { StoreExpressionTreeLeafNodes(tail, value, path); Walk(atom, tail, value, path, WalkTree); } else if (atom.Length > 2 && atom[0] == '(' && atom[atom.Length - 1] == ')') { StoreExpressionTreeLeafNodes(_eval(atom, value, path.Substring(path.LastIndexOf(';') + 1)) + ";" + tail, value, path); } else if (atom.Length > 3 && atom[0] == '?' && atom[1] == '(' && atom[atom.Length - 1] == ')') { Walk(atom, tail, value, path, WalkFiltered); } else if (RegExp(@"^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$").IsMatch(atom)) { Slice(atom, tail, value, path); } else { if (atom.IndexOf(',') >= 0) { foreach (string part in RegExp(@"'?,'?").Split(atom)) { StoreExpressionTreeLeafNodes(part + ";" + tail, value, path); } } } }
IEnumerable <T> Trace <T>(TraceArgs args, Func <object, string[], T> resultor) { var stack = new Stack <TraceArgs>(); stack.Push(args); while (stack.Count > 0) { var popped = stack.Pop(); var expr = popped.Expr; var value = popped.Value; var path = popped.Path; if (string.IsNullOrEmpty(expr)) { if (path != null) { yield return(resultor(value, path.Split(Semicolon))); } continue; } var i = expr.IndexOf(';'); var atom = i >= 0 ? expr.Substring(0, i) : expr; var tail = i >= 0 ? expr.Substring(i + 1) : string.Empty; if (value != null && _system.HasMember(value, atom)) { stack.Push(Args(tail, Index(value, atom), path + ";" + atom)); } else if (atom == "*") { Walk(atom, tail, value, path, (m, l, x, v, p) => stack.Push(Args(m + ";" + x, v, p))); } else if (atom == "..") { Walk(atom, tail, value, path, (m, l, x, v, p) => { var result = Index(v, m.ToString()); if (result != null && !_system.IsPrimitive(result)) { stack.Push(Args("..;" + x, result, p + ";" + m)); } }); stack.Push(Args(tail, value, path)); } else if (atom.Length > 2 && atom[0] == '(' && atom[atom.Length - 1] == ')') // [(exp)] { stack.Push(Args(_eval(atom, value, path.Substring(path.LastIndexOf(';') + 1)) + ";" + tail, value, path)); } else if (atom.Length > 3 && atom[0] == '?' && atom[1] == '(' && atom[atom.Length - 1] == ')') // [?(exp)] { Walk(atom, tail, value, path, (m, l, x, v, p) => { var result = _eval(RegExp.Replace(l, @"^\?\((.*?)\)$", "$1"), Index(v, m.ToString()), m.ToString()); if (Convert.ToBoolean(result, CultureInfo.InvariantCulture)) { stack.Push(Args(m + ";" + x, v, p)); } }); } else if (RegExp.IsMatch(atom, @"^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$")) // [start:end:step] Python slice syntax { foreach (var a in Slice(atom, tail, value, path).Reverse()) { stack.Push(a); } } else if (atom.IndexOf(',') >= 0) // [name1,name2,...] { foreach (var part in RegExp.Split(atom, @"'?,'?").Reverse()) { stack.Push(Args(part + ";" + tail, value, path)); } } } }