Задача 8 Урок 22

Задача 8 Урок 22 "Калькулятор":
Напишите функцию, которая получает на вход произвольную строку вида: 5*(3+4)-7*9+3*(2+(2-7))
(арифметическое выражение со скобками любого уровня вложенности и операциями умножения, вычитания и сложения) и в качестве ответа возвращает результат этого выражения.

var
  s: string;  // Строка, содержащая математическое выражение
  i: integer; // Индекс для прохода по строке (по символам)

function TakeResult(var i: integer; s: string): integer;
var
  str: string;  // Временная строка для хранения числа
  a, midres: integer;  // Переменные для текущего числа и промежуточных результатов
  minus, mult: boolean;  // Логические переменные для обозначения операций вычитания и умножения
begin
  minus := false;  // Инициализация флага для вычитания
  mult := false;   // Инициализация флага для умножения
  result := 0;     // Инициализация результата вычисления

  repeat
    i += 1;    // Переход к следующему символу строки


    if (s[i] >= '0') and (s[i] <= '9') then    // Проверяем, является ли текущий символ цифрой
      str := str + s[i]   // Если да, добавляем символ к строке 'str', которая собирает цифры числа
    else
    begin

      if s[i] = '(' then     // Если встречаем открывающую скобку, начинаем рекурсивное вычисление внутри скобок
      begin
        a := TakeResult(i, s); // Рекурсивно вызываем TakeResult для выражения внутри скобок
        i += 1;  // Переходим на следующий символ после закрывающей скобки
      end
      else
        val(str, a);    // Преобразуем строку 'str' в число 'a'


      if minus = true then  // Если флаг вычитания был установлен, инвертируем знак числа
      begin
        a := a * (-1);   // Инвертируем знак числа
        minus := false;  // Сбрасываем флаг вычитания
      end;


      if mult then     // Если был установлен флаг умножения
      begin
        a := a * midres;  // Умножаем текущее значение на промежуточное
        mult := false;    // Сбрасываем флаг умножения
      end;


      if s[i] = '*' then  // Если текущий символ — это звёздочка (умножение)
      begin
        mult := true;    // Устанавливаем флаг умножения
        midres := a;     // Сохраняем текущее значение в промежуточный результат
      end
      else
        result := result + a;  // Если не умножение, прибавляем значение к результату


      if s[i] = '-' then  // Если текущий символ — минус, устанавливаем флаг вычитания
        minus := true;

      str := '';   // Очищаем строку для следующего числа
    end;

  until (s[i] = ')') or (i > length(s)); // Цикл продолжается до тех пор, пока не встретится закрывающая скобка или не будет достигнут конец строки
end;

begin
  i := 0;  // Инициализация индекса для прохода по строке
  s := '5*(3+4)-7*9+3*(2+(2-7))';  // Математическое выражение в виде строки
  writeln(s, ' = ', TakeResult(i, s));  // Выводим выражение и результат его вычисления
  readln();  // Ожидаем нажатия клавиши для завершения программы
end.     

Вывод консоли:

5*(3+4)-7*9+3*(2+(2-7)) = -37