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

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

                (*--- общедоступные доступы к ВИДам. Из Данные.отд ---*)
ВИД
  ДкПонятию- = ДОСТУП К нПонятие;
  ДкВиду-    = ДОСТУП К нВид;
  ДкОбласти- = ДОСТУП К нОбласть;
  ДкОтделу-  = ДОСТУП К нОтдел;

                   (*--
                           общедоступные ПОСТоянные 
                     --*)
ПОСТ
                (* Род понятий (нПонятие.родп). Из Данные.отд (в ПГ - ВД.отд) *)

  пПост-      = 1; (* постоянная *)
  пВид-       = 2; (* вид данных *)
  пПер-       = 3; (* переменая задачи или приёмник значения *)
  пСсылка-    = 4; (* приёмник ссылки *)
  пСвойство-  = 5; (* свойство набора *)
  пЗадача-    = 6; (* задача *)
  пВстрЗадача-= 7; (* встроенная задача *)
  пОтдел-     = 8; (* отдел *)

(*------------------------------------ ВидПонятие ----------------------------*)
ВИД
(*ВидПонятие- = НАБОР(Набор.Вид)*)
   нПонятие-  = НАБОР(ЧэргаСлеД.нПустой)

    родп+:ЦЕЛ;          (* род понятий:
                         *        пОтдел|пОбласть|пВид|пПост|пПер|пПрСсылки|
                         *        пЗадача|пВстрЗадача|пСвойство               *)
    имя+:Ядро.Имя;      (* имя в области видимости *)
    обл+    :Данные.ДкОбласти; (* область видимости *)
    след+   :Данные.ДкПонятию; (* для списка понятий области видимости *)

    признаки+:МНОЖ;     (* см. ниже *)

    вид+    :Данные.ДкВиду;    (* пВид       - вид
                                * пЗадача    - вид ответа
                                * п...       - вид понятия *)
    первпон+:Данные.ДкПонятию; (* пЗадача    - начало списка приёмников и др. понятий
                                * пОтдел     - начало списка понятий *)
    адр+:ЦЕЛ;           (* пПер       - смещние от FP или № регистра
                         * пСсылка    - смещние от FP или № регистра
                         * пПост      - значение | (0 | смещение для цепочек)
                         * пСвойство  - смещение от начала набора
                         * пВстрЗадача- номер задачи
                         * пОтдел     - порядковый номер отдела в <вхотд> *)
    достцепь+:Пустой.ДкЦепи; (* :ДОСТУП К ЦЕПЬ; *) (* значение цепочки *)
  КОН;

                   (*--
                           общедоступные ПОСТоянные 
                     --*)
ПОСТ
       (* Признаки понятия (нПонятие.признаки). Из Данные.отд (в ПГ - ВД.отд) *)

  прОбщедоступная-  =0;          (* общедоступное понятие                     *)
  прНеизменяемая-   =1;          (* только для чтения                         *)
  прВложенная-      =2;          (* переменная не на уровне отдела            *)
  прОбъявлена-      =3;          (* объявлена как задача, а не заготовка      *)
  прПередаваемая-   =4;          (* задача для иноязычных приложений          *)
  прБыстрая-        =5;          (* быстрая (регистровая) задача (переменная) *)
  прТекущегоОтдела- =6;          (* для пОтдел и пПер уровня отдела           *)           
  прПриёмник-       =7;          (* приёмник задачи                           *)           

                        (* встроенные задачи с одним приёмником *)
  зВЗнак-         = 1;
  зВЦел-          = 2;
  зВШирЦел-       = 3;
  зДлина-         = 4;
  зМакс-          = 5;
  зМин-           = 6;
  зМодуль-        = 7;
  зОбнулить-      = 8;
  зОУзк-          = 9;
  зПолучитьАдрес- =10;
  зПроверить-     =11;
  зСоздать-       =12;
  зСтоп-          =13;
  зУзк-           =14;
  зЦелЧасть-      =15;
  зЧет-           =16;
                       (* встроенные задачи которые допускают >= 2 приёмников *)
  зВПамять-       =17;
  зЗадано-        =18;
  зЗначение-      =19;
  зИзПамяти-      =20;
  зОбраз-         =21;
  зПоставить-     =22;
  зРазмер-        =23;
  зСместить-      =24;
  зСписать-       =25;
  зУвеличить-     =26;
  зУменьшить-     =27;

                   (*--
                           общедоступные ПОСТоянные 
                     --*)
ПОСТ           
                                                (* род видов *)
  вНеопр-   =  1; (* вид ещё не определен *)
  вЯчейка-  =  2; (* встр. ОБХОД.Ячейка   *)
  вОЯчейки- =  3; (* встр. ОБХОД.Ячейки   *)
  вКлюч-    =  4; (* встр. КЛЮЧ           *)
  вЗнак-    =  5; (* встр. ЗНАК           *)
  вЦел8-    =  6; (* встр. ОБХОД.Цел8     *)
  вЦел16-   =  7; (* встр. ОБХОД.Цел16    *)
  вЦел32-   =  8; (* встр. ОБХОД.Цел32    *)
  вЦел64-   =  9; (* встр. ОБХОД.Цел64    *)
  вВещ32-   = 10; (* встр. ВЕШ            *)
  вВещ64-   = 11; (* встр. ШИРВЕЩ         *)
  вМнож-    = 12; (* встр. МНОЖ           *)
  вПусто-   = 13; (* встр. ПУСТО          *)
  вНет-     = 14; (* вида нет             *)
  вДоступ-  = 15; (*       ДОСТУП К       *)
  вЗадача-  = 16; (*       ЗАДАЧА         *)
  вБегунок- = 17; (*       БЕГУНОК        *)
  вРяд-     = 18; (*       РЯД n ИЗ       *)
  вОРяд-    = 19; (* нет!  РЯД ИЗ         *)
  вЦепь-    = 20; (*       ЦЕПЬ[n]        *)
  вОЦепь-   = 21; (* нет!  ЦЕПЬ           *)
  вНабор-   = 22; (*       НАБОР ИЗ       *)

  множЦелых-={вЦел8..вЦел64};
  множВещ-  ={вВещ32,вВещ64};
  множМеток-=множЦелых+{вЗнак};


                            (*--- общедоступные ВИДы ---*)
