99 бутылок: XSLT и TBC
39. TBC (Tokiwa BASIC Compiler). Эта бесплатная версия компилятора является урезанной версией коммерческого компилятора TWK-86BC и написал её японец Tokiwa.
Компилятор умеет компилировать код в COM и DOS EXE-файлы и интересен тем, что имеет интеграцию со встроенным ассемблером и довольно развитый интересный синтаксис, основанный на языке BASIC. Например, присутствует оператор DefInt, который сообщает компилятору, что переменные, начинающиеся с заданных оператором букв, имеют целочисленный тип.
Есть блочные конструкции, операторы обработки ошибок, выбора альтернативы (on ... goto ...), поддержка строк и меток, в связи с чем поддерживаются как обычные процедуры и функции, так и переходы по номерам строк. Предусмотрены операторы ввода-вывода для работы с устройствами DOS и файлами и многое другое.
Кстати, что неприятно удивило — возвращаемым значением для процедур и функций (кстати, можно сказать, что процедуры и функции тут различаются только ключевыми словами) может быть только числовое значение.
Программа, выводящая песню о пиве (beer.tkw)
* Beer song. Written by Evgeny Stepanischev
Integer I
Character S
For I=99 To 1 Step -1
Call Beer(I)
Print S; " on the wall, ";S;"."
Print "Take one and pass around,"
Call Beer(I-1)
Print S; " on the wall." : Print
Next I
Print "No more bottles of beer..."
Print "Go to the store and buy some more..."
Print "99 bottles of beer."
SubRoutine Beer(I)
Integer I
If I=0 Then S="No" Else S=Str$(%1I I)
S=S+" bottle"
If I<>1 Then S=S+"s"
S=S+" of beer"
Return
SubEnd
End
38. XSLT. Язык преобразований одного XML-документа в другой, основанный на XML же. Написано о нём достаточно много, так что останавливаться на нём не буду. Это, в отличие от большинства языков, на которых я программировал — декларативный язык. Строго говоря, XSLT мёртв без другого языка — XPath, языка выборки. С его помощью, например, выполняются все вычисления. В парсерах первых версий нет циклов, что кажется несколько странным, так что мне пришлось использовать рекурсию. Кстати, наиболее странное в XSLT другое — однажды объявленная переменная больше не может менять своего значения. Это ограничение обходят при помощи рекурсии и использования локальных переменных.
Запустить скрипт на выполнение можно, сохранив листинг в файл beer.xml и открыв его браузером Internet Explorer.
Программа, выводящая песню о пиве (beer.xml)
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="#beer"?>
<!-- Beer song. Written by Evgeny Stepanischev -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
id="beer">
<xsl:output method="html"/>
<xsl:strip-space elements="*"/>
<xsl:template name="beer">
<xsl:param name="n"/>
<xsl:choose>
<xsl:when test="boolean($n)">
<xsl:value-of select="$n"/>
</xsl:when>
<xsl:otherwise>
No
</xsl:otherwise>
</xsl:choose>
<xsl:text> bottle</xsl:text>
<xsl:if test="boolean($n - 1)">
<xsl:text>s</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template name="while" match="/">
<xsl:param name="i" select="99"/>
<xsl:choose>
<xsl:when test="$i != 0">
<xsl:variable name="str">
<xsl:call-template name="beer">
<xsl:with-param name="n" select="$i"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$str"/>
<xsl:text> on the wall, </xsl:text>
<xsl:value-of select="$str"/>
<xsl:text> of beer.</xsl:text><br />
<xsl:text>Take one and pass around,</xsl:text><br />
<xsl:call-template name="beer">
<xsl:with-param name="n" select="$i - 1"/>
</xsl:call-template>
<xsl:text> on the wall.</xsl:text><br /><br />
<xsl:call-template name="while">
<xsl:with-param name="i" select="$i - 1"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
No more bottles of beer...<br />
Go to the store and buy some more...<br />
99 bottles of beer.
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>