Execute HQ9+: Difference between revisions
Content added Content deleted
(Stub for XSLT) |
|||
Line 1,103: | Line 1,103: | ||
===XSLT 1.0=== |
===XSLT 1.0=== |
||
====Basic implementation==== |
|||
(This section is currently being added.) |
|||
Requires <code>bottles.xsl</code> (below). |
|||
<lang xml><?xml version="1.0"?> |
|||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> |
|||
<!-- bottles.xsl defines $entire-bottles-song --> |
|||
<xsl:import href="bottles.xsl"/> |
|||
<xsl:output method="text" encoding="utf-8"/> |
|||
<xsl:variable name="hello-world"> |
|||
<xsl:text>Hello, world! </xsl:text> |
|||
</xsl:variable> |
|||
<!-- Main template --> |
|||
<xsl:template match="/"> |
|||
<xsl:call-template name="run"> |
|||
<xsl:with-param name="code" select="string(.)"/> |
|||
</xsl:call-template> |
|||
</xsl:template> |
|||
<!-- Runs HQ9+ code from string starting at given index (default 1) --> |
|||
<xsl:template name="run"> |
|||
<xsl:param name="code"/> |
|||
<xsl:param name="starting-at" select="1"/> |
|||
<!-- Fetches instruction and forces to upper-case --> |
|||
<xsl:variable name="inst" select="translate(substring($code, $starting-at, 1), 'hq', 'HQ')"/> |
|||
<!-- Only if not at end --> |
|||
<xsl:if test="$inst != ''"> |
|||
<xsl:choose> |
|||
<xsl:when test="$inst = 'H'"> |
|||
<xsl:value-of select="$hello-world"/> |
|||
</xsl:when> |
|||
<xsl:when test="$inst = 'Q'"> |
|||
<xsl:value-of select="$code"/> |
|||
<xsl:text> </xsl:text> |
|||
</xsl:when> |
|||
<xsl:when test="$inst = '9'"> |
|||
<xsl:value-of select="$entire-bottles-song"/> |
|||
</xsl:when> |
|||
<xsl:when test="$inst = '+'"> |
|||
<!-- XSLT has no meaningful equivalent of write-only variables --> |
|||
</xsl:when> |
|||
<!-- Otherwise, do nothing --> |
|||
</xsl:choose> |
|||
<!-- Proceed with next instruction --> |
|||
<xsl:call-template name="run"> |
|||
<xsl:with-param name="code" select="$code"/> |
|||
<xsl:with-param name="starting-at" select="$starting-at + 1"/> |
|||
</xsl:call-template> |
|||
</xsl:if> |
|||
</xsl:template> |
|||
</xsl:stylesheet></lang> |
|||
=====Details===== |
|||
Input to this sheet is given by placing the entire source as a single <code><nowiki><code/></nowiki></code> element. For example, to run the example program <code>qqqq</code>, use the sheet to transform the document |
|||
<lang xml><code>qqqq</code></lang> |
|||
Newlines are added in roughly the same places as in the C version. For example, the program <code>qqqq</code> results in four lines of output rather than one long line. |
|||
XSLT has no meaningful way to process a write-only variable like the accumulator, so <code>+</code> is a no-op. |
|||
Characters other than <code>HQhq9+</code> are no-ops, but are echoed verbatim by <code>Q</code>/<code>q</code>. |
|||
====bottles.xsl==== |
|||
This sheet defines a value for the variable <code>$entire-bottles-song</code> (see [[99 Bottles of Beer]] for the general idea). |
|||
<lang xml><?xml version="1.0"?> |
|||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:lo="urn:uuid:59afd337-03a8-49d9-a7a8-8e2cbc4ef9cc"> |
|||
<!-- Note: xmlns:lo is defined as a sort of pseudo-private namespace --> |
|||
<!-- Given a count and a suffix (default " on the wall"), renders one number-containing line of the bottles song --> |
|||
<xsl:template name="lo:line"> |
|||
<xsl:param name="count"/> |
|||
<xsl:param name="suffix"> on the wall</xsl:param> |
|||
<xsl:value-of select="$count"/> |
|||
<xsl:text> bottle</xsl:text> |
|||
<xsl:if test="$count != 1">s</xsl:if> |
|||
<xsl:text> of beer</xsl:text> |
|||
<xsl:value-of select="$suffix"/> |
|||
<xsl:text> </xsl:text> |
|||
</xsl:template> |
|||
<!-- Given a count, renders one verse of the bottles song --> |
|||
<xsl:template name="lo:verse"> |
|||
<xsl:param name="count"/> |
|||
<xsl:call-template name="lo:line"> |
|||
<xsl:with-param name="count" select="$count"/> |
|||
</xsl:call-template> |
|||
<xsl:call-template name="lo:line"> |
|||
<xsl:with-param name="count" select="$count"/> |
|||
<!-- empty suffix for this line --> |
|||
<xsl:with-param name="suffix"/> |
|||
</xsl:call-template> |
|||
<xsl:text>Take one down, pass it around </xsl:text> |
|||
<xsl:call-template name="lo:line"> |
|||
<xsl:with-param name="count" select="$count - 1"/> |
|||
</xsl:call-template> |
|||
<xsl:text> </xsl:text> |
|||
</xsl:template> |
|||
<!-- Given a starting count, renders the entire bottles song --> |
|||
<xsl:template name="lo:song"> |
|||
<xsl:param name="count"/> |
|||
<xsl:if test="$count > 0"> |
|||
<xsl:call-template name="lo:verse"> |
|||
<xsl:with-param name="count" select="$count"/> |
|||
</xsl:call-template> |
|||
<xsl:call-template name="lo:song"> |
|||
<xsl:with-param name="count" select="$count - 1"/> |
|||
</xsl:call-template> |
|||
</xsl:if> |
|||
</xsl:template> |
|||
<!-- The entire bottles song --> |
|||
<xsl:variable name="entire-bottles-song"> |
|||
<xsl:call-template name="lo:song"> |
|||
<xsl:with-param name="count" select="99"/> |
|||
</xsl:call-template> |
|||
</xsl:variable> |
|||
</xsl:stylesheet></lang> |
|||
=={{header|zkl}}== |
=={{header|zkl}}== |