(*~\Глагол\приложкемяLink\МПГ2009 (компилируется, но НЕ раб.?)\~~~~~~~~~~~~~~~*)
(**)                                                     ОТДЕЛ Запуск;
(******************************************************************************
 * НАЗНАЧЕНИЕ: находит ещё не преобразованные отделы и запускает их
 *             на преобразование
 ******************************************************************************)

ИСПОЛЬЗУЕТ
        (*  \Глагол\              *)
  оЦепи   ИЗ "..\..\Отделы\Иное\",
   Пустой ИЗ "..\..\Отделы\Иное\",
ЧэргаСлеД ИЗ "..\..\Отделы\Иное\",
(*
  Набор   ИЗ "..\..\Отделы\Иное\",
  Цепь    ИЗ "..\..\Отделы\Иное\",
*)
        (*  \Глагол\              *)
  Текст   ИЗ "..\..\Отделы\Обмен\",
    Файл  ИЗ "..\..\Отделы\Обмен\",
        (*  \Глагол\              *)
   ВФайл  ИЗ "..\..\Отделы\Обмен\ВводВывод\",
  НаЭкран ИЗ "..\..\Отделы\Обмен\ВводВывод\",
(*
  Писать  ИЗ "..\..\Отделы\Обмен\",
  Вывод   ИЗ "..\..\Отделы\Обмен\",
*)
  Ядро,
  Ошибка,
  Разбор,
  Выражения,
  Данные,
  Узел,
  Рег,
  Настрой,
  Обмен;
                    (*--
                            локальные ПОСТоянные 
                      --*)

     (* имена служебных файлов *)
ПОСТ
  ИмяСпискаНовых="СписокПК.bat"; (* для преобразования кода *)
  ИмяСпискаВсех="Otdely.spi";    (* для редактора связей только лат. буквы *) 


(*------------------------- локальный вид Отдел ------------------------------*)
ВИД
(*Отдел    = ДОСТУП К НАБОР(Набор.Вид)*)
  ДкОтделу = ДОСТУП К нОтдел;
                      нОтдел = НАБОР(ЧэргаСлеД.нПустой)
    имя:Ядро.Имя;
    имяФ:Пустой.ДкЦепи;    (* :ДОСТУП К ЦЕПЬ; *)  (* пОтдел -> имя его файла  *)
    время:Файл.шцВремя
                               КОН;

(*---
                   набор-список из доступов к отделам на обработку
  ---*)
ПЕР
    сПредками:ЧэргаСлеД.нСписок;      (* список отделов с известными предками *)
  наОбработку:ЧэргаСлеД.нСписок;      (* список отделов на обработку *)


