public void CustomFunctionWithVarTest() { InputContext context = new InputContext(); double alpha = 15.0; context.DefineVar("v:alpha", alpha); context.DefineFunc("f:addalpha", "v:alpha + a:0"); double addalpha(double input) { return(alpha + input); } Exline e1 = new Exline("2 * f:addalpha(10)"); Exline e2 = new Exline("f:addalpha(2)"); Exline e3 = new Exline("2 * f:addalpha(1 - (3 * 4)) - 1"); context.CompileLine(e1); context.CompileLine(e2); context.CompileLine(e3); Assert.AreEqual(2.0 * addalpha(10.0), e1.Execute(new object[] { 0.0 })); Assert.AreEqual(addalpha(2.0), e2.Execute(new object[] { 0.0 })); Assert.AreEqual(2.0 * addalpha(1.0 - (3.0 * 4.0)) - 1.0, e3.Execute(new object[] { 0.0 })); alpha = 3.0; context.SetVar("v:alpha", alpha); Assert.AreEqual(2.0 * addalpha(10.0), e1.Execute(new object[] { 0.0 })); Assert.AreEqual(addalpha(2.0), e2.Execute(new object[] { 0.0 })); Assert.AreEqual(2.0 * addalpha(1.0 - (3.0 * 4.0)) - 1.0, e3.Execute(new object[] { 0.0 })); }
public void FunctionArrayIndexTest() { InputContext context = new InputContext(); context.DefineFunc("f:two", "0.5 * a:0, 2.0 * a:0"); double[] two(double input) { return(new double[] { input / 2.0, input * 2.0 }); } Exline e1 = new Exline("2 * f:two(10)[0]"); Exline e2 = new Exline("2 * f:two(10)[1]"); Exline e3 = new Exline("f:two(2)"); Exline e4 = new Exline("2 * f:two(1 - (3 * 4))[0] - 1"); Exline e5 = new Exline("2 * f:two(1 - (3 * 4))[1] - 1"); context.CompileLine(e1); context.CompileLine(e2); context.CompileLine(e3); context.CompileLine(e4); context.CompileLine(e5); Assert.AreEqual(2.0 * two(10.0)[0], e1.Execute(new object[] { 0.0 })); Assert.AreEqual(2.0 * two(10.0)[1], e2.Execute(new object[] { 0.0 })); Assert.AreEqual(two(2.0)[0], (double)((object[])(e3.Execute(new object[] { 0.0 })))[0]); Assert.AreEqual(two(2.0)[1], (double)((object[])(e3.Execute(new object[] { 0.0 })))[1]); Assert.AreEqual(2.0 * two(1.0 - (3.0 * 4.0))[0] - 1.0, e4.Execute(new object[] { 0.0 })); Assert.AreEqual(2.0 * two(1.0 - (3.0 * 4.0))[1] - 1.0, e5.Execute(new object[] { 0.0 })); }
public void ManualObjectTest() { InputContext context = new InputContext(); Exline e1 = new Exline("v:hp := 100; f:damage := {v:hp -= a:0};"); context.CompileLine(e1); e1.Execute(new object[] { 0.0 }); InputClass testClass = new InputClass("test", context); InputObject testObj = testClass.PrintObject("a"); // see that obj has its own var and func implementations and scoping works Exline e2 = new Exline("f:damage(15)"); testObj.Implementation.CompileLine(e2); Assert.AreEqual(new InputVar("v:hp", 85.0), e2.Execute(new object[] { 0.0 })); Assert.AreEqual(new InputVar("v:hp", 70.0), e2.Execute(new object[] { 0.0 })); // but also see that the original class is unaffected by the lines we just executed Exline e3 = new Exline("f:damage(15)"); testClass.Definition.CompileLine(e3); Assert.AreEqual(new InputVar("v:hp", 85.0), e3.Execute(new object[] { 0.0 })); }
public void CustomFunctionChainMultipleInputsTest() { InputContext context = new InputContext(); context.DefineFunc("f:twobytwo", "0.5 * a:0 + 2.0 * a:1, 2.0 * a:0 + 0.5 * a:1"); double[] twobytwo(double input1, double input2) { return(new double[] { input1 / 2.0 + input2 * 2.0, input1 * 2.0 + input2 / 2.0 }); } Exline e1 = new Exline("2 * f:twobytwo(10,4)[0]"); Exline e2 = new Exline("2 * f:twobytwo(f:twobytwo(10,4))[0]"); Exline e3 = new Exline("f:twobytwo(f:twobytwo(f:twobytwo(10,4)))"); context.CompileLine(e1); context.CompileLine(e2); context.CompileLine(e3); double[] first = twobytwo(10.0, 4.0); double[] second = twobytwo(first[0], first[1]); double[] third = twobytwo(second[0], second[1]); Assert.AreEqual(2.0 * twobytwo(10.0, 4.0)[0], e1.Execute(new object[] { 0.0 })); Assert.AreEqual(2.0 * second[0], e2.Execute(new object[] { 0.0 })); object e3result = e3.Execute(new object[] { 0.0 }); Assert.AreEqual(third[0], ((object[])(e3result))[0]); Assert.AreEqual(third[1], ((object[])(e3result))[1]); }
public void GettingStarted() { InputContext context = new InputContext(); // random must be provided if you want to use functions that require random numbers context.Random = new RandomBasic(0); // replace 0 with your random seed // load library providers-- this controls what libraries may be imported into scripts // you may write your own libraries to allow RelaScript to interface with your project context.LibraryProviders.Add(new LibraryProviderBasic()); string scriptText = "a:0 * 2"; // load your script // an Exline represents a script file Exline exscript = new Exline(scriptText); // the Exline must be compiled before it can be run context.CompileLine(exscript); // args are passed into the script upon execution object[] args = new object[] { 2.0 }; object result = exscript.Execute(args); // result --> 4.0 (double) Assert.AreEqual(4.0, result); }
public void InputLibraryInjectTest() { InputContext ic = TestScaffold.ConstructContext(); // create a library InputLibrary il = new InputLibrary("l:testlibrary"); Exline ex = new Exline("a:0 + 5"); ic.CompileLine(ex); il.Funcs.Add("f:add5", ex); // add the library to the inputcontext ic.SetLibrary("anon", il); // test using the library Exline t1 = new Exline("f:add5(10.0)"); Exline t2 = new Exline("f:add5(1.3)"); ic.CompileLine(t1); ic.CompileLine(t2); double r1 = (double)t1.Execute(new object[] { 0 }); double r2 = (double)t2.Execute(new object[] { 0 }); Assert.AreEqual(15.0, r1); Assert.AreEqual(6.3, r2); }
public void DefineFuncFromExline(string name, Exline line) { name = name.ToLower(); // TODO: don't support redefining an existing function this way currently Exline ex = new Exline("COMPILED", funcname: name); ex.Compile(line, this); Funcs.Add(name, ex); }
public static List <double> TestDoubleLines(List <string> lines, List <object[]> args = null, // if non null, pass these args to respective lines List <double> expected = null, // if non null, compare results to these Dictionary <string, double> vars = null, Dictionary <string, string> funcs = null) { // construct a context InputContext context = ConstructContext(); // load vars if they exist if (vars != null) { foreach (var kvp in vars) { context.DefineVar(kvp.Key, kvp.Value); } } // load funcs if they exist if (funcs != null) { foreach (var kvp in funcs) { context.DefineFunc(kvp.Key, kvp.Value); } } // build and compile the lines List <Exline> es = new List <Exline>(); foreach (string s in lines) { Exline e = new Exline(s); es.Add(e); context.CompileLine(e); } // run the lines List <double> rs = new List <double>(); for (int i = 0; i < lines.Count; i++) { object[] arg = new object[] { 0.0 }; if (args != null) { arg = args[i]; } double r = (double)es[i].Execute(arg); rs.Add(r); // compare to expected, if expected values are provided if (expected != null) { Assert.AreEqual(expected[i], r); } } return(rs); }
public void ParensTest() { InputContext context = new InputContext(); Exline e1 = new Exline("2 * (3 - 1)"); Exline e2 = new Exline("2 * (3 - (2 - 1))"); context.CompileLine(e1); context.CompileLine(e2); Assert.AreEqual(4.0, e1.Execute(new object[] { 0.0 })); Assert.AreEqual(4.0, e2.Execute(new object[] { 0.0 })); }
public void FuncScopeTest() { InputContext context = new InputContext(); Exline e1 = new Exline("{f:newfunc(f:test, a:0 / 2.0)}"); context.CompileLine(e1); e1.Execute(new object[] { 0.0 }); // using originator false here because I may change what originator true returns // in the future to be something other than a null var Assert.IsTrue(context.GetFunc("f:test", false) == null); }
public static void DefaultInject(ILibrary library, InputContext context, string asname) { StringBuilder script = new StringBuilder(); script.Append("import ").Append(library.GetLibraryName()).Append(" ").AppendLine(asname); foreach (string fname in library.GetDefaultFunctions()) { script.Append(fname).Append(" := { ").Append(asname).Append('.').Append(fname) .AppendLine("(a:all) }"); } Exline injection = new Exline(script.ToString()); injection.Compile(context); injection.Execute(new object[] { 0 }); }
public void DefineFuncCompiled(string name, CompileContext precompile) { name = name.ToLower(); if (Funcs.ContainsKey(name)) { SetFuncCompiled(name, precompile); return; } //if (Funcs.ContainsKey(name)) // throw new Exception("InputContext already contains custom function '" + name + "'."); // TODO: this approach cannot handle recursion Exline exl = new Exline("COMPILED", funcname: name); exl.Compile(precompile); Funcs.Add(name, exl); }
public void DefineFunc(string name, string source) { name = name.ToLower(); if (Funcs.ContainsKey(name)) { SetFunc(name, source); return; } //if (Funcs.ContainsKey(name)) // throw new Exception("InputContext already contains custom function '" + name + "'."); // TODO: this approach cannot handle recursion (or can it?) Exline exl = new Exline(source, funcname: name); CompileLine(exl); Funcs.Add(name, exl); }
public static List <double> TestDoubleLineRepeat(string line, int count, object[] args = null, Dictionary <string, double> vars = null, Dictionary <string, string> funcs = null) { // construct a context InputContext context = ConstructContext(); // load vars if they exist if (vars != null) { foreach (var kvp in vars) { context.DefineVar(kvp.Key, kvp.Value); } } // load funcs if they exist if (funcs != null) { foreach (var kvp in funcs) { context.DefineFunc(kvp.Key, kvp.Value); } } // build and compile the line Exline e = new Exline(line); context.CompileLine(e); // run the line object[] arg = new object[] { 0.0 }; if (args != null) { arg = args; } List <double> rs = new List <double>(); for (int i = 0; i < count; i++) { double r = (double)e.Execute(arg); rs.Add(r); } return(rs); }
public void FunctionTest() { InputContext context = new InputContext(); context.LibraryProviders.Add(new LibraryProviderBasic()); Exline e1 = new Exline("import basic:math anon \r\n 2 * f:sin(10)"); Exline e2 = new Exline("f:sin(2)"); Exline e3 = new Exline("2 * f:sin(1 - (3 * 4)) - 1"); context.CompileLine(e1); context.CompileLine(e2); context.CompileLine(e3); Assert.AreEqual(2.0 * Math.Sin(10.0), e1.Execute(new object[] { 0.0 })); Assert.AreEqual(Math.Sin(2.0), e2.Execute(new object[] { 0.0 })); Assert.AreEqual(2.0 * Math.Sin(1.0 - (3.0 * 4.0)) - 1.0, e3.Execute(new object[] { 0.0 })); }
public void ArrayIndexTest() { InputContext context = new InputContext(); Exline e1 = new Exline("(1,2,3)[0]"); Exline e2 = new Exline("(1,2,3)[1]"); Exline e3 = new Exline("2 + (1,2,3)[1]"); Exline e4 = new Exline("2 + ((1,2,3)[1])"); context.CompileLine(e1); context.CompileLine(e2); context.CompileLine(e3); context.CompileLine(e4); Assert.AreEqual(1.0, e1.Execute(new object[] { 0.0 })); Assert.AreEqual(2.0, e2.Execute(new object[] { 0.0 })); Assert.AreEqual(4.0, e3.Execute(new object[] { 0.0 })); Assert.AreEqual(4.0, e4.Execute(new object[] { 0.0 })); }
public void FreeObjectTest() { InputContext context = new InputContext(); Exline e1 = new Exline("defn d:blob {\r\n" + " v:size := (0)\r\n" + " f:init := {\r\n" + " a:size\r\n" + " v:size = f:array(a:size)\r\n" + " }\r\n" + "}\r\n" + "\r\n" + "object o:blob1 d:blob (600)\r\n" + "free o:blob1\r\n" + "o:blob1"); context.CompileLine(e1); e1.Execute(new object[] { 0 }); Assert.IsTrue(context.GetObject("o:blob1") == null); }
public Exline GetFunc(string name, bool originator = true) { if (originator) { name = name.ToLower(); } if (!Funcs.TryGetValue(name, out Exline func)) { if (ParentScope != null) { Exline pfunc = ParentScope.GetFunc(name, false); if (pfunc != null) { return(pfunc); } } return(null); } return(func); }
public void WithoutSpacingTest() { InputContext context = new InputContext(); context.DefineVar("v:test", 0); Exline e1 = new Exline("2+3*5"); Exline e2 = new Exline("v:test*2"); Exline e3 = new Exline("a:0*5"); context.CompileLine(e1); context.CompileLine(e2); context.CompileLine(e3); context.SetVar("v:test", (double)e1.Execute(new object[] { 0.0 })); Assert.AreEqual(17.0, context.GetVar("v:test").Value); context.SetVar("v:test", (double)e2.Execute(new object[] { 0.0 })); Assert.AreEqual(34.0, context.GetVar("v:test").Value); context.SetVar("v:test", (double)e3.Execute(new object[] { 50.0 })); Assert.AreEqual(250.0, context.GetVar("v:test").Value); }
static void Main(string[] args) { Console.WriteLine("Hello World!"); InputContext context = new InputContext(); Exline quicktest = new Exline("f:newvar(v:iterator, 1);" + "\r\nf:newvar(v:alpha, 1.0);" + "\r\nf:while(v:iterator <= 100, (" + "\r\n\tf:setvar(v:alpha, v:alpha * 1.0135);" + "\r\n\tf:setvar(v:iterator, v:iterator + 1);" + "\r\n));" + "\r\nc:d(v:alpha)"); context.CompileLine(quicktest); var result = quicktest.Execute(new object[] { 0 }); Console.WriteLine(" " + result); Console.Read(); }
public void CustomFunctionTooManyInputsTest() { InputContext context = new InputContext(); context.DefineFunc("f:half", "0.5 * a:0"); double half(double input) { return(input / 2.0); } Exline e1 = new Exline("2 * f:half(10,5)"); Exline e2 = new Exline("f:half(2,1,3,15)"); Exline e3 = new Exline("2 * f:half(1 - (3 * 4),f:half(2)) - 1"); context.CompileLine(e1); context.CompileLine(e2); context.CompileLine(e3); Assert.AreEqual(2.0 * half(10.0), e1.Execute(new object[] { 0.0 })); Assert.AreEqual(half(2.0), e2.Execute(new object[] { 0.0 })); Assert.AreEqual(2.0 * half(1.0 - (3.0 * 4.0)) - 1.0, e3.Execute(new object[] { 0.0 })); }
public void CustomFunctionMultipleInputsTest() { InputContext context = new InputContext(); context.DefineFunc("f:abc", "0.5 * a:0 + a:1 / a:2"); double abc(double a, double b, double c) { return((a / 2.0) + (b / c)); } Exline e1 = new Exline("2 * f:abc(10,5,3)"); Exline e2 = new Exline("f:abc(8,4,1)"); Exline e3 = new Exline("2 * f:abc(1 - (3 * 4), 2, 7) - 1"); context.CompileLine(e1); context.CompileLine(e2); context.CompileLine(e3); Assert.AreEqual(2.0 * abc(10.0, 5.0, 3.0), e1.Execute(new object[] { 0.0 })); Assert.AreEqual(abc(8.0, 4.0, 1.0), e2.Execute(new object[] { 0.0 })); Assert.AreEqual(2.0 * abc(1.0 - (3.0 * 4.0), 2.0, 7.0) - 1.0, e3.Execute(new object[] { 0.0 })); }
public AccessorResult(Exline func) { IsFunc = true; Func = func; }
public void CompileLine(Exline line) { line.Compile(this); }