CompileAssemblyFromSource以智能方式添加自定义函数

时间:2015-12-02 17:12:49

标签: c# memory

我正在使用c#编写自己的编程语言,我正在使用CompileAssemblyFromSource来实现这一目标。

我正在创建一个字符串,其中包含一个在添加所有解释代码后将被调用的函数。

我的项目中的主要类将新语言的语法转换为c#代码并逐行将其放入该字符串中。

到目前为止一切顺利,它的效果非常好。

现在因为语言应该是非常“高级”而且只是编写更复杂代码的一种奇特方式,我在c#中编写自定义函数,我的语言在解释它时使用。

例如在我的语言中,一行是"DO FANCY"(不是真正的东西)会打印0-1000的所有素数,所以我创建一个名为"prime()"的函数,在调用时输出所有这些数字,并将“DO FANCY”解释为"prime()"

现在我的问题在于,将这些自定义函数添加到我上面提到的字符串中(因此解释的代码可以访问它们)我需要逐行添加它们到字符串中,这已被证明是非常尴尬和令人讨厌的对我来说,我认为“必须有一种方法可以简单地在一个类中编写所有这些函数,并将该类添加到”资源字符串[]“CompileAssemblyFromSource使用。

显然我错了,因此在遇到这个问题后我想到了可能会问这个问题。

我试过了:

1)找到一种将类转换为字符串的方法 事实证明这是不可能的,因为这需要我在执行主程序二进制文件时反编译该类。

2)用本地目录中的I / O读取所有这些函数,我非常不喜欢这个,因为这意味着我需要携带文件并且不能将它全部保存在1个可执行文件中

如果您想知道为什么会这么糟糕,那么在我的语言中添加函数会是什么样的:

        code += "public string[] Combine(string[][] srar,string bywhat)";
        code += Environment.NewLine;
        code += "{";
        code += Environment.NewLine;
        code += "int max = 0;";
        code += Environment.NewLine;
        code += "for (int i = 0; i<srar.Length; i++)";
        code += Environment.NewLine;
        code += "{";
        code += Environment.NewLine;
        code += "if (srar[i].Length > max)";
        code += Environment.NewLine;
        code += "max = srar[i].Length;";
        code += Environment.NewLine;
        code += "}";
        code += Environment.NewLine;
        code += "string[] tempo = new string[max];";
        code += Environment.NewLine;
        code += "string sinline = \"\";";
        code += Environment.NewLine;
        code += "for (int i = 0; i < max; i++)";
        code += Environment.NewLine;
        code += "{";
        code += Environment.NewLine;
        code += "for (int j = 0; j < srar.Length; j++)";
        code += Environment.NewLine;
        code += "{";
        code += Environment.NewLine;
        code += "if (i < srar[j].Length)";
        code += Environment.NewLine;
        code += "sinline += srar[j][i];";
        code += Environment.NewLine;
        code += "if (j != (srar.Length - 1))";
        code += Environment.NewLine;
        code += "sinline += bywhat;";
        code += Environment.NewLine;
        code += "}";
        code += Environment.NewLine;
        code += "tempo[i] = sinline;";
        code += Environment.NewLine;
        code += "sinline = \"\";";
        code += Environment.NewLine;
        code += "}";
        code += Environment.NewLine;
        code += "return tempo;";
        code += Environment.NewLine;
        code += "}";
        code += Environment.NewLine;

这是我用来编译和运行我的代码的代码

using (Microsoft.CSharp.CSharpCodeProvider CodeProv =
        new Microsoft.CSharp.CSharpCodeProvider())
        {
            CompilerResults results = CodeProv.CompileAssemblyFromSource(
                 new System.CodeDom.Compiler.CompilerParameters()
                 {
                     GenerateInMemory = true
                 },
                 code);

             var type = results.CompiledAssembly.GetType("MainClass");

             var obj = Activator.CreateInstance(type);

             var output = type.GetMethod("Execute").Invoke(obj, new object[] { });

             Console.WriteLine(output);
        }

谢谢

0 个答案:

没有答案