Answer the question
In order to leave comments, you need to log in
Where is my mistake in C# code?
I'm developing my mini-interpreter (don't ask why), and so I had a problem: "Prepreter" (as I called it) at the very beginning bypasses the entire code file and searches for functions by the "function" keyword, and then adds them into the list in the form of a structure (the line number of its beginning is indicated). Further, in the main loop, when it comes to the line of the function call, the "postpretator" takes the structure from the list and adds the line number of the initializer of this function to it, then it writes a command like "goto;8" before the function termination character ("}") " and then translates the execution line number to the line number of the start of the function, then after the function is executed, it should translate the execution line number back to the main loop. But the function can be in any part of the script, that's why the "prepretator" was invented. Everything works for me with one function, but it doesn’t want to with two: for some reason it does not substitute the line number translation command into the first function, but it substitutes normally into the second one.
/// <summary>
/// Структура функции
/// </summary>
struct Function
{
public int start;
public int point;
public string name;
}
/// <summary>
/// Список структур функции
/// </summary>
static SortedList<string, Function> funct = new SortedList<string, Function>();
/// <summary>
/// Препретатор функция
/// </summary>
/// <param name="game">Массив строк всего скрипта</param>
/// <param name="main">Сам скрипт</param>
public static void Compilation(string[] game, ref string main)
{
//funct.Clear();
for (int i = 0; i < game.Length; i++)
{
if (game[i].Split(';')[0] == "function")
{
//создание или "взятие" функции
Function fn;
if (!funct.ContainsKey(game[i].Split(';')[1]))
{
fn = new Function();
fn.start = i + 1;
string name = game[i].Split(';')[1];
fn.name = name;
funct.Add(name, fn);
}
else
{
fn = funct[game[i].Split(';')[1]];
}
//Подсчёт строк функции
int o = 1;
for (; !game[i + o].EndsWith("}"); o++) ;
var rrrhhh = ""; //временная переменная с итоговым кодом скрипта
var telo = "";//тело функции
for (int p = 0; p < ((i + o)); p++)
{
rrrhhh += game[p] + "\n"; //заполнение до конца функции
}
for (int q = i; q < i+o; q++)
{
telo += game[q] + "\n"; //заполнение тела
}
telo = telo.Split('\n')[telo.Split('\n').Length - 2];//обрезка } (там 2 должно быть, потому что индекс с 0, а количество с 1)
//Console.WriteLine(telo);
if (!telo.Contains("goto;"))
rrrhhh = rrrhhh.Insert(rrrhhh.Length, String.Format("goto;{0}", fn.point)+"\n}");//если "гото" нет, то добавляем
else//иначе изменяем
{
rrrhhh = rrrhhh.Substring(0, rrrhhh.Length - 3);//обрезаем перенос строки и }
int y = rrrhhh.Length-1;//получаем длинну в виде индекса
int t = 0;//создает временную переменную
for (; rrrhhh[y] == ';'; y--, t++) ;//считаем от конца и до ; (это символ передачи аргументов)
//t++;
rrrhhh = rrrhhh.Substring(0, rrrhhh.Length - t);//обрезаем по него
rrrhhh += ";" + fn.point.ToString() + "\n}";//добавляем новый "гото"
//Console.WriteLine(rrrhhh);
}
main = rrrhhh; //изменяем основной скрипт
}
}
}
/// <summary>
/// Постпретатор функция
/// </summary>
/// <param name="game">Массив строк со скриптом</param>
/// <param name="main">Сам скрипт</param>
/// <param name="name">Имя функции</param>
public static void Compilation(string[] game, ref string main, string name)
{
///Тут всё почти также как и там, но другой начало
for (int i = 0; i < game.Length; i++)
{
if (game[i].Split(';')[0] == "function")
{
//Console.WriteLine(i);
Function fn = funct[name]; //получем функцию из списка по её имени
//Далее всё вроде так же, хотя я мог что то изменить
int o = 1;
for (; !game[i + o].EndsWith("}"); o++) ;
var rrrhhh = "";
var telo = "";
for (int p = 0; p < ((i + o)); p++)
{
rrrhhh += game[p] + "\n";
}
for (int q = i; q < i + o; q++)
{
telo += game[q] + "\n";
}
telo = telo.Split('\n')[telo.Split('\n').Length - 2];
if (!telo.Contains("goto;"))
rrrhhh = rrrhhh.Insert(rrrhhh.Length, String.Format("goto;{0}", fn.point) + "\n}");
else
{
rrrhhh = rrrhhh.Substring(0, rrrhhh.Length - 3);
int y = rrrhhh.Length - 1;
int t = 0;
for (; rrrhhh[y] == ';'; y--, t++) ;
//t++;
rrrhhh = rrrhhh.Substring(0, rrrhhh.Length - t);
rrrhhh += ";" + fn.point.ToString() + "\n}";
//Console.WriteLine(rrrhhh);
}
main = rrrhhh;
//Console.WriteLine(telo);
}
}
}
public static void loadgame(string path)
{
//Начало препретатора
Console.WriteLine("Start Compilation");
Compilation(game.Split('\n'), ref game);
lenght = game.Split('\n').Length;
Console.WriteLine("Stop Compilation");
//конец препретатора
for (int i = 0; i < lenght; i++)
{
switch (game.Split('\n')[i].Split(';')[0])
{
case "func":
//func;test
Function fc = funct[game.Split('\n')[i].Split(';')[1]]; //получение из аргумента имени функции
fc.point = i+2; //передача текущего номера строки
funct[game.Split('\n')[i].Split(';')[1]] = fc; //замена функции в списке
Compilation(game.Split('\n'), ref game, game.Split('\n')[i].Split(';')[1]); //запуск постпретатора
//Compilation(game.Split('\n'), ref game);
lenght = game.Split('\n').Length;//пересчёт новой общей длинны скрипта
i = fc.start;//передача управления другой строке
break;
}
}
}
func;test
//mess - просто текст в консоль выводит
mess;Добро пожаловать в Test.
func;fc
//функции
function;test
isfunction;
mess;Функция, функция
mess;Тело, тело
mess;Кто то батя в C#
}
isfunction;
function;fc
isfunction;
mess;Функция другая
}
Answer the question
In order to leave comments, you need to log in
You came up with an exceptionally moronic shnyaga, and even tried to embody it. You need to read the theory of creating compilers, they write something interesting from Intel. All in English, really)
They answered well on Stack Overflow and did not show off, like here. The problem was in the game and main variables. Here is the solution:
/// <summary>
/// Препретатор и постпретатор функция
/// </summary>
/// <param name="game">Массив строк всего скрипта</param>
/// <param name="main">Сам скрипт</param>
public static void Compilation(string[] game, ref string main, string namefunc = null)
{
//funct.Clear();
for (int i = 0; i < game.Length; i++)
{
game = main.Split('\n');
if (game[i].Split(';')[0] == "function")
{
//создание или "взятие" функции
Function fn;
if(namefunc != null)
{
fn = funct[namefunc]; //получем функцию из списка по её имени
}
else if (!funct.ContainsKey(game[i].Split(';')[1]))
{
fn = new Function();
fn.start = i + 1;
string name = game[i].Split(';')[1];
fn.name = name;
funct.Add(name, fn);
}
else
{
fn = funct[game[i].Split(';')[1]];
}
//Подсчёт строк функции
int o = 1;
for (; !game[i + o].TrimEnd('\n', '\r', '\t').EndsWith("}"); o++) ;
var rrrhhh = ""; //временная переменная с итоговым кодом скрипта
var telo = "";//тело функции
for (int p = 0; p < ((i + o)); p++)
{
rrrhhh += game[p] + "\n"; //заполнение до конца функции
}
//Console.WriteLine(rrrhhh);
for (int q = i; q < i+o; q++)
{
telo += game[q] + "\n"; //заполнение тела
}
telo = telo.Split('\n')[telo.Split('\n').Length - 2];//обрезка } (там 2 должно быть, потому что индекс с 0, а количество с 1)
//Console.WriteLine(telo);
int lenghtgoto = 0;
if (!telo.Contains("goto;")){
rrrhhh = rrrhhh.Insert(rrrhhh.Length, String.Format("goto;{0}", fn.point) + "\n}");//если "гото" нет, то добавляем
lenghtgoto = (String.Format("goto;{0}", fn.point) + "\n}").Length; //вычисляем длинну вставки
}
else//иначе изменяем
{
rrrhhh = rrrhhh.Substring(0, rrrhhh.Length - 3);//обрезаем перенос строки и }
int y = rrrhhh.Length - 1;//получаем длинну в виде индекса
int t = 0;//создает временную переменную
for (; rrrhhh[y] == ';'; y--, t++) ;//считаем от конца и до ; (это символ передачи аргументов)
//t++;
rrrhhh = rrrhhh.Substring(0, rrrhhh.Length - t);//обрезаем по него
rrrhhh += ";" + fn.point.ToString() + "\n}";//добавляем новый "гото"
//Console.WriteLine(rrrhhh);
}
rrrhhh = rrrhhh.Insert(rrrhhh.Length, main.Substring(rrrhhh.Length - (lenghtgoto))); //Добавляем всё что после функции
//Console.WriteLine(rrrhhh);
main = rrrhhh; //изменяем основной скрипт
}
}
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question