private static void Round(IILState <Complex> ils, IReadOnlyList <Node> arguments) { ils.Push(arguments.Check(2)[0]); ils.Push(arguments[1]); ils.Generator.Emit(OpCodes.Conv_I4); ils.Generator.Emit(OpCodes.Call, _round); }
private static void PwlDerivative(IILState <double> ils, IReadOnlyList <Node> arguments) { if (arguments.Count < 3) { throw new ArgumentMismatchException(3, arguments.Count); } int points = (arguments.Count - 1) / 2; if (arguments.Count % 2 == 0) { throw new ArgumentMismatchException(points * 2 + 1, arguments.Count); } var il = ils.Generator; // Create our array ils.Push(arguments[0]); ils.PushInt(points); il.Emit(OpCodes.Newarr, typeof(Point)); for (var i = 0; i < points; i++) { il.Emit(OpCodes.Dup); // Make another reference to the array ils.PushInt(i); // Set the index // Create the point ils.Push(arguments[i * 2 + 1]); ils.Push(arguments[i * 2 + 2]); il.Emit(OpCodes.Newobj, _point); // Store the element il.Emit(OpCodes.Stelem, typeof(Point)); } il.Emit(OpCodes.Call, _pwlDerivative); }
// Three-argument functions private static void If(IILState <Complex> ils, IReadOnlyList <Node> arguments) { var ilsc = (IILComplexState)ils; arguments.Check(3); ilsc.PushReal(arguments[0]); ilsc.PushDouble(0.5); ilsc.PushCheck(OpCodes.Bgt_S, arguments[1], arguments[2]); }
private static void If(IILState <double> ils, IReadOnlyList <Node> arguments) { arguments.Check(3); ils.Push(arguments[0]); ils.Push(0.5); var lblElse = ils.Generator.DefineLabel(); var lblEnd = ils.Generator.DefineLabel(); ils.Generator.Emit(OpCodes.Ble_S, lblElse); ils.Push(arguments[1]); ils.Generator.Emit(OpCodes.Br_S, lblEnd); ils.Generator.MarkLabel(lblElse); ils.Push(arguments[2]); ils.Generator.MarkLabel(lblEnd); }
private static void DU2(IILState <Complex> ils, IReadOnlyList <Node> arguments) => ils.Call(HelperFunctions.Step2Derivative, arguments);
private static void Ceil(IILState <Complex> ils, IReadOnlyList <Node> arguments) => ils.Call(HelperFunctions.Ceiling, arguments);
// One-argument functions private static void Zero(IILState <Complex> ils, IReadOnlyList <Node> arguments) => ils.Push(new Complex());
private static void Sgn(IILState <Complex> ils, IReadOnlyList <Node> arguments) { ils.Call(null, _sgn, arguments.Check(1)); ils.Generator.Emit(OpCodes.Conv_R8); }
private static void Floor(IILState <double> ils, IReadOnlyList <Node> arguments) => ils.Call(Math.Floor, arguments);
// No-argument functions private static void Random(IILState <Complex> ils, IReadOnlyList <Node> arguments) { ils.Call(() => new Complex(_rnd.NextDouble(), 0)); }
private static void Hypot(IILState <double> ils, IReadOnlyList <Node> arguments) => ils.Call(HelperFunctions.Hypot, arguments);
private static void Decibels(IILState <Complex> ils, IReadOnlyList <Node> arguments) => ils.Call(HelperFunctions.Decibels, arguments);
private static void Max(IILState <double> ils, IReadOnlyList <Node> arguments) => ils.Call(Math.Max, arguments);
private static void Atan2(IILState <double> ils, IReadOnlyList <Node> arguments) => ils.Call(Math.Atan2, arguments);
private static void Pwr(IILState <double> ils, IReadOnlyList <Node> arguments) => ils.Call(HelperFunctions.Power, arguments);
private static void Decibels(IILState <double> ils, IReadOnlyList <Node> arguments) { ils.Call(HelperFunctions.Log10, arguments); ils.Push(20.0); ils.Generator.Emit(OpCodes.Mul); }
private static void Square(IILState <double> ils, IReadOnlyList <Node> arguments) { ils.Push(arguments.Check(1)[0]); ils.Generator.Emit(OpCodes.Dup); ils.Generator.Emit(OpCodes.Mul); }
private static void Square(IILState <Complex> ils, IReadOnlyList <Node> arguments) { ils.Call(HelperFunctions.Square, arguments); }
private static void Pwrs(IILState <Complex> ils, IReadOnlyList <Node> arguments) => ils.Call(HelperFunctions.Power2, arguments);
private static void Nint(IILState <Complex> ils, IReadOnlyList <Node> arguments) { ils.Push(arguments.Check(1)[0]); ils.PushInt(0); ils.Generator.Emit(OpCodes.Call, _round); }
private static void DURampDerivative(IILState <double> ils, IReadOnlyList <Node> arguments) => ils.Call(HelperFunctions.RampDerivative, arguments);
// Two-argument functions private static void Pow(IILState <Complex> ils, IReadOnlyList <Node> arguments) => ils.Call(Complex.Pow, arguments);
private static void Ceil(IILState <double> ils, IReadOnlyList <Node> arguments) => ils.Call(Math.Ceiling, arguments);
// No-argument functions private static void Random(IILState <double> ils, IReadOnlyList <Node> arguments) => ils.Call(_rnd.NextDouble);
// One-argument functions private static void Zero(IILState <double> ils, IReadOnlyList <Node> arguments) => ils.Push(0.0);
private static void Limit(IILState <Complex> ils, IReadOnlyList <Node> arguments) => ils.Call(HelperFunctions.Limit, arguments);
/// <summary> /// Initializes a new instance of the <see cref="FunctionFoundEventArgs{T}"/> class. /// </summary> /// <param name="function">The function node.</param> /// <param name="ilState">The IL state.</param> /// <exception cref="ArgumentNullException">Thrown if any parameter is <c>null</c>.</exception> public FunctionFoundEventArgs(FunctionNode function, IILState <T> ilState) { Function = function.ThrowIfNull(nameof(function)); ILState = ilState.ThrowIfNull(nameof(ilState)); }