コード例 #1
0
        public void PutOperator(Code oper)
        {
            Debug.Assert(CodeHelper.IsOp(oper));
            AddCode(oper);

            if (oper != Code.Neg)
            {
                this.stackSize--;
            }
        }
コード例 #2
0
        public override void PutOperator(Code oper)
        {
            Debug.Assert(CodeHelper.IsOp(oper));
            Debug.Assert(this.pos >= 0);

            T value = this.stack[this.pos];

            if (oper != Code.Neg)
            {
                Debug.Assert(this.pos >= 0);
                Debug.Assert(this.pos < this.stack.Length);

                T temp = this.stack[--this.pos];

                if (oper == Code.Add)
                {
                    temp = Generic.Add(temp, value);
                }
                else if (oper == Code.Mul)
                {
                    temp = Generic.Mul(temp, value);
                }
                else if (oper == Code.Sub)
                {
                    temp = Generic.Sub(temp, value);
                }
                else if (oper == Code.Div)
                {
                    temp = Generic.Div(temp, value);
                }
                else if (oper == Code.Mod)
                {
                    temp = Generic.Mod(temp, value);
                }
                else
                {
                    temp = Generic.Pow(temp, value);
                }

                this.stack[this.pos] = temp;
            }
            else
            {
                this.stack[this.pos] = Generic.Neg(value);
            }
        }
コード例 #3
0
        public new void PutOperator(Code oper)
        {
            Debug.Assert(CodeHelper.IsOp(oper));

            if (ConstantFolding)
            {
                // Unary operator optimize ======================
                if (oper == Code.Neg && IsLastKnown())
                {
                    PerformNegate();
                    return;
                }

                // Binary operator optimize =====================
                if (IsLastTwoKnown())
                {
                    PerformBinaryOp(oper);
                    return;
                }

                // Power operator optimize ======================
                Debug.Assert(this.code.Count >= 2);

                if (oper == Code.Pow && PowOptimize &&
                    LastValue(code, 1) == Code.Number &&
                    LastValue(code, 2) == Code.Argument)
                {
                    int?val = this.interp.IsIntegral(LastNumber);
                    if (val.HasValue)
                    {
                        int value = val.Value;
                        if (value > 0 && value < 16)
                        {
                            OptimizePow(value);
                            return;
                        }
                    }
                }
            }

            code.Add(oper);
        }
コード例 #4
0
        public void WriteTo(IExpressionOutput <T> output)
        {
            int i = 0, n = 0,
                f = 0, d = 0;

            while (true)
            {
                Code op = this.code[i++];

                if (CodeHelper.IsOp(op))
                {
                    output.PutOperator(op);
                }
                else if (op == Code.Number)
                {
                    output.PutConstant(this.numbers[n++]);
                }
                else if (op == Code.Argument)
                {
                    output.PutArgument(this.data[d++]);
                }
                else if (op == Code.Function)
                {
                    output.PutCall(
                        this.functions[f++], this.data[d++]);
                }
                else if (op == Code.Separator)
                {
                    output.PutSeparator();
                }
                else if (op == Code.BeginCall)
                {
                    output.PutBeginCall();
                }
                else
                {
                    output.PutExprEnd(); break;
                }
            }
        }
コード例 #5
0
        internal override T Run(T[] stack, T[] args)
        {
            int c = 0,  // code position
                n = 0,  // number position
                f = 0,  // functions pos
                i = -1; // stack marker

            while (true)
            {
                Code op = this.code[c++];
                if (CodeHelper.IsOp(op))
                {
                    T value = stack[i--];
                    if (op != Code.Neg)
                    {
                        if (op == Code.Add)
                        {
                            stack[i] = Generic.Add(stack[i], value);
                        }
                        else if (op == Code.Mul)
                        {
                            stack[i] = Generic.Mul(stack[i], value);
                        }
                        else if (op == Code.Sub)
                        {
                            stack[i] = Generic.Sub(stack[i], value);
                        }
                        else if (op == Code.Div)
                        {
                            stack[i] = Generic.Div(stack[i], value);
                        }
                        else if (op == Code.Mod)
                        {
                            stack[i] = Generic.Mod(stack[i], value);
                        }
                        else
                        {
                            stack[i] = Generic.Pow(stack[i], value);
                        }
                    }
                    else
                    {
                        stack[++i] = Generic.Neg(value);
                    }
                }
                else if (op == Code.Number)
                {
                    stack[++i] = this.numbs[n++];
                }
                else
                {
                    if (op == Code.Argument)
                    {
                        stack[++i] = args[(int)this.code[c++]];
                    }
                    else if (op == Code.Delegate0)
                    {
                        stack[++i] = ((EvalFunc0 <T>) this.funcs[f++])();
                    }
                    else if (op == Code.Delegate1)
                    {
                        stack  [i] = ((EvalFunc1 <T>) this.funcs[f++])(stack[i]);
                    }
                    else if (op == Code.Delegate2)
                    {
                        stack[--i] = ((EvalFunc2 <T>) this.funcs[f++])(stack[i], stack[i + 1]);
                    }
                    else if (op == Code.Function)
                    {
                        ((FuncCall <T>) this.funcs[f++]).Invoke(stack, ref i);
                    }
                    else
                    {
                        return(stack[0]);
                    }
                }
            }
        }
コード例 #6
0
        public void PutOperator(Code oper)
        {
            Debug.Assert(CodeHelper.IsOp(oper));

            this.code.Add(oper);
        }
コード例 #7
0
        protected void CodeGen(ILGenerator il)
        {
            int n = 0, d = 0, c = 0;
            Stack <FuncCall> stack = null;
            FuncCall         call = null;

            for (int i = 0; ; i++)
            {
                Code op = this.code[i];

                if (CodeHelper.IsOp(op))
                {
                    if (this.emitChecks)
                    {
                        Generic.CheckedOp(il, (int)op);
                    }
                    else
                    {
                        Generic.Operation(il, (int)op);
                    }
                }
                else if (op == Code.Number) // ================================
                {
                    if (SupportLiterals)
                    {
                        Generic.LoadConst(il, this.numbers[n++]);
                    }
                    else
                    {
                        EmitLoadObj(il, this.data[d++]);
                    }
                }
                else if (op == Code.Argument) // ==============================
                {
                    EmitLoadArg(il, this.data[d++]);
                }
                else if (op == Code.Separator) // =============================
                {
                    // separator needed only for params calls:
                    Debug.Assert(call != null);
                    if (call.VarCount >= 0)
                    {
                        EmitSeparator(il, call);
                    }
                }
                else if (op == Code.Function) // ==============================
                {
                    EmitFunctionCall(il, call);

                    // parent call info:
                    if (stack == null || stack.Count == 0)
                    {
                        call = null;
                    }
                    else
                    {
                        call = stack.Pop();
                    }
                }
                else if (op == Code.BeginCall) // =============================
                {
                    if (call != null)
                    {
                        // allocate if needed:
                        if (stack == null)
                        {
                            stack = new Stack <FuncCall>();
                        }
                        stack.Push(call);
                    }

                    call = this.calls[c++];

                    // need for local to store params array:
                    if (call.VarCount > 0)
                    {
                        call.Local = il.DeclareLocal(
                            TypeHelper <T> .ArrayType);
                    }

                    if (call.TargetID >= 0)
                    {
                        EmitLoadObj(il, call.TargetID);
                    }

                    if (call.Current == 0 && call.VarCount > 0)
                    {
                        EmitParamArr(il, call);
                    }
                }
                else // =======================================================
                {
                    break;
                }
            }
        }