Esempio n. 1
0
        public IValue Middle(IValue before, IValue after)
        {
            var beforeType = before.ValueType;
            var afterType  = after.ValueType;

            if (beforeType == ValueTypes.String || afterType == ValueTypes.String)
            {
                return(new Constant(before.GetString() + after.GetString()));
            }

            if (beforeType == ValueTypes.Number || afterType == ValueTypes.Number)
            {
                return(new Constant(before.GetNumber() + after.GetNumber()));
            }

            if (beforeType == ValueTypes.Float || afterType == ValueTypes.Float)
            {
                return(new Constant(before.GetFloat() + after.GetFloat()));
            }

            if (beforeType == ValueTypes.Integer || afterType == ValueTypes.Integer)
            {
                return(new Constant(before.GetInteger() + after.GetInteger()));
            }

            throw new Exception(StringHelper.Format("{0} and {1} cannot {2}.", beforeType.ToString(), afterType.ToString(), Code));
        }
Esempio n. 2
0
 public override double GetFloat()
 {
     try
     {
         return(m_pVal.GetFloat());
     }
     catch (ParserError exc)
     {
         exc.GetContext().Ident = GetIdent();
         throw;
     }
 }
Esempio n. 3
0
        public override void Eval(ref IValue ret, IValue[] a_pArg)
        {
            Global.MUP_VERIFY(a_pArg.Length == 2);

            IValue arg1 = a_pArg[0];
            IValue arg2 = a_pArg[1];

            if (arg1.IsNonComplexScalar() || arg2.IsNonComplexScalar())
            {
                if (!arg1.IsNonComplexScalar())
                {
                    throw new ParserError(new ErrorContext(EErrorCodes.ecTYPE_CONFLICT_FUN, -1, GetIdent(), arg1.GetValueType(), 'f', 1));
                }

                if (!arg2.IsNonComplexScalar())
                {
                    throw new ParserError(new ErrorContext(EErrorCodes.ecTYPE_CONFLICT_FUN, -1, GetIdent(), arg2.GetValueType(), 'f', 2));
                }

                if (arg1.IsInteger() && arg2.IsInteger())
                {
                    ret = arg1.GetInteger() - arg2.GetInteger();
                }
                else
                {
                    ret = arg1.GetFloat() - arg2.GetFloat();
                }
            }
            else //if (arg1.IsMatrix() && arg2.IsMatrix())
            {
                // Vector + Vector
                //Matrix a1 = arg1.GetArray(), a2 = arg2.GetArray();
                //if (a1.GetRows() != a2.GetRows())
                //    throw new ParserError(new ErrorContext(EErrorCodes.ecARRAY_SIZE_MISMATCH, -1, GetIdent(), 'm', 'm', 2));

                //var rv = new Matrix(a1.GetRows());
                //for (int i = 0; i < a1.GetRows(); ++i)
                //{
                //    if (!a1.At(i).IsNonComplexScalar())
                //        throw new ParserError(new ErrorContext(EErrorCodes.ecTYPE_CONFLICT_FUN, -1, GetIdent(), a1.At(i).GetValueType(), 'f', 1));

                //    if (!a2.At(i).IsNonComplexScalar())
                //        throw new ParserError(new ErrorContext(EErrorCodes.ecTYPE_CONFLICT_FUN, -1, GetIdent(), a2.At(i).GetValueType(), 'f', 1));

                //    if (a1.At(i).IsInteger() && a2.At(i).IsInteger())
                //        rv.At(i) = a1.At(i).GetInteger() - a2.At(i).GetInteger();
                //    else
                //        rv.At(i) = a1.At(i).GetFloat() - a2.At(i).GetFloat();
                //}

                ret = arg1 - arg2;
            }
        }
Esempio n. 4
0
        public IValue Before(IValue after)
        {
            switch (after.ValueType)
            {
            case ValueTypes.Integer:
                return(new Constant(-after.GetInteger()));

            case ValueTypes.Float:
                return(new Constant(-after.GetFloat()));

            case ValueTypes.Number:
                return(new Constant(-after.GetNumber()));

            default:
                throw new Exception("- 无法应用于" + after.ValueType);
            }
        }
Esempio n. 5
0
        public override void Eval(ref IValue ret, IValue[] a_pArg)
        {
            Global.MUP_VERIFY(a_pArg.Length == 2);

            IValue arg1 = a_pArg[0];
            IValue arg2 = a_pArg[1];

            if (!arg1.IsNonComplexScalar())
            {
                throw new ParserError(new ErrorContext(EErrorCodes.ecTYPE_CONFLICT_FUN, -1, GetIdent(), arg1.GetValueType(), 'f', 1));
            }

            if (!arg2.IsNonComplexScalar())
            {
                throw new ParserError(new ErrorContext(EErrorCodes.ecTYPE_CONFLICT_FUN, -1, GetIdent(), arg2.GetValueType(), 'f', 2));
            }

            ret = arg1.GetFloat() / arg2.GetFloat();
        }
