(*~\Глагол\ПриложенияLink\ПГ\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                              ОТДЕЛ CV;
(*============================================================================*)
(* НАЗНАЧЕНИЕ: запись в COFF файл отладочных данных (ОД)                      *)
(*             совместимых с CodeView (CV) 5-й версии                         *)
(*============================================================================*)

ИСПОЛЬЗУЕТ 
        (*  \Глагол\              *)
 оЦепи    ИЗ "..\..\Отделы\Иное\",
ЧэргаСлеД ИЗ "..\..\Отделы\Иное\",

  НП,ФО,ВД,Coff;

ПОСТ                           (*--- локальные ПОСТоянные ---*)
  ПРЕОБРАЗОВАТЕЛЬ="Глагол";
  КОДФОРМАТА=2;            (* CV 5-й версии                                   *)
  КОДЯЗЫКА=4;              (* 1=C++, 4=PASCAL                                 *)
  ВЫРАВНИВАНИЕ=4;          (* выравнивание записей в .debug$T секции          *)
  ВсегоТиповОД=100;        (* наиб. уровень вложения типов отладочных записей *)
  ПЕРВЫЙОПРЕДТИП=1000H;    (* нач. номер нового определяемого вида            *)

             (* следующие постоянные взяты из файла CVIVFO.H:  *)
  ARRAY_INX_TYPE=0012H;    (* type value used for the type of array indices   *)
  S_COMPILE     =0001H;    (* Compile flags symbol                            *)
  S_UDT         =1003H;    (* User defined type                               *)
  S_END         =0006H;    (* Block, задача, "with" or thunk end              *)
  S_OBJNAME     =0009H;    (* path to object file name                        *)
  S_BPREL32     =1006H;    (* BP-relative                                     *)
  S_LDATA32     =1007H;    (* Module-local symbol                             *)
  S_GDATA32     =1008H;    (* Global data symbol                              *)
  S_LPROC32     =100AH;    (* Local задача start                              *)
  S_GPROC32     =100BH;    (* Global задача start                             *)
  LF_POINTER    =1002H;
  LF_ARRAY      =1003H;
  LF_CLASS      =1004H;
  LF_PROCEDURE  =1008H;
  LF_ARGLIST    =1201H;
  LF_FIELDLIST  =1203H;
  LF_DERIVED    =1400H;
  LF_MEMBER     =1405H;

                    (* Род понятий (нПонятие.родп). Из ВД. *)
  пОтдел     =0;
  пОбласть   =1;
  пВид       =2;
  пПост      =3;
  пПер       =4;
  пПрСсылки  =5;
  пЗадача    =6;
  пВстрЗадача=7;
  пСвойство  =8;
(*
  родп       | n адр   пост    след     область
  ============================================================================
  пОтдел     | 0                        верх    Отдел
  пОбласть   | 1 нстр                   первпер Область действия
  пВид       | 2                                Именованный вид
  пПост      | 3       val                      Постоянная
  пПер       | 4 адр           next             Переменная или приёмник значения
  пПрСсылки  | 5 vadr          next             Приемник переменной
  пЗадача    | 6 сно   sizes   firstpar область Задача
  пВстрЗадача| 7 fno   sizes                    Встроенная задача
  пСвойство  | 8 off           next             Свойство набора

  <сно> является номером в символьной таблице COFF (если <сно> <= 0, то это - адр для связки заготовок)
*)

                    (* Признаки понятия (нПонятие.признаки). Из ВД. *)
  прОбщедоступная=0;
  прНеизменяемая =1;
  прОбъявлена    =2;
  прВложенная    =3;
  прГоловная     =4;
  прПередаваемая =5;
(*
  прОбщедоступная- действует во всех отделах
  прНеизменяемая - только для чтения
  прОбъявлена    - для полностью объявленных задач
  прВложенная    - для вложенных задач
  прГоловная     - для задачи _Zapusk 
  прПередаваемая - для иноязычных приложений
*)

  (*                        Род видов (нВид.родв). Из ВД.
 Причём:
          вЯчейка <= вЦел8 <= вЗнак <= вЦел16 <= вЦел32 <= вЦел64.
   *)
  вНеопр  =0;
  вЯчейка =1;
  вКлюч   =2;
  вЗнак   =3;
  вЦел8   =4;
  вЦел16  =5;
  вЦел32  =6;
  вЦел64  =7;
  вВещ32  =8;
  вВещ64  =9;
  вМнож   =10;
  вПЦепь  =11;
  вПусто  =12;
  вНет    =13;
  вДоступ =14;
  вЗадача =15;
  вБегунок=16;
  вРяд    =17;
  вОРяд   =18;
  вНабор  =19;
  вКон    =20; (* вКон для ДВ. При изменении вКон нужно 3 преобразования с уборка:=ОТКЛ. *)
(*
  родв    | n          овид      след     вхнотд  адрОВ    текстп
  ===============================================================
  вНеопр  | 0
  вЯчейка | 1
  вКлюч   | 2
  вЗнак   | 3
  вЦел8   | 4
  вЦел16  | 5
  вЦел32  | 6
  вЦел64  | 7
  вВещ32  | 8
  вВещ64  | 9
  вМнож   | 10
  вПЦепь  | 11
  вПусто  | 12
  вНет    | 13
  вДоступ | 14         PBaseTyp           вхнотд           текстп
  вЗадача | 15         ResTyp    params   вхнотд           текстп
  вБегунок| 16 шаг     основание          вхнотд  адрОВ    текстп
  вРяд    | 17 nofel   ElemTyp            вхнотд           текстп
  вОРяд   | 18 dim     ElemTyp            вхнотд  lenoff   текстп
  вНабор  | 19         RBaseTyp  fields   вхнотд  адрОВ    текстп
*)

       (* число ячеек, которые занимает код типа отладочной записи в CV файле *)
  РАЗМЕРТИПОД=4;

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

ПЕР                          (* локальные ПЕРеменные *)
  началоСекции:ЦЕЛ;
     следТипОД:ЦЕЛ;
       добавок:ЦЕЛ;
                                (* ряд из наборов *)
  неоТипы:РЯД ВсегоТиповОД ИЗ нНеоТип; (* заготовка типОД = -номер-1 *)


(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА НовыйТипОД():ЦЕЛ;
(* Возвращает незанятую заготовку типОД *)
ПЕР
  номер:ЦЕЛ;
УКАЗ
  номер:=0;
  ПОКА неоТипы[номер].занят ВЫП
    УВЕЛИЧИТЬ(номер);
    ПРОВЕРИТЬ(номер < ВсегоТиповОД)
  КОН;
  неоТипы[номер].занят:=ВКЛ;
  ЧэргаСлеД.ОчиститьСписок(неоТипы[номер].места);
  ВОЗВРАТ -номер-1 (* значение должно быть < 0 *)
КОН НовыйТипОД;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ЗапомнитьПозТипОД(фпоз,типОД:ЦЕЛ);
(* Запоминает в списке мест позицию <фпоз> упоминания <типОД> *)
ПЕР
  номер:ЦЕЛ;
  место:ДкМесту;
УКАЗ
  номер:=-типОД-1;
  ПРОВЕРИТЬ(неоТипы[номер].занят);
  СОЗДАТЬ(место);
  место.фпоз:=фпоз;

  ЧэргаСлеД.ДобавитьНовЗвеноВконСписка(неоТипы[номер].места,место)
КОН ЗапомнитьПозТипОД;

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

    ФО.КодЗакрепить4(место.фпоз,нов);

    звеноД:=звеноД.слеД
  КОН;

  неоТипы[номер].занят:=ОТКЛ;
  ЧэргаСлеД.ОчиститьСписок(неоТипы[номер].места)
КОН ИсправитьТипОД;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ДлинаТекста(цепь-:ЦЕПЬ):ЦЕЛ;
(* вычисление длины текста в кодировке UTF8 *)
ПЕР
  длЯч,поз,ц:ЦЕЛ;
УКАЗ
  длЯч:=0;
  ОТ поз:=0 ДО ДЛИНА(цепь)-1 ВЫП
          ц:=ВЦЕЛ(цепь[поз]);
    ЕСЛИ  ц < 80H ТО
      УВЕЛИЧИТЬ(длЯч,1)
    АЕСЛИ ц < 800H ТО
      УВЕЛИЧИТЬ(длЯч,2)
    ИНАЧЕ
      УВЕЛИЧИТЬ(длЯч,3)
    КОН
  КОН;
  ВОЗВРАТ длЯч
КОН ДлинаТекста;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ЗаписьТекста(цепь-:ЦЕПЬ);
(* запись текста в UTF8 кодировке с предваряющей длиной *)
ПЕР
  длЗн,длЯч,поз,ц:ЦЕЛ;
УКАЗ
                         (* расчёт и запись длины *)
  длЗн:=ДЛИНА(цепь);
  длЯч:=0;
  ОТ поз:=0 ДО длЗн-1 ВЫП
          ц:=ВЦЕЛ(цепь[поз]);
    ЕСЛИ
          ц < 80H
    ТО
      УВЕЛИЧИТЬ(длЯч,1)
    АЕСЛИ
          ц < 800H
    ТО
      УВЕЛИЧИТЬ(длЯч,2)
    ИНАЧЕ
      УВЕЛИЧИТЬ(длЯч,3)
    КОН
  КОН;
  ФО.КодЦел1(длЯч);
                         (* запись цепочки *)
  ОТ поз:=0 ДО длЗн-1 ВЫП
          ц:=ВЦЕЛ(цепь[поз]);
    ЕСЛИ
          ц < 80H
    ТО
      ФО.КодЦел1(ц)
    АЕСЛИ
          ц < 800H
    ТО
      ФО.КодЦел1(0C0H + ( ц ДЕЛИТЬ  40H));
      ФО.КодЦел1(080H + ( ц ОСТАТОК 40H))
    ИНАЧЕ
      ФО.КодЦел1(0E0H + ( ц ДЕЛИТЬ  1000H));
      ФО.КодЦел1(080H + ((ц ДЕЛИТЬ  40H) ОСТАТОК 40H));
      ФО.КодЦел1(080H + ( ц ОСТАТОК 40H))
    КОН
  КОН
КОН ЗаписьТекста;


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

                                    (* Присваивание и запись CV типов *)
ЗАДАЧА ^ТипВид(вид:ВД.ДкВиду);
ЗАДАЧА ^ТипПонятия(пон:ВД.ДкПонятию);
ЗАДАЧА ^ТипВидЗадач(вид:ВД.ДкВиду);

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТипНачало(длина:ЦЕЛ):ЦЕЛ;
ПЕР
  типОД:ЦЕЛ;
УКАЗ
  типОД:=следТипОД;
  УВЕЛИЧИТЬ(следТипОД);
  добавок:=(-длина-2) ОСТАТОК ВЫРАВНИВАНИЕ;
  ФО.КодЦел2(длина+добавок);
  ВОЗВРАТ типОД
КОН ТипНачало;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТипКонец;
ПЕР
  ц,pad:ЦЕЛ;
УКАЗ
  pad:=00F0H+добавок;
  ОТ ц:=1 ДО добавок ВЫП
    ФО.КодЦел1(pad);
    УМЕНЬШИТЬ(pad)
  КОН
КОН ТипКонец;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТипТипОД(типОД:ЦЕЛ);
УКАЗ
  ПРОВЕРИТЬ(типОД # 0);
                               (* записываем заготовку или настоящее значение *)
  ЕСЛИ
       типОД < 0
  ТО
    ЗапомнитьПозТипОД(ФО.КодПозиция(),типОД);
    ФО.КодЦел4(0)
  ИНАЧЕ
    ФО.КодЦел4(типОД)
  КОН
КОН ТипТипОД;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТипДоступ(вид:ВД.ДкВиду);
ПЕР
  типОДо:ЦЕЛ;
УКАЗ
  ТипВид(вид.овид);
  типОДо:=вид.овид.типОД;
  ЕСЛИ
       (типОДо > 0) И (типОДо < 0100H)
  ТО
    вид.типОД:=типОДо+0400H (* доступ к встр. видам *)
  ИНАЧЕ
    вид.типОД:=ТипНачало(6+РАЗМЕРТИПОД);
    ФО.КодЦел2(LF_POINTER);
    ТипТипОД(типОДо);
    ФО.КодЦел4(000AH); 
    ТипКонец
  КОН;
КОН ТипДоступ;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ДлинаТипСвойство(имя-:ЦЕПЬ):ЦЕЛ;
ПЕР
  размер:ЦЕЛ;
УКАЗ
  размер:=10+РАЗМЕРТИПОД+ДлинаТекста(имя)+1;
  УВЕЛИЧИТЬ(размер,(-размер) ОСТАТОК ВЫРАВНИВАНИЕ);
  ВОЗВРАТ размер
КОН ДлинаТипСвойство;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТипСвойство(смещение:ЦЕЛ;
                      типОД:ЦЕЛ; имя-:ЦЕПЬ);
ПЕР
  pad:ЦЕЛ;
УКАЗ
  ФО.КодЦел2(LF_MEMBER);
  ФО.КодЦел2(3);      (* member attribute bit field: public access *)
  ТипТипОД(типОД);
  ФО.КодЦел2(08004H); (* unsigned long numeric leaf *)
  ФО.КодЦел4(смещение);
  ЗаписьТекста(имя);
  pad:=(-ДлинаТекста(имя)-1-10-РАЗМЕРТИПОД) ОСТАТОК ВЫРАВНИВАНИЕ;
  ПОКА
       pad > 0
  ВЫП
    ФО.КодЦел1(00F0H+pad);
    УМЕНЬШИТЬ(pad)
  КОН
КОН ТипСвойство;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТипРасширение(типОД:ЦЕЛ);
УКАЗ
  ФО.КодЦел2(LF_DERIVED);
  ФО.КодЦел2(3);          (* member attribute bit field: public access *)
  ТипТипОД(типОД);
  ФО.КодЦел2(0);
  ФО.КодЦел2(0F1F2H)      (* pad *)
КОН ТипРасширение;

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

  типОД:=ТипНачало(размер);
  ФО.КодЦел2(LF_FIELDLIST);
  ЕСЛИ
       вид.овид # ВД.неопрвид
  ТО 
    ТипРасширение(вид.овид.типОД) 
  КОН;
  пон:=вид.след;
  ПОКА
       пон # ПУСТО
  ВЫП
    ТипСвойство(пон.адр,пон.вид.типОД,пон.имя);
    пон:=пон.след
  КОН;
  ТипКонец
КОН ТипСвойства;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТипНабор(вид:ВД.ДкВиду);
ПЕР
           имя:НП.Имя;
  fieldListInx:ЦЕЛ;
       свойств:ЦЕЛ;

 (*...............................подЗадача...*)
  ЗАДАЧА ВидыСвойств(вид:ВД.ДкВиду);
  ПЕР
    пон:ВД.ДкПонятию;
  УКАЗ
    ЕСЛИ
         вид.овид # ВД.неопрвид
    ТО 
      УВЕЛИЧИТЬ(свойств);
      ТипВид(вид.овид) 
    КОН;
         пон:=вид.след;
    ПОКА
         пон # ПУСТО
    ВЫП
      УВЕЛИЧИТЬ(свойств);
      ТипВид(пон.вид);
      пон:=пон.след
    КОН
  КОН ВидыСвойств;

УКАЗ
  ЕСЛИ
            вид.пон # ПУСТО
  ТО
    СПИСАТЬ(вид.пон.имя,имя)
  ИНАЧЕ
             (* безимянное определение вида (напр. при объявлении переменной) *)
    имя:="@ВИД"
  КОН;
  свойств:=0;
  ВидыСвойств(вид);
  ТипСвойства(вид,fieldListInx);
  вид.типОД:=ТипНачало(6+РАЗМЕРТИПОД+14+1+ДлинаТекста(имя));
  ФО.КодЦел2(LF_CLASS);
  ФО.КодЦел2(свойств); (* number of elements including classes and data members *)
  ФО.КодЦел2(0);       (* property bit field including:forward defs? nested classes? *)
  ТипТипОД(fieldListInx);
  ФО.КодЦел4(0);       (* should be set to 0 by compiler *)
  ФО.КодЦел4(0);       (* type index of virtual function table shape descriptor *)
  ФО.КодЦел2(8004H);   (* numeric leaf, unsigned long *)
  ФО.КодЦел4(вид.размер); (* размер данных набора *)
  ЗаписьТекста(имя);
  ТипКонец
КОН ТипНабор;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТипРяд(вид:ВД.ДкВиду);
УКАЗ
  ТипВид(вид.овид);
  вид.типОД:=ТипНачало(2+РАЗМЕРТИПОД+10+1);
  ФО.КодЦел2(LF_ARRAY);
  ТипТипОД(вид.овид.типОД);
  ФО.КодЦел4(ARRAY_INX_TYPE);
  ФО.КодЦел2(08004H); (* unsigned long numeric leaf *)
  ФО.КодЦел4(вид.размер);
  ФО.КодЦел1(0);
  ТипКонец
КОН ТипРяд;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТипОРяд(вид:ВД.ДкВиду);
ПОСТ
  ИМЯВИДА="ОРЯД";
  СВДЛИНА="РАЗМЕР";
  СВРЯД="ПЕРВ";
ПЕР
  fieldListInx:ЦЕЛ;
УКАЗ
  ТипВид(вид.овид);
  fieldListInx:=ТипНачало(2+ДлинаТипСвойство(СВДЛИНА)+ДлинаТипСвойство(СВРЯД));
  ФО.КодЦел2(LF_FIELDLIST);
  ТипСвойство(4,0075H,СВДЛИНА);
  ТипСвойство(8,вид.овид.типОД,СВРЯД);
  ТипКонец;
  вид.типОД:=ТипНачало(6+РАЗМЕРТИПОД*3+6+1+ДлинаТекста(ИМЯВИДА));
  ФО.КодЦел2(LF_CLASS);
  ФО.КодЦел2(2); (* CV:number of elements including methods and data members *)
  ФО.КодЦел2(0); (* property list including:forward defs? nested classes? *)
  ТипТипОД(fieldListInx);
  ФО.КодЦел4(0); (* CV:should be set to 0 by compiler *)
  ФО.КодЦел4(0); (* type index of virtual function table shape descriptor *)
  ФО.КодЦел2(8004H);  (* numeric leaf, unsigned long *)
  ФО.КодЦел4(8); (* размер набора для одномерного ряда *)
(*
  ФО.КодЦел4(4+4*вид.овид.размер);
*)
  ЗаписьТекста(ИМЯВИДА);
  ТипКонец
КОН ТипОРяд;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТипОРядПриемникаПер(пон:ВД.ДкПонятию);
ПОСТ
  ИМЯВИДА="ОРЯД";
  СВДЛИНА="РАЗМЕР";
  СВРЯД="ЗНАЧ";
ПЕР
  fieldListInx:ЦЕЛ;
  вид:ВД.ДкВиду;
УКАЗ
  ЕСЛИ
       пон.типОД # 0
  ТО
    ВОЗВРАТ
  КОН;
  ТипВид(пон.вид.овид);
  вид:=ВД.СоздатьВид(вДоступ);
  вид.овид:=пон.вид.овид;
  ТипДоступ(вид);
  fieldListInx:=ТипНачало(2+ДлинаТипСвойство(СВДЛИНА)+ДлинаТипСвойство(СВРЯД));
  ФО.КодЦел2(LF_FIELDLIST);
  ТипСвойство(4,0075H,СВДЛИНА); 
  ТипСвойство(0,вид.типОД,СВРЯД);
  ТипКонец;
  пон.типОД:=ТипНачало(6+РАЗМЕРТИПОД*3+6+1+ДлинаТекста(ИМЯВИДА));
  ФО.КодЦел2(LF_CLASS);
  ФО.КодЦел2(2);  (* CV:number of elements including methods and data members *)
  ФО.КодЦел2(0);  (* property list including:forward defs? nested classes?    *)
  ТипТипОД(fieldListInx);
  ФО.КодЦел4(0);  (* CV:should be set to 0 by compiler                        *)
  ФО.КодЦел4(0);  (* type index of virtual function table shape descriptor    *)
  ФО.КодЦел2(8004H);                            (* numeric leaf,unsigned long:*)
  ФО.КодЦел4(8);  (* размер набора *) 
  ЗаписьТекста(ИМЯВИДА);
  ТипКонец
КОН ТипОРядПриемникаПер;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТипБегунок(вид:ВД.ДкВиду);
УКАЗ
  вид.типОД:=ТипНачало(2+4+4+2+4+1);
  ФО.КодЦел2(LF_ARRAY);
  ФО.КодЦел4(22H);            (* переменные вида unsigned long *)
  ФО.КодЦел4(ARRAY_INX_TYPE); (* вид номера *)
  ФО.КодЦел2(08004H);         (* unsigned long numeric leaf: *)
  ФО.КодЦел4(3*4);            (* размер - 3 шт. по 4 байта: тек,нач,кон *)
  ФО.КодЦел1(0);              (* имя *)
  ТипКонец
КОН ТипБегунок;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТипНаборПриемникаПер(пон:ВД.ДкПонятию);
ПОСТ
  ИМЯВИДА="НАБОР";
  СВОВ="ОВ";
  СВДОСТУП="ДОСТУП";
ПЕР
  fieldListInx:ЦЕЛ;
  вид:ВД.ДкВиду;
УКАЗ
  ЕСЛИ
       пон.вид.типОД=0
  ТО
    ТипНабор(пон.вид)
  КОН;
  вид:=ВД.СоздатьВид(вДоступ);
  вид.овид:=пон.вид;
  ТипДоступ(вид);
  fieldListInx:=ТипНачало(2+ДлинаТипСвойство(СВОВ)+ДлинаТипСвойство(СВДОСТУП));
  ФО.КодЦел2(LF_FIELDLIST);
  ТипСвойство(0,0075H,СВОВ); (* uint32 *)
  ТипСвойство(4,вид.типОД,СВДОСТУП);
  ТипКонец;
  пон.типОД:=ТипНачало(6+РАЗМЕРТИПОД*3+6+1+ДлинаТекста(ИМЯВИДА));
  ФО.КодЦел2(LF_CLASS);
  ФО.КодЦел2(2);  (* CV:number of elements including methods and data members *)
  ФО.КодЦел2(0);  (* property list including:forward defs? nested classes?    *)
  ТипТипОД(fieldListInx);
  ФО.КодЦел4(0);  (* CV:should be set to 0 by compiler                        *)
  ФО.КодЦел4(0);  (* type index of virtual function table shape descriptor    *)
  ФО.КодЦел2(8004H);   (* numeric leaf,unsigned long:                         *)
  ФО.КодЦел4(8);  (* размер of structure *)
  ЗаписьТекста(ИМЯВИДА);
  ТипКонец
КОН ТипНаборПриемникаПер;

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

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

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТипПриемники( пон  :ВД.ДкПонятию;
                   типОД+,
              приёмников+ :ЦЕЛ);
ПЕР
           пон1:ВД.ДкПонятию;
УКАЗ
              приёмников:=0;
           пон1:=пон;
  ПОКА
           пон1 # ПУСТО
  ВЫП
    ЕСЛИ
           пон1.родп=пПрСсылки
    ТО
      ЕСЛИ пон1.типОД = 0 ТО ТипВидПриемникаПер(пон1) КОН
    ИНАЧЕ
      ЕСЛИ пон1.вид.типОД = 0 ТО ТипВид(пон1.вид) КОН
    КОН;
    УВЕЛИЧИТЬ(приёмников);
    пон1:=пон1.след
  КОН;
  типОД:=ТипНачало(2+4+приёмников*РАЗМЕРТИПОД);
  ФО.КодЦел2(LF_ARGLIST);
  ФО.КодЦел4(приёмников);

         пон1:=пон;
  ПОКА
         пон1 # ПУСТО
  ВЫП
    ЕСЛИ
         пон1.типОД # 0
    ТО
      ТипТипОД(пон1.типОД)
    ИНАЧЕ
      ТипТипОД(пон1.вид.типОД)
    КОН;
         пон1:=пон1.след
  КОН;
  ТипКонец
КОН ТипПриемники;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТипВидЗадач(вид:ВД.ДкВиду);
ПЕР
  типПриемников:ЦЕЛ;
     приёмников:ЦЕЛ;
УКАЗ
  ТипПриемники(вид.след,типПриемников,приёмников);
  ТипВид(вид.овид);
  вид.типОД:=ТипНачало(2+РАЗМЕРТИПОД+1+1+2+РАЗМЕРТИПОД);
  ФО.КодЦел2(LF_PROCEDURE);
  ТипТипОД(вид.овид.типОД);
  ФО.КодЦел1(2);
  ФО.КодЦел1(0);
  ФО.КодЦел2(приёмников);
  ТипТипОД(типПриемников);
  ТипКонец
КОН ТипВидЗадач;

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

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ТипПонятие(пон:ВД.ДкПонятию);
УКАЗ
  ЕСЛИ
       пон.типОД # 0
  ТО
    ВОЗВРАТ
  КОН;
  ВЫБРАТЬ пон.родп ИЗ
  | пПер:
      ТипВид(пон.вид)
  | пВид:
      ТипВид(пон.вид);
      пон.типОД:=пон.вид.типОД
  | пЗадача:
      ТипЗадача(пон)
  ИНАЧЕ
  КОН
КОН ТипПонятие;

ЗАДАЧА ТипПонятия(пон:ВД.ДкПонятию);
УКАЗ
  ЕСЛИ
       пон # ПУСТО
  ТО
    ТипПонятия(пон.лево);
    ТипПонятие(пон);
    ТипПонятия(пон.право)
  КОН
КОН ТипПонятия;


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

                                                        (* Запись CV символов *)
ЗАДАЧА^ СмвПонятия(пон:ВД.ДкПонятию);
ЗАДАЧА^ СмвПонятие(пон:ВД.ДкПонятию; верхнОбласть:КЛЮЧ);

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА СмвИмяФайла;
УКАЗ
  ФО.КодЦел2(6+ДлинаТекста(ФО.кодИмяФ)+1);
  ФО.КодЦел2(S_OBJNAME);
  ФО.КодЦел4(0); (* precompiled types *)
  ЗаписьТекста(ФО.кодИмяФ)
КОН СмвИмяФайла;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА СмвОПреобразователе;
УКАЗ
  ФО.КодЦел2(6+ДлинаТекста(ПРЕОБРАЗОВАТЕЛЬ)+1);
  ФО.КодЦел2(S_COMPILE);
  ФО.КодЦел1(03H); (* i386 *)
  ФО.КодЦел1(КОДЯЗЫКА);
  ФО.КодЦел1(20H); 
  ФО.КодЦел1(10H); 
  ЗаписьТекста(ПРЕОБРАЗОВАТЕЛЬ)
КОН СмвОПреобразователе;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА СмвВид(пон:ВД.ДкПонятию);
УКАЗ
  ЕСЛИ пон.типОД >= ПЕРВЫЙОПРЕДТИП ТО
    ФО.КодЦел2(6+ДлинаТекста(пон.имя)+1);
    ФО.КодЦел2(S_UDT);
    ФО.КодЦел4(пон.типОД);
    ЗаписьТекста(пон.имя)
  КОН
КОН СмвВид;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА СмвПерОтдела(пон:ВД.ДкПонятию);
ПЕР
  имя:ЦЕПЬ[2*НП.длинаНазвания+1];
УКАЗ
  СПИСАТЬ(НП.отдИмя,имя);
 оЦепи.ДобавитьВКонецЗнак(имя,"^");
 оЦепи.ДобавитьВКонец(имя,пон.имя);
  ФО.КодЦел2(12+ДлинаТекста(имя)+1);
  ЕСЛИ 
       прОбщедоступная В пон.признаки
  ТО
    ФО.КодЦел2(S_GDATA32)
  ИНАЧЕ
    ФО.КодЦел2(S_LDATA32) (* L *)
  КОН;
  ПРОВЕРИТЬ(пон.вид.типОД # 0);
  ФО.КодЦел4(пон.вид.типОД);
  Coff.СоздатьСкр(Coff.ОтлСмв,Coff.СКР_ОТНСЕКЦ,ВД.рПонВхОтд[0].адр+1,ФО.КодПозиция()-началоСекции);
  ФО.КодЦел4(пон.адр);
  Coff.СоздатьСкр(Coff.ОтлСмв,Coff.СКР_СЕКЦИЯ, ВД.рПонВхОтд[0].адр+1,ФО.КодПозиция()-началоСекции);
  ФО.КодЦел2(0); (* сегмент *)
  ЗаписьТекста(имя)
КОН СмвПерОтдела;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА СмвПерЗадачи(пон:ВД.ДкПонятию);
УКАЗ
    ФО.КодЦел2(10+ДлинаТекста(пон.имя)+1);
    ФО.КодЦел2(S_BPREL32);
    ФО.КодЦел4(пон.адр);
  ЕСЛИ
               пон.типОД # 0
  ТО                      (* типОД добавленный для пПрСсылки *)
    ФО.КодЦел4(пон.типОД)
  ИНАЧЕ
    ФО.КодЦел4(пон.вид.типОД)
  КОН;
  ЗаписьТекста(пон.имя)
КОН СмвПерЗадачи;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА СмвКонОбласти;
УКАЗ
  ФО.КодЦел2(2);
  ФО.КодЦел2(S_END)
КОН СмвКонОбласти;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА СмвКодЗадачи(пон:ВД.ДкПонятию);
ПЕР
  имя:ЦЕПЬ[2*НП.длинаНазвания+1];
УКАЗ
  ПРОВЕРИТЬ(пон.debugInfo # ПУСТО);
  СПИСАТЬ(НП.отдИмя,имя);
 оЦепи.ДобавитьВКонецЗнак(имя,"^");
 оЦепи.ДобавитьВКонец(имя,пон.имя);
  ФО.КодЦел2(37+ДлинаТекста(имя)+1);
  ЕСЛИ
       прОбщедоступная В пон.признаки
  ТО
    ФО.КодЦел2(S_GPROC32)
  ИНАЧЕ
    ФО.КодЦел2(S_LPROC32)
  КОН;
  ФО.КодЦел4(0); (* для CVPACK *)
  ФО.КодЦел4(0); (* для CVPACK *)
  ФО.КодЦел4(0); (* для CVPACK *)
  ФО.КодЦел4(пон.debugInfo.procLen);
  ФО.КодЦел4(пон.debugInfo.codeDebugStart);
  ФО.КодЦел4(пон.debugInfo.codeDebugEnd);
  ФО.КодЦел4(пон.типОД);
  Coff.СоздатьСкр(Coff.ОтлСмв,Coff.СКР_ОТНСЕКЦ,пон.адр,ФО.КодПозиция()-началоСекции);
  ФО.КодЦел4(0); (* смещение portion of задача address *)
  Coff.СоздатьСкр(Coff.ОтлСмв,Coff.СКР_СЕКЦИЯ,пон.адр,ФО.КодПозиция()-началоСекции);
  ФО.КодЦел2(0); (* section portion of задача address *)
  ФО.КодЦел1(0); (* задача flags:1 *)
  ЗаписьТекста(имя)
КОН СмвКодЗадачи;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА СмвЗадача(пон:ВД.ДкПонятию);
ПЕР
  пон1:ВД.ДкПонятию;

 (*........................................подЗАДАЧА....*)
  ЗАДАЧА ВложенныеЗадачи(пон:ВД.ДкПонятию);
  УКАЗ
    ЕСЛИ
                         пон # ПУСТО
    ТО
         ВложенныеЗадачи(пон.лево);
      ЕСЛИ
           прВложенная В пон.признаки
      ТО
               СмвЗадача(пон)
      КОН;
         ВложенныеЗадачи(пон.право)
    КОН
  КОН ВложенныеЗадачи;

УКАЗ
  СмвКодЗадачи(пон);
  пон1:=пон.след;            (* приёмники *)
  ПОКА пон1 # ПУСТО ВЫП
    СмвПонятие(пон1,ОТКЛ);
    пон1:=пон1.след
  КОН;
  пон1:=пон.область.область; (* внутренние переменные *)
  ПОКА пон1 # ПУСТО ВЫП
    СмвПонятие(пон1,ОТКЛ);
    пон1:=пон1.след
  КОН;
  ВложенныеЗадачи(пон.область.право);
  СмвКонОбласти
КОН СмвЗадача;

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

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА СмвПонятия(пон:ВД.ДкПонятию);
УКАЗ
  ЕСЛИ
       пон # ПУСТО
  ТО
    СмвПонятия(пон.лево);
    СмвПонятие(пон,ВКЛ);
    СмвПонятия(пон.право)
  КОН
КОН СмвПонятия;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Запись-;
    (* Запись совместимых с CV отладочных данных *)
ПЕР
  ц:ЦЕЛ;
УКАЗ
  следТипОД:=ПЕРВЫЙОПРЕДТИП;
  ФО.КодРовно4;
  началоСекции:=ФО.КодПозиция();
  Coff.StartDebugTypes;
  ФО.КодЦел4(КОДФОРМАТА);
  ОТ ц:=0 ДО ВсегоТиповОД-1 ВЫП
    неоТипы[ц].занят:=ОТКЛ
  КОН;
  ТипПонятия(ВД.текОбласть.право);
  Coff.EndDebugTypes(ФО.КодПозиция()-началоСекции);
  началоСекции:=ФО.КодПозиция();
  Coff.StartDebugSymbols;
  ФО.КодЦел4(КОДФОРМАТА);
  СмвИмяФайла;
  СмвОПреобразователе;
  СмвПонятия(ВД.текОбласть.право);
  Coff.EndDebugSymbols(ФО.КодПозиция()-началоСекции)
КОН Запись;

(*-ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss-*)
УКАЗ
                               (* встроенные виды *)                    
  ВД.ключвид   .типОД:=0030H;
  ВД.знаквид   .типОД:=0071H;
  ВД.множвид   .типОД:=0022H;
  ВД.цел8вид   .типОД:=0020H;
  ВД.цел16вид  .типОД:=0011H;
  ВД.цел32вид  .типОД:=0012H;
  ВД.цел64вид  .типОД:=0013H;
  ВД.вещ32вид  .типОД:=0040H;
  ВД.вещ64вид  .типОД:=0041H;
  ВД.нетвид    .типОД:=0003H;
  ВД.оячвид    .типОД:=0020H;
  ВД.одоствид  .типОД:=0403H
КОН CV.