ВИД
(*------------------------------------ ВидВид --------------------------------*)
(*ВидВид- = НАБОР(Набор.Вид)*)
  нВид-   = НАБОР(ЧэргаСлеД.нПустой)

    родв+   :ЦЕЛ;     (* род вида: вНеопр|вЯчейка|..|вНабор                   *)
    понвида+:Данные.ДкПонятию; (* понятие, определяющее этот вид | ПУСТО      *)
    размер+ :ЦЕЛ;     (* размер (ячеек) переменной данного вида               *)
    номв:ЦЕЛ;         (* номер вида для выходного файла: вНеопр|..|вНабор|..  *)
    овид+   :Данные.ДкВиду;    (* опорный вид у вДоступ, вБегунок, вРяд, вЦепь, вНабор| *)
                               (* вид ответа у вЗадача                                  *)
    первпон+:Данные.ДкПонятию; (* начало списка свойств у вНабор|                       *)
                               (* начало списка приёмников у вЗадача                    *)
    нвхотд+ :ЦЕЛ;     (* у вНабор: 0 для тек. отдела|номер входного отдела (в <вхотд>)  *)
    шаг+    :ЦЕЛ;     (* шаг бегунка или 1 для передаваемых задач             *)
    ов+     :ЦЕЛ;     (* номер описателя вида                                 *)
  КОН;

(*------------------------------------ ВидОбласть ----------------------------*)
(*ВидОбласть- = НАБОР(Набор.Вид)*)
  нОбласть-   = НАБОР(ЧэргаСлеД.нПустой)

    уровень+:ЦЕЛ;        (* уровень вложенности *)
    имя+:Ядро.Имя;       (* имя для кода *)
    окробл+ :Данные.ДкОбласти;   (* окружающая область *)
    первпон+:Данные.ДкПонятию;   (* начало списка понятий *)
    видотв+ :Данные.ДкВиду;      (* вид ответа задачи *)
  КОН;

(*------------------------------------ ВидОтдел ------------------------------*)
(*ВидОтдел- = НАБОР(Набор.Вид)*)
  нОтдел-   = НАБОР(ЧэргаСлеД.нПустой)

    имя+:Ядро.Имя;       (* имя отдела *)
    обл+:Данные.ДкОбласти;      (* область видимости *)
    нвхотд+:ЦЕЛ;                (* порядковый номер отдела в <вхотд> *)
    имяФ:Пустой.ДкЦепи;    (* :ДОСТУП К ЦЕПЬ; *)  (* пОтдел -> имя его файла  *)
  КОН;

                      (*--
                               локальные ПОСТоянные 
                        --*)
ПОСТ
                  (* метки в файле общих понятий *)
  мПост     = 1;
  мВид      = 2;
  мПер      = 3;
  мЗадача   = 4;
  мВидЗадача= 5;
  мДоступ   = 6;
  мБегунок  = 7;
  мРяд      = 8;
  мОРяд     = 9;
  мЦепь     =10;
  мОЦепь    =11;
  мНабор    =12;
  мПриёмники=13;
  мПриёмник =14;
  мСсылка   =15;
  мСвойства =16;
  мСвойство =17;
  мСкрепка  =18;

(*-================================== ПОСТ ПЕР ==============================-*)
ПЕР
  неопрвид-,оячейкавид-,оячейкивид-,ключвид-,знаквид-,
  цел8вид-,цел16вид-,цел32вид-,цел64вид-,вещ32вид-,вещ64вид-,
  множвид-,пустовид-,нетвид-,одоствид-:Данные.ДкВиду;

  текОбласть+:Данные.ДкОбласти;   (* текущая область видимости *)
  обхОбласть :Данные.ДкОбласти;   (* область видимости отдела ОБХОД *)
  глаОбласть :Данные.ДкОбласти;   (* область видимости встроенных понятий *)

  чвхотд-:ЦЕЛ;             (* число входных отделов *)

  вхотд-:РЯД Настрой.ВсегоОтделов ИЗ Данные.ДкОтделу;   (* все входные отделы *)
  
  следномв :ЦЕЛ;           (* следующий номер вида для выходного файла *)
  уровень+ :ЦЕЛ;           (* уровень вложенности текущей задачи, 0 - отдел *)
  быстрая+ :КЛЮЧ;          (* обрабатываемая задача - быстрая *)

  поДоступу-:Данные.ДкПонятию;    (* понятие полученно по доступу *)


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


