impl step6
[jackhill/mal.git] / xslt / printer.xslt
1 <?xml version="1.0" encoding="UTF-8"?>
2 <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/02/xpath-functions" exclude-result-prefixes="xsl xs fn">
3 <!-- expects input as a single <value><malval .../></value> -->
4 <!-- output of form <value>literal string</value> -->
5 <xsl:template name="malprinter-pr_str">
6 <xsl:param name="readably" as="xs:boolean" />
7
8 <xsl:variable name="value">
9 <xsl:sequence select="value/malval" />
10 <xsl:sequence select="atoms"/>
11 </xsl:variable>
12 <xsl:for-each select="$value">
13 <xsl:choose>
14 <xsl:when test="malval/@kind = 'true'">
15 <value>true</value>
16 </xsl:when>
17 <xsl:when test="malval/@kind = 'false'">
18 <value>false</value>
19 </xsl:when>
20 <xsl:when test="malval/@kind = 'nil'">
21 <value>nil</value>
22 </xsl:when>
23 <xsl:when test="malval/@kind = 'string'">
24 <value>
25 <xsl:value-of select="concat(if ($readably) then '&quot;' else '', fn:desc_string(malval/@value, $readably), if ($readably) then '&quot;' else '')" />
26 </value>
27 </xsl:when>
28 <xsl:when test="malval/@kind = 'keyword'">
29 <value>
30 <xsl:value-of select="concat(':', malval/@value)" />
31 </value>
32 </xsl:when>
33 <xsl:when test="malval/@kind = 'symbol'">
34 <value>
35 <xsl:value-of select="malval/@value" />
36 </value>
37 </xsl:when>
38 <xsl:when test="malval/@kind = 'number'">
39 <value>
40 <xsl:value-of select="malval/@value" />
41 </value>
42 </xsl:when>
43 <xsl:when test="malval/@kind = 'list'">
44 <xsl:variable name="val">
45 <xsl:for-each select="malval/lvalue/malval">
46 <xsl:variable name="ctx">
47 <value><xsl:copy-of select="." /></value>
48 </xsl:variable>
49 <xsl:for-each select="$ctx">
50 <xsl:call-template name="malprinter-pr_str"><xsl:with-param name="readably" select="$readably"/></xsl:call-template>
51 </xsl:for-each>
52 </xsl:for-each>
53 </xsl:variable>
54 <xsl:for-each select="$val">
55 <value>
56 <xsl:value-of select="concat('(', string-join(/value, ' '), ')')" />
57 </value>
58 </xsl:for-each>
59 </xsl:when>
60 <xsl:when test="malval/@kind = 'vector'">
61 <xsl:variable name="val">
62 <xsl:for-each select="malval/lvalue/malval">
63 <xsl:variable name="ctx">
64 <value><xsl:copy-of select="." /></value>
65 </xsl:variable>
66 <xsl:for-each select="$ctx">
67 <xsl:call-template name="malprinter-pr_str"><xsl:with-param name="readably" select="$readably"/></xsl:call-template>
68 </xsl:for-each>
69 </xsl:for-each>
70 </xsl:variable>
71 <xsl:for-each select="$val">
72 <value>
73 <xsl:value-of select="concat('[', string-join(/value, ' '), ']')" />
74 </value>
75 </xsl:for-each>
76 </xsl:when>
77 <xsl:when test="malval/@kind = 'hash'">
78 <xsl:variable name="val">
79 <xsl:for-each select="malval/lvalue/malval">
80 <xsl:variable name="ctx">
81 <value><xsl:copy-of select="." /></value>
82 </xsl:variable>
83 <xsl:for-each select="$ctx">
84 <xsl:call-template name="malprinter-pr_str"><xsl:with-param name="readably" select="$readably"/></xsl:call-template>
85 </xsl:for-each>
86 </xsl:for-each>
87 </xsl:variable>
88 <xsl:for-each select="$val">
89 <value>
90 <xsl:value-of select="concat('{', string-join(/value, ' '), '}')" />
91 </value>
92 </xsl:for-each>
93 </xsl:when>
94 <xsl:when test="malval/@kind = 'function'">
95 <value>
96 <xsl:variable name="gt">&gt;</xsl:variable>
97 <xsl:variable name="lt">&lt;</xsl:variable>
98 <xsl:value-of select="concat('#', $lt, 'fn ', malval/@name, $gt)" />
99 </value>
100 </xsl:when>
101 <xsl:when test="malval/@kind = 'userfunction'">
102 <value>
103 <xsl:variable name="gt">&gt;</xsl:variable>
104 <xsl:variable name="lt">&lt;</xsl:variable>
105 <xsl:value-of select="concat('#', $lt, 'function', $gt)" />
106 </value>
107 </xsl:when>
108 <xsl:when test="malval/@kind = 'atom'">
109 <xsl:variable name="val" select="malval"></xsl:variable>
110 <xsl:variable name="inner">
111 <xsl:variable name="ctx">
112 <value>
113 <xsl:sequence select="atoms/atom[@identity = $val/@value]/malval"/>
114 </value>
115 </xsl:variable>
116 <xsl:for-each select="$ctx">
117 <xsl:call-template name="malprinter-pr_str"><xsl:with-param name="readably" select="$readably"/></xsl:call-template>
118 </xsl:for-each>
119 </xsl:variable>
120 <value>
121 <xsl:value-of select="concat('(atom ', $inner/value, ')')" />
122 </value>
123 </xsl:when>
124 <xsl:otherwise>
125 <value>Unknown <xsl:copy-of select="." /></value>
126 </xsl:otherwise>
127 </xsl:choose>
128 </xsl:for-each>
129 </xsl:template>
130
131 <xsl:function name="fn:desc_string" as="xs:string">
132 <xsl:param name="str" as="xs:string" />
133 <xsl:param name="readable" as="xs:boolean" />
134 <xsl:choose>
135 <xsl:when test="($readable)">
136 <xsl:variable name="sx">
137 <xsl:analyze-string select="$str" regex="(\\|&quot;|&#10;)">
138 <xsl:matching-substring>
139 <x>
140 <xsl:choose>
141 <xsl:when test="regex-group(1) = '\'">
142 <xsl:value-of select="'\\'" />
143 </xsl:when>
144 <xsl:when test="regex-group(1) = '&quot;'">
145 <xsl:value-of select="'\&quot;'" />
146 </xsl:when>
147 <xsl:otherwise>
148 <xsl:value-of select="'\n'" />
149 </xsl:otherwise>
150 </xsl:choose>
151 </x>
152 </xsl:matching-substring>
153 <xsl:non-matching-substring><x><xsl:value-of select="." /></x></xsl:non-matching-substring>
154 </xsl:analyze-string>
155 </xsl:variable>
156 <xsl:value-of select="string-join($sx/x, '')" />
157 </xsl:when>
158 <xsl:otherwise>
159 <xsl:value-of select="$str" />
160 </xsl:otherwise>
161 </xsl:choose>
162 </xsl:function>
163 </xsl:stylesheet>