コード例 #1
0
        private List <FunctionParameter> ParseOutParams(string function)
        {
            var outParams = new List <FunctionParameter>();

            string functionHeader = SourceHelper.ExtractFunctionHeader(function);

            string[] headerSplit = functionHeader.Split(',');

            foreach (string variable in headerSplit)
            {
                string[] variableSplit = variable.Trim().Split(' ');

                if (variableSplit.Length == 3 && variableSplit[0] == "out")
                {
                    outParams.Add(new FunctionParameter
                    {
                        // Fix any parameter names that come at the end of the function
                        Name = variableSplit[2].Replace(")", string.Empty),
                        Type = variableSplit[1]
                    });
                }
            }

            return(outParams);
        }
コード例 #2
0
        private int DetectFunctionEnd(string[] code, int functionStart, int codeEnd)
        {
            int indentationCounter = 0;

            for (int i = functionStart; i < codeEnd; i++)
            {
                int openBracket  = SourceHelper.ParseDown(code, "{", i);
                int closeBracket = SourceHelper.ParseDown(code, "}", i);

                if (openBracket > 0 && openBracket < closeBracket)
                {
                    i = openBracket;

                    indentationCounter++;
                }

                if (closeBracket > 0)
                {
                    i = closeBracket;

                    if (indentationCounter == 0)
                    {
                        return(closeBracket);
                    }

                    indentationCounter--;
                }
            }

            throw new Exception("Could not find the end of the function!");
        }
コード例 #3
0
        public FunctionMapping(string[] code)
        {
            _functionTable = new Dictionary <string, string[]>();

            int blockStart = SourceHelper.ParseDown(code, "FUNCTIONS START", 0) + 1;
            int blockEnd   = SourceHelper.ParseDown(code, "FUNCTIONS END", blockStart);

            for (int i = blockStart; i < blockEnd; i++)
            {
                if (string.IsNullOrEmpty(code[i]))
                {
                    continue;
                }

                // Found a function opening
                if (code[i].Contains("protected void"))
                {
                    string functionName = SourceHelper.ExtractFunctionName(code[i]);

                    List <FunctionParameter> outParams = ParseOutParams(code[i]);

                    if (outParams.Count == 0)
                    {
                        throw new Exception($"Function '{code[i]}' must contain out parameters!");
                    }

                    var functionCode   = new List <string>();
                    var paramsReplaced = new HashSet <string>();

                    int functionEnd = DetectFunctionEnd(code, i + 2, blockEnd);

                    // Assume the function starts two lines below the function declaration
                    for (int lineIndex = i + 2; lineIndex < functionEnd; lineIndex++)
                    {
                        foreach (FunctionParameter outParam in outParams)
                        {
                            // Only replace the first usage of the parameter with it's type definition
                            if (code[lineIndex].Contains(outParam.Name) && !paramsReplaced.Contains(outParam.Name))
                            {
                                code[lineIndex] = code[lineIndex].Replace(outParam.Name, $"{outParam.Type} {outParam.Name}");

                                paramsReplaced.Add(outParam.Name);
                                break;
                            }
                        }

                        functionCode.Add(code[lineIndex].Trim());
                    }

                    AddFunction(functionName, functionCode.ToArray());
                }
            }
        }
コード例 #4
0
ファイル: KernelManager.cs プロジェクト: stauders/SpaceSim
        private static KernelFile CreateKernel(string codePath, ConstantMapping constants, FunctionMapping functions)
        {
            string[] lines = File.ReadAllLines(codePath);

            int kernelIndex = SourceHelper.ParseDown(lines, "public void Run", 0);

            string kernelFunction = lines[kernelIndex];

            string kernelParameters = SourceHelper.ExtractFunctionHeader(kernelFunction);

            kernelParameters = kernelParameters.Replace("int[]", "global int*");
            kernelParameters = kernelParameters.Replace("float[]", "global float*");

            var clCode = new List <string>();

            if (IsFP64(kernelFunction))
            {
                clCode.Add("#pragma OPENCL EXTENSION cl_khr_fp64 : enable");
            }

            clCode.Add("kernel void Run " + kernelParameters);

            int codeEnd = lines.Length;

            for (int i = 0; i < 3; i++)
            {
                codeEnd = SourceHelper.ParseUp(lines, "}", codeEnd - 1);
            }

            for (int i = kernelIndex + 1; i < codeEnd + 1; i++)
            {
                clCode.Add(lines[i].Trim());
            }

            // Replace constants and inline functions
            functions.Inline(clCode);
            constants.Replace(clCode);

            return(new KernelFile {
                Code = string.Join("\n", clCode)
            });
        }
コード例 #5
0
        public ConstantMapping(string[] code)
        {
            _constantTable = new Dictionary <string, string>();

            int constantStart = SourceHelper.ParseDown(code, "CONSTANTS START", 0) + 1;
            int constantEnd   = SourceHelper.ParseDown(code, "CONSTANTS END", constantStart);

            for (int i = constantStart; i < constantEnd; i++)
            {
                if (string.IsNullOrEmpty(code[i]))
                {
                    continue;
                }

                string cleanedLine = code[i].Trim();

                string[] lineSplit = cleanedLine.Split(' ');

                string value = lineSplit[5].Substring(0, lineSplit[5].Length - 1);

                AddConstant(lineSplit[3], value);
            }
        }