Esempio n. 6
0
 public double GetFloat()
 {
     return(value.GetFloat());
 }
Esempio n. 7
0
        public override void Eval(ref IValue ret, IValue[] a_pArg)
        {
            Global.MUP_VERIFY(a_pArg.Length == 2);

            IValue arg1 = a_pArg[0];
            IValue arg2 = a_pArg[1];

            if (!arg1.IsNonComplexScalar())
            {
                throw new ParserError(new ErrorContext(EErrorCodes.ecTYPE_CONFLICT_FUN, -1, GetIdent(), arg1.GetValueType(), 'f', 1));
            }

            if (!arg2.IsNonComplexScalar())
            {
                throw new ParserError(new ErrorContext(EErrorCodes.ecTYPE_CONFLICT_FUN, -1, GetIdent(), arg2.GetValueType(), 'f', 2));
            }
            if (arg1.IsInteger() && arg2.IsInteger())
            {
                var i1 = arg1.GetInteger();
                var i2 = arg2.GetInteger();
                switch (i2)
                {
                case 1:
                    ret = i1;
                    break;

                case 2:
                    ret = i1 * i1;
                    break;

                case 3:
                    ret = i1 * i1 * i1;
                    break;

                case 4:
                    ret = i1 * i1 * i1 * i1;
                    break;

                case 5:
                    ret = i1 * i1 * i1 * i1 * i1;
                    break;

                default:
                    ret = (long)Math.Pow(i1, i2);
                    break;
                }
            }
            else
            {
                var i1 = arg1.GetFloat();
                var i2 = arg2.GetFloat();
                switch (i2)
                {
                case 1:
                    ret = i1;
                    break;

                case 2:
                    ret = i1 * i1;
                    break;

                case 3:
                    ret = i1 * i1 * i1;
                    break;

                case 4:
                    ret = i1 * i1 + i1 * i1;
                    break;

                case 5:
                    ret = i1 * i1 * i1 * i1 * i1;
                    break;

                default:
                    ret = Math.Pow(i1, i2);
                    break;
                }
            }
        }
