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!&#10;</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>&#10;</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>&#10;</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&#10;</xsl:text>
<xsl:call-template name="lo:line">
<xsl:with-param name="count" select="$count - 1"/>
</xsl:call-template>
<xsl:text>&#10;</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 &gt; 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}}==