private bool Logic(OperatorNode obj) { bool lhs = ScriptTypeUtil.EvalToBoolean(obj.Lhs.Accept(this)); //Note: Short cut Rhs if (lhs && obj.Token.TokenValue == "||") { return(true); } if (!lhs && obj.Token.TokenValue == "&&") { return(false); } //Note: Eval Rhs bool rhs = ScriptTypeUtil.EvalToBoolean(obj.Rhs.Accept(this)); if (obj.Token.TokenValue == "||") { return(lhs || rhs); } if (obj.Token.TokenValue == "&&") { return(lhs && rhs); } ExceptionHelper.ThrowBinaryOperatorInvalid(obj.Token.TokenValue, lhs, rhs); return(false); }
public override object Visit(OperatorNode obj) { switch (obj.Token.TokenType) { case TokenType.LogicalOperator: return(Logic(obj)); case TokenType.CompareOperator: return(Compare(obj)); case TokenType.ArithmeticOperator: return(Arithmetic(obj)); } ExceptionHelper.ThrowBinaryOperatorInvalid(obj.Token.TokenValue, obj.Lhs.GetType(), obj.Rhs.GetType()); return(null); }
private bool Compare(OperatorNode obj) { object lhs = obj.Lhs.Accept(this); object rhs = obj.Rhs.Accept(this); if (ScriptTypeUtil.IsNumber(lhs) && ScriptTypeUtil.IsNumber(rhs)) { decimal lNumber = ScriptTypeUtil.ConvertToDecimal(lhs); decimal rNumber = ScriptTypeUtil.ConvertToDecimal(rhs); switch (obj.Token.TokenValue) { case ">": return(lNumber > rNumber); case "<": return(lNumber < rNumber); case ">=": return(lNumber >= rNumber); case "<=": return(lNumber <= rNumber); case "==": return(lNumber == rNumber); case "<>": case "!=": return(lNumber != rNumber); } } //Note: If compare equality, null is OK. switch (obj.Token.TokenValue) { case "==": if (lhs == null) { return(rhs == null); } else { return(lhs.Equals(rhs)); } case "<>": case "!=": if (lhs == null) { return(rhs != null); } else { return(!(lhs.Equals(rhs))); } } ExceptionHelper.ThrowBinaryOperatorInvalid(obj.Token.TokenValue, lhs, rhs); return(false); }
private object Arithmetic(OperatorNode obj) { object lhs = obj.Lhs.Accept(this); object rhs = obj.Rhs.Accept(this); //Note:string concat if (obj.Token.TokenValue == "+" && (lhs is string || rhs is string)) { string result = string.Empty; if (lhs != null) { result += lhs.ToString(); } if (rhs != null) { result += rhs.ToString(); } return(result); } //Note:string multiple if (obj.Token.TokenValue == "*" && lhs is string && ScriptTypeUtil.IsLong(rhs)) { StringBuilder result = new StringBuilder(); for (int i = 0; i < (long)rhs; i++) { result.Append(lhs); } return(result.ToString()); } //Note:Only number is valid currently, everything will convert to decimal decimal lNumber = ScriptTypeUtil.ConvertToDecimal(lhs); decimal rNumber = ScriptTypeUtil.ConvertToDecimal(rhs); switch (obj.Token.TokenValue) { case "+": return(lNumber + rNumber); case "-": return(lNumber - rNumber); case "*": return(lNumber * rNumber); case "/": return(lNumber / rNumber); case "%": return(lNumber % rNumber); case "^": double b = double.Parse(lNumber.ToString()); double x = double.Parse(rNumber.ToString()); return((decimal)Math.Pow(b, x)); } ExceptionHelper.ThrowBinaryOperatorInvalid(obj.Token.TokenValue, lhs, rhs); return(null); }