CompileAssemblyFromSource добавляет интеллектуальные функции интеллектуальным способом
Я программирую свой собственный язык программирования на C#, и я использую CompileAssemblyFromSource
для достижения этой цели.
Я создаю строку, которая содержит функцию, которая будет вызываться после добавления всего интерпретируемого кода.
Основной класс в моем проекте превращает синтаксис нового языка в код на C# и построчно помещает его в эту строку.
пока все хорошо, работает отлично.
теперь, поскольку язык должен быть чрезвычайно "высокого уровня" и является просто причудливым способом написания более сложного кода, я пишу пользовательские функции на C#, которые мой язык использует при его интерпретации.
например на моем языке строка "DO FANCY"
(не совсем вещь) напечатает все простые числа от 0 до 1000, поэтому я создаю функцию с именем "prime()"
который выводит все эти числа при вызове и интерпретирует "DO FANCY" в "prime()"
,
Теперь здесь моя проблема заключается в том, чтобы добавить эти пользовательские функции в строку, о которой я упоминал выше (чтобы интерпретированный код мог получить к ним доступ), мне нужно добавить их строку за строкой, это оказалось очень неудобным и удобным для меня, так что я подумал "должен быть способ просто закодировать все эти функции внутри класса и добавить этот класс в" строку ресурсов []" CompileAssemblyFromSource
использует.
вначале я был неправ, и поэтому, получив головную боль от этой проблемы, я подумал о том, чтобы спросить ее здесь.
Я старался:
1) найти способ превратить класс в строку, что оказалось невозможным, потому что это потребовало бы от меня декомпиляции класса при выполнении двоичного файла основной программы.
2) чтение всех этих функций с помощью ввода-вывода из локального каталога, мне очень не нравится это, потому что это означает, что мне нужно будет нести файлы и не могу держать все это в 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);
}
благодарю вас