(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА НайтиПредков(отдМесто-:ЦЕПЬ;
                    отдИмя-  :Ядро.Имя):ДкОтделу;
(*
 * Цель:  или находит <отделД> в списке <сПредками> или создает новый <отделД>,
 *        находит его предков и включает его в список <сПредками>
 * До:    <отдМесто> - местоположение файла данного отдела
 *        <отдИмя>   - имя данного отдела
 * Ответ: <отделД> с предками
 *)
ПЕР
            звеноД:ЧэргаСлеД.ДкЗвену_телоД;
(*          звено :Набор.Звено; *)
  испИмена:ЧэргаСлеД.нСписок;                  (* список испИмена *)

  испИмя:Выражения.ДкИспИмя;  (* доступ к звену в списке испИмена *)

  предок,
  отделД :ДкОтделу;          (* доступ к звену в списке сПредками *)

  испМесто    :Файл.ВПути;

  времяПредков:Файл.шцВремя;

  отдИмяФ     :Файл.ВПолного;                           (* вида ДОСТУП К ЦЕПЬ; *)
УКАЗ
  Файл.СобратьИмя(отдИмяФ,отдМесто,отдИмя,"отд");
                               (* может <отделД> уже есть в списке <сПредками> *)
(*
   Обход списка с 1-го звена до N-го, т.е. пока звеноД.слеД # ПУСТО
 *)
            звеноД:=ЧэргаСлеД.Дк1муЗвену(сПредками);
  ПОКА
            звеноД # ПУСТО
  ВЫП
    отделД:=звеноД.телоД(ДкОтделу);
    ЕСЛИ
              отделД.имяФ^ = отдИмяФ
    ТО
      ЕСЛИ
              отделД.время = МИН(Файл.шцВремя)
      ТО
        Ошибка.Отметить(Ошибка.ПЕРЕКРЕСТНОЕ_ИСПОЛЬЗОВАНИЕ)
      КОН;
      ВОЗВРАТ отделД
    КОН;
            звеноД:=звеноД.слеД
  КОН;
                                          (* создаем и запоминаем новый отдел *)
  ЕСЛИ
                               НЕ Файл.Существует(отдИмяФ)
  ТО
    Ошибка.ОтметитьИмя(Ошибка.ФАЙЛ_НЕ_ОТКРЫВАЕТСЯ,отдИмяФ)
  КОН;

         СОЗДАТЬ(отделД);
  СПИСАТЬ(отдИмя,отделД.имя);
         СОЗДАТЬ(отделД.имяФ,отдИмяФ);
                               (* для обнаружения перекрёстного использования *)
  отделД.время:=МИН(Файл.шцВремя);

   (* создаём новое <звеноД> (с доступом к телоД=отделД) внутри задачи ЧэргаСлеД.ДобавитьНовЗвеноВконСписка(..)
                                                        и присоединяем это звено к концу списка звеньев *)
  ЧэргаСлеД.ДобавитьНовЗвеноВконСписка(сПредками,отделД);

                                               (* смотрим используемые отделы *)
  Обмен.НовоеИмяФ(отдИмяФ);
  Выражения.Отдел(отдИмя,испИмена,ВКЛ); (* найти только испИмена *)
  времяПредков:=МИН(Файл.шцВремя);
(*
   Обход списка с 1-го звена до N-го, т.е. пока звеноД.слеД # ПУСТО
 *)
            звеноД:=ЧэргаСлеД.Дк1муЗвену(испИмена);
  ПОКА
            звеноД # ПУСТО
  ВЫП
    испИмя:=звеноД.телоД(Выражения.ДкИспИмя);

    ЕСЛИ
         испИмя.имя # "ОБХОД"
    ТО
      Разбор.начСлова:=испИмя.начСлова;

      Файл.НайтиМесто(отдМесто,испИмя.путь^,испМесто);
 предок:=НайтиПредков(испМесто,испИмя.имя);
                                              (* возвращаем в Обмен "отдИмяФ" *)
      Обмен.НовоеИмяФ(отдИмяФ);
      ЕСЛИ
           предок.время > времяПредков
      ТО                                           (* наибольшее время предка *)
        времяПредков:=предок.время
      КОН
    КОН;
            звеноД:=звеноД.слеД
  КОН;
  ЕСЛИ Обмен.НужнаОбр(времяПредков) ТО
    отделД.время:=МАКС(Файл.шцВремя);

       (* создаём новое <звеноД> (с доступом к телоД=отделД) внутри задачи ЧэргаСлеД.ДобавитьНовЗвеноВконСписка(..)
                                                            и присоединяем это звено к концу списка звеньев *)
    ЧэргаСлеД.ДобавитьНовЗвеноВконСписка(наОбработку,отделД)
  ИНАЧЕ
                   Файл.ВремяИзменения(Обмен.опгИмяФ,отделД.время)
  КОН;
  ВОЗВРАТ отделД
КОН НайтиПредков;

(******************************************************************************)
ЗАДАЧА ПреобрОтдел(отделД:ДкОтделу);
ПЕР
                              испИмена:ЧэргаСлеД.нСписок;  (* список испИмена *)
УКАЗ
  Данные.Обновить;
  Рег.Обновить;
   Обмен.НовоеИмяФ(отделД.имяФ^);
   Выражения.Отдел(отделД.имя,испИмена,ОТКЛ)
КОН ПреобрОтдел;

(******************************************************************************)
ЗАДАЧА СохранитьСписокВсех;
(* Запись в файл "Otdely.spi" списка всех используемых .код файлов
 ******************************************************************************)
ПЕР
            звеноД:ЧэргаСлеД.ДкЗвену_телоД;
(*          звено :Набор.Звено; *)

  отделД :ДкОтделу;          (* доступ к звену в списке сПредками *)

  поток:ВФайл.ДкПотоку;

  кодИмяФ:Файл.ВПолного;

  путь:Файл.ВПути;
  имя :Ядро.Имя;
  тип :Файл.ВТипа;
УКАЗ
       поток:=ВФайл.Открыть(ИмяСпискаВсех);
  ЕСЛИ поток = ПУСТО ТО
    Ошибка.ОтметитьИмя(Ошибка.ФАЙЛ_НЕ_ОТКРЫВАЕТСЯ,ИмяСпискаВсех)
  КОН;
       поток.цВидЗнаков:=ВФайл.знВин;
(*
   Обход списка с 1-го звена до N-го, т.е. пока звеноД.слеД # ПУСТО
 *)
            звеноД:=ЧэргаСлеД.Дк1муЗвену(сПредками);
  ПОКА
            звеноД # ПУСТО
  ВЫП
    отделД:=звеноД.телоД(ДкОтделу);

    Файл.РазобратьИмя(отделД.имяФ^,путь,имя,тип);
   оЦепи.ДобавитьВКонец(путь,"Код\");                                  
    Файл.СобратьИмя(кодИмяФ,путь,имя,"маш^");
    ВФайл.ЦепьЗнаков(поток,кодИмяФ);

            звеноД:=звеноД.слеД
  КОН;
    ВФайл.Закрыть(поток)
КОН СохранитьСписокВсех;

(******************************************************************************)
ЗАДАЧА СохранитьСписокНовых;
(* Запись в файл "СписокПК.bat" списка обрабатываемых файлов
 ******************************************************************************)
ПЕР
            звеноД:ЧэргаСлеД.ДкЗвену_телоД;
(*          звено :Набор.Звено; *)

  отделД :ДкОтделу;          (* доступ к звену в списке наОбработку *)

  поток:ВФайл.ДкПотоку;

  имяФ:Файл.ВПолного;

  путь:Файл.ВПути;
  имя :Ядро.Имя;
  тип :Файл.ВТипа;
УКАЗ
       поток:=ВФайл.Открыть(ИмяСпискаНовых);
  ЕСЛИ поток = ПУСТО ТО
    Ошибка.ОтметитьИмя(Ошибка.ФАЙЛ_НЕ_ОТКРЫВАЕТСЯ,ИмяСпискаНовых)
  КОН;
       поток.цВидЗнаков:=ВФайл.знДос;
(*
   Обход списка с 1-го звена до N-го, т.е. пока звеноД.слеД # ПУСТО
 *)
            звеноД:=ЧэргаСлеД.Дк1муЗвену(наОбработку);
  ПОКА
            звеноД # ПУСТО
  ВЫП
    отделД:=звеноД.телоД(ДкОтделу);

    Файл.РазобратьИмя(отделД.имяФ^,путь,имя,тип);
   оЦепи.ДобавитьВКонец(путь,"Код\");                                  
    Файл.СобратьИмя(имяФ,путь,имя,"^");
   оЦепи.Вставить("call ПК ",имяФ,0);
    ВФайл.ЦепьЗнаков(поток,имяФ);

            звеноД:=звеноД.слеД
  КОН;
    ВФайл.Закрыть(поток)
КОН СохранитьСписокНовых;

(******************************************************************************)
ЗАДАЧА ВыводОшибки(текст-:ЦЕПЬ);
УКАЗ
  НаЭкран.ВсяЦепь(Обмен.отдИмяФ);

  НаЭкран.Цел4числа(" (%d:%d) - ",Разбор.начСлова.строка,
                                  Разбор.начСлова.колонка,0,0);
  НаЭкран.ВсяЦепь(текст);
  НаЭкран.ВсяЦепь(".^");
  Обмен.УдалитьКод;
  СТОП(1)
КОН ВыводОшибки;

(******************************************************************************)
ЗАДАЧА ПреобрОтделы-(отдИмяФ-,
                    срдМесто- :ЦЕПЬ;
                   настройки  :МНОЖ;
                       свод   :ЦЕЛ);
(*
 * Цель:  преобразовать текст данного отдела и всех обновлённых отделов,
 *        которые он использует (явно или неявно) в машинный код
 * До:    <отдИмяФ>   - местоположение преобразуемого отдела
 *        <срдМесто>  - корневой путь к "СРЕДА.отд"
 *        <настройки> - множество ключей преобразования
 *        <свод>      - свод настроек
 * После: *.опм       - общедоступные понятия (двоичный вид) каждого отдела 
 *        *.код       - машинный код (текстовый вид) каждого отдела
 *)
ПЕР
            звеноД:ЧэргаСлеД.ДкЗвену_телоД;
(*          звено :Набор.Звено; *)

  отделД :ДкОтделу;          (* доступ к звену в списке наОбработку *)

  поток:ВФайл.ДкПотоку;

  место:Файл.ВПути;
  имя  :Ядро.Имя;
  тип  :Файл.ВТипа;
УКАЗ
                                                             (* очистим файлы *)
                поток:=ВФайл.Открыть(ИмяСпискаНовых);
  ВФайл.Закрыть(поток);
                поток:=ВФайл.Открыть(ИмяСпискаВсех);
  ВФайл.Закрыть(поток);

  ЧэргаСлеД.ОчиститьСписок(сПредками);
  ЧэргаСлеД.ОчиститьСписок(наОбработку);

  Ошибка.Подготовить(ВыводОшибки);
  Настрой.Подготовить(настройки,свод);
  Выражения.Подготовить(срдМесто);
  Файл.РазобратьИмя(отдИмяФ,место,имя,тип);

  отделД:=НайтиПредков(место,имя);
(*
   Обход списка с 1-го звена до N-го, т.е. пока звеноД.слеД # ПУСТО
 *)
            звеноД:=ЧэргаСлеД.Дк1муЗвену(наОбработку);
  ПОКА
            звеноД # ПУСТО
  ВЫП
    отделД:=звеноД.телоД(ДкОтделу);

    НаЭкран.ВсяЦепь(отделД.имяФ^);
    НаЭкран.ВсяЦепь("^");
        ПреобрОтдел(отделД);

            звеноД:=звеноД.слеД
  КОН;
  СохранитьСписокНовых;
  СохранитьСписокВсех
КОН ПреобрОтделы;

КОН Запуск.
