示例#1
0
 public void TestNullOrEmpty()
 {
     // string
     Assert.DoesNotThrow(() => ArgChk.NullOrEmpty(_nullString, ArgName));
     Assert.DoesNotThrow(() => ArgChk.NullOrEmpty("", ArgName));
     Assert.Throws <ArgumentNullException>(() => ArgChk.NullOrEmpty("ok", ArgName));
     // ICollection
     Assert.DoesNotThrow(() => ArgChk.NullOrEmpty(_colNull, ArgName));
     Assert.DoesNotThrow(() => ArgChk.NullOrEmpty(_col0, ArgName));
     Assert.Throws <ArgumentNullException>(() => ArgChk.NullOrEmpty(_col1, ArgName));
 }
示例#2
0
        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();
            }
        }