Esempio n. 1
0
        public override INumber Power(RuntimeData runtime, INumber val)
        {
            var me = this.Clone() as Number;

            if (val is Number && (val as Number).Value < 0)
            {
                return(new Fraction(
                           Number.New(this.Value).Power(runtime, val.Multiple(runtime, Number.New(-1))),
                           Number.New(1)));
            }

            if (val is Number)
            {
                if ((val as Number).Value >= 1)
                {
                    var res = me.Value;
                    for (int i = 0; i < (val as Number).Value - 1; i++)
                    {
                        me.Value *= res;
                    }
                    me.Pow = Number.New(1);
                    return(me);
                }
                else if ((val as Number).Value == 0)
                {
                    return(Number.New(1));
                }
                else
                {
                    return(new Fraction(me.Power(runtime, Number.New((val as Number).Value * -1)), Number.New(1)));
                }
            }
            me.Pow = val;
            return(me);
        }
Esempio n. 2
0
        public override INumber Subtract(RuntimeData runtime, INumber val)
        {
            var v = val.Eval(runtime);

            if (v is Number)
            {
                if (this.Pow.Equals(runtime, val.Pow))
                {
                    return(Number.New(this.Value - (val as Number).Value));
                }
                else
                {
                    AdditionFormula af = new Expression.AdditionFormula();
                    af.AddItem(runtime, this);
                    af.AddItem(runtime, val.Multiple(runtime, Number.New(-1)));
                    return(af);
                }
            }
            if (v is Fraction)
            {
                return(v.Multiple(runtime, Number.New(-1)).Add(runtime, this));
            }

            return(v.Subtract(runtime, this));
        }
Esempio n. 3
0
        public override INumber Multiple(RuntimeData runtime, INumber val)
        {
            if (this.Value == 0)
            {
                return(Number.New(0));
            }

            var v = val.Eval(runtime);

            if (v is Number)
            {
                if (this.Pow.Equals(runtime, val.Pow))
                {
                    return(Number.New(this.Value * (v as Number).Value));
                }
                else
                {
                    MultipleFormula mf = new MultipleFormula();
                    mf.AddItem(runtime, this);
                    mf.AddItem(runtime, val);
                    return(mf);
                }
            }

            return(val.Multiple(runtime, this));
        }
Esempio n. 4
0
        public override INumber FinalEval(RuntimeData runtime)
        {
            INumber res = Number.New(1);

            for (int i = 0; i < this.items.Count; i++)
            {
                res = res.Multiple(runtime, this.items[i].FinalEval(runtime));
            }
            return(res);
        }
Esempio n. 5
0
        public override INumber Optimise(RuntimeData runtime)
        {
            INumber res = Number.New(1);

            for (int i = 0; i < this.Count; i++)
            {
                res = res.Multiple(runtime, this.items[i]);
                if (!(res is MultipleFormula))
                {
                    res = res.Optimise(runtime);
                }
            }
            //if (!(res is MultipleFormula))
            //    return res.Optimise(runtime);

            return(res);
        }
Esempio n. 6
0
        public override INumber Multiple(RuntimeData runtime, INumber val)
        {
            if (val is IConstParameter)
            {
                var me = this.Clone() as FloatNumber;
                me.value *= (val as IConstParameter).ConstValue;
                return(me);
            }
            if (val is InfinityValue)
            {
                return(val.Multiple(runtime, this));
            }

            MultipleFormula mf = new MultipleFormula();

            mf.AddItem(runtime, val);
            mf.AddItem(runtime, this);

            return(mf);
        }
Esempio n. 7
0
        public INumber Execute(RuntimeData runtime, INumber left, INumber right)
        {
            // 意味のない計算はここで弾く
            if (left is Number && (left as Number).Value == 1)
            {
                return(right);
            }
            if (right is Number && (right as Number).Value == 1)
            {
                return(left);
            }
            if ((left is Number && (left as Number).Value == 0) ||
                (right is Number && (right as Number).Value == 0))
            {
                return(Number.New(0));
            }

            if (left is Number && right is Number)
            {
                return(Number.New((left as Number).Value * (right as Number).Value));
            }

            return(left.Multiple(runtime, right));
        }
