$ENTRY Go {
       = <Open 'w' 5 'testtime.txt'>
         <Putout 5 <TIME >>
         <XI ('xi9.xsl')>
         <Putout 5 <TIME >>
         ;
         }

/*
        Интерпретатор XSLT, написанный с целью его суперкомпиляции.
        Экспериментальная версия, обладающая рядом недостатков:
        - не обрабатываются тэги вида  <! ... > , <? ... ?>,
        -                    условные операторы,
        -                    сортировка.
        Проще перечислить, что обрабатывается - это видно
        по тексту программы. 
*/

*  Функции, используемые на этапе суперкомпиляции.
*           Преобразование в составные символы:
$EXTRN XiImpl;
*$EXECUTABLE XiImpl;
*           Обращение к парсеру из XML в рефал:
$EXTRN XML_REF2;
*$EXECUTABLE XML_REF2;

*  Функции, используемые на этапе исполнения
*  построенной суперкомпилятором программы.
*           Реализация (xsl:value-of select= e.Tag):
$EXTRN Get_In;
*           Парсер в рефал-выражение:
$EXTRN XML_REF1;
*           Парсер из рефала в XML:
$EXTRN REF_XML;

/*
      Один из способов организации работы суперкомпилятора 
      на неигрушечном примере.
      e.NameXSLT - наименование файла e.XSLT, содержащего трансформации,
      e.NameXML  - наименование трансформируемого файла e.XML.
      Оба они преобразутся парсером в рефал-выражение, но
      e.XSLT на этапе суперкомпиляции, а 
      e.XML  на этапе выполнения порожденной SCP4 программы.
      Поэтому приходится вынужденно вводить два имени функции
      парсера XML_REF.
      REF_XML - обратный парсер, переводит результат работы программы,
      порожденной SCP4, в XML.
*/

XI {
  (e.NameXSLT) , <XML_REF2 e.NameXSLT>: e.XSLTa
               , <XiImpl e.XSLTa>: e.XSLT
               , <XML_REF1 >: e.XML 
               = <REF_XML <XIBegin (e.XSLT) (e.XML) >>;
     }

XIBegin {
  (((Xsl Stylesheet e.1) e.2)) (e.XML) = <Apply Fict (e.2) (e.XML) (e.2)>;
        }

* Нахождение (Xsl Template (Match Is s.Tag1))
* Формат обращения:
*  <Apply s.Tag (e.XSLT) (e.XML) (e.ALL)>
*    где  s.Tag - текущий тэг,
*         e.All - начальный e.XSLT, который не меняется
*                 в процессе суперкомпиляции.

Apply {
   s.Tag (e.XSLT) (s.a e.1) (e.All) =
                s.a <Apply s.Tag (e.XSLT) (e.1) (e.All)>;

   s.Tag (e.XSLT) ( ) (e.All) = ;

   s.Tag (((Xsl Template (Match Is s.Tag s.Tag1)) e.1) e.2)
         (((s.Tag1) e.In) e.on) (e.All) =
                <Int s.Tag1 (e.1) (e.In) (e.All)>
                <Apply s.Tag (e.All) (e.on) (e.All)>;

  s.Tag (((Xsl Template (Match Is s.Tag1 s.Tag2)) e.1) e.2)
         (((s.Tag3) e.In) e.on) (e.All) =
                <Apply s.Tag (e.2) (((s.Tag3) e.In) e.on) (e.All)>;


   s.Tag (((Xsl Template (Match Is s.Tag1)) e.1) e.2)
         (((s.Tag1) e.In) e.on) (e.All) =
                <Int s.Tag1 (e.1) (e.In) (e.All)>
                <Apply s.Tag (e.All) (e.on) (e.All)>;

   s.Tag (((Xsl Template (Match Is s.Tag1)) e.1) e.2)
         (((s.Tag2) e.In) e.on) (e.All) =
                <Apply s.Tag (e.2) (((s.Tag2) e.In) e.on) (e.All)>;

   s.Tag ( ) (((s.Tag2) e.In) e.on) (e.All) = 
                <Apply s.Tag (e.All) (e.on) (e.All)>;

      }

* Интерпретатор одного (Xsl Template (Match Is s.Tag1))

Int {
  s.Tag ( ) (e.XML) (e.All) = ;
  s.Tag (s.a e.1) (e.XML) (e.All) = s.a <Int s.Tag (e.1) (e.XML) (e.All)>;

  s.Tag (((Xsl e.XSLT) e.2) e.3) (e.XML) (e.All) =
             <IntXsl s.Tag ((Xsl e.XSLT) e.2) (e.XML) (e.All)>
             <Int s.Tag (e.3) (e.XML) (e.All)>;

  s.Tag (((e.1) e.2) e.3) (e.XML) (e.All) =
             ((e.1) <Int s.Tag (e.2) (e.XML) (e.All)> )
             <Int s.Tag (e.3) (e.XML) (e.All)>;
    }

* Обработка одного правила трансформаций

IntXsl {
  s.Tag ((Xsl Apply-templates)) (e.XML) (e.All) =
               <Apply s.Tag (e.All) (e.XML) (e.All)>;

  s.Tag ((Xsl Element (Name Is e.N)) e.1) (e.XML) (e.All) =
               <Elem (e.N) <Int s.Tag (e.1) (e.XML) (e.All)>>;

  s.Tag ((Xsl Attribute (Name Is e.N)) e.1) (e.XML) (e.All) =
               (Attr e.N Is <Int s.Tag (e.1) (e.XML) (e.All)>);

  s.Tag ((Xsl For-each (Select Is s.Tag1)) e.1) 
        (((s.Tag1 e.0) e.In) e.on) (e.All) = 
               <Int s.Tag1 (e.1) (e.In) (e.All)>
               <IntXsl s.Tag  ((Xsl For-each (Select Is s.Tag1)) e.1)
                              (e.on) (e.All)>;

  s.Tag ((Xsl For-each (Select Is s.Tag1)) e.1) 
        ((e.In) e.on) (e.All) = 
               <IntXsl s.Tag  ((Xsl For-each (Select Is s.Tag1)) e.1)
                              (e.on) (e.All)>;

  s.Tag ((Xsl For-each (Select Is s.Tag1)) e.1) ( ) (e.All) = ;

  s.Tag ((Xsl Value-of (Select Is  e.Tag1))) (e.In) (e.All),
                           <Get_In (e.Tag1) e.In>:e.n = e.n; 
*   e.1 = e.1;
    }

Elem {
*   только один Attribute
    (e.N) (Attr e.1) e.2 = ((e.N (e.1)) e.2);
     }