(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       СоздатьПонятие-():Данные.ДкПонятию;
ПЕР
          пон:Данные.ДкПонятию;
УКАЗ
  СОЗДАТЬ(пон);
  ВОЗВРАТ пон
КОН СоздатьПонятие;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       СоздатьВид-(родв:ЦЕЛ):Данные.ДкВиду;
ПЕР 
          вид:Данные.ДкВиду;
УКАЗ 
  СОЗДАТЬ(вид);
          вид.родв:=родв;
          вид.размер:=1; (*4*)
          вид.овид:=неопрвид;
  ВОЗВРАТ вид
КОН СоздатьВид;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       СоздатьОбласть-(   имя-:ЦЕПЬ;
                       окробл :Данные.ДкОбласти):Данные.ДкОбласти;
ПЕР
              обл:Данные.ДкОбласти;
УКАЗ 
      СОЗДАТЬ(обл);
              обл.уровень:=уровень;
  СПИСАТЬ(имя,обл.имя);
              обл.окробл:=окробл;
      ВОЗВРАТ обл
КОН СоздатьОбласть;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       СоздатьОтдел-(имя-  :Ядро.Имя;
                     имяФ- :ЦЕПЬ;                     (* :Пустой.ДкЦепи; - несовместимо с задачей
  СОЗДАТЬ(отд.имяФ,имяФ);                              *)
                     окробл:Данные.ДкОбласти):Данные.ДкОтделу;
ПЕР
          отд:Данные.ДкОтделу;
УКАЗ 
  СОЗДАТЬ(отд);
  СОЗДАТЬ(отд.имяФ,имяФ);
          отд.имя:=имя;
          отд.обл:=СоздатьОбласть(имя,окробл);
  ВОЗВРАТ отд
КОН СоздатьОтдел;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       СоздатьВидЦепь-(размер:ЦЕЛ):Данные.ДкВиду;
ПЕР 
          вид:Данные.ДкВиду;
УКАЗ 
  СОЗДАТЬ(вид);
          вид.родв:=вЦепь;
          вид.овид:=знаквид;
          вид.размер:=размер*Настрой.рЗнак;
  ВОЗВРАТ вид
КОН СоздатьВидЦепь;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       СоздатьПостЦепь-(достцепь:Пустой.ДкЦепи):Данные.ДкПонятию;
ПЕР
          пон:Данные.ДкПонятию;
УКАЗ 
          пон:=СоздатьПонятие();
          пон.родп:=Данные.пПост;
          пон.достцепь:=достцепь;
          пон.вид:=СоздатьВидЦепь(РАЗМЕР(пон.достцепь^));
  ВОЗВРАТ пон
КОН СоздатьПостЦепь;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ИскатьВСписке-(пон :Данные.ДкПонятию;
                      имя-:Ядро.Имя):Данные.ДкПонятию;
УКАЗ
  ПОКА пон # ПУСТО ВЫП
    ЕСЛИ пон.имя = имя ТО
      ВОЗВРАТ пон
    КОН;
    пон:=пон.след
  КОН;
  ВОЗВРАТ ПУСТО
КОН ИскатьВСписке;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ИскатьПонятие-(имя-:Ядро.Имя):Данные.ДкПонятию;
(*
 * Цель:  найти в области видимости <текОбласть> и выше понятие с именем <имя>
 * Возвр: понятие или ПУСТО
 *)
ПЕР
  верх:Данные.ДкОбласти;
   пон:Данные.ДкПонятию;
УКАЗ
  верх:=текОбласть;
  ПОКА верх # ПУСТО ВЫП
    пон:=ИскатьВСписке(верх.первпон,имя);
    ЕСЛИ пон # ПУСТО ТО
      ВОЗВРАТ пон
    КОН;
    верх:=верх.окробл
  КОН;
  ВОЗВРАТ ПУСТО
КОН ИскатьПонятие;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ИскатьСвойство-(вид :Данные.ДкВиду;
                       имя-:Ядро.Имя):Данные.ДкПонятию;
(*
 * Цель:  найти в наборе <вид> и его опорных видах свойство с именем <имя>
 * Возвр: понятие или ПУСТО
 *)
ПЕР
  пон:Данные.ДкПонятию;
УКАЗ
  ПОКА вид # неопрвид ВЫП
    пон:=ИскатьВСписке(вид.первпон,имя);
    ЕСЛИ пон # ПУСТО ТО
      ВОЗВРАТ пон
    КОН;
    вид:=вид.овид
  КОН;
  ВОЗВРАТ ПУСТО
КОН ИскатьСвойство;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Вставить-(имя-:ЦЕПЬ):Данные.ДкПонятию;
ПЕР
  пон,пред:Данные.ДкПонятию;
УКАЗ
  пон:=текОбласть.первпон;
  ЕСЛИ пон = ПУСТО ТО
    пон:=СоздатьПонятие();
    текОбласть.первпон:=пон
  ИНАЧЕ
    ПОКА пон # ПУСТО ВЫП
      ЕСЛИ пон.имя = имя ТО
        Ошибка.ОтметитьИмя(Ошибка.ПЕРЕОПРЕДЕЛЕНИЕ,имя)
      КОН;
      пред:=пон;
      пон:=пон.след
    КОН;
    пон:=СоздатьПонятие();
    пред.след:=пон
  КОН;
  пон.обл:=текОбласть;
  СПИСАТЬ(имя,пон.имя);
  ВОЗВРАТ пон
КОН Вставить;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ОткрытьОбласть-(имя-:ЦЕПЬ);
(*
 * Создает головное понятие для новой области видимости и
 * помещает его на вершину <текОбласть>.
 *)
УКАЗ
  текОбласть:=СоздатьОбласть(имя,текОбласть)
КОН ОткрытьОбласть;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ЗакрытьОбласть-;
УКАЗ
  текОбласть:=текОбласть.окробл
КОН ЗакрытьОбласть;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ЭтоПриёмник-(пон:Данные.ДкПонятию):КЛЮЧ;
(*
 * Цель:  определить, является ли понятие <пон> приёмником
 * Ответ: ВКЛ, если это так
 *)
УКАЗ
  ВОЗВРАТ (пон # ПУСТО) И (прПриёмник В пон.признаки)
КОН ЭтоПриёмник;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       УстОтдел-(имя-:Ядро.Имя);
УКАЗ
  вхотд[0]:=СоздатьОтдел(имя,Обмен.отдИмяФ,глаОбласть)
КОН УстОтдел;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Использовать-(опчИмя-,опчПуть-:ЦЕПЬ);
ПЕР
  метка,ц,следномв,номв:ЦЕЛ;
     отд,
  испотд :Данные.ДкОтделу;
  пон,
 было,
 пред :Данные.ДкПонятию;
  обл :Данные.ДкОбласти;
  вид :Данные.ДкВиду;

  вхИмя:Ядро.Имя;
  вхИмяФ:ЦЕПЬ[250];
    (* используемый отдел (вхотдисп[0]) и входные отделы используемого отдела *)
  чвхотдисп,нвхотдисп:ЦЕЛ;

  вхотдисп:РЯД Настрой.ВсегоОтделов ИЗ Данные.ДкОтделу;

  виды:РЯД Настрой.ВсегоВидов ИЗ Данные.ДкВиду;

  урПриёмников,урСвойств:ЦЕЛ;
  послПриёмник,послСвойство:РЯД 6 ИЗ Данные.ДкПонятию;

 (*................................................подЗАДАЧА...*)
  ЗАДАЧА Перевернуть(
                     пон:Данные.ДкПонятию

                    ):Данные.ДкПонятию;
                               (* Цель:  перевернуть список с началом в <пон>
                                * Ответ: новое начало списка *)
  ПЕР
    нач,след:Данные.ДкПонятию;
  УКАЗ
    нач:=ПУСТО;
    ПОКА пон # ПУСТО ВЫП
      след:=пон.след;
      пон.след:=нач;
      нач:=пон;
      пон:=след
    КОН;
    ВОЗВРАТ нач
  КОН Перевернуть;

УКАЗ
  ЕСЛИ опчИмя = "ОБХОД" ТО
    пон:=Вставить(опчИмя);
    пон.родп:=пОтдел;
    пон.первпон:=обхОбласть.первпон;
    пон.вид:=нетвид;
    ВОЗВРАТ
  КОН;
                                                              (* приготовимся *)
  следномв:=вНабор+1;
  урПриёмников:=-1;
  урСвойств:=-1;

  виды[вНеопр] :=неопрвид;   виды[вЯчейка]:=оячейкавид;
  виды[вКлюч]  :=ключвид;    виды[вЗнак]  :=знаквид;
  виды[вЦел8]  :=цел8вид;    виды[вЦел16] :=цел16вид;
  виды[вЦел32] :=цел32вид;   виды[вЦел64] :=цел64вид;
  виды[вВещ32] :=вещ32вид;   виды[вВещ64] :=вещ64вид;
  виды[вМнож]  :=множвид;    виды[вПусто] :=пустовид;
  виды[вНет]   :=нетвид;     виды[вДоступ]:=одоствид;
  виды[вОЯчейки]:=оячейкивид;
  Обмен.ОпчОткрыть(опчИмя,опчПуть);
                                (* читаем входные отделы используемого отдела *)
  испотд:=ПУСТО;
  Обмен.ОпчЦел(чвхотдисп);
  ОТ нвхотдисп:=0 ДО чвхотдисп-1 ВЫП
    Обмен.ОпчЦепь(вхИмя);
    Обмен.ОпчЦепь(вхИмяФ);
                                        (* ищем отдел с таким же именем файла *)
    ц:=0;
    ПОКА (ц < чвхотд) И (вхИмя # вхотд[ц].имя) ВЫП
      УВЕЛИЧИТЬ(ц)
    КОН;
    ЕСЛИ ц < чвхотд ТО (* такой отдел у нас уже есть *)
      ЕСЛИ ц = 0 ТО (* да это же наш отдел *)
        Ошибка.Отметить(Ошибка.ПЕРЕКРЕСТНОЕ_ИСПОЛЬЗОВАНИЕ)
      АЕСЛИ вхИмяФ # вхотд[ц].имяФ^ ТО
        Ошибка.ОтметитьИмя(Ошибка.ОТДЕЛ_ИЗ_РАЗНЫХ_ФАЙЛОВ,вхотд[ц].имяФ^)
      КОН;
      отд:=вхотд[ц]
    ИНАЧЕ
      ЕСЛИ чвхотд >= Настрой.ВсегоОтделов ТО
        Ошибка.Отметить(Ошибка.МНОГО_ОТДЕЛОВ)
      КОН;
      отд:=СоздатьОтдел(вхИмя,вхИмяФ,глаОбласть);
      ЕСЛИ нвхотдисп = 0 ТО (* это используемый отдел
                             * и его необходимо поместить в конец <вхотд>, поэтому пока запомним
                             * этот отдел в промежуточной переменной <испотд> *)
        испотд:=отд
      ИНАЧЕ
        отд.нвхотд:=чвхотд;
        вхотд[чвхотд]:=отд;
        УВЕЛИЧИТЬ(чвхотд)
      КОН
    КОН;
    вхотдисп[нвхотдисп]:=отд
  КОН;
  ЕСЛИ испотд # ПУСТО ТО
    испотд.нвхотд:=чвхотд;
    вхотд[чвхотд]:=испотд;
    УВЕЛИЧИТЬ(чвхотд)
  КОН;
                                                   (* читаем данные с метками *)
  ПОКА НЕ Обмен.ОпчКонец() ВЫП
    Обмен.ОпчЦел(метка);
    ВЫБРАТЬ метка ИЗ
    | мПост,мВид,мПер,мЗадача: (* понятия *)
        пон:=СоздатьПонятие();
        Обмен.ОпчЦел(номв);
        вид:=виды[номв];
        пон.вид:=вид;
        нвхотдисп:=0;
        ВЫБРАТЬ метка ИЗ
        | мВид:
            пон.родп:=пВид;
            ЕСЛИ вид.понвида = ПУСТО ТО 
              вид.понвида:=пон 
            КОН;
            Обмен.ОпчМнож(пон.признаки);
            Обмен.ОпчЦел(нвхотдисп)
        | мПост:
            пон.родп:=пПост;
            ЕСЛИ вид.родв = вЦепь ТО
              Обмен.ОпчПЦепь(пон.достцепь)
            ИНАЧЕ
              Обмен.ОпчЦел(пон.адр)
            КОН
        | мПер:
            пон.родп:=пПер;
            Обмен.ОпчМнож(пон.признаки);
            Обмен.ОпчЦел(пон.адр)
        | мЗадача:
            пон.родп:=пЗадача;
            Обмен.ОпчМнож(пон.признаки);
            пон.первпон:=Перевернуть(послПриёмник[урПриёмников]);
            УМЕНЬШИТЬ(урПриёмников)
        КОН;
        Обмен.ОпчЦепь(пон.имя);
        обл:=вхотдисп[нвхотдисп].обл;
        пон.обл:=обл;
        (* добавляем в конец области видимости новое понятие
         * или исправляем вид *)
        было:=обл.первпон;
        ЕСЛИ было = ПУСТО ТО
          обл.первпон:=пон
        ИНАЧЕ
          КОЛЬЦО
            ЕСЛИ было = ПУСТО ТО
              (* добавляем в конец новое понятие *)
              пред.след:=пон;
              ВЫХОД
            АЕСЛИ было.имя = пон.имя ТО
              ЕСЛИ пон.родп = пВид ТО
                (* этот вид уже был заведён через другой отдел *)
                виды[номв]:=было.вид
              КОН;
              ВЫХОД
            КОН;
            пред:=было;
            было:=было.след
          КОН
        КОН
    | мНабор,мРяд,мОРяд,мЦепь,мОЦепь,мДоступ,мБегунок,мВидЗадача: (* виды *)
        вид:=СоздатьВид(вНеопр);
        Обмен.ОпчЦел(номв);
        вид.овид:=виды[номв];
        Обмен.ОпчЦел(нвхотдисп); (* входной номер отдела в исп. отделе *)
        вид.нвхотд:=вхотдисп[нвхотдисп].нвхотд;
        ВЫБРАТЬ метка ИЗ
        | мДоступ:
            вид.родв:=вДоступ;
            вид.размер:=Настрой.рДоступ
        | мВидЗадача:
            вид.родв:=вЗадача;
            вид.размер:=Настрой.рЗадача;
            вид.первпон:=Перевернуть(послПриёмник[урПриёмников]);
            УМЕНЬШИТЬ(урПриёмников)
        | мБегунок:
            вид.родв:=вБегунок;
            вид.размер:=Настрой.рБегунок;
            Обмен.ОпчЦел(вид.шаг)
        | мРяд:
            вид.родв:=вРяд;
            Обмен.ОпчЦел(вид.размер)
        | мОРяд:
            вид.родв:=вОРяд;
            Обмен.ОпчЦел(вид.размер)
        | мЦепь:
            вид.родв:=вЦепь;
            Обмен.ОпчЦел(вид.размер)
        | мОЦепь:
            вид.родв:=вОЦепь;
            Обмен.ОпчЦел(вид.размер)
        | мНабор:
            вид.родв:=вНабор;
            Обмен.ОпчЦел(вид.размер);
            вид.первпон:=Перевернуть(послСвойство[урСвойств]);
            УМЕНЬШИТЬ(урСвойств);
            ЕСЛИ вид.овид = нетвид ТО
              вид.овид:=неопрвид
            КОН;
            Обмен.ОпчЦел(вид.ов)
        КОН;
        виды[следномв]:=вид;
        УВЕЛИЧИТЬ(следномв)
    | мПриёмники: (* начало списка приёмников *)
        ЕСЛИ урПриёмников >= 5 ТО
          Ошибка.Отметить(Ошибка.МНОГО_ВЛОЖЕННЫХ)
        КОН;
        УВЕЛИЧИТЬ(урПриёмников);
        послПриёмник[урПриёмников]:=ПУСТО
    | мПриёмник,мСсылка: (* приёмник *)
        пон:=СоздатьПонятие();
        ЕСЛИ метка = мПриёмник ТО
          пон.родп:=пПер
        ИНАЧЕ
          пон.родп:=пСсылка
        КОН;
        Обмен.ОпчМнож(пон.признаки);
        Обмен.ОпчЦел(номв);
        пон.вид:=виды[номв];
        Обмен.ОпчЦел(пон.адр);
        Обмен.ОпчЦепь(пон.имя);
        пон.след:=послПриёмник[урПриёмников];
        послПриёмник[урПриёмников]:=пон
    | мСвойства: (* начало списка свойств набора *)  
        ЕСЛИ урСвойств >= 5 ТО
          Ошибка.Отметить(Ошибка.МНОГО_ВЛОЖЕННЫХ)
        КОН;
        УВЕЛИЧИТЬ(урСвойств);
        послСвойство[урСвойств]:=ПУСТО
    | мСвойство:
        пон:=СоздатьПонятие();
        пон.родп:=пСвойство;
        Обмен.ОпчМнож(пон.признаки);
        Обмен.ОпчЦел(номв);
        пон.вид:=виды[номв];
        Обмен.ОпчЦел(пон.адр);
        Обмен.ОпчЦепь(пон.имя);
        пон.след:=послСвойство[урСвойств];
        послСвойство[урСвойств]:=пон
    | мСкрепка: (* ссылка на доступ *)
        Обмен.ОпчЦел(номв);
        вид:=виды[номв];
        Обмен.ОпчЦел(номв);
        ЕСЛИ вид.овид = неопрвид ТО
          вид.овид:=виды[номв]
        КОН
    КОН
  КОН;
  Обмен.ОпчЗакрыть;
  пон:=Вставить(опчИмя);
  пон.родп:=пОтдел;
  пон.первпон:=вхотдисп[0].обл.первпон;
  пон.адр:=вхотдисп[0].нвхотд;
  пон.вид:=нетвид
КОН Использовать;


(*-оооооооооооооо- опережающие определения/заготовки задач -ооооооооооооооооо-*)

ЗАДАЧА ^ВыводВида(видД:Данные.ДкВиду);
ЗАДАЧА ^ВыводПонятия(пон:Данные.ДкПонятию);


(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ВыводПриёмников(пон:Данные.ДкПонятию);
УКАЗ
  Обмен.ОпзЦел(мПриёмники);
  ПОКА ЭтоПриёмник(пон) ВЫП
    ВыводВида(пон.вид);
    ЕСЛИ пон.родп = пПер ТО
      Обмен.ОпзЦел(мПриёмник)
    ИНАЧЕ
      Обмен.ОпзЦел(мСсылка)
    КОН;
    Обмен.ОпзМнож(пон.признаки);
    Обмен.ОпзЦел(пон.вид.номв);
    Обмен.ОпзЦел(пон.адр);
    Обмен.ОпзЦепь(пон.имя);
    пон:=пон.след
  КОН
КОН ВыводПриёмников;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ВыводСвойств(пон:Данные.ДкПонятию);
УКАЗ
  Обмен.ОпзЦел(мСвойства);
  ПОКА пон # ПУСТО ВЫП
    ВыводВида(пон.вид);
    Обмен.ОпзЦел(мСвойство);
    Обмен.ОпзМнож(пон.признаки);
    Обмен.ОпзЦел(пон.вид.номв);
    Обмен.ОпзЦел(пон.адр);
    Обмен.ОпзЦепь(пон.имя);
    пон:=пон.след
  КОН
КОН ВыводСвойств;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ВыводВида(видД:Данные.ДкВиду);
ПЕР
  нвхотд,номвидо:ЦЕЛ;
                овид :Данные.ДкВиду;
УКАЗ
  ЕСЛИ
          видД.номв > 0
  ТО                       (* обработан *)
    ВОЗВРАТ
  КОН;
  нвхотд:=видД.нвхотд;
    овид:=видД.овид;
  ВЫБРАТЬ видД.родв ИЗ
  | вДоступ:
      Обмен.ОпзЦел(мДоступ);
      ЕСЛИ овид.номв > 0 ТО
        Обмен.ОпзЦел(овид.номв)
      ИНАЧЕ
        Обмен.ОпзЦел(вНеопр);

        ЧэргаСлеД.ДобавитьНовЗвеноВконСписка(доступыКнеоВидам,видД)
      КОН;
      Обмен.ОпзЦел(нвхотд)
  | вЗадача:
      ВыводВида(овид);
      ВыводПриёмников(видД.первпон);
      Обмен.ОпзЦел(мВидЗадача);
      Обмен.ОпзЦел(овид.номв);
      Обмен.ОпзЦел(нвхотд)
  | вБегунок:
      Обмен.ОпзЦел(мБегунок);
      Обмен.ОпзЦел(овид.номв);
      Обмен.ОпзЦел(нвхотд);
      Обмен.ОпзЦел(видД.шаг)
  | вРяд:
      ВыводВида(овид);
      Обмен.ОпзЦел(мРяд);
      Обмен.ОпзЦел(овид.номв);
      Обмен.ОпзЦел(нвхотд);
      Обмен.ОпзЦел(видД.размер)
  | вОРяд:
      ВыводВида(овид);
      Обмен.ОпзЦел(мОРяд);
      Обмен.ОпзЦел(овид.номв);
      Обмен.ОпзЦел(нвхотд);
      Обмен.ОпзЦел(видД.размер)
  | вЦепь:
      Обмен.ОпзЦел(мЦепь);
      Обмен.ОпзЦел(овид.номв);
      Обмен.ОпзЦел(нвхотд);
      Обмен.ОпзЦел(видД.размер)
  | вОЦепь:
      Обмен.ОпзЦел(мОЦепь);
      Обмен.ОпзЦел(овид.номв);
      Обмен.ОпзЦел(нвхотд);
      Обмен.ОпзЦел(видД.размер)
  | вНабор:
      ЕСЛИ
           овид = неопрвид
      ТО
        номвидо:=вНет
      ИНАЧЕ
        ВыводВида(овид);
        номвидо:=овид.номв
      КОН;
      ВыводСвойств(видД.первпон);

        Обмен.ОпзЦел(мНабор);
        Обмен.ОпзЦел(номвидо);
        Обмен.ОпзЦел(нвхотд);
        Обмен.ОпзЦел(видД.размер);
      ЕСЛИ
           Настрой.отдВид = Настрой.описание
      ТО
        Обмен.ОпзЦел(0)
      ИНАЧЕ
        Обмен.ОпзЦел(видД.ов)
      КОН
  КОН;
  видД.номв:=следномв;
  УВЕЛИЧИТЬ(следномв);
  ЕСЛИ
       следномв >= Настрой.ВсегоВидов
  ТО
    Ошибка.Отметить(Ошибка.МНОГО_ОБЩЕДОСТУПНЫХ)
  КОН;
  ЕСЛИ
       видД.понвида # ПУСТО
  ТО                                (* это именованный вид *)
    ВыводПонятия(видД.понвида)
  КОН
КОН ВыводВида;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ВыводПонятия(пон:Данные.ДкПонятию);
УКАЗ
  ВЫБРАТЬ пон.родп ИЗ
    пВид:
      ВыводВида(пон.вид);
      Обмен.ОпзЦел(мВид);
      Обмен.ОпзЦел(пон.вид.номв);
      Обмен.ОпзМнож(пон.признаки);
      ЕСЛИ
           пон.вид.понвида # пон
      ТО                                    (* "ВИД в2=О1.в1;" *)
        Обмен.ОпзЦел(0) (* нвхотд для в2 *)
      ИНАЧЕ
        Обмен.ОпзЦел(пон.вид.нвхотд)        (* нвхотд для в1 *)
      КОН;
      Обмен.ОпзЦепь(пон.имя)
  | пПер:
      ВыводВида(пон.вид);
      Обмен.ОпзЦел(мПер);
      Обмен.ОпзЦел(пон.вид.номв);
      Обмен.ОпзМнож(пон.признаки);
      Обмен.ОпзЦел(пон.адр);
      Обмен.ОпзЦепь(пон.имя)
  | пПост:
      Обмен.ОпзЦел(мПост);
      ЕСЛИ пон.вид.родв = вЦепь ТО
        ВыводВида(пон.вид);
        Обмен.ОпзПЦепь(пон.достцепь^)
      ИНАЧЕ
        Обмен.ОпзЦел(пон.вид.номв);
        Обмен.ОпзЦел(пон.адр)
      КОН;
      Обмен.ОпзЦепь(пон.имя)
  | пЗадача:
      ВыводВида(пон.вид);
      ВыводПриёмников(пон.первпон);
      Обмен.ОпзЦел(мЗадача);
      Обмен.ОпзЦел(пон.вид.номв);
      Обмен.ОпзМнож(пон.признаки);
      Обмен.ОпзЦепь(пон.имя)
  | пОтдел:
  КОН
КОН ВыводПонятия;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ВыводПонятий(пон:Данные.ДкПонятию);
УКАЗ
  ПОКА пон # ПУСТО ВЫП
    ЕСЛИ прОбщедоступная В пон.признаки ТО
      пон.признаки:=пон.признаки-{прТекущегоОтдела};
      ВыводПонятия(пон)
    КОН;
    пон:=пон.след
  КОН
КОН ВыводПонятий;

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

    ВыводВида(видД.овид);
    Обмен.ОпзЦел(мСкрепка);
    Обмен.ОпзЦел(видД.номв);
    Обмен.ОпзЦел(видД.овид.номв);

          звеноД:=звеноД.слеД
  КОН;
  ЧэргаСлеД.ОчиститьСписок(доступыКнеоВидам)
КОН ВыводНеоДост;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ВыводИспОтделов;
ПЕР
     но:ЦЕЛ;
УКАЗ
    Обмен.ОпзЦел(чвхотд);
  ОТ но:=0 ДО чвхотд-1 ВЫП
    Обмен.ОпзЦепь(вхотд[но].имя);
    Обмен.ОпзЦепь(вхотд[но].имяФ^)
  КОН
КОН ВыводИспОтделов;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Сохранить-;
УКАЗ
  Обмен.ОпзОткрыть;
  ВыводИспОтделов;
  следномв:=вНабор+1;
  ВыводПонятий(текОбласть.первпон);
  ВыводНеоДост;
  Обмен.ОпзЗакрыть
КОН Сохранить;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ПодготовитьВстрВид(вид+ :Данные.ДкВиду;
                          родв :ЦЕЛ);
УКАЗ
  СОЗДАТЬ(вид);
          вид.родв:=родв;
          вид.номв:=родв;
          вид.размер:=1
КОН ПодготовитьВстрВид;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ДобКлючПост(    имя-:ЦЕПЬ;
                   значение:ЦЕЛ);
ПЕР
  пон:Данные.ДкПонятию;
УКАЗ 
  пон:=Вставить(имя);
  пон.родп:=пПост; 
  пон.вид:=ключвид; 
  пон.адр:=значение
КОН ДобКлючПост;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ДобВстрВид( имя-:ЦЕПЬ;
                  родв,
                размер :ЦЕЛ;
                   вид+:Данные.ДкВиду);
ПЕР
  пон:Данные.ДкПонятию;
УКАЗ 
  пон:=Вставить(имя);

   СОЗДАТЬ(вид);
           вид.родв:=родв;
           вид.понвида:=пон;
           вид.размер:=размер;
           вид.номв:=родв;
  пон.родп:=пВид;
  пон.признаки:={прОбщедоступная};
  пон.вид:=вид
КОН ДобВстрВид;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ДобСиноним(имя-:ЦЕПЬ;
                  вид :Данные.ДкВиду);
ПЕР
  пон:Данные.ДкПонятию;
УКАЗ
  пон:=Вставить(имя);
  пон.родп:=пВид;
  пон.вид:=вид;
  пон.признаки:={прОбщедоступная}
КОН ДобСиноним;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ДобВстрЗадачу(имя-:ЦЕПЬ;
                     ном:ЦЕЛ);
ПЕР
  пон:Данные.ДкПонятию;
УКАЗ 
  пон:=Вставить(имя);
  пон.родп:=пВстрЗадача; 
  пон.вид:=нетвид; 
  пон.адр:=ном
КОН ДобВстрЗадачу;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Обновить-;
УКАЗ
  ПОКА чвхотд > 0 ВЫП
    УМЕНЬШИТЬ(чвхотд);
    вхотд[чвхотд]:=ПУСТО
  КОН;
  ЧэргаСлеД.ОчиститьСписок(доступыКнеоВидам);
  чвхотд:=1
КОН Обновить;

(*-ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss-*)
УКАЗ
  уровень:=0;
  быстрая:=ОТКЛ;
  чвхотд:=0;
  поДоступу:=СоздатьПонятие();
  ПодготовитьВстрВид(неопрвид,вНеопр);
  неопрвид.овид:=неопрвид;
  ПодготовитьВстрВид(нетвид,  вНет);
  ПодготовитьВстрВид(пустовид,вПусто);
  текОбласть:=ПУСТО;
                                           (* подготовка области отдела ОБХОД *)
  ОткрытьОбласть("ОБХОД");
  ДобВстрВид("Доступ",вДоступ, Настрой.рДоступ,одоствид);
  ДобВстрВид("Ячейка",вЯчейка, Настрой.рЯчейка,оячейкавид);
  ДобВстрВид("Ячейки",вОЯчейки,1,              оячейкивид);
  оячейкивид.овид:=оячейкавид;
  ДобВстрВид("Цел8",  вЦел8,   Настрой.рЦел8,  цел8вид );
  ДобВстрВид("Цел16", вЦел16,  Настрой.рЦел16, цел16вид);
  ДобВстрВид("Цел32", вЦел32,  Настрой.рЦел32, цел32вид);
  ДобВстрВид("Вещ32", вВещ32,  Настрой.рВещ32, вещ32вид);
(*                                                         в Малом ПГ нету этих видов с 64 разрядами
  ДобВстрВид("Цел64", вЦел64, Настрой.рЦел64, цел64вид);
  ДобВстрВид("Вещ64", вВещ64, Настрой.рВещ64, вещ64вид);
*)
  ДобВстрЗадачу("ПолучитьАдрес",зПолучитьАдрес);
  ДобВстрЗадачу("ИзПамяти",     зИзПамяти);
  ДобВстрЗадачу("ВПамять",      зВПамять);
  ДобВстрЗадачу("Значение",     зЗначение);
  ДобВстрЗадачу("Образ",        зОбраз);
  ДобВстрЗадачу("Узк",          зОУзк);
  ДобСиноним("Адрес",цел32вид);
  обхОбласть:=текОбласть;
  ЗакрытьОбласть;
                                             (* подготовка встроенной области *)
  ОткрытьОбласть("");
  ДобВстрВид("КЛЮЧ",  вКлюч,Настрой.рКлюч,ключвид);
  ДобВстрВид("ЗНАК",  вЗнак,Настрой.рЗнак,знаквид);
  ДобВстрВид("МНОЖ",  вМнож,Настрой.рМнож,множвид);
  ДобСиноним("ЯЧЦЕЛ", цел8вид);
  ДобСиноним("УЗКЦЕЛ",цел16вид);
  ДобСиноним("ЦЕЛ"   ,цел32вид);
  ДобСиноним("ШИРЦЕЛ",цел32вид);
  ДобСиноним("ВЕЩ"   ,вещ32вид);
  ДобСиноним("ШИРВЕЩ",вещ32вид);
  ДобКлючПост("ОТКЛ",0);
  ДобКлючПост("ВКЛ", 1);
  ДобВстрЗадачу("ВЗНАК",    зВЗнак);
  ДобВстрЗадачу("ВЦЕЛ",     зВЦел);
  ДобВстрЗадачу("ВШИРЦЕЛ",  зВШирЦел);
  ДобВстрЗадачу("ДЛИНА",    зДлина);
  ДобВстрЗадачу("ЗАДАНО",   зЗадано);
  ДобВстрЗадачу("МАКС",     зМакс);
  ДобВстрЗадачу("МОДУЛЬ",   зМодуль);
  ДобВстрЗадачу("МИН",      зМин);
  ДобВстрЗадачу("ОБНУЛИТЬ", зОбнулить);
  ДобВстрЗадачу("ЦЕЛЧАСТЬ", зЦелЧасть);
  ДобВстрЗадачу("ЧЕТ",      зЧет);
  ДобВстрЗадачу("ПОСТАВИТЬ",зПоставить);
  ДобВстрЗадачу("ПРОВЕРИТЬ",зПроверить);
  ДобВстрЗадачу("СМЕСТИТЬ", зСместить);
  ДобВстрЗадачу("РАЗМЕР",   зРазмер);
  ДобВстрЗадачу("СОЗДАТЬ",  зСоздать);
  ДобВстрЗадачу("СПИСАТЬ",  зСписать);
  ДобВстрЗадачу("СТОП",     зСтоп);
  ДобВстрЗадачу("УЗК",      зУзк);
  ДобВстрЗадачу("УВЕЛИЧИТЬ",зУвеличить);
  ДобВстрЗадачу("УМЕНЬШИТЬ",зУменьшить);
  глаОбласть:=текОбласть;
КОН Данные.