Esempio n. 8
0
        public override INumber Eval(RuntimeData runtime)
        {
            // 1しかない場合は変数
            if (this.items.Count == 1)
            {
                if (!(this.items[0] is INumber))
                {
                    throw new NotImplementedException("FunctionFormulaに値以外が紛れ込んでいます");
                }
                return((this.items[0] as INumber).Eval(runtime));
            }

            bool        nextFlag = false;
            IExpression func     = null;
            INumber     multiple = Number.New(1);

            for (int i = 0; i < this.items.Count; i++)
            {
                IExpression ex = this.items[i];

                if (ex is Member &&
                    ((nextFlag && func != null) || (!nextFlag && func == null)))
                {
                    func = FunctionFormula.GetMember(runtime, func, ex as Member);
                    if (func == null)
                    {
                        throw new SyntaxException(string.Format("'{0}'は見つかりませんでした", ex.Token.Text), ex.Token,
                                                  new KeyNotFoundException());
                    }
                    if (func is INumber && !(func is IEvalWithParameters))
                    {
                        multiple = multiple.Multiple(runtime, func as INumber);
                        func     = null;
                    }
                    nextFlag = false;
                    continue;
                }
                if (ex is Operator &&
                    ex.Token.Text == runtime.Setting.Spec.ScopeOperator)
                {
                    nextFlag = true;
                    continue;
                }
                // パラメータ関係
                if ((ex is IFormula) && !nextFlag)
                {
                    if (func == null && multiple is IEvalWithParameters)
                    {
                        func     = multiple;
                        multiple = Number.New(1);
                    }

                    if (func != null)
                    {
                        runtime.AddBlock(new BlockData()
                        {
                            MoreScope = true
                        });
                        runtime.NowBlock.Push(new LineBreak());

                        (ex as IFormula).ExecuteAsParameter(runtime);

                        IExpression res = null;
                        if (func is INumber && func is IEvalWithParameters)
                        {
                            List <INumber> prm = new List <INumber>();
                            for (; runtime.NowBlock.Stack.Length != 0;)
                            {
                                var it = runtime.NowBlock.Pop(); if (it is LineBreak)
                                {
                                    continue;
                                }
                                if (!(it is INumber))
                                {
                                    throw new RuntimeException("インデックス指定で値型(INumber)以外のパラメータを指定することはできません。", it);
                                }
                                prm.Add(it as INumber);
                            }
                            res = (func as IEvalWithParameters).Execute(runtime, prm.ToArray()) as IExpression;
                        }
                        else
                        {
                            res = ExecuteFunc(runtime, func, multiple);
                        }

                        runtime.PopBlock();

                        if (res is INumber)
                        {
                            if (multiple is Number && (multiple as Number).Value != 1)
                            {
                                multiple = multiple.Multiple(runtime, res as INumber);
                            }
                            else
                            {
                                multiple = res as INumber;
                            }
                            func = null;
                        }
                        else if (res == null)
                        {
                            func     = null;
                            multiple = null;
                        }
                        else
                        {
                            func = res;
                            throw new NotImplementedException("関数の戻り値は現在 '値' しか対応していません");
                        }

                        continue;
                    }
                    else
                    {
                        if (multiple.Equals(runtime, Number.New(1)))
                        {
                            return(this); // 未解決のメンバーを実行しようとしている式は評価せずに返す
                        }
                        else
                        {
                            var res = (ex as IFormula).Eval(runtime);
                            multiple = multiple.Multiple(runtime, res);
                        }
                        continue;
                    }
                }

                throw new NotImplementedException();
            }

            if (func == null && multiple == null)
            {
                return(null);
            }
            if (func == null)
            {
                return(multiple);
            }
            if (!(func is INumber))
            {
                throw new RuntimeException("現在、関数の戻り値は値のみに対応しています。関数ポインターを戻り値にすることはできません。", this);
            }


            return((func as INumber).Eval(runtime));
        }
