示例#1
0
        public static RendererFunction GetFunctionHandle(string formula)
        {
            CompiledFunction fn = FunctionCompiler.Compile(2, formula);

            return(new RendererFunction(delegate(double x, double y)
            {
                return fn(x, y);
            }));
        }
        public void TestCompile()
        {
            var f = (Func <SeriesBase, double>)FunctionCompiler.Compile("x => (double)x.Mean()", new[] { typeof(SeriesBase), typeof(double) }, true);

            var s = new Series(new[] { 1, 2, 3 });

            var mean = f.Invoke(s);

            Assert.Equal(2.0, mean);
        }
示例#3
0
        private Tuple <object[], bool> PreprocessAggregators <T>(object[] aggregators)
        {
            var  funcs            = new object[aggregators.Length];
            bool scriptBlockGiven = false;

            for (var i = 0; i < aggregators.Length; ++i)
            {
                var agg = aggregators[i];
                if (agg is ScriptBlock sb)
                {
                    funcs[i]         = agg;
                    scriptBlockGiven = true;
                }
                else if (agg is string st)
                {
                    var match = _methodNameRegex.Match(st);
                    if (match.Success)
                    {
                        if (!match.Groups[1].Success)
                        {
                            // A bare word is given -- treats as a method name.
                            funcs[i] = st;
                            continue;
                        }
                        else
                        {
                            // We accept method name plus arguments for convinience.
                            st = "n => n." + st;
                        }
                    }

                    funcs[i] = (Func <T, object>)FunctionCompiler.Compile(
                        st, new[] { typeof(T), typeof(object) }, true, _dataMap, null);
                }
                else
                {
                    throw new ArgumentException("Aggregators should be a ScriptBlock or string");
                }
            }

            return(Tuple.Create(funcs, scriptBlockGiven));
        }
        public FunctionCompiler CreateFunctionCompiler(AmbientParser.Node methodNode)
        {
            int startOffset;
            var functionBody = ParseFunctionBody(methodNode, out startOffset);

            // Find the function we are inside
            Function func     = null;
            int      funcDist = int.MaxValue;

            if (methodNode != null && _context.TypeOrNamespace is DataType)
            {
                foreach (var f in (_context.TypeOrNamespace as DataType).EnumerateFunctions()
                         .Where(m => m.Source.FullPath == _source.FullPath))
                {
                    int dist = System.Math.Abs(f.Source.Offset - methodNode.StartOffset);
                    if (dist < funcDist)
                    {
                        func     = f;
                        funcDist = dist;
                    }
                }
            }

            // Construct a function compiler for the context
            FunctionCompiler funcCompiler;

            if (func != null)
            {
                funcCompiler = new FunctionCompiler(_compiler, func, _compiler.TypeBuilder.Parameterize(func.DeclaringType), functionBody);
                try
                {
                    funcCompiler.Compile();
                }
                catch (Exception) { }
            }
            else
            {
                funcCompiler = new FunctionCompiler(_compiler, _context.TypeOrNamespace);
            }

            return(funcCompiler);
        }
示例#5
0
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                throw new ArgumentException("Must specify the assembly file to build the functions from");
            }

            string inputAssemblyFile = args[0];

            FunctionCompiler.TargetEnum target = FunctionCompiler.TargetEnum.NETStandard20;
            if (args.Any(x => x.ToLower() == "--netcore21"))
            {
                target = FunctionCompiler.TargetEnum.NETCore21;
            }

            // TODO: convert the input to an absolute path if necessary
            Assembly assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(inputAssemblyFile);
            string   outputBinaryDirectory = Path.GetDirectoryName(assembly.Location);

            // Not sure why the AssemblyLoadContext doesn't deal with the below. I thought it did. Clearly not.
            // TODO: Have a chat with someone who knows a bit more about this.
            AssemblyLoadContext.Default.Resolving += (context, name) =>
            {
                string path = Path.Combine(outputBinaryDirectory, $"{name.Name}.dll");
                //string path = $"{outputBinaryDirectory}\\{name.Name}.dll";
                if (File.Exists(path))
                {
                    Assembly referencedAssembly = context.LoadFromAssemblyPath(path);
                    return(referencedAssembly);
                }
                return(null);
            };

            FunctionCompiler compiler = new FunctionCompiler(assembly, outputBinaryDirectory, target);

            compiler.Compile();
        }
