public void TestNotNullOrEmpty() { // string Assert.Throws <ArgumentNullException>(() => ArgChk.NotNullOrEmpty(_nullString, ArgName)); Assert.Throws <ArgumentNullException>(() => ArgChk.NotNullOrEmpty("", ArgName)); Assert.DoesNotThrow(() => ArgChk.NotNullOrEmpty("ok", ArgName)); // ICollection Assert.Throws <ArgumentNullException>(() => ArgChk.NotNullOrEmpty(_colNull, ArgName)); Assert.Throws <ArgumentNullException>(() => ArgChk.NotNullOrEmpty(_col0, ArgName)); Assert.DoesNotThrow(() => ArgChk.NotNullOrEmpty(_col1, ArgName)); }
internal IConvertible EvalToken([NotNull] IToken token) { ArgChk.NotNull(token, nameof(token)); switch (token.Type) { case TokenType.LiteralNumber: { ArgChk.NullOrEmpty(token.Children, nameof(token.Children)); return(double.Parse(token.Expr)); } case TokenType.Identifier: { ArgChk.NullOrEmpty(token.Children, nameof(token.Children)); return(_context.GetVar(token.Expr)(_context)); } case TokenType.Func: { // parse child argument var args = new List <IConvertible>(); if (token.Children?.Any() ?? false) { var arg = new Queue <IToken>(token.Children); while (arg.Count > 0) { var curArg = arg.Dequeue(); if (curArg.Type != TokenType.FuncArgs) { args.Add(EvalToken(curArg)); } else { ArgChk.NotNullOrEmpty(curArg.Children, nameof(curArg.Children)); foreach (var c in curArg.Children) { arg.Enqueue(c); } } } } return(_context.GetFunc(token.Expr)(_context, args)); } case TokenType.FuncArgs: throw new Sprache.ParseException("unexpected comma"); case TokenType.UnaryPlus: case TokenType.UnaryNoOp: { ExpectArgSize(token.Type.ToString(), token.Children, 1); return(Arg(token, 0)); } case TokenType.UnaryMinus: { ExpectArgSize(token.Type.ToString(), token.Children, 1); return(-ArgDouble(token, 0)); } case TokenType.UnaryNot: { ExpectArgSize(token.Type.ToString(), token.Children, 1); return(!ArgBool(token, 0)); } case TokenType.BinaryPow: { ExpectArgSize(token.Type.ToString(), token.Children, 2); return(Math.Pow(ArgDouble(token, 0), ArgDouble(token, 1))); } case TokenType.BinaryMul: { ExpectArgSize(token.Type.ToString(), token.Children, 2); var arg0 = ArgDouble(token, 0); // short circuit!! if (_context.DoubleNearZero(arg0)) { return(0); } return(arg0 * ArgDouble(token, 1)); } case TokenType.BinaryDiv: { ExpectArgSize(token.Type.ToString(), token.Children, 2); return(ArgDouble(token, 0) / ArgDouble(token, 1)); } case TokenType.BinaryDivInt: { ExpectArgSize(token.Type.ToString(), token.Children, 2); var arg1 = ArgInteger(token, 1); var arg0 = ArgInteger(token, 0); if (arg1 == 0) { return((double)arg0 / arg1); } return(ArgInteger(token, 0) / arg1); } case TokenType.BinaryPlus: { ExpectArgSize(token.Type.ToString(), token.Children, 2); return(ArgDouble(token, 0) + ArgDouble(token, 1)); } case TokenType.BinaryMinus: { ExpectArgSize(token.Type.ToString(), token.Children, 2); return(ArgDouble(token, 0) - ArgDouble(token, 1)); } case TokenType.BinaryLt: { ExpectArgSize(token.Type.ToString(), token.Children, 2); return(ArgDouble(token, 0) < ArgDouble(token, 1)); } case TokenType.BinaryLe: { ExpectArgSize(token.Type.ToString(), token.Children, 2); return(ArgDouble(token, 0) <= ArgDouble(token, 1)); } case TokenType.BinaryGt: { ExpectArgSize(token.Type.ToString(), token.Children, 2); return(ArgDouble(token, 0) > ArgDouble(token, 1)); } case TokenType.BinaryGe: { ExpectArgSize(token.Type.ToString(), token.Children, 2); return(ArgDouble(token, 0) >= ArgDouble(token, 1)); } case TokenType.BinaryEq: { ExpectArgSize(token.Type.ToString(), token.Children, 2); return(_context.DoubleNearZero(ArgDouble(token, 0) - ArgDouble(token, 1))); } case TokenType.BinaryNe: { ExpectArgSize(token.Type.ToString(), token.Children, 2); return(!_context.DoubleNearZero(ArgDouble(token, 0) - ArgDouble(token, 1))); } case TokenType.BinaryAnd: { ExpectArgSize(token.Type.ToString(), token.Children, 2); return(ArgBool(token, 0) && ArgBool(token, 1)); } case TokenType.BinaryOr: { ExpectArgSize(token.Type.ToString(), token.Children, 2); return(ArgBool(token, 0) || ArgBool(token, 1)); } case TokenType.TrinayCondition: { ExpectArgSize(token.Type.ToString(), token.Children, 3); return(ArgBool(token, 0) ? Arg(token, 1) : Arg(token, 2)); } default: throw new ArgumentOutOfRangeException(); } }