we can now self-host :tada:
[jackhill/mal.git] / impls / xslt / printer.xslt
CommitLineData
bfae91cc 1<?xml version="1.0" encoding="UTF-8"?>
342a5b36 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">
bfae91cc
A
3 <!-- expects input as a single <value><malval .../></value> -->
4 <!-- output of form <value>literal string</value> -->
5 <xsl:template name="malprinter-pr_str">
78ec3e62
A
6 <xsl:param name="readably" as="xs:boolean" />
7
bfae91cc 8 <xsl:variable name="value">
ab29f6bd
A
9 <xsl:sequence select="value/malval" />
10 <xsl:sequence select="atoms"/>
bfae91cc
A
11 </xsl:variable>
12 <xsl:for-each select="$value">
13 <xsl:choose>
cdb02176
A
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>
bfae91cc
A
23 <xsl:when test="malval/@kind = 'string'">
24 <value>
342a5b36 25 <xsl:value-of select="concat(if ($readably) then '&quot;' else '', fn:desc_string(malval/@value, $readably), if ($readably) then '&quot;' else '')" />
bfae91cc
A
26 </value>
27 </xsl:when>
cdb02176
A
28 <xsl:when test="malval/@kind = 'keyword'">
29 <value>
30 <xsl:value-of select="concat(':', malval/@value)" />
31 </value>
32 </xsl:when>
bfae91cc
A
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">
78ec3e62 50 <xsl:call-template name="malprinter-pr_str"><xsl:with-param name="readably" select="$readably"/></xsl:call-template>
bfae91cc
A
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>
e1deef63
A
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>
296cab4c 94 <xsl:when test="malval/@kind = 'function'">
b86f74e4 95 <value>
0365ac12
A
96 <xsl:variable name="gt">?</xsl:variable>
97 <xsl:variable name="lt">?</xsl:variable>
296cab4c 98 <xsl:value-of select="concat('#', $lt, 'fn ', malval/@name, $gt)" />
b86f74e4
A
99 </value>
100 </xsl:when>
342a5b36
A
101 <xsl:when test="malval/@kind = 'userfunction'">
102 <value>
0365ac12
A
103 <xsl:variable name="gt">?</xsl:variable>
104 <xsl:variable name="lt">?</xsl:variable>
342a5b36
A
105 <xsl:value-of select="concat('#', $lt, 'function', $gt)" />
106 </value>
107 </xsl:when>
ab29f6bd
A
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>
0365ac12 121 <xsl:value-of select="concat('(atom ', (let $v := $inner/value return if ($v = 'Unknown') then concat('id=', string($val/@value), ' existing=', string-join(atoms/atom/@identity, ',')) else $v), ')')" />
ab29f6bd
A
122 </value>
123 </xsl:when>
bfae91cc 124 <xsl:otherwise>
0365ac12 125 <value>Unknown</value>
bfae91cc
A
126 </xsl:otherwise>
127 </xsl:choose>
128 </xsl:for-each>
129 </xsl:template>
130
78ec3e62
A
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>
342a5b36 135 <xsl:when test="($readable)">
78ec3e62 136 <xsl:variable name="sx">
342a5b36 137 <xsl:analyze-string select="$str" regex="(\\|&quot;|&#10;)">
78ec3e62
A
138 <xsl:matching-substring>
139 <x>
140 <xsl:choose>
342a5b36
A
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;'" />
78ec3e62
A
146 </xsl:when>
147 <xsl:otherwise>
342a5b36 148 <xsl:value-of select="'\n'" />
78ec3e62
A
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>
0365ac12 163</xsl:stylesheet>