public void CanRegisterExtraFunctions() { var extra = new ExtraFunctionality(2.0); var env = new StandardEnvironment(); // Register functions (static): env.Register("Pi", ExtraFunctionality.Pi); env.Register <double, double>("Square", ExtraFunctionality.Square); // Register methods (need object state): env.Register("Circumference", extra.Circumference, extra); env.Register <double, double>("Volume", extra.Volume, extra); env.Register <object[], double>("Volume", extra.Volume, extra); // variadic object r1 = env.Invoke(GetFunction(env, "Pi")); Assert.AreEqual(Math.PI, r1); object r2 = env.Invoke(GetFunction(env, "Square"), 2.0); Assert.AreEqual(4.0, r2); object r3 = env.Invoke(GetFunction(env, "Circumference")); Assert.AreEqual(extra.Radius * Math.PI * 2, r3); object r4 = env.Invoke(GetFunction(env, "Volume"), 3.0); Assert.AreEqual(extra.Radius * extra.Radius * Math.PI * 3.0, r4); object r5 = env.Invoke(GetFunction(env, "Volume"), 1.0, 2.0, 3.0); // variadic Assert.AreEqual(extra.Radius * extra.Radius * Math.PI * 6.0, r5); }
// Functions of the same name must differ by their arity! // This is different from C# method overloading! public static StandardEnvironment RegisterGeometryFunctions( [NotNull] this StandardEnvironment env) { env.Register <object, object>("SHAPEAREA", Area); env.Register <object, object>("SHAPELENGTH", Length); // Nice to have: Area/0 and Length/0 that refer to current row's Shape field (whatever it's named) return(env); }
public static StandardEnvironment RegisterConversionFunctions( [NotNull] this StandardEnvironment env /*, * [CanBeNull] IMapContext mapContext*/) { //var instance = new ConversionFunctions {MapContext = mapContext}; env.Register <object, object>("mm2pt", mm2pt); env.Register <object, object>("pt2mm", pt2mm); //env.Register<object, object>("mm2mu", instance.mm2mu, instance); //env.Register<object, object>("mu2mm", instance.mu2mm, instance); //env.Register<object, object>("pt2mu", instance.pt2mu, instance); //env.Register<object, object>("mu2pt", instance.mu2pt, instance); return(env); }
public static StandardEnvironment RegisterColorFunctions( [NotNull] this StandardEnvironment env) { env.Register <double, double, double, CIMColor>("RGBCOLOR", RgbColor); env.Register <object, CIMColor>("RGBCOLOR", RgbColor); env.Register <double, double, double, double, CIMColor>("CMYKCOLOR", CmykColor); env.Register <object, CIMColor>("CMYKCOLOR", CmykColor); env.Register <object, CIMColor>("GRAYCOLOR", GrayColor); env.Register <object, CIMColor>("GREYCOLOR", GrayColor); env.Register <double, double, double, CIMColor>("HSVCOLOR", HsvColor); env.Register <object, CIMColor>("HSVCOLOR", HsvColor); env.Register <double, double, double, CIMColor>("HLSCOLOR", HlsColor); env.Register <object, CIMColor>("HLSCOLOR", HlsColor); env.Register <string, CIMColor>("MAKECOLOR", MakeColor); env.Register <CIMColor, string>("FORMATCOLOR", FormatColor); // rename? return(env); }
public void CanEvaluateInvocations() { var env = new StandardEnvironment(); // The lambdas below generate non-static methods and upon calling them // from the evaluator we get a TargetException "Object does not match // target type" (which is true: object is the env, target type is the // compiler-generated class). // Why did this work before? Did the compiler create static methods? // My hypothesis: C# 4.0 (with VS 2010) vs C# 5.0 (with VS 2012). // //env.Register("foo", () => "foo"); //env.Register<object, object>("id", v => v); //env.Register<double, double, double>("pyth", (x, y) => Math.Sqrt(x * x + y * y)); // // Workaround is to write "real" (non-lambda) static methods... env.Register("foo", Foo); env.Register <object, object>("id", Identity); env.Register <double, double, double>("pyth", Pythagoras); env.Register("bomb", Bomb); var r1 = Evaluate("foo()", env); Console.WriteLine(r1); Assert.AreEqual("foo", r1); var r2 = Evaluate("id(42)", env); Console.WriteLine(r2); Assert.AreEqual(42, r2); var r3 = Evaluate("pyth(1+2, 10-2*3)", env); Console.WriteLine(r3); Assert.AreEqual(5.0, r3); var r4 = Evaluate("id(1) + pyth(-1+4, 2*2)", env); Console.WriteLine(r4); Assert.AreEqual(6.0, r4); var r5 = Evaluate("pyth(3, null)", env); Console.WriteLine(@"pyth(3, null) == {0} (the null becomes 0.0)", r5); Assert.AreEqual(3.0, r5); var ex6 = Assert.Catch <EvaluationException>(() => Evaluate("null('foo')", env)); Console.WriteLine(@"Expected exception: {0}", ex6.Message); var ex7 = Assert.Catch <EvaluationException>(() => Evaluate("'oops'(3)", env)); Console.WriteLine(@"Expected exception: {0}", ex7.Message); // Exception in invocate target's code is wrapped in a EvaluationException: var ex8 = Assert.Catch <EvaluationException>(() => Evaluate("bomb()", env)); Console.WriteLine(@"Expected exception: {0}", ex8.Message); Assert.NotNull(ex8.InnerException, "ex.InnerException is null"); Assert.AreEqual("TESTING", ex8.InnerException.Message); }