Здравствуйте. Раньше, когда почти не знал C#, хотел написать свой «мега-крутой» язык программирования. Много раз осматривал разные форумы с мыслями скопировать весь код и быть крутым. Но ничего такого никогда не находил, расстраивался и продолжал трудится над изучением C#. Через полгода я смог написать консольное приложение, которое вписывало свой текст, написанный в консоли, в *.cs файл. Еще полгода спустя пытался «позаимствовать» код с Хабрхабра, но код был на другом для меня языке и я забросил это дело. Позже, месяца так через 1-2, я смог написать транслятор в C#, который компилировал .src (я исковеркал .cs) файл и выдавал, как ни странно, .exe файл.
После такого долгого вступления хочу показать вам код и помочь новичкам. Код, конечно, не весь, но смысл должен быть понятен. Так же предупреждаю, что будет ненавистный «IndexOf», по крайней мере я видел, что его не очень любят. Так же скажу, что я не смотрел, есть ли на данный момент похожая на мою статья, но тогда я не нашел, что нужно, поэтому пишу здесь.
Что же, начнем.
class ProgramsMain
{
static void Main()
{
System.Console.Title = "HabrHabr";
while (true) Start.ReadConsoleCommands();
}
}
Это наша точка запуска программы, static — забрасывает её сразу в память, void — метод. Задаем название нашему окну и запускаем вечный цикл, в котором вызывается метод ReadConsoleCommands(). Сам метод.
class Start
{
public static void ReadConsoleCommands()
{
string[] C = System.Console.ReadLine().Split(' ');
try
{
switch (C[0].ToLower().Trim())
{
case "compile":
Vars.PathTo = C[1];
Vars.PathOut = C[2];
Translator.Translate(Vars.PathTo, Vars.PathOut + ".ourlang");
break;
default:
break;
}
}
catch (System.Exception ex)
{
System.Console.WriteLine(ex.Message);
}
}
}
Давайте снова разберем код. string[] C = System.Console.ReadLine().Split(' '); — объявляем переменную, которую будем парсить, в данном случае это — массив. Дальше идет try, он нужен для того, чтобы если мы не дадим нашему парсеру необходимые параметры, наша программа не вылетела. Потом идет конструкция switch-case-default, точно такая же как и if-else if-else, но считается красивее. Проверяем, равен ли наш первый элемент массива «compile», аргументы в switch «C[0].ToLower().Trim()» — делают наш введенный текст равный обычным буквам и удаляет лишние пробелы, таким образом, текст, который введен как: «ПриВет, МиР», будет считаться как: «привет, мир». Если условие истинно, то переменным Vars.PathTo и Vars.PathOut присваивается значение C[1];, C[2];.
Что за переменные Vars.PathTo и Vars.PathOut? Эти переменные у меня хранятся в другом .cs файле под именем Glob. Однако вы можете написать программу в один .cs файл, текст которого будет в конце статьи. Дальше мы вызываем Translator.Translate(string path, string pathTo);, этот метод и есть транслятор, мы задаем ему параметры входного и выходного файла.
public class Translator
{
public static void Translate(string path, string pathTo)
{
System.IO.StreamWriter OutputFile = System.IO.StreamWriter(pathTo);
OutputFile.WriteLine(@"class Program { static void Main() { ");
foreach (string line in System.IO.File.ReadLines(path))
{
string Done = line.Trim().ToLower();
if (Done.IndexOf("print") != -1)
{
string[] args = line.Split(':');
OutputFile.Write("Console.WriteLine(");
for (int i = 0; i < args.Length; i++)
{
OutputFile.Write(args[i]);
}
OutputFile.Write(");");
}
}
OutputFile.Close();
CP.Start();
}
}
Давайте снова разбирать. System.IO.StreamWriter OutputFile = System.IO.StreamWriter(pathTo); — записывает в файл, в аргументах путь к файлу. foreach (string line in System.IO.File.ReadLines(path)) — цикл, который можно заменить for, но foreach удобнее, он объявляет переменную, которой присвоено значение читаемой линии в File.ReadLines(path). Done = line.Trim().ToLower(); — чтобы каждый раз не писать: «line.Trim().ToLower()...». if (Done.IndexOf(«print») != -1) — если найдено слово «print», выполняем код. OutputFile.WriteLine(«Console.WriteLine(»); — вписываем в выходной файл. for (int i = 0; i < args.Length; i++) {OutputFile.WriteLine(args[i]);} — в исходном файле нашего «языка» может быть на одна ':', поэтому на этот случай пишем цикл. OutputFile.Write(");"); — закрываем скобки. OutputFile.Close(); — заканчиваем метод, если мы этого не сделаем, то при следующих компиляциях программа будет вылетать и ее придется перезагружать. CP.Start(); — вызываем наш метод «компиляции». Сам метод.
public class CP
{
public static void Start()
{
try
{
StreamWriter SW = new StreamWriter("CP.bat", false);
SW.Write(@"@echo off
C:WINDOWSMicrosoft.NETFrameworkv3.5csc.exe /out:" + Vars.PathOut + "App.exe "
+ Vars.PathOut + "ToCompile.src"
+ "n");
SW.Close();
Process.Start("CP.bat");
}
catch (Exception ex)
{
Console.Write("n " + ex.Message + " n");
}
}
}
SW.Write(@" @ echo off C:WINDOWSMicrosoft.NETFrameworkv3.5csc.exe /out:" + Vars.PathOut + «App.exe » + Vars.PathOut + «ToCompile.+ „n“); — вписывает в .BAT файл код вызова .NET компилятора(есть в каждой Windows). Process.Start(»CP.bat"); — запускает наш .BAT
Готово! Исходный код в один файл.
class ProgramsMain
{
static void Main()
{
System.Console.Title = "HabrHabr";
while (true) Start.ReadConsoleCommands();
}
}
class Start
{
public static void ReadConsoleCommands()
{
string[] C = System.Console.ReadLine().Split(' ');
try
{
switch (C[0].ToLower().Trim())
{
case "compile":
Vars.PathTo = C[1];
Vars.PathOut = C[2];
Translator.Translate(Vars.PathTo, Vars.PathOut + ".ourlang");
break;
default:
break;
}
}
catch (System.Exception ex)
{
System.Console.WriteLine(ex.Message);
}
}
}
public class Translator
{
public static void Translate(string path, string pathTo)
{
System.IO.StreamWriter OutputFile = System.IO.StreamWriter(pathTo);
OutputFile.WriteLine(@"class Program { static void Main() { ");
foreach (string line in System.IO.File.ReadLines(path))
{
string Done = line.Trim().ToLower();
if (Done.IndexOf("print") != -1)
{
string[] args = line.Split(':');
OutputFile.Write("Console.WriteLine(");
for (int i = 0; i < args.Length; i++)
{
OutputFile.Write(args[i]);
}
OutputFile.Write(");");
}
}
OutputFile.Close();
CP.Start();
}
}
public class CP
{
public static void Start()
{
try
{
StreamWriter SW = new StreamWriter("CP.bat", false);
SW.Write(@"@echo off
C:WINDOWSMicrosoft.NETFrameworkv3.5csc.exe /out:" + Vars.PathOut + "App.exe "
+ Vars.PathOut + "ToCompile.src"
+ "n");
SW.Close();
Process.Start("CP.bat");
}
catch (Exception ex)
{
Console.Write("n " + ex.Message + " n");
}
}
}
Автор: unseyablewiq