public override object Visit(UnaryNode obj) { object val = obj.OperandNode.Accept(this); if (obj.Token.TokenValue == "!") { bool b = ScriptTypeUtil.EvalToBoolean(val); return(!b); } if (val == null) { ExceptionHelper.ThrowEvalNull(); } if (obj.Token.TokenValue == "+") { return(val); } if (obj.Token.TokenValue == "-") { if (ScriptTypeUtil.IsDecimal(val)) { decimal result = ScriptTypeUtil.ConvertToDecimal(val); return(-result); } if (ScriptTypeUtil.IsLong(val)) { long result = ScriptTypeUtil.ConvertToLong(val); return(-result); } } ExceptionHelper.ThrowUnaryOperatorInvalid(obj.Token.TokenValue, val); return(null); }
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); }