public object[] EvulateActionSingle(XPathExpression item, IXPathExpressionItem sender = null) { object curvalue = null; IXPathExpressionItem previtem = null; XPathExpressionItem xoperator = null; object waitvalue = null; string waitop = null; List <object> values = new List <object>(); for (int j = 0; j < item.XPathExpressionItems.Count; j++) { var curitem = item.XPathExpressionItems[j]; var nextitem = (j + 1 < item.XPathExpressionItems.Count) ? item.XPathExpressionItems[j + 1] : null; string nextop = null; XPathExpressionItem nextExp = null; if (nextitem != null && !nextitem.IsSubItem) { nextExp = nextitem as XPathExpressionItem; nextop = (nextExp != null && nextExp.IsOperator) ? nextExp.Value.ToString() : null; } object expvalue = null; if (curitem.IsSubItem) { expvalue = EvulateAction((IXPathExpressionItems)curitem); if (!previtem.IsSubItem) { var prevexp = previtem as XPathExpressionItem; if (prevexp.IsOperator) { expvalue = ((object[])expvalue)[0]; } else { if (XPathFunctions != null) { if (curitem.ParChar == '[') { var xitems = XPathFunctions.BaseItem.FindByXPath(prevexp.Value.ToString()); if (xitems.Count > 0) { xitems = Eliminate(xitems, (IXPathExpressionItems)curitem); } if (xitems.Count > 0) { expvalue = true; } else { expvalue = false; } if (curvalue == null) { curvalue = expvalue; previtem = curitem; continue; } } else if (curitem.ParChar == '(') { var method = XPathFunctions.GetMetohdByName(prevexp.Value.ToString()); if (method != null) { expvalue = ComputeActions.CallMethodDirect(XPathFunctions, method, (object[])expvalue); if (curvalue == null) { curvalue = expvalue; previtem = curitem; continue; } } } } } } } else { var expItem = curitem as XPathExpressionItem; if (nextitem != null && nextitem.IsSubItem) { previtem = curitem; continue; } if (expItem.IsOperator) { if (expItem.Value.ToString() == ",") { if (waitop != null) { curvalue = ComputeActions.OperatorResult(waitvalue, curvalue, waitop); waitvalue = null; waitop = null; } values.Add(curvalue); curvalue = null; xoperator = null; continue; } string opstr = expItem.Value.ToString(); if (opstr == "||" || opstr == "|" || opstr == "or" || opstr == "&&" || opstr == "&" || opstr == "and") { if (waitop != null) { curvalue = ComputeActions.OperatorResult(waitvalue, curvalue, waitop); waitvalue = null; waitop = null; } bool state = PhpFuctions.not_empty(curvalue); if (opstr == "||" || opstr == "|" || opstr == "or") { if (state) { values.Add(true); return(values.ToArray()); } else { curvalue = null; } } else { if (!state) { values.Add(false); return(values.ToArray()); } else { curvalue = null; } } xoperator = null; } else { xoperator = expItem; } previtem = curitem; continue; } else { if (expItem.IsVariable) { if (expItem.Value.ToString().StartsWith("@")) { string s = expItem.Value.ToString().Substring(1); if ((nextExp == null || !nextExp.IsOperator) && (sender is null || !sender.IsSubItem || sender.ParChar != '(')) { expvalue = this.XPathFunctions.BaseItem.ElemAttr.HasAttribute(s); } else { expvalue = this.XPathFunctions.BaseItem.GetAttribute(s); } if (expvalue == null) { expvalue = false; } } else { var items = this.XPathFunctions.BaseItem.FindByXPath(expItem.Value.ToString()); if (items.Count == 0) { expvalue = false; } else { expvalue = items[0].Inner(); } } }
public ComputeResult Compute(object vars = null, InnerItem sender = null, object localvars = null) { var cr = new ComputeResult(); object lastvalue = null; InnerItem xoperator = null; InnerItem previtem = null; InnerItem waititem = null; InnerItem waititem2 = null; string waitop = ""; object waitvalue = null; string waitop2 = ""; object waitvalue2 = null; string waitkey = ""; bool unlemused = false; bool stopdoubledot = false; if (this.IsObject()) { cr.Result.AddObject(new ExpandoObject()); } for (int i = 0; i < this.InnerItems.Count; i++) { object currentitemvalue = null; InnerItem current = this.InnerItems[i]; ParItem paritem = null; if (current.IsParItem()) { paritem = current as ParItem; } if (stopdoubledot) { if (current.IsOperator && current.Value.ToString() == ":") { break; } } InnerItem next = null; string nextop = ""; if (i + 1 < this.InnerItems.Count) { next = this.InnerItems[i + 1]; } if (next != null && next.IsOperator) { nextop = next.Value.ToString(); } if (current.IsParItem()) { var subresult = paritem.Compute(vars, this, localvars); string prevvalue = ""; bool previsvar = false; if (previtem != null && !previtem.IsOperator && previtem.Value != null) { previsvar = previtem.InnerType == InnerType.TYPE_VARIABLE; prevvalue = previtem.Value.ToString(); } object varnew = null; if (lastvalue != null) { varnew = lastvalue; } else { varnew = vars; } if (prevvalue != "") { if (paritem.ParName == "(") { currentitemvalue = ComputeActions.CallMethod(prevvalue, subresult.Result.GetObjects(), varnew, localvars); } else if (paritem.ParName == "[") { var prop = ComputeActions.GetProp(prevvalue, varnew); if (PhpFuctions.is_array(prop)) { int indis = (int)Convert.ChangeType(subresult.Result[0], TypeCode.Int32); var aritem = prop as IList; currentitemvalue = aritem[indis]; } else if (PhpFuctions.is_indis(prop)) { var indisProp = prop.GetType().GetProperty("Item"); var newParams = ParamUtil.MatchParams(subresult.Result.GetObjects(), indisProp.GetIndexParameters()); currentitemvalue = indisProp.GetValue(prop, newParams); } else { int indis = (int)Convert.ChangeType(subresult.Result[0], TypeCode.Int32); currentitemvalue = ((string)prop)[indis]; } } } else { if (paritem.ParName == "(") { currentitemvalue = subresult.Result[0]; } else if (paritem.ParName == "[") { if (subresult.Result.KeysIncluded()) { currentitemvalue = subresult.Result.ToDictionary(); } else { currentitemvalue = subresult.Result.GetObjects(); } } else if (paritem.ParName == "{") { currentitemvalue = subresult.Result.First(); } } } else { if (!current.IsOperator && current.InnerType == InnerType.TYPE_VARIABLE && next != null && next.IsParItem()) { currentitemvalue = null; } else { currentitemvalue = current.Value; } if (current.InnerType == InnerType.TYPE_VARIABLE && (next == null || !next.IsParItem()) && (xoperator == null || xoperator.Value.ToString() != ".")) { if (currentitemvalue == null || currentitemvalue.ToString() == "null") { currentitemvalue = null; } else if (currentitemvalue.ToString() == "false") { currentitemvalue = false; } else if (currentitemvalue.ToString() == "true") { currentitemvalue = true; } else if (!this.IsObject()) { currentitemvalue = ComputeActions.GetPropValue(current, vars, localvars); } } } if (unlemused) { currentitemvalue = !PhpFuctions.not_empty(currentitemvalue); unlemused = false; } if (current.IsOperator) { if (current.Value.ToString() == "!") { unlemused = !unlemused; previtem = current; continue; } if ((this.IsParItem() && current.Value.ToString() == ",") || (this.IsArray() && current.Value.ToString() == "=>" && (waitvalue == null || waitvalue.ToString() == "")) || (this.IsObject() && current.Value.ToString() == ":" && (waitvalue == null || waitvalue.ToString() == ""))) { if (waitop2 != "") { lastvalue = ComputeActions.OperatorResult(waitvalue2, lastvalue, waitop2); waitvalue2 = null; waitop2 = ""; } if (waitop != "") { lastvalue = ComputeActions.OperatorResult(waitvalue, lastvalue, waitop); waitvalue = null; waitop = ""; } if (current.Value.ToString() == ",") { if (this.IsObject()) { var exp = cr.Result.First <IDictionary <string, object> >(); exp.Add(waitkey, lastvalue); } else { cr.Result.AddObject(waitkey, lastvalue); } waitkey = ""; } else { waitkey = lastvalue.ToString(); } lastvalue = null; xoperator = null; previtem = current; continue; } string opstr = current.Value.ToString(); if (opstr == "||" || opstr == "|" || opstr == "or" || opstr == "&&" || opstr == "&" || opstr == "and" || opstr == "?") { if (waitop2 != "") { lastvalue = ComputeActions.OperatorResult(waitvalue2, lastvalue, waitop2); waitvalue2 = null; waitop2 = ""; } if (waitop != "") { lastvalue = ComputeActions.OperatorResult(waitvalue, lastvalue, waitop); waitvalue = null; waitop = ""; } bool state = PhpFuctions.not_empty(lastvalue); xoperator = null; if (opstr == "?") { if (state) { stopdoubledot = true; } else { for (int j = i + 1; j < this.InnerItems.Count; j++) { var item = this.InnerItems[j]; if (item.IsOperator && item.Value.ToString() == ":") { i = j; break; } } } lastvalue = null; previtem = current; continue; } if (opstr == "||" || opstr == "|" || opstr == "or") { if (state) { lastvalue = true; if (opstr != "|") { if (this.IsObject()) { var exp = cr.Result.First <IDictionary <string, object> >(); exp.Add(waitkey, true); } else { cr.Result.AddObject(waitkey, true); } return(cr); } } else { lastvalue = false; } } else { if (!state) { lastvalue = false; if (opstr != "&") { if (this.IsObject()) { var exp = cr.Result.First <IDictionary <string, object> >(); exp.Add(waitkey, false); } else { cr.Result.AddObject(waitkey, false); } return(cr); } } else { lastvalue = true; } } xoperator = current; } else { xoperator = current; } previtem = current; continue; } else { if (xoperator != null) { if (ComputeActions.PriotiryStop.Contains(xoperator.Value.ToString())) { if (waitop2 != "") { lastvalue = ComputeActions.OperatorResult(waitvalue2, lastvalue, waitop2); waitvalue2 = null; waitop2 = ""; } if (waitop != "") { lastvalue = ComputeActions.OperatorResult(waitvalue, lastvalue, waitop); waitvalue = null; waitop = ""; } } if (next != null && next.IsParItem()) { if (xoperator.Value.ToString() == ".") { if (currentitemvalue != null && !string.IsNullOrEmpty(currentitemvalue.ToString())) { lastvalue = ComputeActions.GetProp(currentitemvalue.ToString(), lastvalue); } } else { if (waitop == "") { waitop = xoperator.Value.ToString(); waititem = current; waitvalue = lastvalue; } else if (waitop2 == "") { waitop2 = xoperator.Value.ToString(); waititem2 = current; waitvalue2 = lastvalue; } lastvalue = null; } xoperator = null; previtem = current; continue; } if (xoperator.Value.ToString() == ".") { lastvalue = ComputeActions.GetProp(currentitemvalue.ToString(), lastvalue); } else if (nextop != "." && ((xoperator.Value.ToString() != "+" && xoperator.Value.ToString() != "-") || nextop == "" || (ComputeActions.PriotiryStop.Contains(nextop)))) { var opresult = ComputeActions.OperatorResult(lastvalue, currentitemvalue, xoperator.Value.ToString()); lastvalue = opresult; } else { if (waitop == "") { waitop = xoperator.Value.ToString(); waititem = current; waitvalue = lastvalue; lastvalue = currentitemvalue; } else if (waitop2 == "") { waitop2 = xoperator.Value.ToString(); waititem2 = current; waitvalue2 = lastvalue; lastvalue = currentitemvalue; } continue; } } else { lastvalue = currentitemvalue; } } previtem = current; } if (waitop2 != "") { lastvalue = ComputeActions.OperatorResult(waitvalue2, lastvalue, waitop2); waitvalue2 = null; waitop2 = ""; } if (waitop != "") { lastvalue = ComputeActions.OperatorResult(waitvalue, lastvalue, waitop); waitvalue = null; waitop = ""; } if (this.IsObject()) { var exp = cr.Result.First <IDictionary <string, object> >(); exp.Add(waitkey, lastvalue); } else { cr.Result.AddObject(waitkey, lastvalue); } return(cr); }
public static object OperatorResult(object item1, object item2, string @operator) { if (item1 == null && item2 == null) { return(null); } if ((@operator == "+" || @operator == "-") && item1 == null && item2 != null && TypeUtil.IsNumericType(item2)) { var leftitem = 0d; var rightitem = (double)Convert.ChangeType(item2, typeof(double)); if (@operator == "+") { return(leftitem + rightitem); } else { return(leftitem - rightitem); } } if (@operator == "||" || @operator == "|" || @operator == "or" || @operator == "&&" || @operator == "&" || @operator == "and") { bool lefstate = PhpFuctions.not_empty(item1); bool rightstate = PhpFuctions.not_empty(item2); if (@operator == "||" || @operator == "|" || @operator == "or") { if (lefstate != rightstate) { return(true); } return(lefstate); } else { if (lefstate && rightstate) { return(true); } return(false); } } if ((item1 is string && item2 == null) || item2 is string && item1 == null) { return(false); } if (@operator == "==" || @operator == "=" || @operator == "!=" && (item1 == null || item2 == null)) { if (item1 == null) { if (@operator == "==" || @operator == "=") { return(item2 == null); } else { return(item2 != null); } } else if (item2 == null) { if (@operator == "==" || @operator == "=") { return(item1 == null); } else { return(item1 != null); } } } if (item1 is string && @operator == "+") { return(item1.ToString() + item2); } else if (item2 is string && @operator == "+") { return(item1 + item2.ToString()); } if (item1 is bool && item2 is bool) { var leftitem = (bool)item1; var rightitem = (bool)item2; switch (@operator) { case "==": case "=": return(leftitem == rightitem); case "!=": return(leftitem != rightitem); } } else if ((item1 is DateTime && TypeUtil.IsNumericType(item2)) || (item2 is DateTime && TypeUtil.IsNumericType(item1))) { if (item1 is DateTime) { var leftitem = (DateTime)item1; var rightitem = (double)item2; switch (@operator) { case "+": return(leftitem.AddDays(rightitem)); case "-": return(leftitem.AddDays(-1d * rightitem)); } } else { var leftitem = (double)item1; var rightitem = (DateTime)item2; switch (@operator) { case "+": return(rightitem.AddDays(leftitem)); case "-": return(rightitem.AddDays(-1d * leftitem)); } } } else if (item1 is DateTime && item2 is DateTime) { var leftitem = (DateTime)item1; var rightitem = (DateTime)item2; int cmpres = leftitem.CompareTo(rightitem); switch (@operator) { case "==": case "=": return(cmpres == 0); case "!=": return(cmpres != 0); case "<": return(cmpres == -1); case "<=": return(cmpres == 0 || cmpres == -1); case ">": return(cmpres == 1); case ">=": return(cmpres == 0 || cmpres == 1); default: break; } } else if (item1 is string && item2 is string) { var leftitem = (string)item1; var rightitem = (string)item2; int cmpres = leftitem.CompareTo(rightitem); switch (@operator) { case "==": case "=": return(cmpres == 0); case "!=": return(cmpres != 0); case "<": return(cmpres == -1); case "<=": return(cmpres == 0 || cmpres == -1); case ">": return(cmpres == 1); case ">=": return(cmpres == 0 || cmpres == 1); default: break; } } else { if (item2 == null) { item2 = ""; } if (item1 == null) { item1 = ""; } if (TypeUtil.IsNumericType(item1) && TypeUtil.IsNumericType(item2) || TypeUtil.IsNumericType(item1) && item2.ToString().IsNumeric() || TypeUtil.IsNumericType(item2) && item1.ToString().IsNumeric()) { var leftitem = (double)Convert.ChangeType(item1, typeof(double)); var rightitem = (double)Convert.ChangeType(item2, typeof(double)); switch (@operator) { case "==": case "=": return(leftitem == rightitem); case "!=": return(leftitem != rightitem); case "<": return(leftitem < rightitem); case "<=": return(leftitem <= rightitem); case ">": return(leftitem > rightitem); case ">=": return(leftitem >= rightitem); case "+": return(leftitem + rightitem); case "-": return(leftitem - rightitem); case "*": return(leftitem * rightitem); case "/": case "div": return(leftitem / rightitem); case "%": case "mod": return(leftitem % rightitem); case "^": return(Math.Pow(leftitem, rightitem)); case "&": return((long)leftitem & (long)rightitem); case "|": return((long)leftitem | (long)rightitem); default: break; } } } return(null); }