我正在使用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);
}
谢谢