(*~\Глагол\ПриложенияLink\МПГ2008 (комп., но не раб.)\~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                                            ОТДЕЛ Рег;
(*============================================================================* 
 * НАЗНАЧЕНИЕ: управление машинными регистрами
 *============================================================================*)

ИСПОЛЬЗУЕТ
  Ошибка;

ПОСТ
                                     (* назначение регистров *)
  PC- = 15; (* счётчик команд   *)
  LR- = 14; (* адрес возврата   *)
  SP- = 13; (* указатель стога  *)
  FP- = 12; (* указатель окна   *)

  РОН = 11; (* последний РОН    *)

ПЕР
     мРЕГов:МНОЖ;(* множество занятых РОНов *)
  нужныйРег:ЦЕЛ;                   (* РОН который хотят занять в следующий раз *)


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

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Заняты-():МНОЖ;                         (* возвращает занятые регистры *)
УКАЗ
  ВОЗВРАТ мРЕГов
КОН Заняты;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Освободить-(рег:ЦЕЛ);          (* освобождает регистр, даже если > РОН *)
УКАЗ
   мРЕГов:=мРЕГов-{рег}
КОН Освободить;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Нужен-(рег:ЦЕЛ);                               (* выставляет нужныйРег *)
УКАЗ
   нужныйРег:=рег
КОН Нужен;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА БудутЗаняты-(занРеги:МНОЖ);               (* выставляет занятые регистры *)
УКАЗ
            мРЕГов:=занРеги
КОН БудутЗаняты;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Обновить-;
УКАЗ
       мРЕГов:={};
  нужныйРег  := -1;
КОН Обновить;

КОН Рег.
