<?xml version="1.0"?>
<xsl:stylesheet
   xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
   xmlns:html="http://www.w3.org/TR/REC-html40" 
   version="1.0" >

<!-- Generate C++/C code from MathML declarations.
-->

<xsl:output method="text"/>
<xsl:variable name="currentFn">currentFn</xsl:variable> 
<xsl:variable name="defaultReturnType">double</xsl:variable> 
<xsl:variable name="globalVars"> </xsl:variable> 

 <!-- function declaration -->
 <xsl:template match="declare[@type='fn']">
  <xsl:value-of select="$defaultReturnType"/> 
  <xsl:value-of select="ci[position()=1]"/>
  <xsl:apply-templates select="lambda"/>
 </xsl:template>

 <!-- function body -->
 <xsl:template match="lambda">
   (/*args*/ <xsl:apply-templates select="bvar/ci"/> ) {
    return 
    <xsl:apply-templates select="*[name()!='bvar']"/>
  ;} //end of lambda
  </xsl:template>

 <!-- expressions are translated by functions calls -->
 <xsl:template match="apply[ancestor::lambda|ancestor::condition]">
  <!-- distinguish between applying a predefined or a local function -->
  <xsl:variable name="applyName"><xsl:value-of select="name(*[position()=1])"/> </xsl:variable>
  <xsl:variable name="functionName">
  <xsl:choose>
   <xsl:when test="$applyName = 'ci'">
     <xsl:value-of select="ci"/>
   </xsl:when>
  <xsl:otherwise> 
   <xsl:value-of select="$applyName"/>
  </xsl:otherwise> 
  </xsl:choose> 
  </xsl:variable>
  <xsl:value-of select="$functionName"/> 
  ( <xsl:apply-templates select="*[position() &gt; 1]" /> )
  <xsl:if test="position() &lt; last()">, </xsl:if>
 </xsl:template>

 <!-- take care of commas at end of function arguments - 
 CAUTION: not very robust, the caller must select apropriately 
 -->
 <xsl:template match="ci[ancestor::lambda|ancestor::condition|ancestor::bvar]" >
   <xsl:apply-templates/>
   <xsl:if test="position() &lt; last()">, </xsl:if>
 </xsl:template>

 <!-- called by set -->
 <xsl:template match="condition">
  bool condition ( <xsl:apply-templates select="../bvar//ci" /> ){
  return <xsl:apply-templates select="apply" />;} //end of condition
 </xsl:template>

 <xsl:template match="set">
  <xsl:variable name="currentSet">
  <xsl:choose>
   <xsl:when test="name(..)='declare'">
     <xsl:value-of select="../ci"/>
   </xsl:when>
   <xsl:otherwise>
 set_<xsl:value-of select="generate-id(.)"/>
   </xsl:otherwise>
  </xsl:choose>
  </xsl:variable>
class <xsl:value-of select="$currentSet"/>
 : public math::Set&lt;math::R3&gt; {
  public:
     <xsl:apply-templates select="condition"/>
  };
 </xsl:template>

 <!-- declare C++ variables -->
 <xsl:template match="declare">
  <xsl:apply-templates select="set" />
  <xsl:if test="ci and not(set)">
   <xsl:if test="not(@type)">
    double <xsl:value-of select="ci"/> ;
   </xsl:if>
   <xsl:if test="@type='set'">
math::Set&lt;math::R3&gt;* <xsl:value-of select="ci[1]"/> = new <xsl:value-of select="ci[2]"/> ; 
   </xsl:if>
  </xsl:if>
 </xsl:template>

 <!-- assignments of 1srt level variables -->
 <xsl:template match="apply[not(ancestor::lambda|ancestor::condition)]">
  <xsl:apply-templates select="*[2]"/> = <xsl:apply-templates select="*[3]"/> ;
 </xsl:template>

 <!-- recursive copy engine -->
 <xsl:template match="*|@*">
  <xsl:copy>
    <xsl:apply-templates />
  </xsl:copy>
 </xsl:template>

 <!-- top-level -->
 <xsl:template match="/"> 
   <container>
     <xsl:apply-templates/>
   </container>
 </xsl:template>
</xsl:stylesheet> 