Esempio n. 8
0
        public static void EqnTest(string a_str, dynamic d, bool a_fPass, int nExprVar = -1)
        {
            IValue[] fVal  = new IValue[5];
            IValue   a_val = d;

            try
            {
                // p1 is a pointer since I'm going to delete it in order to test if
                // parsers after copy construction still refer to members of the deleted object.
                // !! If this is the case this function will crash !!
                ParserX p1 = new ParserX();

                // Add variables
                Value[] vVarVal = { 1, 2, 3, -2, -1 };

                // m1 ist die Einheitsmatrix
                var m1 = new Value(3, 3, 0L);
                m1.At(0, 0) = 1L;
                m1.At(1, 1) = 1L;
                m1.At(2, 2) = 1L;

                // m2 ist die Einheitsmatrix
                Value m2 = new Value(3, 3, 0);
                m2.At(0, 0) = 1;
                m2.At(0, 1) = 2;
                m2.At(0, 2) = 3;
                m2.At(1, 0) = 4;
                m2.At(1, 1) = 5;
                m2.At(1, 2) = 6;
                m2.At(2, 0) = 7;
                m2.At(2, 1) = 8;
                m2.At(2, 2) = 9;

                p1.DefineOprt(new DbgSillyAdd());
                p1.DefineFun(new FunTest0());

                p1.DefineVar("a", new Variable(vVarVal[0]));
                p1.DefineVar("b", new Variable(vVarVal[1]));
                p1.DefineVar("c", new Variable(vVarVal[2]));
                p1.DefineVar("d", new Variable(vVarVal[3]));
                p1.DefineVar("f", new Variable(vVarVal[4]));
                p1.DefineVar("m1", new Variable(m1));
                p1.DefineVar("m2", new Variable(m2));

                // Add constants
                p1.DefineConst("const", 1);
                p1.DefineConst("const1", 2);
                p1.DefineConst("const2", 3);

                // some vector variables
                Value aVal1 = new Value(3, 0);
                aVal1.At(0) = 1;
                aVal1.At(1) = 2;
                aVal1.At(2) = 3;

                Value aVal2 = new Value(3, 0);
                aVal2.At(0) = 4;
                aVal2.At(1) = 3;
                aVal2.At(2) = 2;
                p1.DefineVar("va", new Variable(aVal1));
                p1.DefineVar("vb", new Variable(aVal2));

                // complex variables
                Value[] cVal = new Value[3];
                cVal[0] = new Complex(1, 1);
                cVal[1] = new Complex(2, 3);
                cVal[2] = new Complex(3, 4);
                p1.DefineVar("ca", new Variable(cVal[0]));
                p1.DefineVar("cb", new Variable(cVal[1]));
                p1.DefineVar("cc", new Variable(cVal[2]));

                p1.SetExpr(a_str);

                fVal[0] = p1.Eval();
                p1.DumpRPN();
                // Test copy and assignement operators
                List <ParserX> vParser = new List <ParserX>();
                vParser.Add(p1);            // Push p1 into the vector
                ParserX p2 = new ParserX(); // take parser from vector
                p2.Assign(vParser[0]);
                // destroy the originals from p2
                vParser.Clear();     // delete the vector
                p1 = null;           // delete the original

                fVal[1] = p2.Eval(); // If copy constructions does not work
                // we may see a crash here

                ParserX p3 = new ParserX(p2);
                fVal[2] = p3.Eval(); // If assignment does not work
                // we may see a crash here

                // Calculating a second time will parse from rpn rather than from
                // string. The result must be the same...
                fVal[3] = p3.Eval();

                // Calculate yet another time. There is the possibility of
                // changing variables as a side effect of expression
                // evaluation. So there are really bugs that could make this fail...
                fVal[4] = p3.Eval();

                // Check i number of used variables is correct
                if (nExprVar != -1)
                {
                    int n2 = p2.GetExprVar().Count;
                    int n3 = p3.GetExprVar().Count;

                    if (n2 + n3 != 2 * n2 || n2 != nExprVar)
                    {
                        var msg =
                            $"Number of expression variables is incorrect. (expected: {nExprVar}; detected: {n2})";
                        Assert.Fail(msg);
                    }
                }

                // Check the three results
                // 1.) computed results must have identic type
                char cType = fVal[0].GetValueType();
                bool bStat = cType == fVal[1].GetValueType() &&
                             cType == fVal[2].GetValueType() &&
                             cType == fVal[3].GetValueType() &&
                             cType == fVal[4].GetValueType();
                if (!bStat)
                {
                    var msg = $"{a_str} :  inconsistent result type " +
                              $"({fVal[0].GetValueType()}, {fVal[1].GetValueType()}, " +
                              $"{fVal[2].GetValueType()}, {fVal[3].GetValueType()}, {fVal[4].GetValueType()})";
                    Assert.Fail(msg);
                }

                if ((cType == 'x' || a_val.GetValueType() == 'x') && cType != a_val.GetValueType())
                {
                    var msg = $"{a_str}:  Complex value sliced!";
                    Assert.Fail(msg);
                }

                // Compare the results
                switch (cType)
                {
                case 'i':
                case 'b':
                case 's':
                    bStat = (a_val == fVal[0] &&
                             a_val == fVal[1] &&
                             a_val == fVal[2] &&
                             a_val == fVal[3] &&
                             a_val == fVal[4]);
                    break;

                // We need more attention for comaring float values due to floating point
                // inaccuracies.
                case 'f':
                {
                    bStat = true;
                    int num = fVal.Length;
                    for (int i = 0; i < num; ++i)
                    {
                        bStat &= Math.Abs(a_val.GetFloat() - fVal[i].GetFloat()) <=
                                 Math.Abs(fVal[i].GetFloat() * 0.0001);
                    }
                }
                break;

                case 'z':
                {
                    bStat = true;
                    int num = fVal.Length;
                    for (int i = 0; i < num; ++i)
                    {
                        bStat &= Math.Abs(a_val.AsFloat() - fVal[i].AsFloat()) <=
                                 Math.Max(1e-15, Math.Abs(fVal[i].AsFloat() * 0.0000001));
                        bStat &= Math.Abs(a_val.GetImag() - fVal[i].GetImag()) <=
                                 Math.Max(1e-15, Math.Abs(fVal[i].GetImag() * 0.0000001));
                    }
                }
                break;

                case 'm':
                {
                    bStat = true;
                    int num = fVal.Length;

                    for (int i = 0; i < num; ++i)
                    {
                        bStat = Check(a_val, fVal[i]);
                        if (!bStat)
                        {
                            break;
                        }
                    }
                }
                break;

                default:
                    Assert.Fail($"Parser return value has an unexpected typecode '{cType}'.");
                    break;
                }

                Assert.AreEqual(bStat, a_fPass);
            }
            catch (ParserError p)
            {
                Assert.Fail(p.GetMsg());
            }
            catch (Exception e)
            {
                var msg = a_str + ": " + e.Message;
                Assert.Fail(msg);
            }

            bool Check(IValue v1, IValue v2, bool checkType = true)
            {
                if (checkType && v1.GetValueType() != v2.GetValueType())
                {
                    return(false);
                }

                if (v1.GetRows() != v2.GetRows())
                {
                    return(false);
                }

                if (v1.IsMatrix())
                {
                    for (int i = 0; i < v1.GetRows(); ++i)
                    {
                        for (int j = 0; j < v1.GetCols(); ++j)
                        {
                            if (!Check(v1.At(i, j), v2.At(i, j)))
                            {
                                return(false);
                            }
                        }
                    }

                    return(true);
                }
                else
                {
                    return(Math.Abs(v1.GetFloat() - v2.GetFloat()) <=
                           Math.Max(1e-15, Math.Abs(v1.GetFloat() * 0.0000001)));
                }
            }
        }