public void PutOperator(Code oper) { Debug.Assert(CodeHelper.IsOp(oper)); AddCode(oper); if (oper != Code.Neg) { this.stackSize--; } }
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); } }
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); }
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; } } }
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]); } } } }
public void PutOperator(Code oper) { Debug.Assert(CodeHelper.IsOp(oper)); this.code.Add(oper); }
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; } } }