예제 #1
0
 public Token([NotNull] string expr, IEnumerable <IToken> tokens, TokenType type)
 {
     ArgChk.NotNull(expr, nameof(expr));
     Expr     = expr;
     Type     = type;
     Children = tokens?.ToList();
 }
예제 #2
0
 public Token([NotNull] string expr, TokenType type)
 {
     ArgChk.NotNull(expr, nameof(expr));
     Expr     = expr;
     Type     = type;
     Children = null;
 }
예제 #3
0
 internal Expr([NotNull] IToken root, [NotNull] IExprContext context)
 {
     ArgChk.NotNull(root, nameof(root));
     ArgChk.NotNull(context, nameof(context));
     _root     = root;
     _context  = context;
     FuncNames = new HashSet <string>(GetFunctionName(_root));
     VarNames  = new HashSet <string>(GetVariableName(_root));
 }
예제 #4
0
 public void TestDefinedInEnum()
 {
     Assert.DoesNotThrow(() => ArgChk.DefinedInEnum(TestEnum.T1, ArgName));
     Assert.Throws <ArgumentException>(() => ArgChk.DefinedInEnum((TestEnum)(-1), ArgName));
     Assert.DoesNotThrow(() => ArgChk.DefinedInEnum((TestEnum)0, ArgName));
     Assert.DoesNotThrow(() => ArgChk.DefinedInEnum((TestEnum)1, ArgName));
     Assert.DoesNotThrow(() => ArgChk.DefinedInEnum((TestEnum)2, ArgName));
     Assert.Throws <ArgumentException>(() => ArgChk.DefinedInEnum((TestEnum)4, ArgName));
 }
예제 #5
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));
 }
예제 #6
0
 public void TestLt()
 {
     // int
     Assert.DoesNotThrow(() => ArgChk.Lt(0, ArgName, 1));
     Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.Lt(0, ArgName, 0));
     Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.Lt(1, ArgName, 0));
     // collection
     Assert.Throws <ArgumentNullException>(() => ArgChk.Lt(_colNull, ArgName, 1));
     Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.Lt(_col0, ArgName, 0));
     Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.Lt(_col1, ArgName, 0));
     Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.Lt(_col3, ArgName, 2));
     Assert.DoesNotThrow(() => ArgChk.Lt(_col3, ArgName, 4));
 }
예제 #7
0
 public void TestNe()
 {
     // int
     Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.Ne(0, ArgName, 0));
     Assert.DoesNotThrow(() => ArgChk.Ne(0, ArgName, 1));
     Assert.DoesNotThrow(() => ArgChk.Ne(1, ArgName, 0));
     // string
     Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.Ne(_nullString, ArgName, _nullString));
     Assert.DoesNotThrow(() => ArgChk.Ne(_nullString, ArgName, string.Empty));
     Assert.DoesNotThrow(() => ArgChk.Ne(string.Empty, ArgName, _nullString));
     Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.Ne(string.Empty, ArgName, string.Empty));
     Assert.DoesNotThrow(() => ArgChk.Ne("abc", ArgName, string.Empty));
     Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.Ne("abc", ArgName, "abc"));
     Assert.DoesNotThrow(() => ArgChk.Ne("xyz", ArgName, "abc"));
     // collection
     Assert.Throws <ArgumentNullException>(() => ArgChk.Ne(_colNull, ArgName, 1));
     Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.Ne(_col0, ArgName, 0));
     Assert.DoesNotThrow(() => ArgChk.Ne(_col1, ArgName, 0));
     Assert.DoesNotThrow(() => ArgChk.Ne(_col3, ArgName, 2));
     Assert.DoesNotThrow(() => ArgChk.Ne(_col3, ArgName, 4));
 }
예제 #8
0
        public void TestInBound()
        {
            // int
            //[6,5,4)
            Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.InBound(5, ArgName, 4, 6));
            //[5,6,4)
            Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.InBound(6, ArgName, 4, 5));
            //[4,6,5)
            Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.InBound(6, ArgName, 5, 4));
            //[6,4,5)
            Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.InBound(4, ArgName, 5, 6));
            //[4,5,6)
            Assert.DoesNotThrow(() => ArgChk.InBound(5, ArgName, 6, 4));
            //[5,4,6)
            Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.InBound(4, ArgName, 6, 5));
            //[0,-1,1)
            Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.InBound(-1, ArgName, 1));
            //[0,1,-1)
            Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.InBound(1, ArgName, -1));
            //[0,0,0)
            Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.InBound(0, ArgName, 0));
            //[0,0,0)
            Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.InBound(0, ArgName, 0));
            //[0,1,2)
            Assert.DoesNotThrow(() => ArgChk.InBound(1, ArgName, 2));
            //[0,1,1)
            Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.InBound(1, ArgName, 1));

            // collection
            var col3 = new Collection <int> {
                1, 2, 3
            };

            Assert.DoesNotThrow(() => ArgChk.InBound(0, ArgName, col3));
            Assert.DoesNotThrow(() => ArgChk.InBound(2, ArgName, col3));
            Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.InBound(-1, ArgName, col3));
            Assert.Throws <ArgumentOutOfRangeException>(() => ArgChk.InBound(3, ArgName, col3));
        }
예제 #9
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();
            }
        }
예제 #10
0
 internal IConvertible Arg([NotNull] IToken token, int idx)
 {
     ArgChk.NotNull(token, nameof(token));
     ArgChk.InBound(idx, nameof(idx), token.Children);
     return(EvalToken(token.Children[idx]));
 }
예제 #11
0
 public void TestNull()
 {
     Assert.Throws <ArgumentNullException>(() => ArgChk.Null(0, ArgName));
     Assert.DoesNotThrow(() => ArgChk.Null(_nullObj, ArgName));
     Assert.DoesNotThrow(() => ArgChk.Null(_nullInt, ArgName));
 }
예제 #12
0
 public void TestPredicate()
 {
     Assert.Throws <ArgumentNullException>(() => ArgChk.Predicate(_nullPredicate, ArgName));
     Assert.Throws <ArgumentException>(() => ArgChk.Predicate(() => false, ArgName));
     Assert.DoesNotThrow(() => ArgChk.Predicate(() => true, ArgName));
 }