Esempio n. 9
0
        public override INumber Divide(RuntimeData runtime, INumber val)
        {
            if (val is Number)
            {
                Fraction me = this.Clone() as Fraction;
                me.Denominator = me.Denominator.Multiple(runtime, val);
                if (runtime.Setting.DoOptimize)
                {
                    return(me.Optimise(runtime));
                }
                else
                {
                    return(me);
                }
            }
            if (val is Fraction)
            {
                var res = new Fraction(
                    this.Denominator.Multiple(runtime, (val as Fraction).Numerator),
                    this.Numerator.Multiple(runtime, (val as Fraction).Denominator));
                if (runtime.Setting.DoOptimize)
                {
                    return(res.Optimise(runtime));
                }
                else
                {
                    return(res);
                }
            }
            if (this.Denominator is MultipleFormula)
            {
                bool mf_res;
                var  dv_res = (this.Denominator as MultipleFormula).TryDivide(runtime, val, out mf_res);
                if (mf_res)
                {
                    var me = this.Clone() as Fraction;
                    me.Denominator = dv_res;
                    if (runtime.Setting.DoOptimize)
                    {
                        return(me.Optimise(runtime));
                    }
                    else
                    {
                        return(me);
                    }
                }
                else
                {
                    var me = this.Clone() as Fraction;
                    me.Denominator = me.Denominator.Multiple(runtime, val);
                    if (runtime.Setting.DoOptimize)
                    {
                        return(me.Optimise(runtime));
                    }
                    else
                    {
                        return(me);
                    }
                }
            }

            return(val.Multiple(runtime, new Fraction(this.Numerator, this.Denominator)));
        }
Esempio n. 10
0
        INumber CheckMulti(RuntimeData runtime, string varname, INumber val, out INumber pow)
        {
            if (val is IConstParameter)
            {
                pow = Number.New(0);
                return(val);
            }
            if (val is Variable)
            {
                if ((val as Variable).Name == varname)
                {
                    pow = val.Pow;
                    return((val as Variable).Multi);
                }
                else
                {
                    pow = Number.New(0);
                    return(val);
                }
            }
            if (val is Member)
            {
                if ((val as Member).Text == varname)
                {
                    pow = val.Pow;
                    return((val as Member).Multi);
                }
                else
                {
                    pow = Number.New(0);
                    return(val);
                }
            }
            if (val is MultipleFormula)
            {
                MultipleFormula mf   = val as MultipleFormula;
                INumber         res  = Number.New(0);
                INumber         pres = Number.New(1);
                bool            flag = false;

                for (int i = 0; i < mf.Items.Count; i++)
                {
                    var item = mf.Items[i];

                    INumber p = null;
                    var     r = this.CheckMulti(runtime, varname, item, out p);
                    if (p is Number && (p as Number).Value == 0)
                    {
                        res = res.Multiple(runtime, r);
                    }
                    else
                    {
                        flag = true;
                        pres = pres.Add(runtime, p);
                        res  = res.Multiple(runtime, r);
                    }
                }
                if (flag)
                {
                    pow = pres;
                    return(res);
                }
                else
                {
                    pow = Number.New(0);
                    return(res);
                }
            }
            if (val is AdditionFormula)
            {
                throw new RuntimeException("バグ: [AF]のアイテム評価関数に[AF]が指定されました。", val);
            }

            throw new NotImplementedException("[AF]のアイテム評価関数の未実装");
        }
Esempio n. 11
0
 public INumber Execute(RuntimeData runtime, INumber left, INumber right)
 {
     return(right.Multiple(runtime, Number.New(-1)));
 }