示例#6
0
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                throw new ArgumentException("Must specify the assembly file to build the functions from");
            }

            string inputAssemblyFile = args[0];
            bool   outputProxiesJson = true;

            if (args.Length > 1)
            {
                outputProxiesJson = bool.Parse(args[1]);
            }


            // TODO: convert the input to an absolute path if necessary
            Assembly assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(inputAssemblyFile);
            string   outputBinaryDirectory = Path.GetDirectoryName(assembly.Location);

            // Not sure why the AssemblyLoadContext doesn't deal with the below. I thought it did. Clearly not.
            // TODO: Have a chat with someone who knows a bit more about this.
            AssemblyLoadContext.Default.Resolving += (context, name) =>
            {
                string path = $"{outputBinaryDirectory}\\{name.Name}.dll";
                if (File.Exists(path))
                {
                    Assembly referencedAssembly = context.LoadFromAssemblyPath(path);
                    return(referencedAssembly);
                }
                return(null);
            };

            FunctionCompiler compiler = new FunctionCompiler(assembly, outputBinaryDirectory, outputProxiesJson);

            compiler.Compile();
        }
示例#7
0
 public ScriptBlock(string functionString)
 {
     _func     = FunctionCompiler.Compile(functionString);
     _toString = functionString;
 }
示例#8
0
        static void Main(string[] args)
        {
            CompilerLog compilerLog = new CompilerLog();

            compilerLog.Message("Compiler starting");
            LogOutputType outputType = args.Any(x => x.ToLower() == "--jsonoutput")
                ? LogOutputType.Json
                : LogOutputType.Console;

            CompileTargetEnum target = args.Any(x => x.ToLower() == "--netcore21") ? CompileTargetEnum.NETCore21 : CompileTargetEnum.NETStandard20;
            string            outputBinaryDirectory = String.Empty;

            compilerLog.Message($"Targeting {target}");

            if (args.Length == 0)
            {
                compilerLog.Error("Must specify the assembly file to build the functions from");
            }
            else
            {
                try
                {
                    string inputAssemblyFile = args[0];
                    compilerLog.Message($"Loading assembly {inputAssemblyFile}");
                    // TODO: convert the input to an absolute path if necessary
                    Assembly assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(inputAssemblyFile);
                    outputBinaryDirectory = Path.GetDirectoryName(assembly.Location);

                    // Not sure why the AssemblyLoadContext doesn't deal with the below. I thought it did. Clearly not.
                    // TODO: Have a chat with someone who knows a bit more about this.
                    AssemblyLoadContext.Default.Resolving += (context, name) =>
                    {
                        string path = Path.Combine(outputBinaryDirectory, $"{name.Name}.dll");
                        //string path = $"{outputBinaryDirectory}\\{name.Name}.dll";
                        if (File.Exists(path))
                        {
                            Assembly referencedAssembly = context.LoadFromAssemblyPath(path);
                            return(referencedAssembly);
                        }
                        return(null);
                    };

                    FunctionCompiler compiler = new FunctionCompiler(assembly, outputBinaryDirectory, target, compilerLog);
                    compiler.Compile();
                }
                catch (Exception e)
                {
                    compilerLog.Error($"Unexpected error: {e.Message}");
                }
            }
            compilerLog.Message("Compilation complete");

            if (compilerLog.HasItems)
            {
                if (string.IsNullOrWhiteSpace(outputBinaryDirectory) && outputType == LogOutputType.Json)
                {
                    compilerLog.Warning("Cannot write errors to output file as no output directory can be found, likely a missing assembly");
                    outputType = LogOutputType.Console;
                }

                if (outputType == LogOutputType.Console)
                {
                    System.Console.WriteLine(compilerLog.ToConsole());
                }
                else
                {
                    string outputPath = Path.Combine(outputBinaryDirectory, "__fm__errors.json");
                    File.WriteAllText(outputPath, compilerLog.ToJson());
                }
            }
        }
        public void TestCompile()
        {
            var f = FunctionCompiler.Compile("x => x * 2 + 1");

            Assert.AreEqual(7, f.Invoke(3));
        }
示例#10
0
 public ScriptBlock(string functionString, Type[] parameterTypes)
 {
     _func     = FunctionCompiler.Compile(functionString, parameterTypes, true);
     _toString = functionString;
 }